1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 """Test suite for repoze.who.plugins.ldap"""
18
19 import unittest
20
21 from dataflake.ldapconnection.tests import fakeldap
22 import ldap
23 from ldap import modlist, dn
24 from ldap.ldapobject import SimpleLDAPObject
25 from zope.interface.verify import verifyClass
26 from repoze.who.interfaces import IAuthenticator, IMetadataProvider
27
28 from repoze.who.plugins.ldap import LDAPAuthenticatorPlugin, \
29 LDAPAttributesPlugin, \
30 LDAPSearchAuthenticatorPlugin
31 from repoze.who.plugins.ldap.plugins import make_ldap_connection
32
33 from base64 import b64encode
34
35
36 -class Base(unittest.TestCase):
37 """Base test case for the plugins"""
38
40
41 conn = fakeldap.FakeLDAPConnection()
42 conn.simple_bind_s('Manager', 'some password')
43
44 fakeldap.addTreeItems(base_dn)
45
46 person_attr = {'cn': [fakeuser['cn']],
47 'uid': fakeuser['uid'],
48 'userPassword': [fakeuser['hashedPassword']],
49 'telephone': [fakeuser['telephone']],
50 'mail':[fakeuser['mail']]}
51 conn.add_s(fakeuser['dn'], modlist.addModlist(person_attr))
52 self.connection = conn
53
54 self.env = self._makeEnviron()
55
57 self.connection.delete_s(fakeuser['dn'])
58
60 """Create a fake WSGI environment
61
62 This is based on the same method of the test suite of repoze.who.
63
64 """
65 environ = {}
66 environ['wsgi.version'] = (1,0)
67 if kw is not None:
68 environ.update(kw)
69 return environ
70
71
72
73
74
76 """Tests for the constructor of the L{LDAPAuthenticatorPlugin} plugin"""
77
81
86
90
93
94
96 """Tests for the L{LDAPAuthenticatorPlugin} IAuthenticator plugin"""
97
102
105
107 result = self.plugin.authenticate(self.env, None)
108 self.assertEqual(result, None)
109
111 identity1 = {'login': fakeuser['uid']}
112 identity2 = {'password': fakeuser['password']}
113 result1 = self.plugin.authenticate(self.env, identity1)
114 result2 = self.plugin.authenticate(self.env, identity2)
115 self.assertEqual(result1, None)
116 self.assertEqual(result2, None)
117
119 identity = {'login': 'i_dont_exist',
120 'password': 'super secure password'}
121 result = self.plugin.authenticate(self.env, identity)
122 self.assertEqual(result, None)
123
125 identity = {'login': fakeuser['uid'],
126 'password': 'wrong password'}
127 result = self.plugin.authenticate(self.env, identity)
128 self.assertEqual(result, None)
129
131 identity = {'login': fakeuser['uid'],
132 'password': fakeuser['password']}
133 result = self.plugin.authenticate(self.env, identity)
134 self.assertEqual(result, fakeuser['dn'])
135
137 """L{LDAPAuthenticatorPlugin._get_dn} should be overriden with no
138 problems"""
139 plugin = CustomLDAPAuthenticatorPlugin(self.connection, base_dn)
140 identity = {'login': fakeuser['uid'],
141 'password': fakeuser['password']}
142 result = plugin.authenticate(self.env, identity)
143 expected = 'uid=%s,%s' % (fakeuser['uid'], base_dn)
144 self.assertEqual(result, expected)
145 self.assertTrue(plugin.called)
146
148 """Tests for the L{LDAPSearchAuthenticatorPlugin} IAuthenticator plugin"""
149
158
160 identity = {'login': 'i_dont_exist',
161 'password': 'super secure password'}
162 result = self.plugin.authenticate(self.env, identity)
163 self.assertEqual(result, None)
164
166 identity = {'login': fakeuser['telephone'],
167 'password': 'wrong password'}
168 result = self.plugin.authenticate(self.env, identity)
169 self.assertEqual(result, None)
170
172 identity = {'login': fakeuser['telephone'],
173 'password': fakeuser['password']}
174 result = self.plugin.authenticate(self.env, identity)
175 self.assertEqual(result, fakeuser['dn'])
176
178 """
179 Tests the L{LDAPAuthenticatorPlugin} IAuthenticator plugin returning
180 login.
181
182 """
183
192
194 identity = {'login': 'i_dont_exist',
195 'password': 'super secure password'}
196 result = self.plugin.authenticate(self.env, identity)
197 self.assertEqual(result, None)
198
200 identity = {'login': fakeuser['uid'],
201 'password': 'wrong password'}
202 result = self.plugin.authenticate(self.env, identity)
203 self.assertEqual(result, None)
204
206 identity = {'login': fakeuser['uid'],
207 'password': fakeuser['password']}
208 result = self.plugin.authenticate(self.env, identity)
209 self.assertEqual(result, fakeuser['uid'])
210
212 identity = {'login': fakeuser['uid'],
213 'password': fakeuser['password']}
214 expected_dn = '<dn:%s>' % b64encode(fakeuser['dn'])
215 result = self.plugin.authenticate(self.env, identity)
216 self.assertEqual(identity['userdata'], expected_dn)
217
218
220 """
221 Tests the L{LDAPSearchAuthenticatorPlugin} IAuthenticator plugin returning
222 login.
223
224 """
225
234
236 identity = {'login': 'i_dont_exist',
237 'password': 'super secure password'}
238 result = self.plugin.authenticate(self.env, identity)
239 self.assertEqual(result, None)
240
242 identity = {'login': fakeuser['uid'],
243 'password': 'wrong password'}
244 result = self.plugin.authenticate(self.env, identity)
245 self.assertEqual(result, None)
246
248 identity = {'login': fakeuser['uid'],
249 'password': fakeuser['password']}
250 result = self.plugin.authenticate(self.env, identity)
251 self.assertEqual(result, fakeuser['uid'])
252
254 identity = {'login': fakeuser['uid'],
255 'password': fakeuser['password']}
256 expected_dn = '<dn:%s>' % b64encode(fakeuser['dn'])
257 result = self.plugin.authenticate(self.env, identity)
258 self.assertEqual(identity['userdata'], expected_dn)
259
260
262 """Tests for the L{LDAPAuthenticatorPlugin} IAuthenticator plugin"""
263
269
272
273
275 """Tests for the constructor of L{LDAPAttributesPlugin}"""
276
279
281 """If attributes is None then fetch all the attributes"""
282 plugin = LDAPAttributesPlugin('ldap://localhost', None)
283 self.assertEqual(plugin.attributes, None)
284
286 attributes = "cn,uid,mail"
287 plugin = LDAPAttributesPlugin('ldap://localhost', attributes)
288 self.assertEqual(plugin.attributes, attributes.split(','))
289
291 attributes = "mail"
292 plugin = LDAPAttributesPlugin('ldap://localhost', attributes)
293 self.assertEqual(plugin.attributes, ['mail'])
294
296
297 attributes_t = ('cn', 'mail')
298 plugin_t = LDAPAttributesPlugin('ldap://localhost', attributes_t)
299 self.assertEqual(plugin_t.attributes, list(attributes_t))
300
301 attributes_l = ['cn', 'mail']
302 plugin_l = LDAPAttributesPlugin('ldap://localhost', attributes_l)
303 self.assertEqual(plugin_l.attributes, attributes_l)
304
305 attributes_d = {'first': 'cn', 'second': 'mail'}
306 plugin_d = LDAPAttributesPlugin('ldap://localhost', attributes_d)
307 self.assertEqual(plugin_d.attributes, list(attributes_d))
308
312
315
316
318 """Tests for the L{LDAPAttributesPlugin} IMetadata plugin"""
319
322
337
338
339
340
342 """Tests for L{make_ldap_connection}"""
343
347
349 conn = make_ldap_connection('ldap://example.org')
350 self.assertTrue(isinstance(conn, SimpleLDAPObject))
351
353 conn = make_ldap_connection(u'ldap://example.org')
354 self.assertTrue(isinstance(conn, SimpleLDAPObject))
355
358
359
360
361
363 """Connection use tests"""
364
366
367 conn = fakeldap.FakeLDAPConnection()
368 conn.simple_bind_s('Manager', 'some password')
369
370 fakeldap.addTreeItems(base_dn)
371
372 self.person_attr = {'cn': [fakeuser['cn']],
373 'uid': fakeuser['uid'],
374 'userPassword': [fakeuser['hashedPassword']],
375 'telephone':[fakeuser['telephone']],
376 'objectClass': ['top']}
377 conn.add_s(fakeuser['dn'], modlist.addModlist(self.person_attr))
378 self.connection = conn
379
381 self.connection.delete_s(fakeuser['dn'])
382
384 rs = self.connection.search_s(
385 base_dn,
386 ldap.SCOPE_SUBTREE,
387 '(uid=%s)' % fakeuser['uid'],
388 )
389 self.assertEqual(rs[0][0], fakeuser['dn'])
390 self.assertEqual(rs[0][1], self.person_attr )
391
393 rs = self.connection.search_s(
394 base_dn,
395 ldap.SCOPE_SUBTREE,
396 '(&(objectclass=*)(uid=%s))' % fakeuser['uid'],
397 )
398 self.assertEqual(rs[0][0], fakeuser['dn'])
399 self.assertEqual(rs[0][1], self.person_attr )
400
402 rs = self.connection.search_s(
403 base_dn,
404 ldap.SCOPE_SUBTREE,
405 'uid=%s' % fakeuser['uid'],
406 )
407 self.assertEqual(rs[0][0], fakeuser['dn'])
408 self.assertEqual(rs[0][1], self.person_attr )
409
411 rs = self.connection.search_s(
412 base_dn,
413 ldap.SCOPE_SUBTREE,
414 '(mail=%s)' % fakeuser['mail'],
415 )
416 self.assertEqual(rs[0][0], fakeuser['dn'])
417 self.assertEqual(rs[0][1], self.person_attr )
418
420 rs = self.connection.search_s(
421 base_dn,
422 ldap.SCOPE_SUBTREE,
423 '(telephone=+%s)' % fakeuser['telephone'],
424 )
425 self.assertEqual(rs[0][0], fakeuser['dn'])
426 self.assertEqual(rs[0][1], self.person_attr )
427
428
429
430 base_dn = 'ou=people,dc=example,dc=org'
431
432 fakeuser = {
433 'dn': 'uid=carla,%s' % base_dn,
434 'uid': 'carla',
435 'cn': 'Carla Paola',
436 'mail': 'carla@example.org',
437 'telephone': '39 123 456 789',
438 'password': 'hello',
439 'hashedPassword': '{SHA}qvTGHdzF6KLavt4PO0gs2a6pQ00='
440 }
441
442
444 """Fake class to test that L{LDAPAuthenticatorPlugin._get_dn} can be
445 overriden with no problems"""
446
447 - def _get_dn(self, environ, identity):
448 self.called = True
449 try:
450 return u'uid=%s,%s' % (identity['login'], self.base_dn)
451 except (KeyError, TypeError):
452 raise ValueError, ('Could not find the DN from the identity and '
453 'environment')
454
455
456
457
458
460 """
461 Return the test suite.
462
463 @return: The test suite for the plugin.
464 @rtype: C{unittest.TestSuite}
465
466 """
467 suite = unittest.TestSuite()
468 suite.addTest(unittest.makeSuite(TestLDAPConnection, "test"))
469 suite.addTest(unittest.makeSuite(TestMakeLDAPAuthenticatorPlugin, "test"))
470 suite.addTest(unittest.makeSuite(TestLDAPAuthenticatorPlugin, "test"))
471 suite.addTest(unittest.makeSuite(TestMakeLDAPAttributesPlugin, "test"))
472 suite.addTest(unittest.makeSuite(TestLDAPAttributesPlugin, "test"))
473 suite.addTest(unittest.makeSuite(TestLDAPConnectionFactory, "test"))
474 suite.addTest(unittest.makeSuite(TestLDAPSearchAuthenticatorPluginNaming,
475 "test"))
476 suite.addTest(unittest.makeSuite(TestLDAPAuthenticatorReturnLogin, "test"))
477 suite.addTest(unittest.makeSuite(TestLDAPSearchAuthenticatorReturnLogin,
478 "test"))
479 suite.addTest(unittest.makeSuite(TestLDAPAuthenticatorPluginStartTls,
480 "test"))
481 return suite
482
483
484 if __name__ == '__main__':
485 unittest.main(defaultTest='suite')
486