Skip to content

Commit fc37777

Browse files
Fixed some type lint errors
1 parent 8461d09 commit fc37777

File tree

3 files changed

+47
-171
lines changed

3 files changed

+47
-171
lines changed

routers/organization.py

Lines changed: 12 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,22 @@
11
from logging import getLogger
2-
from datetime import datetime
2+
from typing import Annotated
33
from fastapi import APIRouter, Depends, Form, Request
44
from fastapi.responses import RedirectResponse
55
from fastapi.templating import Jinja2Templates
6-
from pydantic import BaseModel, ConfigDict, field_validator
6+
from pydantic import StringConstraints
77
from sqlmodel import Session, select
88
from utils.db import get_session, default_roles
99
from utils.dependencies import get_authenticated_user, get_user_with_relations
1010
from utils.models import Organization, User, Role, utc_time
1111
from utils.enums import ValidPermissions
12-
from exceptions.http_exceptions import EmptyOrganizationNameError, OrganizationNotFoundError, OrganizationNameTakenError, InsufficientPermissionsError
12+
from exceptions.http_exceptions import OrganizationNotFoundError, OrganizationNameTakenError, InsufficientPermissionsError
1313

1414
logger = getLogger("uvicorn.error")
1515

1616
router = APIRouter(prefix="/organizations", tags=["organizations"])
1717
templates = Jinja2Templates(directory="templates")
1818

1919

20-
# --- Server Request and Response Models ---
21-
22-
23-
class OrganizationCreate(BaseModel):
24-
name: str
25-
26-
@field_validator('name')
27-
@classmethod
28-
def validate_name(cls, name: str) -> str:
29-
if not name.strip():
30-
raise EmptyOrganizationNameError()
31-
return name.strip()
32-
33-
@classmethod
34-
async def as_form(cls, name: str = Form(...)):
35-
return cls(name=name)
36-
37-
38-
class OrganizationRead(BaseModel):
39-
model_config = ConfigDict(from_attributes=True)
40-
41-
id: int
42-
name: str
43-
created_at: datetime
44-
updated_at: datetime
45-
46-
47-
class OrganizationUpdate(BaseModel):
48-
id: int
49-
name: str
50-
51-
@field_validator('name')
52-
@classmethod
53-
def validate_name(cls, name: str) -> str:
54-
if not name.strip():
55-
raise EmptyOrganizationNameError()
56-
return name.strip()
57-
58-
@classmethod
59-
async def as_form(cls, id: int = Form(...), name: str = Form(...)):
60-
return cls(id=id, name=name)
61-
62-
6320
# --- Routes ---
6421

6522

@@ -84,26 +41,26 @@ async def read_organization(
8441

8542
@router.post("/create", response_class=RedirectResponse)
8643
def create_organization(
87-
org: OrganizationCreate = Depends(OrganizationCreate.as_form),
44+
name: Annotated[str, StringConstraints(min_length=1, strip_whitespace=True)] = Form(...),
8845
user: User = Depends(get_authenticated_user),
8946
session: Session = Depends(get_session)
9047
) -> RedirectResponse:
9148
# Check if organization already exists
9249
db_org = session.exec(select(Organization).where(
93-
Organization.name == org.name)).first()
50+
Organization.name == name)).first()
9451
if db_org:
9552
raise OrganizationNameTakenError()
9653

9754
# Create organization first
98-
db_org = Organization(name=org.name)
55+
db_org = Organization(name=name)
9956
session.add(db_org)
10057
# This gets us the org ID without committing
10158
session.flush()
10259

10360
# Create default roles with organization_id
10461
initial_roles = [
105-
Role(name=name, organization_id=db_org.id)
106-
for name in default_roles
62+
Role(name=role_name, organization_id=db_org.id)
63+
for role_name in default_roles
10764
]
10865
session.add_all(initial_roles)
10966
session.flush()
@@ -124,7 +81,7 @@ def create_organization(
12481
@router.post("/update/{org_id}", name="update_organization", response_class=RedirectResponse)
12582
def update_organization(
12683
org_id: int,
127-
org: OrganizationUpdate = Depends(OrganizationUpdate.as_form),
84+
name: Annotated[str, StringConstraints(min_length=1, strip_whitespace=True)] = Form(...),
12885
user: User = Depends(get_user_with_relations),
12986
session: Session = Depends(get_session)
13087
) -> RedirectResponse:
@@ -139,14 +96,14 @@ def update_organization(
13996
# Check if new name already exists for another organization
14097
existing_org = session.exec(
14198
select(Organization)
142-
.where(Organization.name == org.name)
143-
.where(Organization.id != org.id)
99+
.where(Organization.name == name)
100+
.where(Organization.id != org_id)
144101
).first()
145102
if existing_org:
146103
raise OrganizationNameTakenError()
147104

148105
# Update organization name
149-
organization.name = org.name
106+
organization.name = name
150107
organization.updated_at = utc_time()
151108
session.add(organization)
152109
session.commit()

routers/role.py

Lines changed: 25 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
from logging import getLogger
55
from fastapi import APIRouter, Depends, Form
66
from fastapi.responses import RedirectResponse
7-
from pydantic import BaseModel, ConfigDict
87
from sqlmodel import Session, select, col
98
from sqlalchemy.orm import selectinload
109
from utils.db import get_session
@@ -16,102 +15,39 @@
1615

1716
router = APIRouter(prefix="/roles", tags=["roles"])
1817

19-
# --- Server Request Models ---
20-
21-
class RoleCreate(BaseModel):
22-
model_config = ConfigDict(from_attributes=True)
23-
24-
name: str
25-
organization_id: int
26-
permissions: List[ValidPermissions]
27-
28-
@classmethod
29-
async def as_form(
30-
cls,
31-
name: str = Form(...),
32-
organization_id: int = Form(...),
33-
permissions: List[ValidPermissions] = Form(...)
34-
):
35-
# Pass session to validator context
36-
return cls(
37-
name=name,
38-
organization_id=organization_id,
39-
permissions=permissions
40-
)
41-
42-
43-
class RoleUpdate(BaseModel):
44-
model_config = ConfigDict(from_attributes=True)
45-
46-
id: int
47-
name: str
48-
organization_id: int
49-
permissions: List[ValidPermissions]
50-
51-
@classmethod
52-
async def as_form(
53-
cls,
54-
id: int = Form(...),
55-
name: str = Form(...),
56-
organization_id: int = Form(...),
57-
permissions: List[ValidPermissions] = Form(...)
58-
):
59-
return cls(
60-
id=id,
61-
name=name,
62-
organization_id=organization_id,
63-
permissions=permissions
64-
)
65-
66-
67-
class RoleDelete(BaseModel):
68-
model_config = ConfigDict(from_attributes=True)
69-
70-
id: int
71-
organization_id: int
72-
73-
@classmethod
74-
async def as_form(
75-
cls,
76-
id: int = Form(...),
77-
organization_id: int = Form(...)
78-
):
79-
return cls(id=id, organization_id=organization_id)
80-
81-
8218
# --- Routes ---
8319

84-
8520
@router.post("/create", response_class=RedirectResponse)
8621
def create_role(
87-
role: RoleCreate = Depends(RoleCreate.as_form),
22+
name: str = Form(...),
23+
organization_id: int = Form(...),
8824
user: User = Depends(get_authenticated_user),
8925
session: Session = Depends(get_session)
9026
) -> RedirectResponse:
9127
# Check that the user-selected role name is unique for the organization
9228
if session.exec(
9329
select(Role).where(
94-
Role.name == role.name,
95-
Role.organization_id == role.organization_id
30+
Role.name == name,
31+
Role.organization_id == organization_id
9632
)
9733
).first():
9834
raise RoleAlreadyExistsError()
9935

10036
# Check that the user is authorized to create roles in the organization
101-
if not user.has_permission(ValidPermissions.CREATE_ROLE, role.organization_id):
37+
if not user.has_permission(ValidPermissions.CREATE_ROLE, organization_id):
10238
raise InsufficientPermissionsError()
10339

10440
# Create role
10541
db_role = Role(
106-
name=role.name,
107-
organization_id=role.organization_id
42+
name=name,
43+
organization_id=organization_id
10844
)
10945
session.add(db_role)
11046

11147
# Select Permission records corresponding to the user-selected permissions
11248
# and associate them with the newly created role
11349
permissions: Sequence[Permission] = session.exec(
114-
select(Permission).where(col(Permission.name).in_(role.permissions))
50+
select(Permission).where(col(Permission.name).in_(permissions))
11551
).all()
11652
db_role.permissions.extend(permissions)
11753

@@ -123,30 +59,33 @@ def create_role(
12359

12460
@router.post("/update", response_class=RedirectResponse)
12561
def update_role(
126-
role: RoleUpdate = Depends(RoleUpdate.as_form),
62+
id: int = Form(...),
63+
name: str = Form(...),
64+
organization_id: int = Form(...),
65+
permissions: List[ValidPermissions] = Form(...),
12766
user: User = Depends(get_authenticated_user),
12867
session: Session = Depends(get_session)
12968
) -> RedirectResponse:
13069
# Check that the user is authorized to update the role
131-
if not user.has_permission(ValidPermissions.EDIT_ROLE, role.organization_id):
70+
if not user.has_permission(ValidPermissions.EDIT_ROLE, organization_id):
13271
raise InsufficientPermissionsError()
13372

13473
# Select db_role to update, along with its permissions, by ID
13574
db_role: Optional[Role] = session.exec(
136-
select(Role).where(Role.id == role.id).options(
75+
select(Role).where(Role.id == id).options(
13776
selectinload(Role.permissions))
13877
).first()
13978

14079
if not db_role:
14180
raise RoleNotFoundError()
14281

14382
# If any user-selected permissions are not valid, raise an error
144-
for permission in role.permissions:
83+
for permission in permissions:
14584
if permission not in ValidPermissions:
14685
raise InvalidPermissionError(permission)
14786

14887
# Add any user-selected permissions that are not already associated with the role
149-
for permission in role.permissions:
88+
for permission in permissions:
15089
if permission not in [p.name for p in db_role.permissions]:
15190
db_permission: Optional[Permission] = session.exec(
15291
select(Permission).where(Permission.name == permission)
@@ -158,21 +97,21 @@ def update_role(
15897

15998
# Remove any permissions that are not user-selected
16099
for db_permission in db_role.permissions:
161-
if db_permission.name not in role.permissions:
100+
if db_permission.name not in permissions:
162101
db_role.permissions.remove(db_permission)
163102

164103
# Check that no existing organization role has the same name but a different ID
165104
if session.exec(
166105
select(Role).where(
167-
Role.name == role.name,
168-
Role.organization_id == role.organization_id,
169-
Role.id != role.id
106+
Role.name == name,
107+
Role.organization_id == organization_id,
108+
Role.id != id
170109
)
171110
).first():
172111
raise RoleAlreadyExistsError()
173112

174113
# Update role name and updated_at timestamp
175-
db_role.name = role.name
114+
db_role.name = name
176115
db_role.updated_at = utc_time()
177116

178117
session.commit()
@@ -182,17 +121,18 @@ def update_role(
182121

183122
@router.post("/delete", response_class=RedirectResponse)
184123
def delete_role(
185-
role: RoleDelete = Depends(RoleDelete.as_form),
124+
id: int = Form(...),
125+
organization_id: int = Form(...),
186126
user: User = Depends(get_authenticated_user),
187127
session: Session = Depends(get_session)
188128
) -> RedirectResponse:
189129
# Check that the user is authorized to delete the role
190-
if not user.has_permission(ValidPermissions.DELETE_ROLE, role.organization_id):
130+
if not user.has_permission(ValidPermissions.DELETE_ROLE, organization_id):
191131
raise InsufficientPermissionsError()
192132

193133
# Select the role to delete by ID, along with its users
194134
db_role: Role | None = session.exec(
195-
select(Role).where(Role.id == role.id).options(
135+
select(Role).where(Role.id == id).options(
196136
selectinload(Role.users)
197137
)
198138
).first()

0 commit comments

Comments
 (0)