providers/scim: improve SCIM error messages (#5600)

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
Jens L 2023-05-15 14:39:27 +02:00 committed by GitHub
parent 259c87fa37
commit 47f09ac285
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 26 additions and 15 deletions

View File

@ -51,7 +51,7 @@ class SCIMClient(Generic[T, SchemaType]):
}, },
) )
except RequestException as exc: except RequestException as exc:
raise SCIMRequestException(None) from exc raise SCIMRequestException(message="Failed to send request") from exc
self.logger.debug("scim request", path=path, method=method, **kwargs) self.logger.debug("scim request", path=path, method=method, **kwargs)
if response.status_code >= 400: if response.status_code >= 400:
if response.status_code == 404: if response.status_code == 404:

View File

@ -2,10 +2,10 @@
from typing import Optional from typing import Optional
from pydantic import ValidationError from pydantic import ValidationError
from pydanticscim.responses import SCIMError
from requests import Response from requests import Response
from authentik.lib.sentry import SentryIgnoredException from authentik.lib.sentry import SentryIgnoredException
from authentik.providers.scim.clients.schema import SCIMError
class StopSync(SentryIgnoredException): class StopSync(SentryIgnoredException):
@ -16,7 +16,8 @@ class StopSync(SentryIgnoredException):
self.obj = obj self.obj = obj
self.mapping = mapping self.mapping = mapping
def __str__(self) -> str: def detail(self) -> str:
"""Get human readable details of this error"""
msg = f"Error {str(self.exc)}, caused by {self.obj}" msg = f"Error {str(self.exc)}, caused by {self.obj}"
if self.mapping: if self.mapping:
@ -28,19 +29,22 @@ class SCIMRequestException(SentryIgnoredException):
"""Exception raised when an SCIM request fails""" """Exception raised when an SCIM request fails"""
_response: Optional[Response] _response: Optional[Response]
_message: Optional[str]
def __init__(self, response: Optional[Response] = None) -> None: def __init__(self, response: Optional[Response] = None, message: Optional[str] = None) -> None:
self._response = response self._response = response
self._message = message
def __str__(self) -> str: def detail(self) -> str:
"""Get human readable details of this error"""
if not self._response: if not self._response:
return super().__str__() return self._message
try: try:
error = SCIMError.parse_raw(self._response.text) error = SCIMError.parse_raw(self._response.text)
return error.detail return error.detail
except ValidationError: except ValidationError:
pass pass
return super().__str__() return self._message
class ResourceMissing(SCIMRequestException): class ResourceMissing(SCIMRequestException):

View File

@ -3,6 +3,7 @@ from typing import Optional
from pydanticscim.group import Group as BaseGroup from pydanticscim.group import Group as BaseGroup
from pydanticscim.responses import PatchRequest as BasePatchRequest from pydanticscim.responses import PatchRequest as BasePatchRequest
from pydanticscim.responses import SCIMError as BaseSCIMError
from pydanticscim.service_provider import Bulk, ChangePassword, Filter, Patch from pydanticscim.service_provider import Bulk, ChangePassword, Filter, Patch
from pydanticscim.service_provider import ( from pydanticscim.service_provider import (
ServiceProviderConfiguration as BaseServiceProviderConfiguration, ServiceProviderConfiguration as BaseServiceProviderConfiguration,
@ -52,3 +53,9 @@ class PatchRequest(BasePatchRequest):
"""PatchRequest which correctly sets schemas""" """PatchRequest which correctly sets schemas"""
schemas: tuple[str] = ["urn:ietf:params:scim:api:messages:2.0:PatchOp"] schemas: tuple[str] = ["urn:ietf:params:scim:api:messages:2.0:PatchOp"]
class SCIMError(BaseSCIMError):
"""SCIM error with optional status code"""
status: Optional[int]

View File

@ -87,10 +87,10 @@ def scim_sync_users(page: int, provider_pk: int):
LOGGER.warning("failed to sync user", exc=exc, user=user) LOGGER.warning("failed to sync user", exc=exc, user=user)
messages.append( messages.append(
_( _(
"Failed to sync user due to remote error %(name)s: %(error)s" "Failed to sync user %(user_name)s due to remote error: %(error)s"
% { % {
"name": user.username, "user_name": user.username,
"error": str(exc), "error": exc.detail(),
} }
) )
) )
@ -100,7 +100,7 @@ def scim_sync_users(page: int, provider_pk: int):
_( _(
"Stopping sync due to error: %(error)s" "Stopping sync due to error: %(error)s"
% { % {
"error": str(exc), "error": exc.detail(),
} }
) )
) )
@ -128,10 +128,10 @@ def scim_sync_group(page: int, provider_pk: int):
LOGGER.warning("failed to sync group", exc=exc, group=group) LOGGER.warning("failed to sync group", exc=exc, group=group)
messages.append( messages.append(
_( _(
"Failed to sync group due to remote error %(name)s: %(error)s" "Failed to sync group %(group_name)s due to remote error: %(error)s"
% { % {
"name": group.name, "group_name": group.name,
"error": str(exc), "error": exc.detail(),
} }
) )
) )
@ -141,7 +141,7 @@ def scim_sync_group(page: int, provider_pk: int):
_( _(
"Stopping sync due to error: %(error)s" "Stopping sync due to error: %(error)s"
% { % {
"error": str(exc), "error": exc.detail(),
} }
) )
) )