Commit 28bf59af authored by Daniel Klaffenbach's avatar Daniel Klaffenbach 🐍

Cut of attribute values which are too long

Otherwise we might violate the database schema, if the values from LDAP
exceed the `max_length` defined by the user model.
parent 42e4ee53
Pipeline #5940 passed with stage
in 46 seconds
......@@ -6,6 +6,7 @@ from ldap3.core.exceptions import LDAPException
from ldap3.core.tls import Tls
from ldap3.utils.uri import parse_uri
from django.conf import settings
from django.contrib.auth import get_user_model
from django.utils.functional import cached_property
DEFAULT_LDAP_TIMEOUT = 3
......@@ -29,6 +30,15 @@ class Ldap(object):
self.LDAP_SYNC_USER_ATTRIBUTES = getattr(settings, 'LDAP_SYNC_USER_ATTRIBUTES', DEFAULT_LDAP_SYNC_USER_ATTRIBUTES)
self.LDAP_CA_CERT = getattr(settings, 'LDAP_CA_CERT', DEFAULT_CA_CERT)
self.LDAP_TIMEOUT = getattr(settings, 'LDAP_TIMEOUT', DEFAULT_LDAP_TIMEOUT)
# Get the `max_length` of synced attributes from the installed User model.
# This is used in `get_attributes` to cut off values which are too long for
# the database schema.
User = get_user_model()
self.USER_MODEL_ATTRS_MAX_LENGTH = {}
for field_name in self.LDAP_SYNC_USER_ATTRIBUTES.values():
field = User._meta.get_field(field_name)
self.USER_MODEL_ATTRS_MAX_LENGTH[field_name] = field.max_length
@cached_property
def connection(self):
......@@ -84,5 +94,9 @@ class Ldap(object):
if result:
for attr in self.LDAP_SYNC_USER_ATTRIBUTES:
if attr in conn.response[0]['attributes'] and conn.response[0]['attributes'][attr]:
model_attrs[self.LDAP_SYNC_USER_ATTRIBUTES[attr]] = conn.response[0]['attributes'][attr][0]
field_name = self.LDAP_SYNC_USER_ATTRIBUTES[attr]
ldap_value = conn.response[0]['attributes'][attr][0]
# Limit the LDAP value to the `max_length` of the field. Otherwise
# we run into validation errors.
model_attrs[field_name] = ldap_value[0:self.USER_MODEL_ATTRS_MAX_LENGTH[field_name]]
return model_attrs
......@@ -49,6 +49,16 @@ objectClass: inetOrgPerson
sn: Surname
userPassword: al1ce
dn: cn=Long Name,ou=Users,dc=example,dc=org
uid: long
givenName: Long Name
mail: longname@example.org
objectclass: top
objectclass: person
objectClass: inetOrgPerson
sn: This User Has A Very Long Surname Which Exceeds The Maximum Allowed Length
userPassword: l0ng
"""
......
......@@ -88,3 +88,16 @@ class LdapTestCase(TestCase):
self.assertEquals(user.last_name, '')
self.assertEquals(user.email, '')
def test_attribute_max_lenth(self):
"""
Tests if LDAP attributes, which are longer than the `max_length` of
the equivalent Django field, are cut off properly.
"""
last_name_field = self.USER_MODEL._meta.get_field('last_name')
if last_name_field.max_length >= 74:
self.skipTest("The `max_length` of the `last_name` field is too large for this test.")
with self.settings():
user = self.USER_MODEL.objects.create(username='long')
self.assertEquals(user.first_name, 'Long Name')
self.assertEquals(len(user.last_name), last_name_field.max_length)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment