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:
raise SCIMRequestException(None) from exc
raise SCIMRequestException(message="Failed to send request") from exc
self.logger.debug("scim request", path=path, method=method, **kwargs)
if response.status_code >= 400:
if response.status_code == 404:

View file

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

View file

@ -3,6 +3,7 @@ from typing import Optional
from pydanticscim.group import Group as BaseGroup
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 (
ServiceProviderConfiguration as BaseServiceProviderConfiguration,
@ -52,3 +53,9 @@ class PatchRequest(BasePatchRequest):
"""PatchRequest which correctly sets schemas"""
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)
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,
"error": str(exc),
"user_name": user.username,
"error": exc.detail(),
}
)
)
@ -100,7 +100,7 @@ def scim_sync_users(page: int, provider_pk: int):
_(
"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)
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,
"error": str(exc),
"group_name": group.name,
"error": exc.detail(),
}
)
)
@ -141,7 +141,7 @@ def scim_sync_group(page: int, provider_pk: int):
_(
"Stopping sync due to error: %(error)s"
% {
"error": str(exc),
"error": exc.detail(),
}
)
)