Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / tests.py @ d2b8ec7b

History | View | Annotate | Download (50.6 kB)

1
# Copyright 2011 GRNET S.A. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
#
7
#   1. Redistributions of source code must retain the above
8
#      copyright notice, this list of conditions and the following
9
#      disclaimer.
10
#
11
#   2. Redistributions in binary form must reproduce the above
12
#      copyright notice, this list of conditions and the following
13
#      disclaimer in the documentation and/or other materials
14
#      provided with the distribution.
15
#
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
#
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.
33
from contextlib import contextmanager
34

    
35
import copy
36
import datetime
37
import functools
38

    
39
from snf_django.utils.testing import with_settings, override_settings
40

    
41
from django.test import TestCase, Client
42
from django.core import mail
43
from django.http import SimpleCookie, HttpRequest, QueryDict
44
from django.utils.importlib import import_module
45

    
46
from astakos.im.activation_backends import *
47
from astakos.im.target.shibboleth import Tokens as ShibbolethTokens
48
from astakos.im.models import *
49
from astakos.im import functions
50
from astakos.im import settings as astakos_settings
51
from astakos.im import forms
52

    
53
from urllib import quote
54

    
55
from astakos.im import messages
56
from astakos.im import auth_providers
57
from django.conf import settings
58

    
59

    
60
# set some common settings
61
astakos_settings.EMAILCHANGE_ENABLED = True
62
astakos_settings.RECAPTCHA_ENABLED = False
63

    
64
settings.LOGGING_SETUP['disable_existing_loggers'] = False
65

    
66

    
67
prefixes = {'im': 'ASTAKOS_', 'providers': 'ASTAKOS_AUTH_PROVIDER_',
68
            'shibboleth': 'ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_',
69
            'local': 'ASTAKOS_AUTH_PROVIDER_LOCAL_'}
70
im_settings = functools.partial(with_settings, settings, prefix=prefixes['im'])
71
provider_settings = functools.partial(with_settings, settings,
72
                                      prefix=prefixes['providers'])
73
shibboleth_settings = functools.partial(with_settings,
74
                                        settings,
75
                                        prefix=prefixes['shibboleth'])
76
localauth_settings = functools.partial(with_settings, settings,
77
                                       prefix=prefixes['local'])
78

    
79
class AstakosTestClient(Client):
80
    pass
81

    
82
class ShibbolethClient(AstakosTestClient):
83
    """
84
    A shibboleth agnostic client.
85
    """
86
    VALID_TOKENS = filter(lambda x: not x.startswith("_"),
87
                          dir(ShibbolethTokens))
88

    
89
    def __init__(self, *args, **kwargs):
90
        self.tokens = kwargs.pop('tokens', {})
91
        super(ShibbolethClient, self).__init__(*args, **kwargs)
92

    
93
    def set_tokens(self, **kwargs):
94
        for key, value in kwargs.iteritems():
95
            key = 'SHIB_%s' % key.upper()
96
            if not key in self.VALID_TOKENS:
97
                raise Exception('Invalid shibboleth token')
98

    
99
            self.tokens[key] = value
100

    
101
    def unset_tokens(self, *keys):
102
        for key in keys:
103
            key = 'SHIB_%s' % param.upper()
104
            if key in self.tokens:
105
                del self.tokens[key]
106

    
107
    def reset_tokens(self):
108
        self.tokens = {}
109

    
110
    def get_http_token(self, key):
111
        http_header = getattr(ShibbolethTokens, key)
112
        return http_header
113

    
114
    def request(self, **request):
115
        """
116
        Transform valid shibboleth tokens to http headers
117
        """
118
        for token, value in self.tokens.iteritems():
119
            request[self.get_http_token(token)] = value
120

    
121
        for param in request.keys():
122
            key = 'SHIB_%s' % param.upper()
123
            if key in self.VALID_TOKENS:
124
                request[self.get_http_token(key)] = request[param]
125
                del request[param]
126

    
127
        return super(ShibbolethClient, self).request(**request)
128

    
129

    
130
def get_local_user(username, **kwargs):
131
        try:
132
            return AstakosUser.objects.get(email=username)
133
        except:
134
            user_params = {
135
                'username': username,
136
                'email': username,
137
                'is_active': True,
138
                'activation_sent': datetime.now(),
139
                'email_verified': True,
140
                'provider': 'local'
141
            }
142
            user_params.update(kwargs)
143
            user = AstakosUser(**user_params)
144
            user.set_password(kwargs.get('password', 'password'))
145
            user.save()
146
            user.add_auth_provider('local', auth_backend='astakos')
147
            if kwargs.get('is_active', True):
148
                user.is_active = True
149
            else:
150
                user.is_active = False
151
            user.save()
152
            return user
153

    
154

    
155
def get_mailbox(email):
156
    mails = []
157
    for sent_email in mail.outbox:
158
        for recipient in sent_email.recipients():
159
            if email in recipient:
160
                mails.append(sent_email)
161
    return mails
162

    
163

    
164
class ShibbolethTests(TestCase):
165
    """
166
    Testing shibboleth authentication.
167
    """
168

    
169
    fixtures = ['groups']
170

    
171
    def setUp(self):
172
        self.client = ShibbolethClient()
173
        astakos_settings.IM_MODULES = ['local', 'shibboleth']
174
        astakos_settings.MODERATION_ENABLED = True
175

    
176
    def test_create_account(self):
177

    
178
        client = ShibbolethClient()
179

    
180
        # shibboleth views validation
181
        # eepn required
182
        r = client.get('/im/login/shibboleth?', follow=True)
183
        self.assertContains(r, messages.SHIBBOLETH_MISSING_EPPN % {
184
            'domain': astakos_settings.BASEURL,
185
            'contact_email': settings.CONTACT_EMAIL
186
        })
187
        client.set_tokens(eppn="kpapeppn")
188

    
189
        astakos_settings.SHIBBOLETH_REQUIRE_NAME_INFO = True
190
        # shibboleth user info required
191
        r = client.get('/im/login/shibboleth?', follow=True)
192
        self.assertContains(r, messages.SHIBBOLETH_MISSING_NAME)
193
        astakos_settings.SHIBBOLETH_REQUIRE_NAME_INFO = False
194

    
195
        # shibboleth logged us in
196
        client.set_tokens(mail="kpap@grnet.gr", eppn="kpapeppn",
197
                          cn="Kostas Papadimitriou",
198
                          ep_affiliation="Test Affiliation")
199
        r = client.get('/im/login/shibboleth?', follow=True)
200
        token = PendingThirdPartyUser.objects.get().token
201
        self.assertRedirects(r, '/im/signup?third_party_token=%s' % token)
202
        self.assertEqual(r.status_code, 200)
203

    
204
        # a new pending user created
205
        pending_user = PendingThirdPartyUser.objects.get(
206
            third_party_identifier="kpapeppn")
207
        self.assertEqual(PendingThirdPartyUser.objects.count(), 1)
208
        # keep the token for future use
209
        token = pending_user.token
210
        # from now on no shibboleth headers are sent to the server
211
        client.reset_tokens()
212

    
213
        # this is the old way, it should fail, to avoid pending user take over
214
        r = client.get('/im/shibboleth/signup/%s' % pending_user.username)
215
        self.assertEqual(r.status_code, 404)
216

    
217
        # this is the signup unique url associated with the pending user
218
        # created
219
        r = client.get('/im/signup/?third_party_token=%s' % token)
220
        identifier = pending_user.third_party_identifier
221
        post_data = {'third_party_identifier': identifier,
222
                     'first_name': 'Kostas',
223
                     'third_party_token': token,
224
                     'last_name': 'Mitroglou',
225
                     'provider': 'shibboleth'}
226

    
227
        # invlid email
228
        post_data['email'] = 'kpap'
229
        r = client.post('/im/signup', post_data)
230
        self.assertContains(r, token)
231

    
232
        # existing email
233
        existing_user = get_local_user('test@test.com')
234
        post_data['email'] = 'test@test.com'
235
        r = client.post('/im/signup', post_data)
236
        self.assertContains(r, messages.EMAIL_USED)
237
        existing_user.delete()
238

    
239
        # and finally a valid signup
240
        post_data['email'] = 'kpap@grnet.gr'
241
        r = client.post('/im/signup', post_data, follow=True)
242
        self.assertContains(r, messages.NOTIFICATION_SENT)
243

    
244
        # everything is ok in our db
245
        self.assertEqual(AstakosUser.objects.count(), 1)
246
        self.assertEqual(AstakosUserAuthProvider.objects.count(), 1)
247
        self.assertEqual(PendingThirdPartyUser.objects.count(), 0)
248

    
249
        # provider info stored
250
        provider = AstakosUserAuthProvider.objects.get(module="shibboleth")
251
        self.assertEqual(provider.affiliation, 'Test Affiliation')
252
        self.assertEqual(provider.info, {u'email': u'kpap@grnet.gr',
253
                                         u'eppn': u'kpapeppn',
254
                                         u'name': u'Kostas Papadimitriou'})
255

    
256
        # lets login (not activated yet)
257
        client.set_tokens(mail="kpap@grnet.gr", eppn="kpapeppn",
258
                          cn="Kostas Papadimitriou", )
259
        r = client.get("/im/login/shibboleth?", follow=True)
260
        self.assertContains(r, 'is pending moderation')
261
        r = client.get("/im/profile", follow=True)
262
        self.assertRedirects(r, 'http://testserver/im/?next=/im/profile')
263

    
264
        # admin activates our user
265
        u = AstakosUser.objects.get(username="kpap@grnet.gr")
266
        functions.activate(u)
267
        self.assertEqual(u.is_active, True)
268

    
269
        # we see our profile
270
        r = client.get("/im/login/shibboleth?", follow=True)
271
        self.assertRedirects(r, '/im/landing')
272
        self.assertEqual(r.status_code, 200)
273

    
274
    def test_existing(self):
275
        """
276
        Test adding of third party login to an existing account
277
        """
278

    
279
        # this is our existing user
280
        existing_user = get_local_user('kpap@grnet.gr')
281
        existing_inactive = get_local_user('kpap-inactive@grnet.gr')
282
        existing_inactive.is_active = False
283
        existing_inactive.save()
284

    
285
        existing_unverified = get_local_user('kpap-unverified@grnet.gr')
286
        existing_unverified.is_active = False
287
        existing_unverified.activation_sent = None
288
        existing_unverified.email_verified = False
289
        existing_unverified.is_verified = False
290
        existing_unverified.save()
291

    
292
        client = ShibbolethClient()
293
        # shibboleth logged us in, notice that we use different email
294
        client.set_tokens(mail="kpap@shibboleth.gr", eppn="kpapeppn",
295
                          cn="Kostas Papadimitriou", )
296
        r = client.get("/im/login/shibboleth?", follow=True)
297

    
298
        # a new pending user created
299
        pending_user = PendingThirdPartyUser.objects.get()
300
        token = pending_user.token
301
        self.assertEqual(PendingThirdPartyUser.objects.count(), 1)
302
        pending_key = pending_user.token
303
        client.reset_tokens()
304
        self.assertRedirects(r, "/im/signup?third_party_token=%s" % token)
305

    
306
        form = r.context['form']
307
        signupdata = copy.copy(form.initial)
308
        signupdata['email'] = 'kpap@grnet.gr'
309
        signupdata['third_party_token'] = token
310
        signupdata['provider'] = 'shibboleth'
311
        del signupdata['id']
312

    
313
        # the email exists to another user
314
        r = client.post("/im/signup", signupdata)
315
        self.assertContains(r, "There is already an account with this email "
316
                               "address")
317
        # change the case, still cannot create
318
        signupdata['email'] = 'KPAP@grnet.GR'
319
        r = client.post("/im/signup", signupdata)
320
        self.assertContains(r, "There is already an account with this email "
321
                               "address")
322
        # inactive user
323
        signupdata['email'] = 'KPAP-inactive@grnet.GR'
324
        r = client.post("/im/signup", signupdata)
325
        self.assertContains(r, "There is already an account with this email "
326
                               "address")
327

    
328
        # unverified user, this should pass, old entry will be deleted
329
        signupdata['email'] = 'KAPAP-unverified@grnet.GR'
330
        r = client.post("/im/signup", signupdata)
331

    
332
        post_data = {'password': 'password',
333
                     'username': 'kpap@grnet.gr'}
334
        r = client.post('/im/local', post_data, follow=True)
335
        self.assertTrue(r.context['request'].user.is_authenticated())
336
        client.set_tokens(mail="kpap@shibboleth.gr", eppn="kpapeppn",
337
                          cn="Kostas Papadimitriou", )
338
        r = client.get("/im/login/shibboleth?", follow=True)
339
        self.assertContains(r, "enabled for this account")
340
        client.reset_tokens()
341

    
342
        user = existing_user
343
        self.assertTrue(user.has_auth_provider('shibboleth'))
344
        self.assertTrue(user.has_auth_provider('local',
345
                                               auth_backend='astakos'))
346
        client.logout()
347

    
348
        # look Ma, i can login with both my shibboleth and local account
349
        client.set_tokens(mail="kpap@shibboleth.gr", eppn="kpapeppn",
350
                          cn="Kostas Papadimitriou")
351
        r = client.get("/im/login/shibboleth?", follow=True)
352
        self.assertTrue(r.context['request'].user.is_authenticated())
353
        self.assertTrue(r.context['request'].user.email == "kpap@grnet.gr")
354
        self.assertRedirects(r, '/im/landing')
355
        self.assertEqual(r.status_code, 200)
356
        client.logout()
357
        client.reset_tokens()
358

    
359
        # logged out
360
        r = client.get("/im/profile", follow=True)
361
        self.assertFalse(r.context['request'].user.is_authenticated())
362

    
363
        # login with local account also works
364
        post_data = {'password': 'password',
365
                     'username': 'kpap@grnet.gr'}
366
        r = self.client.post('/im/local', post_data, follow=True)
367
        self.assertTrue(r.context['request'].user.is_authenticated())
368
        self.assertTrue(r.context['request'].user.email == "kpap@grnet.gr")
369
        self.assertRedirects(r, '/im/landing')
370
        self.assertEqual(r.status_code, 200)
371

    
372
        # cannot add the same eppn
373
        client.set_tokens(mail="secondary@shibboleth.gr", eppn="kpapeppn",
374
                          cn="Kostas Papadimitriou", )
375
        r = client.get("/im/login/shibboleth?", follow=True)
376
        self.assertRedirects(r, '/im/landing')
377
        self.assertTrue(r.status_code, 200)
378
        self.assertEquals(existing_user.auth_providers.count(), 2)
379

    
380
        # only one allowed by default
381
        client.set_tokens(mail="secondary@shibboleth.gr", eppn="kpapeppn2",
382
                          cn="Kostas Papadimitriou", ep_affiliation="affil2")
383
        prov = auth_providers.get_provider('shibboleth')
384
        r = client.get("/im/login/shibboleth?", follow=True)
385
        self.assertContains(r, "Failed to add")
386
        self.assertRedirects(r, '/im/profile')
387
        self.assertTrue(r.status_code, 200)
388
        self.assertEquals(existing_user.auth_providers.count(), 2)
389
        client.logout()
390
        client.reset_tokens()
391

    
392
        # cannot login with another eppn
393
        client.set_tokens(mail="kpap@grnet.gr", eppn="kpapeppninvalid",
394
                          cn="Kostas Papadimitriou")
395
        r = client.get("/im/login/shibboleth?", follow=True)
396
        self.assertFalse(r.context['request'].user.is_authenticated())
397

    
398
        # cannot
399

    
400
        # lets remove local password
401
        user = AstakosUser.objects.get(username="kpap@grnet.gr",
402
                                       email="kpap@grnet.gr")
403
        remove_local_url = user.get_auth_provider('local').get_remove_url
404
        remove_shibbo_url = user.get_auth_provider('shibboleth',
405
                                                   'kpapeppn').get_remove_url
406
        client.set_tokens(mail="kpap@shibboleth.gr", eppn="kpapeppn",
407
                          cn="Kostas Papadimtriou")
408
        r = client.get("/im/login/shibboleth?", follow=True)
409
        client.reset_tokens()
410

    
411
        # TODO: this view should use POST
412
        r = client.get(remove_local_url)
413
        # 2 providers left
414
        self.assertEqual(user.auth_providers.count(), 1)
415
        # cannot remove last provider
416
        r = client.get(remove_shibbo_url)
417
        self.assertEqual(r.status_code, 403)
418
        self.client.logout()
419

    
420
        # cannot login using local credentials (notice we use another client)
421
        post_data = {'password': 'password',
422
                     'username': 'kpap@grnet.gr'}
423
        r = self.client.post('/im/local', post_data, follow=True)
424
        self.assertFalse(r.context['request'].user.is_authenticated())
425

    
426
        # we can reenable the local provider by setting a password
427
        r = client.get("/im/password_change", follow=True)
428
        r = client.post("/im/password_change", {'new_password1':'111',
429
                                                'new_password2': '111'},
430
                        follow=True)
431
        user = r.context['request'].user
432
        self.assertTrue(user.has_auth_provider('local'))
433
        self.assertTrue(user.has_auth_provider('shibboleth'))
434
        self.assertTrue(user.check_password('111'))
435
        self.assertTrue(user.has_usable_password())
436
        self.client.logout()
437

    
438
        # now we can login
439
        post_data = {'password': '111',
440
                     'username': 'kpap@grnet.gr'}
441
        r = self.client.post('/im/local', post_data, follow=True)
442
        self.assertTrue(r.context['request'].user.is_authenticated())
443

    
444
        client.reset_tokens()
445

    
446
        # we cannot take over another shibboleth identifier
447
        user2 = get_local_user('another@grnet.gr')
448
        user2.add_auth_provider('shibboleth', identifier='existingeppn')
449
        # login
450
        client.set_tokens(mail="kpap@shibboleth.gr", eppn="kpapeppn",
451
                          cn="Kostas Papadimitriou")
452
        r = client.get("/im/login/shibboleth?", follow=True)
453
        # try to assign existing shibboleth identifier of another user
454
        client.set_tokens(mail="kpap_second@shibboleth.gr",
455
                          eppn="existingeppn", cn="Kostas Papadimitriou")
456
        r = client.get("/im/login/shibboleth?", follow=True)
457
        self.assertContains(r, "this account is already assigned")
458

    
459

    
460
class TestLocal(TestCase):
461

    
462
    fixtures = ['groups']
463

    
464
    def setUp(self):
465
        settings.ADMINS = (('admin', 'support@cloud.grnet.gr'),)
466
        settings.SERVER_EMAIL = 'no-reply@grnet.gr'
467
        self._orig_moderation = astakos_settings.MODERATION_ENABLED
468
        settings.ASTAKOS_MODERATION_ENABLED = True
469

    
470
    def tearDown(self):
471
        settings.ASTAKOS_MODERATION_ENABLED = self._orig_moderation
472

    
473
    def test_no_moderation(self):
474
        # disable moderation
475
        astakos_settings.MODERATION_ENABLED = False
476

    
477
        # create a new user
478
        r = self.client.get("/im/signup")
479
        self.assertEqual(r.status_code, 200)
480
        data = {'email': 'kpap@grnet.gr', 'password1': 'password',
481
                'password2': 'password', 'first_name': 'Kostas',
482
                'last_name': 'Mitroglou', 'provider': 'local'}
483
        r = self.client.post("/im/signup", data)
484

    
485
        # user created
486
        self.assertEqual(AstakosUser.objects.count(), 1)
487
        user = AstakosUser.objects.get(username="kpap@grnet.gr",
488
                                       email="kpap@grnet.gr")
489
        self.assertEqual(user.username, 'kpap@grnet.gr')
490
        self.assertEqual(user.has_auth_provider('local'), True)
491
        self.assertFalse(user.is_active)
492

    
493
        # user (but not admin) gets notified
494
        self.assertEqual(len(get_mailbox('support@cloud.grnet.gr')), 0)
495
        self.assertEqual(len(get_mailbox('kpap@grnet.gr')), 1)
496
        astakos_settings.MODERATION_ENABLED = True
497

    
498
    def test_email_case(self):
499
        data = {
500
            'email': 'kPap@grnet.gr',
501
            'password1': '1234',
502
            'password2': '1234'
503
        }
504

    
505
        form = forms.LocalUserCreationForm(data)
506
        self.assertTrue(form.is_valid())
507
        user = form.save()
508
        form.store_user(user, {})
509

    
510
        u = AstakosUser.objects.get()
511
        self.assertEqual(u.email, 'kPap@grnet.gr')
512
        self.assertEqual(u.username, 'kpap@grnet.gr')
513
        u.is_active = True
514
        u.email_verified = True
515
        u.save()
516

    
517
        data = {'username': 'kpap@grnet.gr', 'password': '1234'}
518
        login = forms.LoginForm(data=data)
519
        self.assertTrue(login.is_valid())
520

    
521
        data = {'username': 'KpaP@grnet.gr', 'password': '1234'}
522
        login = forms.LoginForm(data=data)
523
        self.assertTrue(login.is_valid())
524

    
525
        data = {
526
            'email': 'kpap@grnet.gr',
527
            'password1': '1234',
528
            'password2': '1234'
529
        }
530
        form = forms.LocalUserCreationForm(data)
531
        self.assertFalse(form.is_valid())
532

    
533
    @with_settings(settings, HELPDESK=(('support','support@synnefo.org'),))
534
    def test_local_provider(self):
535
        self.helpdesk_email = astakos_settings.HELPDESK[0][1]
536
        # enable moderation
537
        astakos_settings.MODERATION_ENABLED = True
538

    
539
        # create a user
540
        r = self.client.get("/im/signup")
541
        self.assertEqual(r.status_code, 200)
542
        data = {'email': 'kpap@grnet.gr', 'password1': 'password',
543
                'password2': 'password', 'first_name': 'Kostas',
544
                'last_name': 'Mitroglou', 'provider': 'local'}
545
        r = self.client.post("/im/signup", data)
546

    
547
        # user created
548
        self.assertEqual(AstakosUser.objects.count(), 1)
549
        user = AstakosUser.objects.get(username="kpap@grnet.gr",
550
                                       email="kpap@grnet.gr")
551
        self.assertEqual(user.username, 'kpap@grnet.gr')
552
        self.assertEqual(user.has_auth_provider('local'), True)
553
        self.assertFalse(user.is_active)  # not activated
554
        self.assertFalse(user.email_verified)  # not verified
555
        self.assertFalse(user.activation_sent)  # activation automatically sent
556

    
557
        # admin gets notified and activates the user from the command line
558

    
559
        self.assertEqual(len(get_mailbox(self.helpdesk_email)), 1)
560
        r = self.client.post('/im/local', {'username': 'kpap@grnet.gr',
561
                                           'password': 'password'})
562
        self.assertContains(r, messages.NOTIFICATION_SENT)
563
        functions.send_activation(user)
564

    
565
        # user activation fields updated and user gets notified via email
566
        user = AstakosUser.objects.get(pk=user.pk)
567
        self.assertTrue(user.activation_sent)
568
        self.assertFalse(user.email_verified)
569
        self.assertFalse(user.is_active)
570
        self.assertEqual(len(get_mailbox('kpap@grnet.gr')), 1)
571

    
572
        # user forgot she got registered and tries to submit registration
573
        # form. Notice the upper case in email
574
        data = {'email': 'KPAP@grnet.gr', 'password1': 'password',
575
                'password2': 'password', 'first_name': 'Kostas',
576
                'last_name': 'Mitroglou', 'provider': 'local'}
577
        r = self.client.post("/im/signup", data, follow=True)
578
        self.assertRedirects(r, reverse('index'))
579
        self.assertContains(r, messages.NOTIFICATION_SENT)
580

    
581
        user = AstakosUser.objects.get()
582
        functions.send_activation(user)
583

    
584
        # previous user replaced
585
        self.assertTrue(user.activation_sent)
586
        self.assertFalse(user.email_verified)
587
        self.assertFalse(user.is_active)
588
        self.assertEqual(len(get_mailbox('KPAP@grnet.gr')), 1)
589

    
590
        # hmmm, email exists; lets request a password change
591
        r = self.client.get('/im/local/password_reset')
592
        self.assertEqual(r.status_code, 200)
593
        data = {'email': 'kpap@grnet.gr'}
594
        r = self.client.post('/im/local/password_reset', data, follow=True)
595
        # she can't because account is not active yet
596
        self.assertContains(r, 'pending activation')
597

    
598
        # moderation is enabled and an activation email has already been sent
599
        # so user can trigger resend of the activation email
600
        r = self.client.get('/im/send/activation/%d' % user.pk, follow=True)
601
        self.assertContains(r, 'has been sent to your email address.')
602
        self.assertEqual(len(get_mailbox('KPAP@grnet.gr')), 2)
603

    
604
        # also she cannot login
605
        data = {'username': 'kpap@grnet.gr', 'password': 'password'}
606
        r = self.client.post('/im/local', data, follow=True)
607
        self.assertContains(r, 'Resend activation')
608
        self.assertFalse(r.context['request'].user.is_authenticated())
609
        self.assertFalse('_pithos2_a' in self.client.cookies)
610

    
611
        # user sees the message and resends activation
612
        r = self.client.get('/im/send/activation/%d' % user.pk, follow=True)
613
        self.assertEqual(len(get_mailbox('KPAP@grnet.gr')), 3)
614

    
615
        # switch back moderation setting
616
        astakos_settings.MODERATION_ENABLED = True
617
        r = self.client.get(user.get_activation_url(), follow=True)
618
        self.assertRedirects(r, "/im/landing")
619
        r = self.client.get('/im/profile', follow=True)
620
        self.assertTrue(r.context['request'].user.is_authenticated())
621
        self.assertTrue('_pithos2_a' in self.client.cookies)
622
        self.assertContains(r, "KPAP@grnet.gr")
623
        self.assertEqual(len(get_mailbox('KPAP@grnet.gr')), 4)
624

    
625
        user = AstakosUser.objects.get(pk=user.pk)
626
        # user activated and logged in, token cookie set
627
        self.assertTrue(r.context['request'].user.is_authenticated())
628
        self.assertTrue('_pithos2_a' in self.client.cookies)
629
        cookies = self.client.cookies
630
        self.assertTrue(quote(user.auth_token) in
631
                        cookies.get('_pithos2_a').value)
632
        r = self.client.get('/im/logout', follow=True)
633
        r = self.client.get('/im/')
634
        # user logged out, token cookie removed
635
        self.assertFalse(r.context['request'].user.is_authenticated())
636
        self.assertFalse(self.client.cookies.get('_pithos2_a').value)
637

    
638
        #https://docs.djangoproject.com/en/dev/topics/testing/#persistent-state
639
        del self.client.cookies['_pithos2_a']
640

    
641
        # user can login
642
        r = self.client.post('/im/local', {'username': 'kpap@grnet.gr',
643
                                           'password': 'password'},
644
                             follow=True)
645
        self.assertTrue(r.context['request'].user.is_authenticated())
646
        self.assertTrue('_pithos2_a' in self.client.cookies)
647
        cookies = self.client.cookies
648
        self.assertTrue(quote(user.auth_token) in
649
                        cookies.get('_pithos2_a').value)
650
        self.client.get('/im/logout', follow=True)
651

    
652
        # user forgot password
653
        old_pass = user.password
654
        r = self.client.get('/im/local/password_reset')
655
        self.assertEqual(r.status_code, 200)
656
        r = self.client.post('/im/local/password_reset', {'email':
657
                                                          'kpap@grnet.gr'})
658
        self.assertEqual(r.status_code, 302)
659
        # email sent
660
        self.assertEqual(len(get_mailbox('KPAP@grnet.gr')), 5)
661

    
662
        # user visits change password link
663
        r = self.client.get(user.get_password_reset_url())
664
        r = self.client.post(user.get_password_reset_url(),
665
                             {'new_password1': 'newpass',
666
                              'new_password2': 'newpass'})
667

    
668
        user = AstakosUser.objects.get(pk=user.pk)
669
        self.assertNotEqual(old_pass, user.password)
670

    
671
        # old pass is not usable
672
        r = self.client.post('/im/local', {'username': 'kpap@grnet.gr',
673
                                           'password': 'password'})
674
        self.assertContains(r, 'Please enter a correct username and password')
675
        r = self.client.post('/im/local', {'username': 'kpap@grnet.gr',
676
                                           'password': 'newpass'},
677
                             follow=True)
678
        self.assertTrue(r.context['request'].user.is_authenticated())
679
        self.client.logout()
680

    
681
        # tests of special local backends
682
        user = AstakosUser.objects.get(pk=user.pk)
683
        user.auth_providers.filter(module='local').update(auth_backend='ldap')
684
        user.save()
685

    
686
        # non astakos local backends do not support password reset
687
        r = self.client.get('/im/local/password_reset')
688
        self.assertEqual(r.status_code, 200)
689
        r = self.client.post('/im/local/password_reset', {'email':
690
                                                          'kpap@grnet.gr'})
691
        # she can't because account is not active yet
692
        self.assertContains(r, "Changing password is not")
693

    
694

    
695
class UserActionsTests(TestCase):
696

    
697
    def test_email_change(self):
698
        # to test existing email validation
699
        get_local_user('existing@grnet.gr')
700

    
701
        # local user
702
        user = get_local_user('kpap@grnet.gr')
703

    
704
        # login as kpap
705
        self.client.login(username='kpap@grnet.gr', password='password')
706
        r = self.client.get('/im/profile', follow=True)
707
        user = r.context['request'].user
708
        self.assertTrue(user.is_authenticated())
709

    
710
        # change email is enabled
711
        r = self.client.get('/im/email_change')
712
        self.assertEqual(r.status_code, 200)
713
        self.assertFalse(user.email_change_is_pending())
714

    
715
        # request email change to an existing email fails
716
        data = {'new_email_address': 'existing@grnet.gr'}
717
        r = self.client.post('/im/email_change', data)
718
        self.assertContains(r, messages.EMAIL_USED)
719

    
720
        # proper email change
721
        data = {'new_email_address': 'kpap@gmail.com'}
722
        r = self.client.post('/im/email_change', data, follow=True)
723
        self.assertRedirects(r, '/im/profile')
724
        self.assertContains(r, messages.EMAIL_CHANGE_REGISTERED)
725
        change1 = EmailChange.objects.get()
726

    
727
        # user sees a warning
728
        r = self.client.get('/im/email_change')
729
        self.assertEqual(r.status_code, 200)
730
        self.assertContains(r, messages.PENDING_EMAIL_CHANGE_REQUEST)
731
        self.assertTrue(user.email_change_is_pending())
732

    
733
        # link was sent
734
        self.assertEqual(len(get_mailbox('kpap@grnet.gr')), 0)
735
        self.assertEqual(len(get_mailbox('kpap@gmail.com')), 1)
736

    
737
        # proper email change
738
        data = {'new_email_address': 'kpap@yahoo.com'}
739
        r = self.client.post('/im/email_change', data, follow=True)
740
        self.assertRedirects(r, '/im/profile')
741
        self.assertContains(r, messages.EMAIL_CHANGE_REGISTERED)
742
        self.assertEqual(len(get_mailbox('kpap@grnet.gr')), 0)
743
        self.assertEqual(len(get_mailbox('kpap@yahoo.com')), 1)
744
        change2 = EmailChange.objects.get()
745

    
746
        r = self.client.get(change1.get_url())
747
        self.assertEquals(r.status_code, 302)
748
        self.client.logout()
749

    
750
        r = self.client.post('/im/local?next=' + change2.get_url(),
751
                             {'username': 'kpap@grnet.gr',
752
                              'password': 'password',
753
                              'next': change2.get_url()},
754
                             follow=True)
755
        self.assertRedirects(r, '/im/profile')
756
        user = r.context['request'].user
757
        self.assertEquals(user.email, 'kpap@yahoo.com')
758
        self.assertEquals(user.username, 'kpap@yahoo.com')
759

    
760
        self.client.logout()
761
        r = self.client.post('/im/local?next=' + change2.get_url(),
762
                             {'username': 'kpap@grnet.gr',
763
                              'password': 'password',
764
                              'next': change2.get_url()},
765
                             follow=True)
766
        self.assertContains(r, "Please enter a correct username and password")
767
        self.assertEqual(user.emailchanges.count(), 0)
768

    
769

    
770
class TestAuthProviderViews(TestCase):
771

    
772
    @shibboleth_settings(CREATION_GROUPS_POLICY=['academic-login'])
773
    @shibboleth_settings(AUTOMODERATE_POLICY=True)
774
    @im_settings(IM_MODULES=['shibboleth', 'local'])
775
    @im_settings(MODERATION_ENABLED=True)
776
    def test_user(self):
777
        Profile = AuthProviderPolicyProfile
778
        Pending = PendingThirdPartyUser
779
        User = AstakosUser
780

    
781
        oldpendinguser = User.objects.create(email="newuser@grnet.gr")
782
        olduser = get_local_user("olduser@grnet.gr")
783
        cl_olduser = ShibbolethClient()
784
        olduser2 = get_local_user("olduser2@grnet.gr")
785
        cl_olduser2 = ShibbolethClient()
786
        cl_newuser = ShibbolethClient()
787
        cl_newuser2 = Client()
788

    
789
        policy = ('only_academic', 'shibboleth')
790
        academic_group, created = Group.objects.get_or_create(
791
            name='academic-login')
792
        academic_users = academic_group.user_set
793
        assert created
794
        policy_only_academic = Profile.objects.add_policy('academic_strict',
795
                                                          'shibboleth',
796
                                                          academic_group,
797
                                                          exclusive=True,
798
                                                          login=False,
799
                                                          add=False)
800

    
801

    
802
        # new academic user
803
        self.assertFalse(academic_users.filter(email='newuser@grnet.gr'))
804
        cl_newuser.set_tokens(eppn="newusereppn")
805
        r = cl_newuser.get('/im/login/shibboleth?', follow=True)
806
        pending = Pending.objects.get()
807
        identifier = pending.third_party_identifier
808
        signup_data = {'third_party_identifier': identifier,
809
                       'first_name': 'Academic',
810
                       'third_party_token': pending.token,
811
                       'last_name': 'New User',
812
                       'provider': 'shibboleth'}
813
        r = cl_newuser.post('/im/signup', signup_data)
814
        self.assertContains(r, "This field is required", )
815
        signup_data['email'] = 'olduser@grnet.gr'
816
        r = cl_newuser.post('/im/signup', signup_data)
817
        self.assertContains(r, "already an account with this email", )
818
        signup_data['email'] = 'newuser@grnet.gr'
819
        r = cl_newuser.post('/im/signup', signup_data, follow=True)
820
        r = cl_newuser.post('/im/signup', signup_data, follow=True)
821
        self.assertEqual(r.status_code, 404)
822
        newuser = User.objects.get(email="newuser@grnet.gr")
823
        activation_link = newuser.get_activation_url()
824
        self.assertTrue(academic_users.get(email='newuser@grnet.gr'))
825

    
826
        # new non-academic user
827
        signup_data = {'first_name': 'Non Academic',
828
                       'last_name': 'New User',
829
                       'provider': 'local',
830
                       'password1': 'password',
831
                       'password2': 'password'}
832
        signup_data['email'] = 'olduser@grnet.gr'
833
        r = cl_newuser2.post('/im/signup', signup_data)
834
        self.assertContains(r, 'There is already an account with this '
835
                               'email address')
836
        signup_data['email'] = 'newuser@grnet.gr'
837
        r = cl_newuser2.post('/im/signup/', signup_data)
838
        self.assertFalse(academic_users.filter(email='newuser@grnet.gr'))
839
        r = self.client.get(activation_link, follow=True)
840
        self.assertEqual(r.status_code, 400)
841
        newuser = User.objects.get(email="newuser@grnet.gr")
842
        self.assertFalse(newuser.activation_sent)
843
        r = self.client.get(newuser.get_activation_url(), follow=True)
844
        self.assertContains(r, "pending moderation")
845

    
846
        self.assertFalse(academic_users.filter(email='newuser@grnet.gr'))
847
        r = cl_newuser.get('/im/login/shibboleth?', follow=True)
848
        pending = Pending.objects.get()
849
        identifier = pending.third_party_identifier
850
        signup_data = {'third_party_identifier': identifier,
851
                       'first_name': 'Academic',
852
                       'third_party_token': pending.token,
853
                       'last_name': 'New User',
854
                       'provider': 'shibboleth'}
855
        signup_data['email'] = 'newuser@grnet.gr'
856
        r = cl_newuser.post('/im/signup', signup_data)
857
        newuser = User.objects.get(email="newuser@grnet.gr")
858
        self.assertTrue(newuser.activation_sent)
859
        activation_link = newuser.get_activation_url()
860
        self.assertTrue(academic_users.get(email='newuser@grnet.gr'))
861
        r = cl_newuser.get(newuser.get_activation_url(), follow=True)
862
        self.assertRedirects(r, '/im/landing')
863
        newuser = User.objects.get(email="newuser@grnet.gr")
864
        self.assertEqual(newuser.is_active, True)
865
        self.assertEqual(newuser.email_verified, True)
866
        cl_newuser.logout()
867

    
868
        # cannot reactivate if suspended
869
        newuser.is_active = False
870
        newuser.save()
871
        r = cl_newuser.get(newuser.get_activation_url())
872
        newuser = User.objects.get(email="newuser@grnet.gr")
873
        self.assertFalse(newuser.is_active)
874

    
875
        # release suspension
876
        newuser.is_active = True
877
        newuser.save()
878

    
879
        cl_newuser.get('/im/login/shibboleth?', follow=True)
880
        local = auth.get_provider('local', newuser)
881
        self.assertEqual(local.get_add_policy, False)
882
        self.assertEqual(local.get_login_policy, False)
883
        r = cl_newuser.get(local.get_add_url, follow=True)
884
        self.assertRedirects(r, '/im/profile')
885
        self.assertContains(r, 'disabled for your')
886

    
887
        cl_olduser.login(username='olduser@grnet.gr', password="password")
888
        r = cl_olduser.get('/im/profile', follow=True)
889
        self.assertEqual(r.status_code, 200)
890
        r = cl_olduser.get('/im/login/shibboleth?', follow=True)
891
        self.assertContains(r, 'Your request is missing a unique token')
892
        cl_olduser.set_tokens(eppn="newusereppn")
893
        r = cl_olduser.get('/im/login/shibboleth?', follow=True)
894
        self.assertContains(r, 'is already assigned to another user')
895
        cl_olduser.set_tokens(eppn="oldusereppn")
896
        r = cl_olduser.get('/im/login/shibboleth?', follow=True)
897
        self.assertContains(r, 'Academic login enabled for this account')
898

    
899
        user = User.objects.get(email="olduser@grnet.gr")
900
        shib_provider = user.get_auth_provider('shibboleth', 'oldusereppn')
901
        local_provider = user.get_auth_provider('local')
902
        self.assertEqual(shib_provider.get_remove_policy, True)
903
        self.assertEqual(local_provider.get_remove_policy, True)
904

    
905

    
906
        policy_only_academic = Profile.objects.add_policy('academic_strict2',
907
                                                          'shibboleth',
908
                                                          academic_group,
909
                                                          remove=False)
910
        user.groups.add(academic_group)
911
        shib_provider = user.get_auth_provider('shibboleth', 'oldusereppn')
912
        local_provider = user.get_auth_provider('local')
913
        self.assertEqual(shib_provider.get_remove_policy, False)
914
        self.assertEqual(local_provider.get_remove_policy, True)
915
        self.assertEqual(local_provider.get_login_policy, False)
916

    
917
        cl_olduser.logout()
918
        login_data = {'username': 'olduser@grnet.gr', 'password': 'password'}
919
        r = cl_olduser.post('/im/local', login_data, follow=True)
920
        self.assertContains(r, "href='/im/login/shibboleth'>Academic login")
921

    
922

    
923
class TestAuthProvidersAPI(TestCase):
924
    """
925
    Test auth_providers module API
926
    """
927

    
928
    @im_settings(IM_MODULES=['local', 'shibboleth'])
929
    def test_create(self):
930
        user = AstakosUser.objects.create(email="kpap@grnet.gr")
931
        user2 = AstakosUser.objects.create(email="kpap2@grnet.gr")
932

    
933
        module = 'shibboleth'
934
        identifier = 'SHIB_UUID'
935
        provider_params = {
936
            'affiliation': 'UNIVERSITY',
937
            'info': {'age': 27}
938
        }
939
        provider = auth.get_provider(module, user2, identifier,
940
                                     **provider_params)
941
        provider.add_to_user()
942
        provider = auth.get_provider(module, user, identifier,
943
                                     **provider_params)
944
        provider.add_to_user()
945
        user.email_verified = True
946
        user.save()
947
        self.assertRaises(Exception, provider.add_to_user)
948
        provider = user.get_auth_provider(module, identifier)
949
        self.assertEqual(user.get_auth_provider(
950
            module, identifier)._instance.info.get('age'), 27)
951

    
952
        module = 'local'
953
        identifier = None
954
        provider_params = {'auth_backend': 'ldap', 'info':
955
                          {'office': 'A1'}}
956
        provider = auth.get_provider(module, user, identifier,
957
                                     **provider_params)
958
        provider.add_to_user()
959
        self.assertFalse(provider.get_add_policy)
960
        self.assertRaises(Exception, provider.add_to_user)
961

    
962
        shib = user.get_auth_provider('shibboleth',
963
                                      'SHIB_UUID')
964
        self.assertTrue(shib.get_remove_policy)
965

    
966
        local = user.get_auth_provider('local')
967
        self.assertTrue(local.get_remove_policy)
968

    
969
        local.remove_from_user()
970
        self.assertFalse(shib.get_remove_policy)
971
        self.assertRaises(Exception, shib.remove_from_user)
972

    
973
        provider = user.get_auth_providers()[0]
974
        self.assertRaises(Exception, provider.add_to_user)
975

    
976
    @im_settings(IM_MODULES=['local', 'shibboleth'])
977
    @shibboleth_settings(ADD_GROUPS_POLICY=['group1', 'group2'])
978
    @shibboleth_settings(CREATION_GROUPS_POLICY=['group-create', 'group1',
979
                                                 'group2'])
980
    @localauth_settings(ADD_GROUPS_POLICY=['localgroup'])
981
    @localauth_settings(CREATION_GROUPS_POLICY=['localgroup-create',
982
                                                'group-create'])
983
    def test_add_groups(self):
984
        user = AstakosUser.objects.create(email="kpap@grnet.gr")
985
        provider = auth.get_provider('shibboleth', user, 'test123')
986
        provider.add_to_user()
987
        user = AstakosUser.objects.get()
988
        self.assertItemsEqual(user.groups.values_list('name', flat=True),
989
                              [u'group1', u'group2', u'group-create'])
990

    
991
        local = auth.get_provider('local', user)
992
        local.add_to_user()
993
        provider = user.get_auth_provider('shibboleth')
994
        self.assertEqual(provider.get_add_groups_policy, ['group1', 'group2'])
995
        provider.remove_from_user()
996
        user = AstakosUser.objects.get()
997
        self.assertEqual(len(user.get_auth_providers()), 1)
998
        self.assertItemsEqual(user.groups.values_list('name', flat=True),
999
                              [u'group-create', u'localgroup'])
1000

    
1001
        local = user.get_auth_provider('local')
1002
        self.assertRaises(Exception, local.remove_from_user)
1003
        provider = auth.get_provider('shibboleth', user, 'test123')
1004
        provider.add_to_user()
1005
        user = AstakosUser.objects.get()
1006
        self.assertItemsEqual(user.groups.values_list('name', flat=True),
1007
                              [u'group-create', u'group1', u'group2',
1008
                               u'localgroup'])
1009

    
1010

    
1011

    
1012
    @im_settings(IM_MODULES=['local', 'shibboleth'])
1013
    def test_policies(self):
1014
        group_old, created = Group.objects.get_or_create(name='olduser')
1015

    
1016
        astakos_settings.MODERATION_ENABLED = True
1017
        settings.ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_CREATION_GROUPS_POLICY = \
1018
            ['academic-user']
1019
        settings.ASTAKOS_AUTH_PROVIDER_GOOGLE_ADD_GROUPS_POLICY = \
1020
            ['google-user']
1021

    
1022
        user = AstakosUser.objects.create(email="kpap@grnet.gr")
1023
        user.groups.add(group_old)
1024
        user.add_auth_provider('local')
1025

    
1026
        user2 = AstakosUser.objects.create(email="kpap2@grnet.gr")
1027
        user2.add_auth_provider('shibboleth', identifier='shibid')
1028

    
1029
        user3 = AstakosUser.objects.create(email="kpap3@grnet.gr")
1030
        user3.groups.add(group_old)
1031
        user3.add_auth_provider('local')
1032
        user3.add_auth_provider('shibboleth', identifier='1234')
1033

    
1034
        self.assertTrue(user2.groups.get(name='academic-user'))
1035
        self.assertFalse(user2.groups.filter(name='olduser').count())
1036

    
1037
        local = auth_providers.get_provider('local')
1038
        self.assertTrue(local.get_add_policy)
1039

    
1040
        academic_group = Group.objects.get(name='academic-user')
1041
        AuthProviderPolicyProfile.objects.add_policy('academic', 'shibboleth',
1042
                                                     academic_group,
1043
                                                     exclusive=True,
1044
                                                     add=False,
1045
                                                     login=False)
1046
        AuthProviderPolicyProfile.objects.add_policy('academic', 'shibboleth',
1047
                                                     academic_group,
1048
                                                     exclusive=True,
1049
                                                     login=False,
1050
                                                     add=False)
1051
        # no duplicate entry gets created
1052
        self.assertEqual(academic_group.authpolicy_profiles.count(), 1)
1053

    
1054
        self.assertEqual(user2.authpolicy_profiles.count(), 0)
1055
        AuthProviderPolicyProfile.objects.add_policy('academic', 'shibboleth',
1056
                                                     user2,
1057
                                                     remove=False)
1058
        self.assertEqual(user2.authpolicy_profiles.count(), 1)
1059

    
1060
        local = auth_providers.get_provider('local', user2)
1061
        google = auth_providers.get_provider('google', user2)
1062
        shibboleth = auth_providers.get_provider('shibboleth', user2)
1063
        self.assertTrue(shibboleth.get_login_policy)
1064
        self.assertFalse(shibboleth.get_remove_policy)
1065
        self.assertFalse(local.get_add_policy)
1066
        self.assertFalse(local.get_add_policy)
1067
        self.assertFalse(google.get_add_policy)
1068

    
1069
        user2.groups.remove(Group.objects.get(name='academic-user'))
1070
        self.assertTrue(local.get_add_policy)
1071
        self.assertTrue(google.get_add_policy)
1072
        user2.groups.add(Group.objects.get(name='academic-user'))
1073

    
1074
        AuthProviderPolicyProfile.objects.add_policy('academic', 'shibboleth',
1075
                                                     user2,
1076
                                                     exclusive=True,
1077
                                                     add=True)
1078
        self.assertTrue(local.get_add_policy)
1079
        self.assertTrue(google.get_add_policy)
1080

    
1081
        settings.ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_AUTOMODERATE_POLICY = True
1082
        self.assertFalse(local.get_automoderate_policy)
1083
        self.assertFalse(google.get_automoderate_policy)
1084
        self.assertTrue(shibboleth.get_automoderate_policy)
1085

    
1086
        for s in ['SHIBBOLETH_CREATION_GROUPS_POLICY',
1087
                  'GOOGLE_ADD_GROUPS_POLICY']:
1088
            delattr(settings, 'ASTAKOS_AUTH_PROVIDER_%s' % s)
1089

    
1090

    
1091
    @shibboleth_settings(CREATE_POLICY=True)
1092
    @im_settings(IM_MODULES=['local', 'shibboleth'])
1093
    def test_create_http(self):
1094
        # this should be wrapped inside a transaction
1095
        user = AstakosUser(email="test@test.com")
1096
        user.save()
1097
        provider = auth_providers.get_provider('shibboleth', user,
1098
                                               'test@academia.test')
1099
        provider.add_to_user()
1100
        user.get_auth_provider('shibboleth', 'test@academia.test')
1101
        provider = auth_providers.get_provider('local', user)
1102
        provider.add_to_user()
1103
        user.get_auth_provider('local')
1104

    
1105
        settings.ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_CREATE_POLICY = False
1106
        user = AstakosUser(email="test2@test.com")
1107
        user.save()
1108
        provider = auth_providers.get_provider('shibboleth', user,
1109
                                               'test@shibboleth.com',
1110
                                               **{'info': {'name':
1111
                                                                'User Test'}})
1112
        self.assertFalse(provider.get_create_policy)
1113
        settings.ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_CREATE_POLICY = True
1114
        self.assertTrue(provider.get_create_policy)
1115
        academic = provider.add_to_user()
1116

    
1117
    @im_settings(IM_MODULES=['local', 'shibboleth'])
1118
    @shibboleth_settings(LIMIT_POLICY=2)
1119
    def test_policies(self):
1120
        user = get_local_user('kpap@grnet.gr')
1121
        user.add_auth_provider('shibboleth', identifier='1234')
1122
        user.add_auth_provider('shibboleth', identifier='12345')
1123

    
1124
        # default limit is 1
1125
        local = user.get_auth_provider('local')
1126
        self.assertEqual(local.get_add_policy, False)
1127

    
1128
        settings.ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_LIMIT_POLICY = 3
1129
        academic = user.get_auth_provider('shibboleth',
1130
                                          identifier='1234')
1131
        self.assertEqual(academic.get_add_policy, False)
1132
        newacademic = auth_providers.get_provider('shibboleth', user,
1133
                                                  identifier='123456')
1134
        self.assertEqual(newacademic.get_add_policy, True)
1135
        user.add_auth_provider('shibboleth', identifier='123456')
1136
        self.assertEqual(academic.get_add_policy, False)
1137
        settings.ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_LIMIT_POLICY = 1
1138

    
1139
    @im_settings(IM_MODULES=['local', 'shibboleth'])
1140
    @shibboleth_settings(LIMIT_POLICY=2)
1141
    def test_messages(self):
1142
        user = get_local_user('kpap@grnet.gr')
1143
        user.add_auth_provider('shibboleth', identifier='1234')
1144
        user.add_auth_provider('shibboleth', identifier='12345')
1145
        provider = auth_providers.get_provider('shibboleth')
1146
        self.assertEqual(provider.get_message('title'), 'Academic')
1147
        settings.ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_TITLE = 'New title'
1148
        # regenerate messages cache
1149
        provider = auth_providers.get_provider('shibboleth')
1150
        self.assertEqual(provider.get_message('title'), 'New title')
1151
        self.assertEqual(provider.get_message('login_title'),
1152
                         'New title LOGIN')
1153
        self.assertEqual(provider.get_login_title_msg, 'New title LOGIN')
1154
        self.assertEqual(provider.get_module_icon,
1155
                         settings.MEDIA_URL + 'im/auth/icons/shibboleth.png')
1156
        self.assertEqual(provider.get_module_medium_icon,
1157
                         settings.MEDIA_URL +
1158
                         'im/auth/icons-medium/shibboleth.png')
1159

    
1160
        settings.ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_TITLE = None
1161
        provider = auth_providers.get_provider('shibboleth', user, '12345')
1162
        self.assertEqual(provider.get_method_details_msg,
1163
                         'Account: 12345')
1164
        provider = auth_providers.get_provider('shibboleth', user, '1234')
1165
        self.assertEqual(provider.get_method_details_msg,
1166
                         'Account: 1234')
1167

    
1168
        provider = auth_providers.get_provider('shibboleth', user, '1234')
1169
        self.assertEqual(provider.get_not_active_msg,
1170
                         "'Academic login' is disabled.")
1171

    
1172
    @im_settings(IM_MODULES=['local', 'shibboleth'])
1173
    @shibboleth_settings(LIMIT_POLICY=2)
1174
    def test_templates(self):
1175
        user = get_local_user('kpap@grnet.gr')
1176
        user.add_auth_provider('shibboleth', identifier='1234')
1177
        user.add_auth_provider('shibboleth', identifier='12345')
1178

    
1179
        provider = auth_providers.get_provider('shibboleth')
1180
        self.assertEqual(provider.get_template('login'),
1181
                         'im/auth/shibboleth_login.html')
1182
        provider = auth_providers.get_provider('google')
1183
        self.assertEqual(provider.get_template('login'),
1184
                         'im/auth/generic_login.html')
1185

    
1186