Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 0 additions & 12 deletions backend/app/api/deps.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,18 +123,6 @@ def get_current_active_superuser_org(current_user: CurrentUserOrg) -> User:
return current_user


async def http_exception_handler(request: Request, exc: HTTPException):
"""
Global handler for HTTPException to return standardized response format.
"""
return JSONResponse(
status_code=exc.status_code,
content=APIResponse.failure_response(exc.detail).model_dump()
# TEMPORARY: Keep "detail" for backward compatibility
| {"detail": exc.detail},
)


def verify_user_project_organization(
db: SessionDep,
current_user: CurrentUserOrg,
Expand Down
91 changes: 45 additions & 46 deletions backend/app/api/routes/api_keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
from app.crud.project import validate_project
from app.models import APIKeyPublic, User
from app.utils import APIResponse
from app.core.exception_handlers import HTTPException

router = APIRouter(prefix="/apikeys", tags=["API Keys"])


# Create API Key
@router.post("/", response_model=APIResponse[APIKeyPublic])
def create_key(
project_id: int,
Expand All @@ -27,31 +27,26 @@
"""
Generate a new API key for the user's organization.
"""
try:
# Validate organization
project = validate_project(session, project_id)

existing_api_key = get_api_key_by_project_user(session, project_id, user_id)
if existing_api_key:
raise HTTPException(
status_code=400,
detail="API Key already exists for this user and project.",
)

# Create and return API key
api_key = create_api_key(
session,
organization_id=project.organization_id,
user_id=user_id,
project_id=project_id,
# Validate organization
project = validate_project(session, project_id)

existing_api_key = get_api_key_by_project_user(session, project_id, user_id)
if existing_api_key:
raise HTTPException(
status_code=400,
detail="API Key already exists for this user and project.",
)
return APIResponse.success_response(api_key)

except ValueError as e:
raise HTTPException(status_code=400, detail=str(e))
# Create and return API key
api_key = create_api_key(
session,
organization_id=project.organization_id,
user_id=user_id,
project_id=project_id,
)
return APIResponse.success_response(api_key)


# List API Keys
@router.get("/", response_model=APIResponse[list[APIKeyPublic]])
def list_keys(
project_id: int,
Expand All @@ -62,27 +57,29 @@
Retrieve all API keys for the given project. Superusers get all keys;
regular users get only their own.
"""
try:
# Validate project
project = validate_project(session=session, project_id=project_id)

if current_user.is_superuser:
# Superuser: fetch all API keys for the project
api_keys = get_api_keys_by_project(session=session, project_id=project_id)
else:
# Regular user: fetch only their own API key
user_api_key = get_api_key_by_project_user(
session=session, project_id=project_id, user_id=current_user.id
)
api_keys = [user_api_key] if user_api_key else []
# Validate project
project = validate_project(session=session, project_id=project_id)

if current_user.is_superuser:
# Superuser: fetch all API keys for the project
api_keys = get_api_keys_by_project(session=session, project_id=project_id)
else:
# Regular user: fetch only their own API key
user_api_key = get_api_key_by_project_user(

Check warning on line 68 in backend/app/api/routes/api_keys.py

View check run for this annotation

Codecov / codecov/patch

backend/app/api/routes/api_keys.py#L68

Added line #L68 was not covered by tests
session=session, project_id=project_id, user_id=current_user.id
)
api_keys = [user_api_key] if user_api_key else []

Check warning on line 71 in backend/app/api/routes/api_keys.py

View check run for this annotation

Codecov / codecov/patch

backend/app/api/routes/api_keys.py#L71

Added line #L71 was not covered by tests

return APIResponse.success_response(api_keys)
# Raise an exception if no API keys are found for the project
if not api_keys:
raise HTTPException(

Check warning on line 75 in backend/app/api/routes/api_keys.py

View check run for this annotation

Codecov / codecov/patch

backend/app/api/routes/api_keys.py#L75

Added line #L75 was not covered by tests
status_code=404,
detail="No API keys found for this project.",
)

except ValueError as e:
raise HTTPException(status_code=400, detail=str(e))
return APIResponse.success_response(api_keys)


# Get API Key by ID
@router.get("/{api_key_id}", response_model=APIResponse[APIKeyPublic])
def get_key(
api_key_id: int,
Expand All @@ -94,12 +91,11 @@
"""
api_key = get_api_key(session, api_key_id)
if not api_key:
raise HTTPException(status_code=404, detail="API Key does not exist")
raise HTTPException(404, "API Key does not exist")

return APIResponse.success_response(api_key)


# Revoke API Key (Soft Delete)
@router.delete("/{api_key_id}", response_model=APIResponse[dict])
def revoke_key(
api_key_id: int,
Expand All @@ -109,8 +105,11 @@
"""
Soft delete an API key (revoke access).
"""
try:
delete_api_key(session, api_key_id)
return APIResponse.success_response({"message": "API key revoked successfully"})
except ValueError as e:
raise HTTPException(status_code=400, detail=str(e))
api_key = get_api_key(session, api_key_id)

if not api_key:
raise HTTPException(404, "API key not found or already deleted")

delete_api_key(session, api_key_id)

return APIResponse.success_response({"message": "API key revoked successfully"})
26 changes: 4 additions & 22 deletions backend/app/api/routes/collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -317,15 +317,7 @@
collection_id: UUID = FastPath(description="Collection to retrieve"),
):
collection_crud = CollectionCrud(session, current_user.id)
try:
data = collection_crud.read_one(collection_id)
except NoResultFound as err:
raise HTTPException(status_code=404, detail=str(err))
except MultipleResultsFound as err:
raise HTTPException(status_code=503, detail=str(err))
except Exception as err:
raise_from_unknown(err)

data = collection_crud.read_one(collection_id)

Check warning on line 320 in backend/app/api/routes/collections.py

View check run for this annotation

Codecov / codecov/patch

backend/app/api/routes/collections.py#L320

Added line #L320 was not covered by tests
return APIResponse.success_response(data)


Expand All @@ -339,13 +331,7 @@
current_user: CurrentUser,
):
collection_crud = CollectionCrud(session, current_user.id)
try:
data = collection_crud.read_all()
except (ValueError, SQLAlchemyError) as err:
raise HTTPException(status_code=403, detail=str(err))
except Exception as err:
raise_from_unknown(err)

data = collection_crud.read_all()

Check warning on line 334 in backend/app/api/routes/collections.py

View check run for this annotation

Codecov / codecov/patch

backend/app/api/routes/collections.py#L334

Added line #L334 was not covered by tests
return APIResponse.success_response(data)


Expand All @@ -363,10 +349,6 @@
):
collection_crud = CollectionCrud(session, current_user.id)
document_collection_crud = DocumentCollectionCrud(session)
try:
collection = collection_crud.read_one(collection_id)
data = document_collection_crud.read(collection, skip, limit)
except (SQLAlchemyError, ValueError) as err:
raise HTTPException(status_code=400, detail=str(err))

collection = collection_crud.read_one(collection_id)
data = document_collection_crud.read(collection, skip, limit)

Check warning on line 353 in backend/app/api/routes/collections.py

View check run for this annotation

Codecov / codecov/patch

backend/app/api/routes/collections.py#L352-L353

Added lines #L352 - L353 were not covered by tests
return APIResponse.success_response(data)
Loading