root/AuthKit/trunk/test/test.py

Revision 152 (checked in by thejimmyg, 8 months ago)

Added a series of updates to SQLAlchemy code plus a fix to the OpenID support and an encoding problem with form.py

Line 
1 """
2 Very basic tests which so no more than check each of the authentication
3 methods to ensure that an unprotected page is accessible and that a
4 protected page triggers the a sign in.
5
6 Note: Should the Form and Forward methods return 401 or 200 when they
7 generate an HTML page for the user to sign in?
8 """
9
10 import sys
11 import os
12 import paste.lint
13
14 from authkit.authenticate import middleware, sample_app
15 from paste.fixture import *
16
17 sys.path.insert(0, os.getcwd()+'/examples/docs')
18
19 from form import app as form_app
20 from basic import app as basic_app
21 from digest import app as digest_app
22 from forward import app as forward_app
23 from open_id import app as openid_app
24 from redirect import app as redirect_app
25
26 # Add the paste validation middleware
27 form_app = paste.lint.middleware(form_app)
28 basic_app = paste.lint.middleware(basic_app)
29 digest_app = paste.lint.middleware(digest_app)
30 forward_app = paste.lint.middleware(forward_app)
31 openid_app = paste.lint.middleware(openid_app)
32 redirect_app = paste.lint.middleware(redirect_app)
33
34 sys.path.insert(0, os.getcwd()+'/examples/config')
35 from digest import app as config_app
36
37 def assertEqual(a,b):
38     if a != b:
39         raise AssertionError('%s != %s'%(a,b))
40
41 def assertAllEqual(*args):
42     if not len(args)>2:
43         raise Exception("Need two arguments")
44     a = args[0]
45     for b in args[1:]:
46         if a != b:
47             raise AssertionError('%s != %s'%(a,b))
48
49 apps = [
50     form_app,
51     basic_app,
52     digest_app,
53     forward_app,
54     openid_app,
55     redirect_app,
56     config_app,
57 ]
58
59 def test_ok():
60     for app in apps:
61         if app == forward_app:
62             res = TestApp(app).get('')
63             assertEqual(res.header('content-type'), 'text/plain')
64             assertEqual(res.full_status, '200 OK')
65             assert 'You Have Access To This Page.' in res
66         else:
67             res = TestApp(app).get('')
68             assertEqual(res.header('content-type'), 'text/plain; charset=UTF-8')
69             assertEqual(res.full_status, '200 OK')
70             assert 'You Have Access To This Page.' in res
71
72 def test_intercept():
73     # XXX Note, these tests don't test when the inclusion of a username and only test form
74     # should also test all the other methods too for correct behaviour
75     def sample_app(environ, start_response):
76         if environ.get('PATH_INFO') == '/403':
77             start_response('403 Forbidden', [('Content-type', 'text/plain')])
78             return ['Access denied']
79         elif environ.get('PATH_INFO') == '/401':
80             start_response('401 Unauth', [('Content-type', 'text/plain')])
81             return ['Not Authed']
82         elif environ.get('PATH_INFO') == '/702':
83             start_response('702 Doesnt exist', [('Content-type', 'text/plain')])
84             return ['Access denied']
85         elif environ.get('PATH_INFO') == '/500':
86             start_response('500 Error', [('Content-type', 'text/plain')])
87             return ['Error']
88
89     app = middleware(
90         sample_app,
91         setup_method='digest',
92         digest_realm='test',
93         digest_authenticate_user_data = """
94             Username1:password1
95             username2:password2
96         """,
97         cookie_signoutpath = '/signout',
98         setup_intercept = "403, 702",
99     )
100     res = TestApp(app).get('/403', status=401)
101     assertEqual(res.header('content-type'), 'text/plain')
102     # XXX Should this keep the original status code or not?
103     assertEqual(res.full_status, '401 Unauthorized')
104     assert 'This server could not verify that you are authorized' in res
105
106     res = TestApp(app).get('/702', status=401)
107     assertEqual(res.header('content-type'), 'text/plain')
108     # XXX Should this keep the original status code or not?
109     assertEqual(res.full_status, '401 Unauthorized')
110     assert 'This server could not verify that you are authorized' in res
111
112     res = TestApp(app).get('/500', status=500)
113     assertEqual(res.header('content-type'), 'text/plain')
114     assertEqual(res.full_status, '500 Error')
115     assert 'Error' in res
116    
117     res = TestApp(app).get('/401', status=401)
118     assertEqual(res.header('content-type'), 'text/plain')
119     assertEqual(res.full_status, '401 Unauth')
120     assert 'Not Authed' in res
121    
122 def test_fail():
123     for app in [basic_app, digest_app, config_app]:
124         res = TestApp(app).get('/private', status=401)
125         assertEqual(res.header('content-type'),'text/plain')
126         assertEqual(res.full_status, '401 Unauthorized')
127         #raise Exception(res)
128         assert 'This server could not verify that you are' in res
129
130 def test_form_fail():
131     res = TestApp(form_app).get('/private', status=200)
132     assertEqual(res.header('content-type'),'text/html; charset=UTF-8')
133     assertEqual(res.full_status, '200 OK')
134     assert 'Please Sign In' in res
135
136 def test_forward_fail():
137     res = TestApp(forward_app).get('/private')
138     assertEqual(res.header('content-type'),'text/html')
139     # XXX Not sure about this but using a 401 triggers an infinite loop
140     # of redirects.
141     assertEqual(res.full_status, '200 Sign in required')
142     assert 'Please Sign In' in res
143
144 def test_openid_fail():
145     res = TestApp(openid_app).get('/private')
146     assertEqual(res.header('content-type'),'text/html; charset=UTF-8')
147     assertEqual(res.full_status, '200 OK')
148     assert 'Please Sign In' in res
149
150 def test_redirect_fail():
151     res = TestApp(redirect_app).get('/private', status=302)
152     assertEqual(res.header('Location'),'http://3aims.com')
153     assertEqual(res.full_status, '302 Found')
154
155 def test_users_api_database():
156     try:
157         from authkit.users.sqlalchemy_04_driver import UsersFromDatabase, setup_model
158     except ImportError:
159         raise Exception("Could not run the SQLAlchemy tests, not installed")
160     try:
161         from sqlalchemymanager import SQLAlchemyManager
162     except ImportError:
163         raise Exception("Could not run the SQLAlchemy tests, SQLAlchemyManager is not installed")
164     if os.path.exists("mydb.db"):
165         os.remove("mydb.db")
166
167     app = SQLAlchemyManager(
168         None,
169         {'sqlalchemy.url':'sqlite:///mydb.db'},
170         [setup_model]
171     )
172     app.create_all()
173     connection = app.engine.connect()
174     session = app.session_maker(bind=connection)
175     try:
176         environ = {}
177         environ['sqlalchemy.session'] = session
178         environ['sqlalchemy.model'] = app.model
179         d = UsersFromDatabase(environ)
180         d.role_create("wiki")
181         d.role_create("adMin")
182         d.role_create("editor")
183         d.group_create("pyLOns")
184         d.group_create("dJAngo")
185         d.user_create("jaMEs", "passWOrd1", "pyLoNs")
186         d.user_create("ben", "password2")
187         d.user_create("Simon", "password3")
188         d.user_create("ian", "paSsword4")
189         assertEqual(d.list_roles(),["admin", "editor", "wiki"])
190         assertEqual(d.list_groups(),["django", "pylons"])
191         assertEqual(d.list_users(),['ben', 'ian', 'james', 'simon'])
192         assertEqual(d.user_has_password("james", "passWOrd1"), True)
193         assertEqual(d.user_has_password("james", "password1"), False)
194        
195         d.role_create("test_role")
196         d.group_create("test_group")
197         d.user_create("test_user", "password")
198         assertEqual(d.list_roles(),["admin", "editor", "test_role", "wiki"])
199         assertEqual(d.list_groups(),["django", "pylons", "test_group"])
200         assertEqual(d.list_users(),['ben', 'ian', 'james', 'simon', "test_user"])
201         d.role_delete("test_role")
202         d.group_delete("test_group")
203         d.user_delete("test_user")
204         assertEqual(d.list_roles(),["admin", "editor", "wiki"])
205         assertEqual(d.list_groups(),["django", "pylons"])
206         assertEqual(d.list_users(),['ben', 'ian', 'james', 'simon'])
207    
208         assertEqual(d.user_has_role("james", "admin"), False)
209         d.user_add_role("james", "admin")
210         assertEqual(d.user_has_role("james", "admin"), True)
211         d.user_remove_role("james", "admin")
212         assertEqual(d.user_has_role("james", "admin"), False)
213    
214         d.user_add_role("james", "wiki")
215         d.user_add_role("simon", "wiki")
216         d.user_add_role("james", "admin")
217         #d.user_add_role("james", "editor")
218         d.user_add_role("ben", "editor")
219        
220         assertEqual(d.user_has_group("james", "pylons"), True)
221         assertEqual(d.user_has_group("simon", None), True)
222         assertEqual(d.user_has_group("simon", "django"), False)
223         d.user_set_group("simon", "dJangO")
224         assertEqual(d.user_has_group("simon", None), False)
225         d.user_set_group("bEn", "PyLONS")
226         assertEqual(d.user_has_group("simon", "django"), True)
227         assertEqual(d.user_has_group("bEn", "pYlons"), True)
228         d.user_remove_group("bEn")
229         assertEqual(d.user_has_group("bEn", "pYlons"), False)
230         d.user_set_group("bEn", "PyLONS")
231         assertEqual(d.user_has_group("bEn", "pYlons"), True)
232        
233         assertEqual(d.list_users(),['ben', 'ian', 'james', 'simon'])
234         d.user_set_username("james", "jim")
235         assertEqual(d.list_users(),['ben', 'ian', 'jim', 'simon'])
236         d.user_set_username("jim", "james")
237        
238         from authkit.users import UsersFromFile, UsersFromString, AuthKitNoSuchUserError, AuthKitNoSuchGroupError,AuthKitNoSuchRoleError
239         string_data = """jaMEs:passWOrd1:pyLOns wiki adMin
240         ben:password2:pylons admin editor
241         simon:password3:dJAngo
242         ian:paSsword4 wiki
243         """
244         filename = 'test/user_file_data.txt'
245        
246         s = UsersFromString(string_data)
247         f = UsersFromFile(filename)
248    
249         # Test Parsing
250         assertAllEqual(
251             s.passwords,
252             f.passwords,
253             {
254                 'james':'passWOrd1',
255                 'ben':'password2',
256                 'simon':'password3',
257                 'ian':'paSsword4',
258             },
259         )
260         assertAllEqual(
261             s.roles,
262             f.roles,
263             {
264                 'james':['admin', 'wiki'],
265                 'ben':['admin','editor'],
266                 'ian':['wiki'],
267                 'simon':[],
268             },
269         )
270         assertAllEqual(
271             s.groups,
272             f.groups,
273             {
274                 'james':'pylons',
275                 'ben':'pylons',
276                 'ian': None,
277                 'simon':'django',
278             },
279         )
280         assertAllEqual(
281             s.usernames,
282             f.usernames,
283             ['ben', 'ian', 'james', 'simon'],
284         )
285    
286         # Test list functions
287         assertAllEqual(
288             s.list_users(),
289             f.list_users(),
290             d.list_users(),
291             ['ben', 'ian', 'james', 'simon'],
292         )
293         assertAllEqual(
294             s.list_roles(),
295             f.list_roles(),
296             d.list_roles(),
297             ['admin', 'editor', 'wiki'],
298         )
299         assertAllEqual(
300             s.list_groups(),
301             f.list_groups(),
302             d.list_groups(),
303             ['django','pylons'],
304         )
305    
306         # Test user has functions
307         assertAllEqual(
308             s.user_has_role('jAMes','WiKi'),
309             f.user_has_role('jAMes','WiKi'),
310             d.user_has_role('jAMes','WiKi'),
311             True
312         )
313         assertAllEqual(
314             s.user_has_role('jAMes','editOr'),
315             f.user_has_role('jAMes','editOr'),
316             d.user_has_role('jAMes','editOr'),
317             False
318         )
319        
320         assertAllEqual(
321             s.user_has_group('jAMeS','PyLons'),
322             f.user_has_group('jAMes','pylOns'),
323             d.user_has_group('jAMes','pylOns'),
324             True
325         )
326         assertAllEqual(
327             s.user_has_group('jameS','djaNgo'),
328             f.user_has_group('JAMes','djAngo'),
329             d.user_has_group('JAMes','djAngo'),
330             False
331         )
332    
333         assertAllEqual(
334             s.user_has_password('jAMeS','passWOrd1'),
335             f.user_has_password('jAMes','passWOrd1'),
336             d.user_has_password('jAMes','passWOrd1'),
337             True
338         )
339         assertAllEqual(
340             s.user_has_password('jameS','PASSWORD1'),
341             f.user_has_password('JAMes','PASSWORD1'),
342             d.user_has_password('JAMes','PASSWORD1'),
343             False
344         )
345    
346         # Existence Methods
347         assertAllEqual(
348             s.user_exists('jAMeS'),
349             f.user_exists('jAMes'),
350             d.user_exists('jAMes'),
351             True
352         )
353         assertAllEqual(
354             s.user_exists('nobody'),
355             f.user_exists('nobody'),
356             d.user_exists('nobody'),
357             False
358         )
359        
360         # Existence Methods
361         assertAllEqual(
362             s.role_exists('wiKi'),
363             f.role_exists('Wiki'),
364             d.role_exists('Wiki'),
365             True
366         )
367         assertAllEqual(
368             s.role_exists('norole'),
369             f.role_exists('norole'),
370             d.role_exists('norole'),
371             False
372         )
373        
374         assertAllEqual(
375             s.group_exists('pyLons'),
376             f.group_exists('PYlons'),
377             d.group_exists('PYlons'),
378             True
379         )
380         assertAllEqual(
381             s.group_exists('nogroup'),
382             f.group_exists('nogroup'),
383             d.group_exists('nogroup'),
384             False
385         )
386    
387    
388         # User Methods
389        
390         assertAllEqual(
391             s.user('James'),
392             f.user('James'),
393             d.user('James'),
394             {
395                 'username': 'james',
396                 'group':    'pylons',
397                 'password': 'passWOrd1',
398                 'roles':    ['admin','wiki'],
399             }
400         )
401        
402         # Test all user methods raise:
403         for plugin in [s,f,d]:
404             for func in [
405                 'user',
406                 'user_roles',
407                 'user_group',
408                 'user_password',
409             ]:
410                 try:
411                     getattr(plugin, func)('nouser')
412                 except AuthKitNoSuchUserError, e:
413                     pass
414                 else:
415                     raise AssertionError("Failed to throw a no user error")
416         for plugin in [s,f,d]:
417             for func in [
418                 'user_has_password',
419                 'user_has_role',
420                 'user_has_group',
421             ]:
422                 try:
423                     getattr(plugin, func)('nouser','somevar')
424                 except AuthKitNoSuchUserError, e:
425                     pass
426                 else:
427                     raise AssertionError("Failed to throw a no user error")
428    
429         assertAllEqual(
430             s.user_roles('James'),
431             f.user_roles('James'),
432             d.user_roles('James'),
433             ['admin','wiki']
434         )
435         assertAllEqual(
436             s.user_group('James'),
437             f.user_group('James'),
438             d.user_group('James'),
439             'pylons'
440         )
441         assertAllEqual(
442             s.user_password('James'),
443             f.user_password('James'),
444             d.user_password('James'),
445             'passWOrd1'
446         )
447        
448         session.flush()
449         session.commit()
450     finally:
451         session.close()
452         connection.close()
453
454        
455
456 def test_users_model_api_database():
457     sys.path.insert(0, os.getcwd()+'/examples/user/database-model')
458     try:
459         from authkit.users.sqlalchemy_driver import UsersFromDatabase
460     except ImportError:
461         raise Exception("Could not run the SQLAlchemy tests, not installed")
462     if os.path.exists("test.db"):
463         os.remove("test.db")
464     import model as test_model
465
466     # Setup SQLAlchemy database engine
467     from sqlalchemy import engine_from_config
468     engine = engine_from_config({'sqlalchemy.url':'sqlite:///test.db'}, 'sqlalchemy.')
469     test_model.init_model(engine)
470     test_model.engine = engine
471  
472     d = UsersFromDatabase(test_model)
473    
474     test_model.meta.metadata.create_all(test_model.engine)
475    
476     d.role_create("wiki")
477     d.role_create("adMin")
478     d.role_create("editor")
479     d.group_create("pyLOns")
480     d.group_create("dJAngo")
481     d.user_create("jaMEs", "passWOrd1", "pyLoNs")
482     d.user_create("ben", "password2")
483     d.user_create("Simon", "password3")
484     d.user_create("ian", "paSsword4")
485     assertEqual(d.list_roles(),["admin", "editor", "wiki"])
486     assertEqual(d.list_groups(),["django", "pylons"])
487     assertEqual(d.list_users(),['ben', 'ian', 'james', 'simon'])
488     assertEqual(d.user_has_password("james", "passWOrd1"), True)
489     assertEqual(d.user_has_password("james", "password1"), False)
490    
491     d.role_create("test_role")
492     d.group_create("test_group")
493     d.user_create("test_user", "password")
494     assertEqual(d.list_roles(),["admin", "editor", "test_role", "wiki"])
495     assertEqual(d.list_groups(),["django", "pylons", "test_group"])
496     assertEqual(d.list_users(),['ben', 'ian', 'james', 'simon', "test_user"])
497     d.role_delete("test_role")
498     d.group_delete("test_group")
499     d.user_delete("test_user")
500     assertEqual(d.list_roles(),["admin", "editor", "wiki"])
501     assertEqual(d.list_groups(),["django", "pylons"])
502     assertEqual(d.list_users(),['ben', 'ian', 'james', 'simon'])
503
504     assertEqual(d.user_has_role("james", "admin"), False)
505     d.user_add_role("james", "admin")
506     assertEqual(d.user_has_role("james", "admin"), True)
507     d.user_remove_role("james", "admin")
508     assertEqual(d.user_has_role("james", "admin"), False)
509
510     d.user_add_role("james", "wiki")
511     d.user_add_role("simon", "wiki")
512     d.user_add_role("james", "admin")
513     #d.user_add_role("james", "editor")
514     d.user_add_role("ben", "editor")
515    
516     assertEqual(d.user_has_group("james", "pylons"), True)
517     assertEqual(d.user_has_group("simon", None), True)
518     assertEqual(d.user_has_group("simon", "django"), False)
519     d.user_set_group("simon", "dJangO")
520     assertEqual(d.user_has_group("simon", None), False)
521     d.user_set_group("bEn", "PyLONS")
522     assertEqual(d.user_has_group("simon", "django"), True)
523     assertEqual(d.user_has_group("bEn", "pYlons"), True)
524     d.user_remove_group("bEn")
525     assertEqual(d.user_has_group("bEn", "pYlons"), False)
526     d.user_set_group("bEn", "PyLONS")
527     assertEqual(d.user_has_group("bEn", "pYlons"), True)
528    
529     assertEqual(d.list_users(),['ben', 'ian', 'james', 'simon'])
530     d.user_set_username("james", "jim")
531     assertEqual(d.list_users(),['ben', 'ian', 'jim', 'simon'])
532     d.user_set_username("jim", "james")
533    
534     from authkit.users import UsersFromFile, UsersFromString, AuthKitNoSuchUserError, AuthKitNoSuchGroupError,AuthKitNoSuchRoleError
535     string_data = """jaMEs:passWOrd1:pyLOns wiki adMin
536     ben:password2:pylons admin editor
537     simon:password3:dJAngo
538     ian:paSsword4 wiki
539     """
540     filename = 'test/user_file_data.txt'
541    
542     s = UsersFromString(string_data)
543     f = UsersFromFile(filename)
544
545     # Test Parsing
546     assertAllEqual(
547         s.passwords,
548         f.passwords,
549         {
550             'james':'passWOrd1',
551             'ben':'password2',
552             'simon':'password3',
553             'ian':'paSsword4',
554         },
555     )
556     assertAllEqual(
557         s.roles,
558         f.roles,
559         {
560             'james':['admin', 'wiki'],
561             'ben':['admin','editor'],
562             'ian':['wiki'],
563             'simon':[],
564         },
565     )
566     assertAllEqual(
567         s.groups,
568         f.groups,
569         {
570             'james':'pylons',
571             'ben':'pylons',
572             'ian': None,
573             'simon':'django',
574         },
575     )
576     assertAllEqual(
577         s.usernames,
578         f.usernames,
579         ['ben', 'ian', 'james', 'simon'],
580     )
581
582     # Test list functions
583     assertAllEqual(
584         s.list_users(),
585         f.list_users(),
586         d.list_users(),
587         ['ben', 'ian', 'james', 'simon'],
588     )
589     assertAllEqual(
590         s.list_roles(),
591         f.list_roles(),
592         d.list_roles(),
593         ['admin', 'editor', 'wiki'],
594     )
595     assertAllEqual(
596         s.list_groups(),
597         f.list_groups(),
598         d.list_groups(),
599         ['django','pylons'],
600     )
601
602     # Test user has functions
603     assertAllEqual(
604         s.user_has_role('jAMes','WiKi'),
605         f.user_has_role('jAMes','WiKi'),
606         d.user_has_role('jAMes','WiKi'),
607         True
608     )
609     assertAllEqual(
610         s.user_has_role('jAMes','editOr'),
611         f.user_has_role('jAMes','editOr'),
612         d.user_has_role('jAMes','editOr'),
613         False
614     )
615    
616     assertAllEqual(
617         s.user_has_group('jAMeS','PyLons'),
618         f.user_has_group('jAMes','pylOns'),
619         d.user_has_group('jAMes','pylOns'),
620         True
621     )
622     assertAllEqual(
623         s.user_has_group('jameS','djaNgo'),
624         f.user_has_group('JAMes','djAngo'),
625         d.user_has_group('JAMes','djAngo'),
626         False
627     )
628
629     assertAllEqual(
630         s.user_has_password('jAMeS','passWOrd1'),
631         f.user_has_password('jAMes','passWOrd1'),
632         d.user_has_password('jAMes','passWOrd1'),
633         True
634     )
635     assertAllEqual(
636         s.user_has_password('jameS','PASSWORD1'),
637         f.user_has_password('JAMes','PASSWORD1'),
638         d.user_has_password('JAMes','PASSWORD1'),
639         False
640     )
641
642     # Existence Methods
643     assertAllEqual(
644         s.user_exists('jAMeS'),
645         f.user_exists('jAMes'),
646         d.user_exists('jAMes'),
647         True
648     )
649     assertAllEqual(
650         s.user_exists('nobody'),
651         f.user_exists('nobody'),
652         d.user_exists('nobody'),
653         False
654     )
655    
656     # Existence Methods
657     assertAllEqual(
658         s.role_exists('wiKi'),
659         f.role_exists('Wiki'),
660         d.role_exists('Wiki'),
661         True
662     )
663     assertAllEqual(
664         s.role_exists('norole'),
665         f.role_exists('norole'),
666         d.role_exists('norole'),
667         False
668     )
669    
670     assertAllEqual(
671         s.group_exists('pyLons'),
672         f.group_exists('PYlons'),
673         d.group_exists('PYlons'),
674         True
675     )
676     assertAllEqual(
677         s.group_exists('nogroup'),
678         f.group_exists('nogroup'),
679         d.group_exists('nogroup'),
680         False
681     )
682
683
684     # User Methods
685    
686     assertAllEqual(
687         s.user('James'),
688         f.user('James'),
689         d.user('James'),
690         {
691             'username': 'james',
692             'group':    'pylons',
693             'password': 'passWOrd1',
694             'roles':    ['admin','wiki'],
695         }
696     )
697    
698     # Test all user methods raise:
699     for plugin in [s,f,d]:
700         for func in [
701             'user',
702             'user_roles',
703             'user_group',
704             'user_password',
705         ]:
706             try:
707                 getattr(plugin, func)('nouser')
708             except AuthKitNoSuchUserError, e:
709                 pass
710             else:
711                 raise AssertionError("Failed to throw a no user error")
712     for plugin in [s,f,d]:
713         for func in [
714             'user_has_password',
715             'user_has_role',
716             'user_has_group',
717         ]:
718             try:
719                 getattr(plugin, func)('nouser','somevar')
720             except AuthKitNoSuchUserError, e:
721                 pass
722             else:
723                 raise AssertionError("Failed to throw a no user error")
724
725     assertAllEqual(
726         s.user_roles('James'),
727         f.user_roles('James'),
728         d.user_roles('James'),
729         ['admin','wiki']
730     )
731     assertAllEqual(
732         s.user_group('James'),
733         f.user_group('James'),
734         d.user_group('James'),
735         'pylons'
736     )
737     assertAllEqual(
738         s.user_password('James'),
739         f.user_password('James'),
740         d.user_password('James'),
741         'passWOrd1'
742     )
743        
744        
745        
Note: See TracBrowser for help on using the browser.