From 049f79dc87e325fc239340f7cff8d36562a827e7 Mon Sep 17 00:00:00 2001 From: Arkadiusz Adamski Date: Thu, 9 Apr 2015 09:39:57 +0200 Subject: [PATCH] fixed unicode error and empty country by default in LDAP Prevent error like ``UnicodeEncodeError: 'ascii' codec can't encode character``. --- .travis.yml | 1 + src/ralph/account/ldap.py | 10 ++++-- src/ralph/account/tests/test_models.py | 45 ++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6fb3cdd4d0..2a5a6322e5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,6 +16,7 @@ install: - make install - pip install coveralls - pip install flake8 + - pip install django-auth-ldap==1.1.3 # command to run tests, e.g. python setup.py test diff --git a/src/ralph/account/ldap.py b/src/ralph/account/ldap.py index 7104459a09..a8a4bcbe56 100644 --- a/src/ralph/account/ldap.py +++ b/src/ralph/account/ldap.py @@ -50,14 +50,20 @@ def manager_country_attribute_populate(sender, profile, ldap_user, **kwargs): if profile_map['manager'] in ldap_user.attrs: manager_ref = ldap_user.attrs[profile_map['manager']][0] # CN=John Smith,OU=TOR,OU=Corp-Users,DC=mydomain,DC=internal - manager_ref = manager_ref.decode('utf-8') + # prevent UnicodeEncodeError + if not isinstance(manager_ref, unicode): + manager_ref = manager_ref.decode('utf-8') cn = manager_ref.split(',')[0][3:] profile.manager = cn + # raw value from LDAP is in profile.country for this reason we assign + # some correct value + profile.country = None if 'country' in profile_map: if profile_map['country'] in ldap_user.attrs: country = ldap_user.attrs[profile_map['country']][0] if len(country) == 2: - profile.country = getattr(Country, country.lower()) + # assign None if `country` doesn't exist in Country + profile.country = getattr(Country, country.lower(), None) class MappedGroupOfNamesType(ActiveDirectoryGroupType): diff --git a/src/ralph/account/tests/test_models.py b/src/ralph/account/tests/test_models.py index cc81381ddb..de61068f14 100644 --- a/src/ralph/account/tests/test_models.py +++ b/src/ralph/account/tests/test_models.py @@ -12,6 +12,7 @@ from django.conf import settings from ralph.account.models import Region from ralph.account.tests import utils +from ralph.account.ldap import manager_country_attribute_populate try: @@ -71,3 +72,47 @@ def test_short_surname_stays_unmodified(self): def test_truncate_works_when_no_sn(self): ldap_dict = {} _truncate_surname(ldap_dict) + + +@unittest.skipIf(NO_LDAP_MODULE, "'ldap' module is not installed") +class LdapPopulateTest(TestCase): + + def _get_mocked_ldap_user(self, attrs): + class MockedLdapUser(object): + @property + def attrs(self): + return attrs + return MockedLdapUser() + + def test_manager_country_attribute_populate_country(self): + ldap_attr = 'c' + override_settings = {'country': ldap_attr} + user = utils.UserFactory() + user_profile = user.get_profile() + faked_ldap_user = self._get_mocked_ldap_user({ + ldap_attr: ['XXX'] + }) + with self.settings(AUTH_LDAP_PROFILE_ATTR_MAP=override_settings): + manager_country_attribute_populate( + None, user_profile, faked_ldap_user + ) + self.assertEqual(user_profile.country, None) + + def test_manager_country_attribute_populate_unicode_in_manager(self): + ldap_attr = 'manager' + override_settings = {'manager': ldap_attr} + manager_names = [unicode('Żółcień'), str('John Smith')] + user = utils.UserFactory() + user_profile = user.get_profile() + + for manager_name in manager_names: + faked_ldap_user = self._get_mocked_ldap_user({ + ldap_attr: ['CN={},OU=XXX,DC=group'.format(manager_name)] + }) + + with self.settings(AUTH_LDAP_PROFILE_ATTR_MAP=override_settings): + manager_country_attribute_populate( + None, user_profile, faked_ldap_user + ) + self.assertEqual(user_profile.manager, manager_name) + self.assertTrue(isinstance(user_profile.manager, unicode))