This commit is contained in:
Timothy Jaeryang Baek
2025-12-29 01:20:04 +04:00
parent 88dbc14abc
commit 5d1459df16
3 changed files with 148 additions and 112 deletions
+29 -21
View File
@@ -300,7 +300,7 @@ def get_scim_auth(
)
def user_to_scim(user: UserModel, request: Request) -> SCIMUser:
def user_to_scim(user: UserModel, request: Request, db=None) -> SCIMUser:
"""Convert internal User model to SCIM User"""
# Parse display name into name components
name_parts = user.name.split(" ", 1) if user.name else ["", ""]
@@ -308,7 +308,7 @@ def user_to_scim(user: UserModel, request: Request) -> SCIMUser:
family_name = name_parts[1] if len(name_parts) > 1 else ""
# Get user's groups
user_groups = Groups.get_groups_by_member_id(user.id)
user_groups = Groups.get_groups_by_member_id(user.id, db=db)
groups = [
{
"value": group.id,
@@ -487,6 +487,7 @@ async def get_users(
count: int = Query(20, ge=1, le=100),
filter: Optional[str] = None,
_: bool = Depends(get_scim_auth),
db: Session = Depends(get_session),
):
"""List SCIM Users"""
skip = startIndex - 1
@@ -498,20 +499,20 @@ async def get_users(
# In production, you'd want a more robust filter parser
if "userName eq" in filter:
email = filter.split('"')[1]
user = Users.get_user_by_email(email)
user = Users.get_user_by_email(email, db=db)
users_list = [user] if user else []
total = 1 if user else 0
else:
response = Users.get_users(skip=skip, limit=limit)
response = Users.get_users(skip=skip, limit=limit, db=db)
users_list = response["users"]
total = response["total"]
else:
response = Users.get_users(skip=skip, limit=limit)
response = Users.get_users(skip=skip, limit=limit, db=db)
users_list = response["users"]
total = response["total"]
# Convert to SCIM format
scim_users = [user_to_scim(user, request) for user in users_list]
scim_users = [user_to_scim(user, request, db=db) for user in users_list]
return SCIMListResponse(
totalResults=total,
@@ -526,15 +527,16 @@ async def get_user(
user_id: str,
request: Request,
_: bool = Depends(get_scim_auth),
db: Session = Depends(get_session),
):
"""Get SCIM User by ID"""
user = Users.get_user_by_id(user_id)
user = Users.get_user_by_id(user_id, db=db)
if not user:
return scim_error(
status_code=status.HTTP_404_NOT_FOUND, detail=f"User {user_id} not found"
)
return user_to_scim(user, request)
return user_to_scim(user, request, db=db)
@router.post("/Users", response_model=SCIMUser, status_code=status.HTTP_201_CREATED)
@@ -542,10 +544,11 @@ async def create_user(
request: Request,
user_data: SCIMUserCreateRequest,
_: bool = Depends(get_scim_auth),
db: Session = Depends(get_session),
):
"""Create SCIM User"""
# Check if user already exists
existing_user = Users.get_user_by_email(user_data.userName)
existing_user = Users.get_user_by_email(user_data.userName, db=db)
if existing_user:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT,
@@ -576,6 +579,7 @@ async def create_user(
email=email,
profile_image_url=profile_image,
role="user" if user_data.active else "pending",
db=db,
)
if not new_user:
@@ -584,7 +588,7 @@ async def create_user(
detail="Failed to create user",
)
return user_to_scim(new_user, request)
return user_to_scim(new_user, request, db=db)
@router.put("/Users/{user_id}", response_model=SCIMUser)
@@ -593,9 +597,10 @@ async def update_user(
request: Request,
user_data: SCIMUserUpdateRequest,
_: bool = Depends(get_scim_auth),
db: Session = Depends(get_session),
):
"""Update SCIM User (full update)"""
user = Users.get_user_by_id(user_id)
user = Users.get_user_by_id(user_id, db=db)
if not user:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
@@ -628,14 +633,14 @@ async def update_user(
update_data["profile_image_url"] = user_data.photos[0].value
# Update user
updated_user = Users.update_user_by_id(user_id, update_data)
updated_user = Users.update_user_by_id(user_id, update_data, db=db)
if not updated_user:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Failed to update user",
)
return user_to_scim(updated_user, request)
return user_to_scim(updated_user, request, db=db)
@router.patch("/Users/{user_id}", response_model=SCIMUser)
@@ -644,9 +649,10 @@ async def patch_user(
request: Request,
patch_data: SCIMPatchRequest,
_: bool = Depends(get_scim_auth),
db: Session = Depends(get_session),
):
"""Update SCIM User (partial update)"""
user = Users.get_user_by_id(user_id)
user = Users.get_user_by_id(user_id, db=db)
if not user:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
@@ -674,7 +680,7 @@ async def patch_user(
# Update user
if update_data:
updated_user = Users.update_user_by_id(user_id, update_data)
updated_user = Users.update_user_by_id(user_id, update_data, db=db)
if not updated_user:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
@@ -683,7 +689,7 @@ async def patch_user(
else:
updated_user = user
return user_to_scim(updated_user, request)
return user_to_scim(updated_user, request, db=db)
@router.delete("/Users/{user_id}", status_code=status.HTTP_204_NO_CONTENT)
@@ -691,16 +697,17 @@ async def delete_user(
user_id: str,
request: Request,
_: bool = Depends(get_scim_auth),
db: Session = Depends(get_session),
):
"""Delete SCIM User"""
user = Users.get_user_by_id(user_id)
user = Users.get_user_by_id(user_id, db=db)
if not user:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"User {user_id} not found",
)
success = Users.delete_user_by_id(user_id)
success = Users.delete_user_by_id(user_id, db=db)
if not success:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
@@ -749,7 +756,7 @@ async def get_group(
db: Session = Depends(get_session),
):
"""Get SCIM Group by ID"""
group = Groups.get_group_by_id(group_id)
group = Groups.get_group_by_id(group_id, db=db)
if not group:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
@@ -921,16 +928,17 @@ async def delete_group(
group_id: str,
request: Request,
_: bool = Depends(get_scim_auth),
db: Session = Depends(get_session),
):
"""Delete SCIM Group"""
group = Groups.get_group_by_id(group_id)
group = Groups.get_group_by_id(group_id, db=db)
if not group:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Group {group_id} not found",
)
success = Groups.delete_group_by_id(group_id)
success = Groups.delete_group_by_id(group_id, db=db)
if not success:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,