Implement authentication system with access control UI
This commit is contained in:
@@ -47,6 +47,13 @@ class ProjectUpdate(BaseModel):
|
||||
is_public: Optional[bool] = None
|
||||
|
||||
|
||||
class ProjectWithAccessResponse(ProjectResponse):
|
||||
"""Project response with user's access level included"""
|
||||
|
||||
access_level: Optional[str] = None # 'read', 'write', 'admin', or None
|
||||
is_owner: bool = False
|
||||
|
||||
|
||||
# Package format and platform enums
|
||||
PACKAGE_FORMATS = [
|
||||
"generic",
|
||||
@@ -686,3 +693,173 @@ class StatsReportResponse(BaseModel):
|
||||
format: str # "json", "csv", "markdown"
|
||||
generated_at: datetime
|
||||
content: str # The report content
|
||||
|
||||
|
||||
# Authentication schemas
|
||||
class LoginRequest(BaseModel):
|
||||
"""Login request with username and password"""
|
||||
username: str
|
||||
password: str
|
||||
|
||||
|
||||
class LoginResponse(BaseModel):
|
||||
"""Login response with user info"""
|
||||
id: UUID
|
||||
username: str
|
||||
email: Optional[str]
|
||||
is_admin: bool
|
||||
must_change_password: bool
|
||||
|
||||
|
||||
class ChangePasswordRequest(BaseModel):
|
||||
"""Change password request"""
|
||||
current_password: str
|
||||
new_password: str
|
||||
|
||||
|
||||
class UserResponse(BaseModel):
|
||||
"""User information response"""
|
||||
id: UUID
|
||||
username: str
|
||||
email: Optional[str]
|
||||
is_admin: bool
|
||||
is_active: bool
|
||||
must_change_password: bool
|
||||
created_at: datetime
|
||||
last_login: Optional[datetime]
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class UserCreate(BaseModel):
|
||||
"""Create user request (admin only)"""
|
||||
username: str
|
||||
password: str
|
||||
email: Optional[str] = None
|
||||
is_admin: bool = False
|
||||
|
||||
|
||||
class UserUpdate(BaseModel):
|
||||
"""Update user request (admin only)"""
|
||||
email: Optional[str] = None
|
||||
is_admin: Optional[bool] = None
|
||||
is_active: Optional[bool] = None
|
||||
|
||||
|
||||
class ResetPasswordRequest(BaseModel):
|
||||
"""Reset password request (admin only)"""
|
||||
new_password: str
|
||||
|
||||
|
||||
class APIKeyCreate(BaseModel):
|
||||
"""Create API key request"""
|
||||
name: str
|
||||
description: Optional[str] = None
|
||||
scopes: Optional[List[str]] = None
|
||||
|
||||
|
||||
class APIKeyResponse(BaseModel):
|
||||
"""API key response (without the secret key)"""
|
||||
id: UUID
|
||||
name: str
|
||||
description: Optional[str]
|
||||
scopes: Optional[List[str]]
|
||||
created_at: datetime
|
||||
expires_at: Optional[datetime]
|
||||
last_used: Optional[datetime]
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class APIKeyCreateResponse(BaseModel):
|
||||
"""API key creation response (includes the secret key - only shown once)"""
|
||||
id: UUID
|
||||
name: str
|
||||
description: Optional[str]
|
||||
scopes: Optional[List[str]]
|
||||
key: str # The actual API key - only returned on creation
|
||||
created_at: datetime
|
||||
expires_at: Optional[datetime]
|
||||
|
||||
|
||||
# OIDC Configuration schemas
|
||||
class OIDCConfigResponse(BaseModel):
|
||||
"""OIDC configuration response (hides client secret)"""
|
||||
enabled: bool
|
||||
issuer_url: str
|
||||
client_id: str
|
||||
has_client_secret: bool # True if secret is configured, but don't expose it
|
||||
scopes: List[str]
|
||||
auto_create_users: bool
|
||||
admin_group: str
|
||||
|
||||
|
||||
class OIDCConfigUpdate(BaseModel):
|
||||
"""Update OIDC configuration"""
|
||||
enabled: Optional[bool] = None
|
||||
issuer_url: Optional[str] = None
|
||||
client_id: Optional[str] = None
|
||||
client_secret: Optional[str] = None # Only set if changing
|
||||
scopes: Optional[List[str]] = None
|
||||
auto_create_users: Optional[bool] = None
|
||||
admin_group: Optional[str] = None
|
||||
|
||||
|
||||
class OIDCStatusResponse(BaseModel):
|
||||
"""Public OIDC status response"""
|
||||
enabled: bool
|
||||
issuer_url: Optional[str] = None # Only included if enabled
|
||||
|
||||
|
||||
class OIDCLoginResponse(BaseModel):
|
||||
"""OIDC login initiation response"""
|
||||
authorization_url: str
|
||||
|
||||
|
||||
# Access Permission schemas
|
||||
class AccessPermissionCreate(BaseModel):
|
||||
"""Grant access to a user for a project"""
|
||||
username: str
|
||||
level: str # 'read', 'write', or 'admin'
|
||||
expires_at: Optional[datetime] = None
|
||||
|
||||
@field_validator('level')
|
||||
@classmethod
|
||||
def validate_level(cls, v):
|
||||
if v not in ('read', 'write', 'admin'):
|
||||
raise ValueError("level must be 'read', 'write', or 'admin'")
|
||||
return v
|
||||
|
||||
|
||||
class AccessPermissionUpdate(BaseModel):
|
||||
"""Update access permission"""
|
||||
level: Optional[str] = None
|
||||
expires_at: Optional[datetime] = None
|
||||
|
||||
@field_validator('level')
|
||||
@classmethod
|
||||
def validate_level(cls, v):
|
||||
if v is not None and v not in ('read', 'write', 'admin'):
|
||||
raise ValueError("level must be 'read', 'write', or 'admin'")
|
||||
return v
|
||||
|
||||
|
||||
class AccessPermissionResponse(BaseModel):
|
||||
"""Access permission response"""
|
||||
id: UUID
|
||||
project_id: UUID
|
||||
user_id: str
|
||||
level: str
|
||||
created_at: datetime
|
||||
expires_at: Optional[datetime]
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class ProjectWithAccessResponse(ProjectResponse):
|
||||
"""Project response with user's access level"""
|
||||
user_access_level: Optional[str] = None
|
||||
|
||||
|
||||
Reference in New Issue
Block a user