diff --git a/requirements-swh-server.txt b/requirements-swh-server.txt --- a/requirements-swh-server.txt +++ b/requirements-swh-server.txt @@ -2,4 +2,4 @@ swh.loader.core >= 0.0.71 swh.scheduler >= 0.7.0 swh.model >= 0.3.8 -swh.auth[django] >= 0.3.3 +swh.auth[django] >= 0.3.5 diff --git a/swh/deposit/auth.py b/swh/deposit/auth.py --- a/swh/deposit/auth.py +++ b/swh/deposit/auth.py @@ -3,6 +3,7 @@ # License: GNU General Public License version 3, or any later version # See top-level LICENSE file for more information +import json import logging from typing import Optional @@ -16,7 +17,7 @@ from swh.auth.django.models import OIDCUser from swh.auth.django.utils import oidc_user_from_profile -from swh.auth.keycloak import KeycloakOpenIDConnect +from swh.auth.keycloak import KeycloakError, KeycloakOpenIDConnect from swh.deposit.models import DepositClient from .errors import UNAUTHORIZED, make_error_response @@ -145,8 +146,11 @@ if not oidc_user: try: oidc_profile = self.client.login(user_id, password) - except Exception as e: - raise AuthenticationFailed(e) + except KeycloakError as e: + logger.debug("KeycloakError: e: %s", e) + msg_dict = json.loads(e.error_message.decode()) + error_msg = f"{msg_dict['error']}: {msg_dict['error_description']}" + raise AuthenticationFailed(error_msg) oidc_user = oidc_user_from_profile(self.client, oidc_profile) ttl = int( diff --git a/swh/deposit/tests/conftest.py b/swh/deposit/tests/conftest.py --- a/swh/deposit/tests/conftest.py +++ b/swh/deposit/tests/conftest.py @@ -7,6 +7,7 @@ from copy import deepcopy from functools import partial from io import BytesIO +import json import os import re from typing import TYPE_CHECKING, Dict, Mapping @@ -20,6 +21,7 @@ from rest_framework.test import APIClient import yaml +from swh.auth.keycloak import KeycloakError from swh.auth.pytest_plugin import keycloak_mock_factory from swh.core.config import read from swh.core.pytest_plugin import get_response_cb @@ -314,6 +316,13 @@ @pytest.fixture def mock_keycloakopenidconnect_ko(mocker, keycloak_mock_auth_failure): """Mock keycloak so it always refuses connections.""" + error = { + "error": "invalid_grant", + "error_description": "Invalid user credentials", + } + error_message = json.dumps(error).encode() + exception = KeycloakError(error_message=error_message, response_code=401) + keycloak_mock_auth_failure.login.side_effect = exception return mock_keycloakopenidconnect(mocker, keycloak_mock_auth_failure)