Spaces:
Runtime error
Runtime error
Fixing Backend to allow easy RFID linking
Browse files- src/models.py +13 -12
- src/routers/token.py +14 -1
- src/routers/users.py +1 -12
src/models.py
CHANGED
|
@@ -9,33 +9,33 @@ import os
|
|
| 9 |
|
| 10 |
Base = declarative_base()
|
| 11 |
|
| 12 |
-
JWT_SECRET_KEY = os.getenv("JWT_SECRET_KEY")
|
|
|
|
|
|
|
| 13 |
|
| 14 |
-
# Enums - Values
|
| 15 |
class UserRole(str, enum.Enum):
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
ADMIN = "admin"
|
| 20 |
|
| 21 |
class ClearanceStatusEnum(str, enum.Enum):
|
| 22 |
-
# Assuming this enum in the DB uses capitalized labels
|
| 23 |
COMPLETED = "COMPLETED"
|
| 24 |
NOT_COMPLETED = "NOT_COMPLETED"
|
| 25 |
PENDING = "PENDING"
|
| 26 |
|
| 27 |
class ClearanceDepartment(str, enum.Enum):
|
| 28 |
-
DEPARTMENTAL = "DEPARTMENTAL"
|
| 29 |
LIBRARY = "LIBRARY"
|
| 30 |
BURSARY = "BURSARY"
|
| 31 |
ALUMNI = "ALUMNI"
|
|
|
|
| 32 |
class TargetUserType(str, enum.Enum):
|
| 33 |
-
#
|
| 34 |
-
STUDENT = "
|
| 35 |
-
STAFF_ADMIN = "
|
| 36 |
|
| 37 |
class OverallClearanceStatusEnum(str, enum.Enum):
|
| 38 |
-
# These are used within the API logic and may not correspond to a DB type
|
| 39 |
COMPLETED = "COMPLETED"
|
| 40 |
PENDING = "PENDING"
|
| 41 |
|
|
@@ -96,6 +96,7 @@ class PendingTagLink(Base):
|
|
| 96 |
__tablename__ = "pending_tag_links"
|
| 97 |
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
|
| 98 |
device_id_fk = Column(Integer, ForeignKey("devices.id"), index=True, nullable=False, name="device_id")
|
|
|
|
| 99 |
target_user_type = Column(SQLAlchemyEnum(TargetUserType, name="targetusertype", create_type=False, values_callable=enum_values_callable), nullable=False)
|
| 100 |
target_identifier = Column(String, nullable=False)
|
| 101 |
initiated_by_user_id = Column(Integer, ForeignKey("users.id"), nullable=False)
|
|
|
|
| 9 |
|
| 10 |
Base = declarative_base()
|
| 11 |
|
| 12 |
+
JWT_SECRET_KEY = os.getenv("JWT_SECRET_KEY", "your-default-secret-key-for-dev-only-CHANGE-ME")
|
| 13 |
+
if JWT_SECRET_KEY == "your-default-secret-key-for-dev-only-CHANGE-ME":
|
| 14 |
+
print("WARNING: Using default JWT_SECRET_KEY. Please set a strong JWT_SECRET_KEY environment variable for production.")
|
| 15 |
|
| 16 |
+
# Enums - Values are now ALL CAPS to match the PostgreSQL ENUM type labels, based on testing.
|
| 17 |
class UserRole(str, enum.Enum):
|
| 18 |
+
STUDENT = "STUDENT"
|
| 19 |
+
STAFF = "STAFF"
|
| 20 |
+
ADMIN = "ADMIN"
|
|
|
|
| 21 |
|
| 22 |
class ClearanceStatusEnum(str, enum.Enum):
|
|
|
|
| 23 |
COMPLETED = "COMPLETED"
|
| 24 |
NOT_COMPLETED = "NOT_COMPLETED"
|
| 25 |
PENDING = "PENDING"
|
| 26 |
|
| 27 |
class ClearanceDepartment(str, enum.Enum):
|
| 28 |
+
DEPARTMENTAL = "DEPARTMENTAL"
|
| 29 |
LIBRARY = "LIBRARY"
|
| 30 |
BURSARY = "BURSARY"
|
| 31 |
ALUMNI = "ALUMNI"
|
| 32 |
+
|
| 33 |
class TargetUserType(str, enum.Enum):
|
| 34 |
+
# Corrected to ALL CAPS to match other enums and likely DB schema
|
| 35 |
+
STUDENT = "STUDENT"
|
| 36 |
+
STAFF_ADMIN = "STAFF_ADMIN"
|
| 37 |
|
| 38 |
class OverallClearanceStatusEnum(str, enum.Enum):
|
|
|
|
| 39 |
COMPLETED = "COMPLETED"
|
| 40 |
PENDING = "PENDING"
|
| 41 |
|
|
|
|
| 96 |
__tablename__ = "pending_tag_links"
|
| 97 |
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
|
| 98 |
device_id_fk = Column(Integer, ForeignKey("devices.id"), index=True, nullable=False, name="device_id")
|
| 99 |
+
# ** FIX: Correctly define the column using SQLAlchemyEnum **
|
| 100 |
target_user_type = Column(SQLAlchemyEnum(TargetUserType, name="targetusertype", create_type=False, values_callable=enum_values_callable), nullable=False)
|
| 101 |
target_identifier = Column(String, nullable=False)
|
| 102 |
initiated_by_user_id = Column(Integer, ForeignKey("users.id"), nullable=False)
|
src/routers/token.py
CHANGED
|
@@ -4,7 +4,7 @@ from fastapi.concurrency import run_in_threadpool # To call sync CRUD in async e
|
|
| 4 |
from sqlalchemy.orm import Session as SQLAlchemySessionType
|
| 5 |
|
| 6 |
from src import crud, models # crud now contains sync ORM functions
|
| 7 |
-
from src.auth import create_access_token # JWT creation is sync
|
| 8 |
from src.database import get_db # Dependency for SQLAlchemy session
|
| 9 |
|
| 10 |
router = APIRouter(
|
|
@@ -47,3 +47,16 @@ async def login_for_access_token( # Endpoint remains async
|
|
| 47 |
data={"sub": user.username, "role": user.role.value} # user.role is UserRole enum
|
| 48 |
)
|
| 49 |
return {"access_token": access_token, "token_type": "bearer"}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4 |
from sqlalchemy.orm import Session as SQLAlchemySessionType
|
| 5 |
|
| 6 |
from src import crud, models # crud now contains sync ORM functions
|
| 7 |
+
from src.auth import create_access_token, get_current_active_user # JWT creation is sync
|
| 8 |
from src.database import get_db # Dependency for SQLAlchemy session
|
| 9 |
|
| 10 |
router = APIRouter(
|
|
|
|
| 47 |
data={"sub": user.username, "role": user.role.value} # user.role is UserRole enum
|
| 48 |
)
|
| 49 |
return {"access_token": access_token, "token_type": "bearer"}
|
| 50 |
+
|
| 51 |
+
|
| 52 |
+
@router.get("/users/me", response_model=models.UserResponse, summary="Get current authenticated user details")
|
| 53 |
+
async def read_users_me(
|
| 54 |
+
current_user_orm: models.User = Depends(get_current_active_user) # Depends on token auth
|
| 55 |
+
):
|
| 56 |
+
"""
|
| 57 |
+
Returns the details of the currently authenticated user (via token).
|
| 58 |
+
The user object is already an ORM model instance.
|
| 59 |
+
Pydantic's UserResponse will convert it using from_attributes=True.
|
| 60 |
+
"""
|
| 61 |
+
return current_user_orm
|
| 62 |
+
|
src/routers/users.py
CHANGED
|
@@ -71,15 +71,4 @@ async def list_all_users(
|
|
| 71 |
"""
|
| 72 |
# crud.get_users is sync, call with run_in_threadpool
|
| 73 |
users_orm_list = await run_in_threadpool(crud.get_users, db, skip, limit)
|
| 74 |
-
return users_orm_list # Pydantic will convert the list of ORM User models
|
| 75 |
-
|
| 76 |
-
@router.get("/users/me", response_model=models.UserResponse, summary="Get current authenticated user details")
|
| 77 |
-
async def read_users_me(
|
| 78 |
-
current_user_orm: models.User = Depends(get_current_active_user) # Depends on token auth
|
| 79 |
-
):
|
| 80 |
-
"""
|
| 81 |
-
Returns the details of the currently authenticated user (via token).
|
| 82 |
-
The user object is already an ORM model instance.
|
| 83 |
-
Pydantic's UserResponse will convert it using from_attributes=True.
|
| 84 |
-
"""
|
| 85 |
-
return current_user_orm
|
|
|
|
| 71 |
"""
|
| 72 |
# crud.get_users is sync, call with run_in_threadpool
|
| 73 |
users_orm_list = await run_in_threadpool(crud.get_users, db, skip, limit)
|
| 74 |
+
return users_orm_list # Pydantic will convert the list of ORM User models
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|