Skip to content
Snippets Groups Projects
Commit 7162f01b authored by Jenkins for Software Heritage's avatar Jenkins for Software Heritage
Browse files

New upstream version 0.6.1

parents 97461398 508b476d
No related branches found
No related tags found
No related merge requests found
Metadata-Version: 2.1
Name: swh.auth
Version: 0.6.0
Version: 0.6.1
Summary: Software Heritage Authentication Utilities
Home-page: https://forge.softwareheritage.org/source/swh-auth/
Author: Software Heritage developers
......
Metadata-Version: 2.1
Name: swh.auth
Version: 0.6.0
Version: 0.6.1
Summary: Software Heritage Authentication Utilities
Home-page: https://forge.softwareheritage.org/source/swh-auth/
Author: Software Heritage developers
......
......@@ -106,7 +106,8 @@ class OIDCAuthorizationCodePKCEBackend:
def get_user(self, user_id: int) -> Optional[OIDCUser]:
# get oidc profile from cache
oidc_client = keycloak_oidc_client()
oidc_profile = cache.get(oidc_profile_cache_key(oidc_client, user_id))
cache_key = oidc_profile_cache_key(oidc_client, user_id)
oidc_profile = cache.get(cache_key)
if oidc_profile:
try:
user = oidc_user_from_profile(oidc_client, oidc_profile)
......@@ -115,6 +116,12 @@ class OIDCAuthorizationCodePKCEBackend:
# restore auth backend
setattr(user, "backend", f"{__name__}.{self.__class__.__name__}")
return user
except KeycloakError as ke:
error_msg = keycloak_error_message(ke)
if error_msg == "invalid_grant: Session not active":
# user session no longer active, remove oidc profile from cache
cache.delete(cache_key)
return None
except Exception as e:
sentry_sdk.capture_exception(e)
return None
......
......@@ -4,17 +4,19 @@
# See top-level LICENSE file for more information
from datetime import datetime, timedelta
import json
from unittest.mock import Mock
from django.conf import settings
from django.contrib.auth import authenticate, get_backends
from django.core.cache import cache
import pytest
from rest_framework.exceptions import AuthenticationFailed
from swh.auth.django.backends import OIDCBearerTokenAuthentication
from swh.auth.django.models import OIDCUser
from swh.auth.django.utils import reverse
from swh.auth.keycloak import ExpiredSignatureError
from swh.auth.django.utils import oidc_profile_cache_key, reverse
from swh.auth.keycloak import ExpiredSignatureError, KeycloakError
def _authenticate_user(request_factory):
......@@ -123,18 +125,43 @@ def test_oidc_code_pkce_auth_backend_refresh_token_failure(
"""
Checks access token renewal failure using refresh token.
"""
# authenticate user
user = _authenticate_user(request_factory)
assert user is not None
# OIDC profile should be in cache
cache_key = oidc_profile_cache_key(keycloak_oidc, user.id)
assert cache.get(cache_key) is not None
# simulate terminated OIDC session
keycloak_oidc.decode_token = Mock()
keycloak_oidc.decode_token.side_effect = ExpiredSignatureError(
"access token token has expired"
)
keycloak_oidc.refresh_token.side_effect = Exception("OIDC session has expired")
user = _authenticate_user(request_factory)
kc_error_dict = {
"error": "invalid_grant",
"error_description": "Session not active",
}
keycloak_oidc.refresh_token.side_effect = KeycloakError(
error_message=json.dumps(kc_error_dict).encode(), response_code=400
)
backend_path = "swh.auth.django.backends.OIDCAuthorizationCodePKCEBackend"
assert user.backend == backend_path
backend_idx = settings.AUTHENTICATION_BACKENDS.index(backend_path)
# try to authenticate user again from its id and cached OIDC profile
user = get_backends()[backend_idx].get_user(user.id)
# it should have tried to refresh token
oidc_profile = keycloak_oidc.login()
keycloak_oidc.refresh_token.assert_called_with(oidc_profile["refresh_token"])
# authentication failed
assert user is None
# invalid OIDC profile should have been removed from cache
assert cache.get(cache_key) is None
@pytest.mark.django_db
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment