def handle(self, *args, **options): self.ldap = LdapController() self.ldap.connect(LDAP_HOSTNAME, LDAP_PORT, LDAP_BASE_SEARCH, LDAP_PROTOCOL) ldap_groups = list( itertools.chain.from_iterable( [group['cn'] for group in self.ldap.get_groups_all()])) groups_to_create = RtGroup.objects.find_groups_not_listed(ldap_groups) if groups_to_create: for group in groups_to_create: RtGroup.objects.create(name=group, type=USER_DEFINED) tmp_set_for_unique_usernames = set() for ldap_groupname in args: tmp_set_for_unique_usernames.update( self.ldap.get_groups_member(ldap_groupname)) ldap_username_list = list(tmp_set_for_unique_usernames) rt_users = RtUser.objects.filter(name__in=ldap_username_list) for user in rt_users: user_groups = self._get_groups_from_ldap_user(user) for group in RtGroupMember.objects.extra_ldap_groups( user, user_groups): RtGroupMember.objects.create( group=RtGroup.objects.get(name=group), member=user) RtGroupMember.objects.filter( group__in=RtGroupMember.objects.extra_rt_groups( user, user_groups), member=user).delete()
class Command(BaseCommand): args = '<ldap_group> <ldap_group ...>' help = 'Synchronizes the LDAP groups and membership to RequestTracker' def handle(self, *args, **options): self.ldap = LdapController() self.ldap.connect(LDAP_HOSTNAME, LDAP_PORT, LDAP_BASE_SEARCH, LDAP_PROTOCOL) ldap_groups = list(itertools.chain.from_iterable([group['cn'] for group in self.ldap.get_groups_all()])) groups_to_create = RtGroup.objects.find_groups_not_listed(ldap_groups) if groups_to_create: for group in groups_to_create: RtGroup.objects.create(name=group, type=USER_DEFINED) tmp_set_for_unique_usernames = set() for ldap_groupname in args: tmp_set_for_unique_usernames.update(self.ldap.get_groups_member(ldap_groupname)) ldap_username_list = list(tmp_set_for_unique_usernames) rt_users = RtUser.objects.filter(name__in=ldap_username_list) for user in rt_users: user_groups = self._get_groups_from_ldap_user(user) for group in RtGroupMember.objects.extra_ldap_groups(user, user_groups): RtGroupMember.objects.create(group=RtGroup.objects.get(name=group), member=user) RtGroupMember.objects.filter(group__in=RtGroupMember.objects.extra_rt_groups(user, user_groups), member=user).delete() def _get_groups_from_ldap_user(self, ldap_username): return self.ldap.get_groups(ldap_username)
def setUp(self): mock_ldap = mock.MagicMock(simpleldap) self.module = LdapController(mock_ldap)
class LDAPTestCase(unittest.TestCase): def setUp(self): mock_ldap = mock.MagicMock(simpleldap) self.module = LdapController(mock_ldap) def _mock_valid_connection(self): connection_mock = mock.MagicMock(name='LdapController._connection') connection_mock.return_value = True self.module.Connection = connection_mock #setattr(self.module, '_connection', connection_mock) def test_connect_fail_no_hostname(self): self.assertRaises(ValueError, lambda: self.module.connect(None, 412)) def test_connect_hostname_set(self): self.module.connect('a_hostname', 666, None, None) self.assertEquals('a_hostname', getattr(self.module, 'hostname')) def test_connect_fail_no_port(self): self.assertRaises(ValueError, lambda: self.module.connect('foo', None)) self.assertRaises(ValueError, lambda: self.module.connect('foo', 0)) def test_connect_fail_port_below_1(self): self.assertRaises(ValueError, lambda: self.module.connect('foo', -1)) def test_connect_fail_port_above_65535(self): self.assertRaises(ValueError, lambda: self.module.connect('foo', 65536)) def test__mock_valid_connection(self): self._mock_valid_connection() self.assertFalse(getattr(self.module, '_connection')) self.assertFalse(self.module.is_connected()) self.assertTrue(self.module.connect('foo', 1)) self.assertTrue(getattr(self.module, '_connection')) self.assertTrue(self.module.is_connected()) self.module.close() self.assertFalse(getattr(self.module, '_connection')) self.assertFalse(self.module.is_connected()) def test_connect_min_valid_port(self): self._mock_valid_connection() self.assertTrue(self.module.connect('foo', 1)) def test_connect_max_valid_port(self): self._mock_valid_connection() self.assertTrue(self.module.connect('foo', 65535)) def test_if_protocol_is_ssl_on_ssl_port(self): self.module.connect('foo', 636, None, 'ldap') self.assertEquals('ldaps', getattr(self.module, '_protocol')) def test_if_protocol_ldap(self): self.module.connect('foo', 2323, None, 'ldap') self.assertEquals('ldap', getattr(self.module, '_protocol')) def test_if_protocol_ldaps(self): self.module.connect('foo', 2323, None, 'ldaps') self.assertEquals('ldaps', getattr(self.module, '_protocol')) def test_get_users_without_connection(self): self.assertRaises(simpleldap.ConnectionException, lambda: self.module.get_users()) def test_get_groups_without_connection(self): self.assertRaises(simpleldap.ConnectionException, lambda: self.module.get_groups('foo')) def test_get_users_single_row(self): self._mock_valid_connection() self.assertTrue(self.module.connect('foo', 1)) self.module._get_search_results = mock.MagicMock(name='ldap._get_search_results') self.module._get_search_results.return_value = [{'cn': ['tadaa'], 'objectclass': ['account', 'posixAccount'], 'loginshell': ['/bin/bash'], 'uidnumber': ['1000'], 'gidnumber': ['1000'], 'gecos': ['Rockj'], 'homedirectory': ['/home/rockj'], 'uid': ['tadaa']}] #[{'cn': ['tadaa'], 'objectclass': ['account', 'posixAccount'], 'loginshell': ['/bin/bash'], 'uidnumber': ['1000'], 'gidnumber': ['1000'], 'gecos': ['Rockj'], 'homedirectory': ['/home/rockj'], 'uid': ['tadaa']}] results = self.module.get_users() self.assertEquals(1, len(results)) self.assertEquals('tadaa', results[0]['cn'][0]) self.assertTrue(results[0]['uidnumber']) self.assertEquals('1000', results[0]['uidnumber'][0]) def test_get_users_multiple_rows(self): self._mock_valid_connection() self.assertTrue(self.module.connect('foo', 1)) self.module._get_search_results = mock.MagicMock(name='ldap._get_search_results') self.module._get_search_results = mock.MagicMock(name='ldap._get_search_results') self.module._get_search_results.return_value = [{'cn': ['tadaa'], 'objectclass': ['account', 'posixAccount'], 'loginshell': ['/bin/bash'], 'uidnumber': ['1000'], 'gidnumber': ['1000'], 'gecos': ['Rockj'], 'homedirectory': ['/home/rockj'], 'uid': ['tadaa']}, {'cn': ['jadda'], 'objectclass': ['account', 'posixAccount'], 'loginshell': ['/bin/bash'], 'uidnumber': ['1001'], 'gidnumber': ['1001'], 'gecos': ['Rasasd'], 'homedirectory': ['/home/sdaf'], 'uid': ['jadda']}] results = self.module.get_users() self.assertEquals(2, len(results)) def test_get_users_usernames(self): self._mock_valid_connection() self.assertTrue(self.module.connect('foo', 1)) self.module._get_search_results = mock.MagicMock(name='ldap._get_search_results') self.module._get_search_results = mock.MagicMock(name='ldap._get_search_results') self.module._get_search_results.return_value = [{'cn': ['tadaa'], 'objectclass': ['account', 'posixAccount'], 'loginshell': ['/bin/bash'], 'uidnumber': ['1000'], 'gidnumber': ['1000'], 'gecos': ['Rockj'], 'homedirectory': ['/home/rockj'], 'uid': ['tadaa']}, {'cn': ['jadda'], 'objectclass': ['account', 'posixAccount'], 'loginshell': ['/bin/bash'], 'uidnumber': ['1001'], 'gidnumber': ['1001'], 'gecos': ['Rasasd'], 'homedirectory': ['/home/sdaf'], 'uid': ['jadda']}] results = self.module.get_users() self.assertEquals(2, len(results)) def test_get_groups_no_groups(self): self._mock_valid_connection() self.assertTrue(self.module.connect('foo', 1)) self.module._get_search_results = mock.MagicMock(name='ldap._get_search_results') self.module._get_search_results.return_value = [] results = self.module.get_groups('unknown_user') self.assertEquals(0, len(results)) def test_get_groups_for_user_single_row(self): self._mock_valid_connection() self.assertTrue(self.module.connect('foo', 1)) self.module._get_search_results = mock.MagicMock(name='ldap._get_search_results') self.module._get_search_results.return_value = [{'cn': ['dotkom'], 'gidNumber': ['22'], 'memberUid': ['fellingh', 'norangsh' 'dagolap'], 'objectClass': ['posixGroup', 'top']}] results = self.module.get_groups('norangsh') self.assertEquals(1, len(results)) def test_get_groups_for_user_multiple_rows(self): self._mock_valid_connection() self.assertTrue(self.module.connect('foo', 1)) self.module._get_search_results = mock.MagicMock(name='ldap._get_search_results') self.module._get_search_results.return_value = [{'cn': ['dotkom'], 'gidNumber': ['42'], 'memberUid': ['glennrub', 'fellingh', 'norangsh'], 'objectClass': ['posixGroup', 'top']}, {'cn': ['komiteer'], 'gidNumber': ['69'], 'memberUid': ['glennrub', 'dagolap', 'norangsh'], 'objectClass': ['posixGroup', 'top']}] results = self.module.get_groups('norangsh') self.assertEquals(2, len(results)) def test_get_groups_membership(self): self._mock_valid_connection() self.assertTrue(self.module.connect('foo', 1)) self.module._get_search_results = mock.MagicMock(name='ldap._get_search_results') self.module._get_search_results.return_value = [{'cn': ['dotkom'], 'memberUid': ['norangsh', 'dagolap', 'fellingh']}] results = self.module.get_groups_member('dotkom') import itertools chain = itertools.chain.from_iterable([group['memberUid'] for group in results]) self.assertEquals(['norangsh', 'dagolap', 'fellingh'], list(chain)) def test_get_groups_membership_too_many_groups_returned(self): # This case should never happen tho # as CN has to be unique. self._mock_valid_connection() self.assertTrue(self.module.connect('foo', 1)) self.module._get_search_results = mock.MagicMock(name='ldap._get_search_results') self.module._get_search_results.return_value = [{'cn': ['dotkom'], 'memberUid': ['norangsh', 'dagolap', 'fellingh']}, {'cn': ['dotfood'], 'memberUid': ['norangsh', 'dagolap', 'fellingh']}] self.assertRaises(ValueError, lambda: self.module.get_groups_member('dot'))