Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DM-47789: Convert to the Safir pagination support #1168

Merged
merged 3 commits into from
Nov 26, 2024
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
8 changes: 4 additions & 4 deletions docs/dev/internals.rst
Original file line number Diff line number Diff line change
Expand Up @@ -52,19 +52,19 @@ Python internal API
:include-all-objects:
:inherited-members:

.. automodapi:: gafaelfawr.models.history
.. automodapi:: gafaelfawr.models.enums
:include-all-objects:
:inherited-members:

.. automodapi:: gafaelfawr.models.kubernetes
.. automodapi:: gafaelfawr.models.history
:include-all-objects:
:inherited-members:

.. automodapi:: gafaelfawr.models.ldap
.. automodapi:: gafaelfawr.models.kubernetes
:include-all-objects:
:inherited-members:

.. automodapi:: gafaelfawr.models.link
.. automodapi:: gafaelfawr.models.ldap
:include-all-objects:
:inherited-members:

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ dependencies = [
"pyjwt",
"pyyaml",
"redis>=4.2.0",
"safir[db,kubernetes]>=6.5.1",
"safir[db,kubernetes]>=8.0.0",
"sentry-sdk[fastapi]",
"sqlalchemy>=2.0.0",
"structlog",
Expand Down
418 changes: 209 additions & 209 deletions requirements/dev.txt

Large diffs are not rendered by default.

370 changes: 179 additions & 191 deletions requirements/main.txt

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions requirements/tox.txt
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ uv==0.5.4 \
--hash=sha256:f511faf719b797ef0f14688f1abe20b3fd126209cf58512354d1813249745119 \
--hash=sha256:f806af0ee451a81099c449c4cff0e813056fdf7dd264f3d3a8fd321b17ff9efc
# via tox-uv
virtualenv==20.27.1 \
--hash=sha256:142c6be10212543b32c6c45d3d3893dff89112cc588b7d0879ae5a1ec03a47ba \
--hash=sha256:f11f1b8a29525562925f745563bfd48b189450f61fb34c4f9cc79dd5aa32a1f4
virtualenv==20.28.0 \
--hash=sha256:23eae1b4516ecd610481eda647f3a7c09aea295055337331bb4e6892ecce47b0 \
--hash=sha256:2c9c3262bb8e7b87ea801d715fae4495e6032450c71d2309be9550e7364049aa
# via tox
10 changes: 0 additions & 10 deletions src/gafaelfawr/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
"InvalidCSRFError",
"InvalidClientError",
"InvalidClientIdError",
"InvalidCursorError",
"InvalidDelegateToError",
"InvalidExpiresError",
"InvalidGrantError",
Expand Down Expand Up @@ -113,15 +112,6 @@ def __init__(self, message: str) -> None:
super().__init__(message, ErrorLocation.header, ["X-CSRF-Token"])


class InvalidCursorError(InputValidationError):
"""The provided cursor was invalid."""

error = "invalid_cursor"

def __init__(self, message: str) -> None:
super().__init__(message, ErrorLocation.query, ["cursor"])


class InvalidDelegateToError(InputValidationError):
"""The ``delegate_to`` parameter was set to an invalid value."""

Expand Down
18 changes: 13 additions & 5 deletions src/gafaelfawr/handlers/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,24 @@
from ..exceptions import ExternalUserInfoError, NotFoundError
from ..models.admin import Admin
from ..models.auth import APIConfig, APILoginResponse, Scope
from ..models.history import TokenChangeHistoryEntry
from ..models.enums import TokenType
from ..models.history import TokenChangeHistoryCursor, TokenChangeHistoryEntry
from ..models.token import (
AdminTokenRequest,
NewToken,
TokenData,
TokenInfo,
TokenType,
UserTokenModifyRequest,
UserTokenRequest,
)
from ..models.userinfo import UserInfo
from ..util import random_128_bits

router = APIRouter(route_class=SlackRouteErrorHandler)
"""Router for API routes."""

__all__ = ["router"]

router = APIRouter(route_class=SlackRouteErrorHandler)
authenticate_read = AuthenticateRead()
authenticate_write = AuthenticateWrite()
authenticate_admin_read = AuthenticateRead(
Expand Down Expand Up @@ -246,9 +248,12 @@ async def get_admin_token_change_history(
response: Response,
) -> list[dict[str, Any]]:
token_service = context.factory.create_token_service()
parsed_cursor = None
if cursor:
parsed_cursor = TokenChangeHistoryCursor.from_str(cursor)
results = await token_service.get_change_history(
auth_data,
cursor=cursor,
cursor=parsed_cursor,
limit=limit,
since=since,
until=until,
Expand Down Expand Up @@ -471,9 +476,12 @@ async def get_user_token_change_history(
response: Response,
) -> list[dict[str, Any]]:
token_service = context.factory.create_token_service()
parsed_cursor = None
if cursor:
parsed_cursor = TokenChangeHistoryCursor.from_str(cursor)
results = await token_service.get_change_history(
auth_data,
cursor=cursor,
cursor=parsed_cursor,
username=username,
limit=limit,
since=since,
Expand Down
3 changes: 2 additions & 1 deletion src/gafaelfawr/handlers/oidc.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,15 @@
from ..dependencies.context import RequestContext, context_dependency
from ..exceptions import InvalidRequestError, InvalidTokenError, OAuthError
from ..models.auth import AuthType
from ..models.enums import TokenType
from ..models.oidc import (
JWKS,
OIDCConfig,
OIDCErrorReply,
OIDCScope,
OIDCTokenReply,
)
from ..models.token import TokenData, TokenType
from ..models.token import TokenData

__all__ = ["router"]

Expand Down
64 changes: 64 additions & 0 deletions src/gafaelfawr/models/enums.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
"""Enums used in Gafaelfawr models.

Notes
-----
These are kept in a separate module because some models need to import ORM
objects in order to define pagination cursors, but ORM objects often refer to
enums for column definitions.
"""

from __future__ import annotations

from enum import Enum

__all__ = [
"AdminChange",
"TokenChange",
"TokenType",
]


class AdminChange(Enum):
"""Type of change made to a token admin."""

add = "add"
remove = "remove"


class TokenChange(Enum):
"""Type of change made to a token."""

create = "create"
revoke = "revoke"
expire = "expire"
edit = "edit"


class TokenType(Enum):
"""The class of token."""

session = "session"
"""An interactive user web session."""

user = "user"
"""A user-generated token that may be used programmatically."""

notebook = "notebook"
"""The token delegated to a Jupyter notebook for the user."""

internal = "internal"
"""Service-to-service token chained from a user request.

A service-to-service token used for internal sub-calls made as part of
processing a user request.
"""

service = "service"
"""Service-to-service token independent of a user request.

A service-to-service token used for internal calls initiated by
services, unrelated to a user request.
"""

oidc = "oidc"
"""Access token for an OpenID Connect client."""
Loading