minor: ruff formatter
All changes are either: - Correcting tabs - Adding/removing line breaks - Adding trailing commas
This commit is contained in:
parent
b2e5dd2ebb
commit
c689ac1e10
91 changed files with 1710 additions and 689 deletions
|
|
@ -1,3 +1,3 @@
|
|||
"""
|
||||
Configurations for the user module
|
||||
"""
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
"""
|
||||
Constants for the user module
|
||||
"""
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ Exports:
|
|||
- user_model_query_dependency: user_model: Gets user model from db, if it exists. Uses user_id from query param
|
||||
- user_model_body_dependency: user_model: Gets user model from db, if it exists. Uses user_id from request body.
|
||||
"""
|
||||
|
||||
from typing import Annotated
|
||||
from fastapi import Depends, Query
|
||||
|
||||
|
|
@ -28,6 +29,7 @@ async def get_user_model_claims(claims: claims_dependency, db: db_dependency):
|
|||
|
||||
return user_model
|
||||
|
||||
|
||||
user_model_claims_dependency = Annotated[type[User], Depends(get_user_model_claims)]
|
||||
|
||||
|
||||
|
|
@ -38,6 +40,7 @@ async def get_user_model_query(db: db_dependency, user_id: Annotated[int, Query(
|
|||
|
||||
return user_model
|
||||
|
||||
|
||||
user_model_query_dependency = Annotated[type[User], Depends(get_user_model_query)]
|
||||
|
||||
|
||||
|
|
@ -48,4 +51,5 @@ async def get_user_model_body(db: db_dependency, request_model: UserIDMixin):
|
|||
|
||||
return user_model
|
||||
|
||||
|
||||
user_model_body_dependency = Annotated[type[User], Depends(get_user_model_body)]
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ Exceptions related to the user module
|
|||
Exceptions:
|
||||
- UserNotFoundException: Takes an optional user_id int
|
||||
"""
|
||||
|
||||
from typing import Optional
|
||||
|
||||
from fastapi import HTTPException, status
|
||||
|
|
@ -11,7 +12,11 @@ from fastapi import HTTPException, status
|
|||
|
||||
class UserNotFoundException(HTTPException):
|
||||
def __init__(self, user_id: Optional[int] = None) -> None:
|
||||
detail = "User not found" if user_id is None else f"User with ID '{user_id}' was not found."
|
||||
detail = (
|
||||
"User not found"
|
||||
if user_id is None
|
||||
else f"User with ID '{user_id}' was not found."
|
||||
)
|
||||
super().__init__(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail=detail,
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ Models:
|
|||
- organisations: Calc property list of organisation_rel.name
|
||||
- groups: Calc property dict of {group_rel.org_rel.name: group_rel.name}
|
||||
"""
|
||||
|
||||
from collections import defaultdict
|
||||
|
||||
from sqlalchemy import Column, Integer, String
|
||||
|
|
@ -18,29 +19,29 @@ from src.database import Base
|
|||
|
||||
|
||||
class User(Base):
|
||||
__tablename__ = "user"
|
||||
__tablename__ = "user"
|
||||
|
||||
id = Column(Integer, primary_key=True)
|
||||
email = Column(String)
|
||||
first_name = Column(String)
|
||||
last_name = Column(String)
|
||||
oidc_id = Column(String, index=True, unique=True)
|
||||
id = Column(Integer, primary_key=True)
|
||||
email = Column(String)
|
||||
first_name = Column(String)
|
||||
last_name = Column(String)
|
||||
oidc_id = Column(String, index=True, unique=True)
|
||||
|
||||
organisation_rel = relationship(
|
||||
"Organisation", secondary="orgusers", back_populates="user_rel"
|
||||
)
|
||||
organisation_rel = relationship(
|
||||
"Organisation", secondary="orgusers", back_populates="user_rel"
|
||||
)
|
||||
|
||||
@property
|
||||
def organisations(self):
|
||||
return [{"name": org.name, "id": org.id} for org in self.organisation_rel]
|
||||
@property
|
||||
def organisations(self):
|
||||
return [{"name": org.name, "id": org.id} for org in self.organisation_rel]
|
||||
|
||||
group_rel = relationship(
|
||||
"Group", secondary="user_groups", back_populates="user_rel"
|
||||
)
|
||||
group_rel = relationship(
|
||||
"Group", secondary="user_groups", back_populates="user_rel"
|
||||
)
|
||||
|
||||
@property
|
||||
def groups(self):
|
||||
result = defaultdict(list)
|
||||
for group in self.group_rel:
|
||||
result[group.org_rel.name].append({"name": group.name, "id": group.id})
|
||||
return dict(result)
|
||||
@property
|
||||
def groups(self):
|
||||
result = defaultdict(list)
|
||||
for group in self.group_rel:
|
||||
result[group.org_rel.name].append({"name": group.name, "id": group.id})
|
||||
return dict(result)
|
||||
|
|
|
|||
|
|
@ -7,11 +7,16 @@ Endpoints:
|
|||
- [GET](/user/): [super admin]: Returns user(id) details.
|
||||
- [DELETE](/user/): [super admin]: Removes a User(id) from the hub database.
|
||||
"""
|
||||
|
||||
from fastapi import APIRouter
|
||||
from starlette import status
|
||||
|
||||
from src.user.schemas import UserResponse, OIDCClaims, UserDeleteUserRequest
|
||||
from src.user.dependencies import user_model_claims_dependency, user_model_query_dependency, user_model_body_dependency
|
||||
from src.user.dependencies import (
|
||||
user_model_claims_dependency,
|
||||
user_model_query_dependency,
|
||||
user_model_body_dependency,
|
||||
)
|
||||
|
||||
from src.auth.dependencies import super_admin_dependency
|
||||
from src.auth.service import claims_dependency
|
||||
|
|
@ -23,13 +28,15 @@ router = APIRouter(
|
|||
)
|
||||
|
||||
|
||||
@router.get("/self/claims",
|
||||
summary="Get current user OIDC claims.",
|
||||
response_model=OIDCClaims,
|
||||
status_code=status.HTTP_200_OK,
|
||||
responses={
|
||||
status.HTTP_200_OK: {"description": "Successful retrieval from database"},
|
||||
})
|
||||
@router.get(
|
||||
"/self/claims",
|
||||
summary="Get current user OIDC claims.",
|
||||
response_model=OIDCClaims,
|
||||
status_code=status.HTTP_200_OK,
|
||||
responses={
|
||||
status.HTTP_200_OK: {"description": "Successful retrieval from database"},
|
||||
},
|
||||
)
|
||||
async def current_user_claims(user: claims_dependency):
|
||||
"""
|
||||
Returns the full OIDC claims associated with the currently logged-in user.
|
||||
|
|
@ -38,14 +45,16 @@ async def current_user_claims(user: claims_dependency):
|
|||
return user
|
||||
|
||||
|
||||
@router.get("/self/db",
|
||||
summary="Get current user hub details.",
|
||||
response_model=UserResponse,
|
||||
status_code=status.HTTP_200_OK,
|
||||
responses={
|
||||
status.HTTP_404_NOT_FOUND: {"description": "User not found"},
|
||||
status.HTTP_200_OK: {"description": "Successful retrieval from database"},
|
||||
})
|
||||
@router.get(
|
||||
"/self/db",
|
||||
summary="Get current user hub details.",
|
||||
response_model=UserResponse,
|
||||
status_code=status.HTTP_200_OK,
|
||||
responses={
|
||||
status.HTTP_404_NOT_FOUND: {"description": "User not found"},
|
||||
status.HTTP_200_OK: {"description": "Successful retrieval from database"},
|
||||
},
|
||||
)
|
||||
async def current_user(user_model: user_model_claims_dependency):
|
||||
"""
|
||||
Returns the database details associated with the currently logged-in user.
|
||||
|
|
@ -53,30 +62,40 @@ async def current_user(user_model: user_model_claims_dependency):
|
|||
return user_model
|
||||
|
||||
|
||||
@router.get("/",
|
||||
summary="Get user hub details by ID.",
|
||||
response_model=UserResponse,
|
||||
status_code=status.HTTP_200_OK,
|
||||
responses={
|
||||
status.HTTP_404_NOT_FOUND: {"description": "User not found"},
|
||||
status.HTTP_200_OK: {"description": "Successful retrieval from database"},
|
||||
})
|
||||
async def get_user_by_id(user_model: user_model_query_dependency, su: super_admin_dependency):
|
||||
@router.get(
|
||||
"/",
|
||||
summary="Get user hub details by ID.",
|
||||
response_model=UserResponse,
|
||||
status_code=status.HTTP_200_OK,
|
||||
responses={
|
||||
status.HTTP_404_NOT_FOUND: {"description": "User not found"},
|
||||
status.HTTP_200_OK: {"description": "Successful retrieval from database"},
|
||||
},
|
||||
)
|
||||
async def get_user_by_id(
|
||||
user_model: user_model_query_dependency, su: super_admin_dependency
|
||||
):
|
||||
"""
|
||||
Returns the database details associated with the provided user ID.
|
||||
"""
|
||||
return user_model
|
||||
|
||||
|
||||
@router.delete("/",
|
||||
summary="Delete user from hub by ID.",
|
||||
status_code=status.HTTP_204_NO_CONTENT,
|
||||
responses={
|
||||
status.HTTP_204_NO_CONTENT: {"description": "User deleted"},
|
||||
status.HTTP_404_NOT_FOUND: {"description": "User not found"},
|
||||
})
|
||||
async def delete_user_by_id(db: db_dependency, user_model: user_model_body_dependency, su: super_admin_dependency,
|
||||
request_model: UserDeleteUserRequest):
|
||||
@router.delete(
|
||||
"/",
|
||||
summary="Delete user from hub by ID.",
|
||||
status_code=status.HTTP_204_NO_CONTENT,
|
||||
responses={
|
||||
status.HTTP_204_NO_CONTENT: {"description": "User deleted"},
|
||||
status.HTTP_404_NOT_FOUND: {"description": "User not found"},
|
||||
},
|
||||
)
|
||||
async def delete_user_by_id(
|
||||
db: db_dependency,
|
||||
user_model: user_model_body_dependency,
|
||||
su: super_admin_dependency,
|
||||
request_model: UserDeleteUserRequest,
|
||||
):
|
||||
"""
|
||||
Deletes the user with the provided ID from the database. This will not remove them from OIDC, and they will be automatically readded on next login.
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
"""
|
||||
Pydantic models for the user module
|
||||
"""
|
||||
|
||||
from typing import Optional
|
||||
from pydantic import Field
|
||||
|
||||
|
|
@ -47,8 +48,8 @@ class UserResponse(CustomBaseModel):
|
|||
first_name: str
|
||||
last_name: str
|
||||
email: str
|
||||
organisations: list[Optional[dict[str, str|int]]]
|
||||
groups: Optional[dict[str, list[dict[str, str|int]]]] = None
|
||||
organisations: list[Optional[dict[str, str | int]]]
|
||||
groups: Optional[dict[str, list[dict[str, str | int]]]] = None
|
||||
|
||||
|
||||
class OrgResponse(CustomBaseModel):
|
||||
|
|
@ -57,4 +58,4 @@ class OrgResponse(CustomBaseModel):
|
|||
|
||||
|
||||
class UserDeleteUserRequest(UserIDMixin):
|
||||
pass
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ Module specific business logic for user module
|
|||
Exports:
|
||||
- add_user_to_db: Creates a User record from OIDC claims, or updates user details
|
||||
"""
|
||||
|
||||
from typing import Any
|
||||
|
||||
from sqlalchemy.orm import Session
|
||||
|
|
@ -16,7 +17,12 @@ from src.user.models import User
|
|||
|
||||
async def add_user_to_db(db: Session, user_claims: dict[str, Any]) -> int:
|
||||
try:
|
||||
valid_user = OIDCUser(first_name=user_claims["given_name"], last_name=user_claims["family_name"], email=user_claims["email"], oidc_id=user_claims["sub"])
|
||||
valid_user = OIDCUser(
|
||||
first_name=user_claims["given_name"],
|
||||
last_name=user_claims["family_name"],
|
||||
email=user_claims["email"],
|
||||
oidc_id=user_claims["sub"],
|
||||
)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
raise UnprocessableContentException("Invalid or missing OIDC data")
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
"""
|
||||
Non-business logic reusable functions and classes for the user module
|
||||
"""
|
||||
"""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue