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
20 changes: 10 additions & 10 deletions diracx-routers/src/diracx/routers/auth/authorize_code_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@
from __future__ import annotations

import logging
from http import HTTPStatus
from typing import Literal

from fastapi import (
HTTPException,
Request,
responses,
status,
)
from fastapi.responses import RedirectResponse

from diracx.core.exceptions import AuthorizationError, IAMClientError, IAMServerError
from diracx.core.settings import AuthSettings
Expand Down Expand Up @@ -48,7 +48,7 @@ async def initiate_authorization_flow(
config: Config,
available_properties: AvailableSecurityProperties,
settings: AuthSettings,
) -> responses.RedirectResponse:
) -> RedirectResponse:
"""Initiate the authorization flow.

It will redirect to the actual OpenID server (IAM, CheckIn) to
Expand Down Expand Up @@ -85,11 +85,11 @@ async def initiate_authorization_flow(
)
except ValueError as e:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
status_code=HTTPStatus.BAD_REQUEST,
detail=str(e),
) from e

return responses.RedirectResponse(redirect_uri)
return RedirectResponse(redirect_uri)


@router.get("/authorize/complete")
Expand All @@ -100,7 +100,7 @@ async def complete_authorization_flow(
auth_db: AuthDB,
config: Config,
settings: AuthSettings,
) -> responses.RedirectResponse:
) -> RedirectResponse:
"""Complete the authorization flow.

The user is redirected back to the DIRAC auth service after completing the IAM's authorization flow.
Expand All @@ -119,17 +119,17 @@ async def complete_authorization_flow(
except AuthorizationError as e:
logger.warning("Authorization flow failed with invalid state: %s", e)
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, detail="Invalid state"
status_code=HTTPStatus.BAD_REQUEST, detail="Invalid state"
) from e
except IAMServerError as e:
logger.warning("IAM server error during authorization flow: %s", e)
raise HTTPException(
status_code=status.HTTP_502_BAD_GATEWAY,
status_code=HTTPStatus.BAD_GATEWAY,
detail="Failed to contact IAM server",
) from e
except IAMClientError as e:
logger.warning("IAM client error during authorization flow: %s", e)
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid code"
status_code=HTTPStatus.UNAUTHORIZED, detail="Invalid code"
) from e
return responses.RedirectResponse(redirect_uri)
return RedirectResponse(redirect_uri)
17 changes: 8 additions & 9 deletions diracx-routers/src/diracx/routers/auth/device_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,12 @@
from __future__ import annotations

import logging
from http import HTTPStatus

from fastapi import (
HTTPException,
Request,
Response,
responses,
status,
)
from fastapi.responses import RedirectResponse
from sqlalchemy.exc import NoResultFound
Expand Down Expand Up @@ -78,7 +77,7 @@ async def initiate_device_flow(
)
except ValueError as e:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
status_code=HTTPStatus.BAD_REQUEST,
detail=e.args[0],
) from e

Expand Down Expand Up @@ -116,19 +115,19 @@ async def do_device_flow(
except NoResultFound as e:
logger.warning("Invalid or expired user_code: %s", e)
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
status_code=HTTPStatus.BAD_REQUEST,
detail=e.args[0],
) from e
except ValueError as e:
logger.warning("Invalid scope during device flow: %s", e)
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
status_code=HTTPStatus.BAD_REQUEST,
detail=e.args[0],
) from e
except IAMServerError as e:
logger.warning("IAM server error during device flow: %s", e)
raise HTTPException(
status_code=status.HTTP_502_BAD_GATEWAY,
status_code=HTTPStatus.BAD_GATEWAY,
detail=e.args[0],
) from e
return RedirectResponse(authorization_flow_url)
Expand Down Expand Up @@ -163,17 +162,17 @@ async def finish_device_flow(
except IAMServerError as e:
logger.warning("IAM server error during device flow completion: %s", e)
raise HTTPException(
status_code=status.HTTP_502_BAD_GATEWAY,
status_code=HTTPStatus.BAD_GATEWAY,
detail=e.args[0],
) from e
except IAMClientError as e:
logger.warning("IAM client error during device flow completion: %s", e)
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
status_code=HTTPStatus.UNAUTHORIZED,
detail=e.args[0],
) from e

return responses.RedirectResponse(f"{request_url}/finished")
return RedirectResponse(f"{request_url}/finished")


@router.get("/device/complete/finished")
Expand Down
13 changes: 7 additions & 6 deletions diracx-routers/src/diracx/routers/auth/management.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
from __future__ import annotations

import logging
from http import HTTPStatus
from typing import Annotated, Any

from fastapi import Depends, Form, HTTPException, status
from fastapi import Depends, Form, HTTPException
from joserfc.errors import DecodeError
from typing_extensions import TypedDict
from uuid_utils import UUID
Expand Down Expand Up @@ -92,12 +93,12 @@ async def revoke_refresh_token_by_refresh_token(
)
except ValueError as e:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
status_code=HTTPStatus.BAD_REQUEST,
detail=str(e),
) from e
except InvalidCredentialsError as e:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
status_code=HTTPStatus.UNAUTHORIZED,
detail=str(e),
headers={"WWW-Authenticate": "Bearer"},
) from e
Expand All @@ -124,17 +125,17 @@ async def revoke_refresh_token_by_jti(
await revoke_refresh_token_by_jti_bl(auth_db, subject, UUID(jti))
except ValueError as e:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
status_code=HTTPStatus.BAD_REQUEST,
detail=str(e),
) from e
except PermissionError as e:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
status_code=HTTPStatus.FORBIDDEN,
detail=str(e),
) from e
except TokenNotFoundError as e:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
status_code=HTTPStatus.NOT_FOUND,
detail=str(e),
) from e
return "Refresh token revoked"
Expand Down
21 changes: 11 additions & 10 deletions diracx-routers/src/diracx/routers/auth/token.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@

import logging
import os
from http import HTTPStatus
from typing import Annotated, Literal

from fastapi import Depends, Form, Header, HTTPException, status
from fastapi import Depends, Form, Header, HTTPException
from joserfc.errors import JoseError

from diracx.core.exceptions import (
Expand Down Expand Up @@ -47,7 +48,7 @@ async def mint_token(
"""Enrich the token with policy specific content and mint it."""
if not refresh_payload and not existing_refresh_token:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
detail="Refresh token is not set and no refresh token was provided",
)

Expand Down Expand Up @@ -140,26 +141,26 @@ async def get_oidc_token(
)
except PendingAuthorizationError as e:
raise DiracHttpResponseError(
status_code=status.HTTP_400_BAD_REQUEST,
status_code=HTTPStatus.BAD_REQUEST,
data={"error": "authorization_pending"},
) from e
except ValueError as e:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
status_code=HTTPStatus.BAD_REQUEST,
detail=str(e),
) from e
except (
InvalidCredentialsError,
JoseError,
) as e:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
status_code=HTTPStatus.UNAUTHORIZED,
detail=str(e),
headers={"WWW-Authenticate": "Bearer"},
) from e
except PermissionError as e:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
status_code=HTTPStatus.FORBIDDEN,
detail=str(e),
) from e
return await mint_token(
Expand Down Expand Up @@ -196,7 +197,7 @@ async def perform_legacy_exchange(
expected_api_key := os.environ.get("DIRACX_LEGACY_EXCHANGE_HASHED_API_KEY")
):
raise HTTPException(
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
status_code=HTTPStatus.SERVICE_UNAVAILABLE,
detail="Legacy exchange is not enabled",
)

Expand All @@ -214,18 +215,18 @@ async def perform_legacy_exchange(
)
except ValueError as e:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
status_code=HTTPStatus.BAD_REQUEST,
detail=str(e),
) from e
except InvalidCredentialsError as e:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
status_code=HTTPStatus.UNAUTHORIZED,
detail=str(e),
headers={"WWW-Authenticate": "Bearer"},
) from e
except PermissionError as e:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
status_code=HTTPStatus.FORBIDDEN,
detail=str(e),
) from e
return await mint_token(
Expand Down
6 changes: 3 additions & 3 deletions diracx-routers/src/diracx/routers/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@

import logging
from datetime import datetime, timezone
from http import HTTPStatus
from typing import Annotated

from fastapi import (
Header,
HTTPException,
Response,
status,
)

from diracx.routers.dependencies import Config
Expand Down Expand Up @@ -48,7 +48,7 @@ async def serve_config(
}

if if_none_match == config._hexsha:
raise HTTPException(status_code=status.HTTP_304_NOT_MODIFIED, headers=headers)
raise HTTPException(status_code=HTTPStatus.NOT_MODIFIED, headers=headers)

# This is to prevent flip/flopping in case
# a server gets out of sync with disk
Expand All @@ -64,7 +64,7 @@ async def serve_config(
else:
if not_before > config._modified:
raise HTTPException(
status_code=status.HTTP_304_NOT_MODIFIED, headers=headers
status_code=HTTPStatus.NOT_MODIFIED, headers=headers
)

response.headers.update(headers)
Expand Down
4 changes: 2 additions & 2 deletions diracx-routers/src/diracx/routers/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

import dotenv
from cachetools import TTLCache
from fastapi import APIRouter, Depends, FastAPI, HTTPException, Request, status
from fastapi import APIRouter, Depends, FastAPI, HTTPException, Request
from fastapi.dependencies.models import Dependant
from fastapi.exception_handlers import request_validation_exception_handler
from fastapi.exceptions import RequestValidationError
Expand Down Expand Up @@ -414,7 +414,7 @@ def route_unavailable_error_hander(request: Request, exc: DBUnavailableError):
exc_info=True,
)
return JSONResponse(
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
status_code=HTTPStatus.SERVICE_UNAVAILABLE,
headers={"Retry-After": "10"},
content={"detail": str(exc)},
)
Expand Down
17 changes: 9 additions & 8 deletions diracx-routers/src/diracx/routers/jobs/access_policies.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

from collections.abc import Callable
from enum import StrEnum, auto
from http import HTTPStatus
from typing import Annotated

from fastapi import Depends, HTTPException, status
from fastapi import Depends, HTTPException

from diracx.core.models import VectorSearchOperator
from diracx.core.properties import GENERIC_PILOT, JOB_ADMINISTRATOR, NORMAL_USER
Expand Down Expand Up @@ -60,7 +61,7 @@ async def policy(
"job_ids is not None with ActionType.CREATE. This shouldn't happen"
)
if NORMAL_USER not in user_info.properties:
raise HTTPException(status.HTTP_403_FORBIDDEN)
raise HTTPException(HTTPStatus.FORBIDDEN)
return

if GENERIC_PILOT in user_info.properties and action == ActionType.MANAGE:
Expand All @@ -71,7 +72,7 @@ async def policy(
return

if NORMAL_USER not in user_info.properties:
raise HTTPException(status.HTTP_403_FORBIDDEN)
raise HTTPException(HTTPStatus.FORBIDDEN)

if action == ActionType.QUERY:
if job_ids is not None:
Expand Down Expand Up @@ -109,7 +110,7 @@ async def policy(
if job_owners == [expected_owner]:
return

raise HTTPException(status.HTTP_403_FORBIDDEN)
raise HTTPException(HTTPStatus.FORBIDDEN)


CheckWMSPolicyCallable = Annotated[Callable, Depends(WMSAccessPolicy.check)]
Expand Down Expand Up @@ -138,14 +139,14 @@ async def policy(

if action == ActionType.CREATE:
if NORMAL_USER not in user_info.properties:
raise HTTPException(status.HTTP_403_FORBIDDEN)
raise HTTPException(HTTPStatus.FORBIDDEN)
return

if JOB_ADMINISTRATOR in user_info.properties:
return

if NORMAL_USER not in user_info.properties:
raise HTTPException(status.HTTP_403_FORBIDDEN)
raise HTTPException(HTTPStatus.FORBIDDEN)

# Getting a sandbox or modifying it
if pfns:
Expand All @@ -158,7 +159,7 @@ async def policy(
for pfn in pfns:
if not pfn.startswith(required_prefix):
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
status_code=HTTPStatus.FORBIDDEN,
detail=f"Invalid PFN. PFN must start with {required_prefix}",
)
# Checking if the user owns the sandbox
Expand All @@ -168,7 +169,7 @@ async def policy(
)
if not owner_id or owner_id != sandbox_owner_id:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
status_code=HTTPStatus.FORBIDDEN,
detail=f"{user_info.preferred_username} is not the owner of the sandbox",
)

Expand Down
Loading
Loading