sources/ldap: handle user_sync errors better, show warning when user exists already

This commit is contained in:
Jens Langhammer 2020-02-19 16:20:33 +01:00
parent 995615d0a0
commit 07b7951390
1 changed files with 29 additions and 13 deletions

View File

@ -4,6 +4,7 @@ from typing import Any, Dict, Optional
import ldap3 import ldap3
import ldap3.core.exceptions import ldap3.core.exceptions
from structlog import get_logger from structlog import get_logger
from django.db.utils import IntegrityError
from passbook.core.exceptions import PropertyMappingExpressionException from passbook.core.exceptions import PropertyMappingExpressionException
from passbook.core.models import Group, User from passbook.core.models import Group, User
@ -94,12 +95,25 @@ class Connector:
) )
for user in users: for user in users:
attributes = user.get("attributes", {}) attributes = user.get("attributes", {})
try:
uniq = attributes[self._source.object_uniqueness_field]
except KeyError:
LOGGER.warning("Cannot find uniqueness Field in attributes")
continue
try:
user, created = User.objects.update_or_create( user, created = User.objects.update_or_create(
attributes__ldap_uniq=attributes.get( attributes__ldap_uniq=uniq,
self._source.object_uniqueness_field, ""
),
defaults=self._build_object_properties(attributes), defaults=self._build_object_properties(attributes),
) )
except IntegrityError as exc:
LOGGER.warning("Failed to create user", exc=exc)
LOGGER.warning(
(
"To merge new User with existing user, set the User's "
f"Attribute 'ldap_uniq' to '{uniq}'"
)
)
else:
if created: if created:
user.set_unusable_password() user.set_unusable_password()
user.save() user.save()
@ -155,13 +169,15 @@ class Connector:
) -> Dict[str, Dict[Any, Any]]: ) -> Dict[str, Dict[Any, Any]]:
properties = {"attributes": {}} properties = {"attributes": {}}
for mapping in self._source.property_mappings.all().select_subclasses(): for mapping in self._source.property_mappings.all().select_subclasses():
if not isinstance(mapping, LDAPPropertyMapping):
continue
mapping: LDAPPropertyMapping mapping: LDAPPropertyMapping
try: try:
properties[mapping.object_field] = mapping.evaluate( properties[mapping.object_field] = mapping.evaluate(
user=None, request=None, ldap=attributes user=None, request=None, ldap=attributes
) )
except PropertyMappingExpressionException as exc: except PropertyMappingExpressionException as exc:
LOGGER.warning(exc) LOGGER.warning("Mapping failed to evaluate", exc=exc, mapping=mapping)
continue continue
if self._source.object_uniqueness_field in attributes: if self._source.object_uniqueness_field in attributes:
properties["attributes"]["ldap_uniq"] = attributes.get( properties["attributes"]["ldap_uniq"] = attributes.get(