feat(api): add bulk user creation endpoint
This commit is contained in:
@ -1,5 +1,6 @@
|
||||
import re
|
||||
from typing import Optional, List
|
||||
from pydantic import BaseModel, RootModel, Field
|
||||
from pydantic import BaseModel, RootModel, Field, field_validator
|
||||
|
||||
|
||||
class UserInfoResponse(BaseModel):
|
||||
@ -26,6 +27,27 @@ class AddUserInputBody(BaseModel):
|
||||
creation_date: Optional[str] = None
|
||||
unlimited: bool = False
|
||||
|
||||
@field_validator('username')
|
||||
def validate_username(cls, v):
|
||||
if not re.match(r"^[a-zA-Z0-9_]+$", v):
|
||||
raise ValueError('Username can only contain letters, numbers, and underscores.')
|
||||
return v
|
||||
|
||||
|
||||
class AddBulkUsersInputBody(BaseModel):
|
||||
traffic_gb: float
|
||||
expiration_days: int
|
||||
count: int
|
||||
prefix: str
|
||||
start_number: int = 1
|
||||
unlimited: bool = False
|
||||
|
||||
@field_validator('prefix')
|
||||
def validate_prefix(cls, v):
|
||||
if not re.match(r"^[a-zA-Z0-9_]*$", v):
|
||||
raise ValueError('Prefix can only contain letters, numbers, and underscores.')
|
||||
return v
|
||||
|
||||
|
||||
class EditUserInputBody(BaseModel):
|
||||
new_username: Optional[str] = None
|
||||
@ -36,6 +58,12 @@ class EditUserInputBody(BaseModel):
|
||||
blocked: Optional[bool] = None
|
||||
unlimited_ip: Optional[bool] = None
|
||||
|
||||
@field_validator('new_username')
|
||||
def validate_new_username(cls, v):
|
||||
if v and not re.match(r"^[a-zA-Z0-9_]+$", v):
|
||||
raise ValueError('Username can only contain letters, numbers, and underscores.')
|
||||
return v
|
||||
|
||||
class NodeUri(BaseModel):
|
||||
name: str
|
||||
uri: str
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import json
|
||||
from fastapi import APIRouter, HTTPException
|
||||
|
||||
from .schema.user import UserListResponse, UserInfoResponse, AddUserInputBody, EditUserInputBody, UserUriResponse
|
||||
from .schema.user import UserListResponse, UserInfoResponse, AddUserInputBody, EditUserInputBody, UserUriResponse, AddBulkUsersInputBody
|
||||
from .schema.response import DetailResponse
|
||||
import cli_api
|
||||
|
||||
@ -57,6 +57,29 @@ async def add_user_api(body: AddUserInputBody):
|
||||
detail=f"An unexpected error occurred while adding user '{body.username}': {str(e)}")
|
||||
|
||||
|
||||
@router.post('/bulk/', response_model=DetailResponse, status_code=201)
|
||||
async def add_bulk_users_api(body: AddBulkUsersInputBody):
|
||||
"""
|
||||
Add multiple users in bulk.
|
||||
"""
|
||||
try:
|
||||
cli_api.bulk_user_add(
|
||||
traffic_gb=body.traffic_gb,
|
||||
expiration_days=body.expiration_days,
|
||||
count=body.count,
|
||||
prefix=body.prefix,
|
||||
start_number=body.start_number,
|
||||
unlimited=body.unlimited
|
||||
)
|
||||
return DetailResponse(detail=f"Successfully started adding {body.count} users with prefix '{body.prefix}'.")
|
||||
except cli_api.CommandExecutionError as e:
|
||||
raise HTTPException(status_code=400,
|
||||
detail=f'Failed to add bulk users: {str(e)}')
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500,
|
||||
detail=f"An unexpected error occurred while adding bulk users: {str(e)}")
|
||||
|
||||
|
||||
@router.get('/{username}', response_model=UserInfoResponse)
|
||||
async def get_user_api(username: str):
|
||||
"""
|
||||
@ -191,4 +214,4 @@ async def show_user_uri_api(username: str):
|
||||
except HTTPException:
|
||||
raise
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=400, detail=f'Unexpected error: {str(e)}')
|
||||
raise HTTPException(status_code=400, detail=f'Unexpected error: {str(e)}')
|
||||
Reference in New Issue
Block a user