source: main/waeup.cas/trunk/waeup/cas/tests/test_authenticators.py @ 10492

Last change on this file since 10492 was 10478, checked in by uli, 11 years ago

Kofa authenticator now really contacts Kofa instances for authentication.

File size: 6.3 KB
RevLine 
[10478]1# Tests for waeup.cas.authentictors
[10462]2import os
[10478]3import threading
[10394]4import unittest
[10462]5from paste.deploy import loadapp
[10478]6try:
7    from SimpleXMLRPCServer import SimpleXMLRPCServer  # Python 2.x
8except ImportError:
9    from xmlrpc.server import SimpleXMLRPCServer       # Python 3.x
10try:
11    import xmlrpclib                     # Python 2.x
12except ImportError:
13    import xmlrpc.client as xmlrpclib    # Python 3.x
[10394]14from waeup.cas.authenticators import (
15    get_all_authenticators, get_authenticator, filter_auth_opts,
[10462]16    Authenticator, DummyAuthenticator, KofaAuthenticator
[10394]17    )
[10462]18from waeup.cas.server import CASServer
[10394]19
20
21class TestHelpers(unittest.TestCase):
22
23    def test_get_all_authenticators(self):
24        # we can get authenticators via entry points
25        auths = get_all_authenticators()
26        assert 'dummy' in auths
27        assert auths['dummy'] is DummyAuthenticator
28
29    def test_filter_auth_opts(self):
30        # we can filter auth opts
31        result = filter_auth_opts(
32            dict(auth='foo', auth_bar='baz', auth_baz='blah')
33            )
34        assert result == (
35            {'auth': 'foo'},
36            {'auth_bar': 'baz', 'auth_baz': 'blah'}
37            )
38
39    def test_get_authenticator(self):
40        # we can parse a paste.deploy config dict for auth
41        result = get_authenticator({})
42        assert result == {}
43        result = get_authenticator({'auth': 'dummy'})
44        assert isinstance(result['auth'], DummyAuthenticator)
45
46
47class AuthenticatorTests(unittest.TestCase):
48
49    def test_create(self):
50        # we can create Authenticator instances
51        auth = Authenticator()
52        assert isinstance(auth, Authenticator)
53
54
55class DummyAuthenticatorTests(unittest.TestCase):
56
57    def test_create(self):
58        # we can create DummyAuthenticator instances
59        auth = DummyAuthenticator()
60        assert isinstance(auth, DummyAuthenticator)
61
62    def test_check_credentials(self):
63        # we can succeed with 'bird'/'bebop'. Others will fail.
64        auth = DummyAuthenticator()
65        result1 = auth.check_credentials('bird', 'bebop')
[10396]66        assert result1 == (True, '')
[10394]67        result2 = auth.check_credentials('foo', 'bar')
[10396]68        assert result2 == (False, 'Invalid username or password.')
[10462]69
70
[10478]71BACKENDS1 = dict(
[10476]72    inst1=dict(
73        url='http://localhost:6666/app',
[10478]74        marker='^MA-',
[10474]75        )
[10462]76    )
77
[10478]78BACKENDS2 = dict(
79    inst1=dict(
80        url='http://localhost:6666/',
81        marker='^SCHOOL1-',
82        )
83    )
[10476]84
[10478]85
[10462]86class KofaAuthenticatorTests(unittest.TestCase):
87
88    def test_create(self):
89        # we can create KofaAuthenticator instances
90        auth = KofaAuthenticator()
91        assert isinstance(auth, KofaAuthenticator)
92
93    def test_options_defaults(self):
94        # all options have sensible defaults
95        auth = KofaAuthenticator()
[10475]96        assert auth.backends == {}
[10462]97
98    def test_options(self):
99        # we can pass options
[10478]100        auth = KofaAuthenticator(auth_backends=str(BACKENDS1))
101        assert auth.backends == BACKENDS1
[10475]102        auth = KofaAuthenticator(auth_backends='{"foo": {"url": "bar"}}')
103        assert auth.backends['foo']['marker'] == '.+'
104        self.assertRaises(
105            ValueError, KofaAuthenticator, auth_backends='not-a-py-expr')
106        self.assertRaises(
107            ValueError, KofaAuthenticator, auth_backends='"Not a dict"')
108        self.assertRaises(
109            ValueError, KofaAuthenticator,
110            auth_backends='{"foo": "not-a-dict"}')
111        self.assertRaises(
112            ValueError, KofaAuthenticator,
113            auth_backends='{"foo": {"no-url-key": "bar"}}')
114        self.assertRaises(
115            ValueError, KofaAuthenticator,
116            auth_backends='{"foo": {"url": "bar", "marker": "inv_re)"}}')
[10462]117
118    def test_paste_deploy_options(self):
119        # we can set CAS server-related options via paste.deploy config
120        paste_conf = os.path.join(
121            os.path.dirname(__file__), 'sample3.ini')
122        app = loadapp('config:%s' % paste_conf)
123        assert isinstance(app, CASServer)
124        assert app.db_connection_string == 'sqlite:///:memory:'
125        assert isinstance(app.auth, KofaAuthenticator)
126
[10478]127
128class FakeKofaServer(SimpleXMLRPCServer):
129    # A fake Kofa server that provides only XMLRPC methods
130
131    allow_reuse_address = True
132
133    def __init__(self, *args, **kw):
134        kw.update(allow_none=True)
135        SimpleXMLRPCServer.__init__(self, *args, **kw)
136        self.register_function(self._check_credentials, 'check_credentials')
137
138    def _check_credentials(self, username, password):
139        # fake waeup.kofa check_credentials method.
140        #
141        # This method is supposed to mimic the behaviour of an
142        # original waeup.kofa check_credentials method. It returns a
143        # positive result for the credentials `bird`/`bebop`.
144        if username == 'bird' and password == 'bebop':
145            return {'id': 'bird', 'email': 'bird@gods.net',
146                    'description': 'Mr. Charles Parker'}
147        return None
148
149
150class XMLRPCFakeKofaTestCase(unittest.TestCase):
151    # A test case where a fake Kofa server is started before tests (and
152    # shut down afterwards).
153
154    server = None
155    th = None
156
157    @classmethod
158    def setUpClass(cls):
159        cls.server = FakeKofaServer(('localhost', 6666))
160        cls.th = threading.Thread(target=cls.server.serve_forever)
161        cls.th.daemon = True
162        cls.th.start()
163
164    @classmethod
165    def tearDownClass(cls):
166        cls.server.shutdown()
167        cls.server.server_close()
168
169
170class MyCase(XMLRPCFakeKofaTestCase):
171
172    def test_fake_kofa_works(self):
173        # make sure the local fake kofa works
174        proxy = xmlrpclib.ServerProxy("http://localhost:6666", allow_none=True)
175        result = proxy.check_credentials('bird', 'bebop')
176        assert result == {
177            'description': 'Mr. Charles Parker',
178            'email': 'bird@gods.net',
179            'id': 'bird'}
180        return
181
182    def test_check_credentials(self):
[10462]183        # we get real responses when querying Kofa instances
[10478]184        auth = KofaAuthenticator(auth_backends=str(BACKENDS2))
185        result1 = auth.check_credentials('SCHOOL1-bird', 'bebop')
[10462]186        assert result1 == (True, '')
[10478]187        result2 = auth.check_credentials('SCHOOL1-foo', 'bar')
[10462]188        assert result2 == (False, 'Invalid username or password.')
[10478]189        result3 = auth.check_credentials('SCHOOL2-bar', 'baz')
190        assert result3 == (False, 'Invalid username or password.')
Note: See TracBrowser for help on using the repository browser.