Skip to content

Commit

Permalink
Change to correct API_AUTHORIZATION_FIELD & dump claims to sentry data
Browse files Browse the repository at this point in the history
  • Loading branch information
matti-lamppu committed Sep 25, 2024
1 parent d84d14e commit 2c2d7a9
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 15 deletions.
9 changes: 4 additions & 5 deletions api/gdpr/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,15 @@ def has_permission(self, request: Request, view: TilavarauspalveluGDPRAPIView) -
# Ensure request is made with by a strongly authenticated user,
# following best practices set by the City of Helsinki.
loa = request.auth.data.get("loa", "").lower()
required_loa = ["substantial", "high"]
has_correct_loa = loa in required_loa
allowed_loa = ["substantial", "high"]
has_correct_loa = loa in allowed_loa

details = {
"request_method": request_method,
"request_api_scopes": list(request.auth._authorized_api_scopes), # noqa: SLF001
"request_loa": loa,
"allowed_loa": required_loa,
"allowed_loa": allowed_loa,
"required_query_scope": settings.GDPR_API_QUERY_SCOPE,
"required_delete_scope": settings.GDPR_API_DELETE_SCOPE,
"auth_claims": request.auth.data,
}

if request.method == "GET":
Expand Down
3 changes: 1 addition & 2 deletions tests/test_gdpr_api/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ def patch_oidc_config():
def get_gdpr_auth_header(user: User, *, scopes: list[str], loa: Literal["substantial", "high", "low"] = "high") -> str:
audience = api_token_auth_settings.AUDIENCE
issuer = api_token_auth_settings.ISSUER
auth_field = api_token_auth_settings.API_AUTHORIZATION_FIELD

now = datetime.datetime.now(tz=get_default_timezone())
expire = now + datetime.timedelta(days=14)
Expand All @@ -41,7 +40,7 @@ def get_gdpr_auth_header(user: User, *, scopes: list[str], loa: Literal["substan
"iat": int(now.timestamp()),
"exp": int(expire.timestamp()),
"loa": loa,
auth_field: scopes,
"authorization": {"permissions": [{"scopes": scopes}]},
}
encoded_jwt = jwt.encode(jwt_data, key=RSA.private_key_pem, algorithm=RSA.jose_algorithm)
return f"{api_token_auth_settings.AUTH_SCHEME} {encoded_jwt}"
Expand Down
49 changes: 41 additions & 8 deletions tests/test_gdpr_api/test_gdpr_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from dateutil.relativedelta import relativedelta
from django.urls import reverse
from django.utils import timezone
from freezegun import freeze_time
from rest_framework.exceptions import ErrorDetail

from merchants.enums import OrderStatus
Expand Down Expand Up @@ -439,6 +440,7 @@ def test_query_user_data__not_authenticated(api_client, settings):


@patch_method(SentryLogger.log_message)
@freeze_time("2024-01-01T00:00:00")
def test_query_user_data__wrong_scope(api_client, settings):
user = UserFactory.create()

Expand All @@ -458,16 +460,24 @@ def test_query_user_data__wrong_scope(api_client, settings):
assert SentryLogger.log_message.call_args.kwargs == {
"details": {
"request_method": "GET",
"request_api_scopes": ["invalid"],
"request_loa": "high",
"allowed_loa": ["substantial", "high"],
"required_query_scope": "gdprquery",
"required_delete_scope": "gdprdelete",
"auth_claims": {
"aud": "TUNNISTAMO_AUDIENCE",
"authorization": {"permissions": [{"scopes": ["invalid"]}]},
"exp": 1705276800,
"iat": 1704067200,
"iss": "TUNNISTAMO_ISSUER",
"loa": "high",
"sub": str(user.uuid),
},
}
}


@patch_method(SentryLogger.log_message)
@freeze_time("2024-01-01T00:00:00")
def test_query_user_data__insufficient_loa(api_client, settings):
user = UserFactory.create(username="foo")

Expand All @@ -489,11 +499,18 @@ def test_query_user_data__insufficient_loa(api_client, settings):
assert SentryLogger.log_message.call_args.kwargs == {
"details": {
"request_method": "GET",
"request_api_scopes": ["gdprquery"],
"request_loa": "low",
"allowed_loa": ["substantial", "high"],
"required_query_scope": "gdprquery",
"required_delete_scope": "gdprdelete",
"auth_claims": {
"aud": "TUNNISTAMO_AUDIENCE",
"authorization": {"permissions": [{"scopes": ["gdprquery"]}]},
"exp": 1705276800,
"iat": 1704067200,
"iss": "TUNNISTAMO_ISSUER",
"loa": "low",
"sub": str(user.uuid),
},
}
}

Expand Down Expand Up @@ -735,6 +752,7 @@ def test_delete_user_data__not_authenticated(api_client, settings):


@patch_method(SentryLogger.log_message)
@freeze_time("2024-01-01T00:00:00")
def test_delete_user_data__wrong_scope(api_client, settings):
user = UserFactory.create(username="foo")

Expand All @@ -756,16 +774,24 @@ def test_delete_user_data__wrong_scope(api_client, settings):
assert SentryLogger.log_message.call_args.kwargs == {
"details": {
"request_method": "DELETE",
"request_api_scopes": ["invalid"],
"request_loa": "high",
"allowed_loa": ["substantial", "high"],
"required_query_scope": "gdprquery",
"required_delete_scope": "gdprdelete",
"auth_claims": {
"aud": "TUNNISTAMO_AUDIENCE",
"authorization": {"permissions": [{"scopes": ["invalid"]}]},
"exp": 1705276800,
"iat": 1704067200,
"iss": "TUNNISTAMO_ISSUER",
"loa": "high",
"sub": str(user.uuid),
},
}
}


@patch_method(SentryLogger.log_message)
@freeze_time("2024-01-01T00:00:00")
def test_delete_user_data__insufficient_loa(api_client, settings):
user = UserFactory.create(username="foo")

Expand All @@ -787,11 +813,18 @@ def test_delete_user_data__insufficient_loa(api_client, settings):
assert SentryLogger.log_message.call_args.kwargs == {
"details": {
"request_method": "DELETE",
"request_api_scopes": ["gdprdelete"],
"request_loa": "low",
"allowed_loa": ["substantial", "high"],
"required_query_scope": "gdprquery",
"required_delete_scope": "gdprdelete",
"auth_claims": {
"aud": "TUNNISTAMO_AUDIENCE",
"authorization": {"permissions": [{"scopes": ["gdprdelete"]}]},
"exp": 1705276800,
"iat": 1704067200,
"iss": "TUNNISTAMO_ISSUER",
"loa": "low",
"sub": str(user.uuid),
},
}
}

Expand Down
1 change: 1 addition & 0 deletions tilavarauspalvelu/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,7 @@ def OIDC_AUTH(cls):
def OIDC_API_TOKEN_AUTH(cls):
# See 'helusers/settings.py'
return {
"API_AUTHORIZATION_FIELD": "authorization.permissions.scopes",
"AUDIENCE": cls.GDPR_API_AUDIENCE,
"ISSUER": cls.GDPR_API_ISSUER,
}
Expand Down

0 comments on commit 2c2d7a9

Please sign in to comment.