Revision 9d20fe23 snf-astakos-app/astakos/im/tests.py

b/snf-astakos-app/astakos/im/tests.py
31 31
# interpreted as representing official policies, either expressed
32 32
# or implied, of GRNET S.A.
33 33

  
34
import copy
34 35
import datetime
35 36

  
36 37
from django.test import TestCase, Client
37 38
from django.conf import settings
38 39
from django.core import mail
39 40

  
41
from astakos.im.activation_backends import *
40 42
from astakos.im.target.shibboleth import Tokens as ShibbolethTokens
41 43
from astakos.im.models import *
42 44
from astakos.im import functions
......
46 48
from urllib import quote
47 49

  
48 50
from astakos.im import messages
51
from astakos.im import auth_providers
49 52

  
50 53

  
51 54
astakos_settings.EMAILCHANGE_ENABLED = True
52 55

  
56

  
53 57
class ShibbolethClient(Client):
54 58
    """
55 59
    A shibboleth agnostic client.
56 60
    """
57
    VALID_TOKENS = filter(lambda x: not x.startswith("_"), dir(ShibbolethTokens))
61
    VALID_TOKENS = filter(lambda x: not x.startswith("_"),
62
                          dir(ShibbolethTokens))
58 63

  
59 64
    def __init__(self, *args, **kwargs):
60 65
        self.tokens = kwargs.pop('tokens', {})
......
140 145

  
141 146
    def setUp(self):
142 147
        self.client = ShibbolethClient()
143
        settings.ASTAKOS_IM_MODULES = ['local', 'shibboleth']
144
        settings.ASTAKOS_MODERATION_ENABLED = True
148
        astakos_settings.IM_MODULES = ['local', 'shibboleth']
149
        astakos_settings.MODERATION_ENABLED = True
145 150

  
146 151
    def test_create_account(self):
147 152

  
......
167 172
                          cn="Kostas Papadimitriou",
168 173
                          ep_affiliation="Test Affiliation")
169 174
        r = client.get('/im/login/shibboleth?', follow=True)
175
        token = PendingThirdPartyUser.objects.get().token
176
        self.assertRedirects(r, '/im/signup?third_party_token=%s' % token)
170 177
        self.assertEqual(r.status_code, 200)
171 178

  
172
        # astakos asks if we want to add shibboleth
173
        self.assertContains(r, "Already have an account?")
174

  
175 179
        # a new pending user created
176 180
        pending_user = PendingThirdPartyUser.objects.get(
177 181
            third_party_identifier="kpapeppn")
......
185 189
        r = client.get('/im/shibboleth/signup/%s' % pending_user.username)
186 190
        self.assertEqual(r.status_code, 404)
187 191

  
188
        # this is the signup unique url associated with the pending user created
192
        # this is the signup unique url associated with the pending user
193
        # created
189 194
        r = client.get('/im/signup/?third_party_token=%s' % token)
190
        form = r.context['form']
191
        post_data = {'third_party_identifier': pending_user.third_party_identifier,
195
        identifier = pending_user.third_party_identifier
196
        post_data = {'third_party_identifier': identifier,
192 197
                     'first_name': 'Kostas',
193 198
                     'third_party_token': token,
194 199
                     'last_name': 'Mitroglou',
195
                     'provider': 'shibboleth'
196
                    }
200
                     'provider': 'shibboleth'}
197 201

  
198 202
        # invlid email
199 203
        post_data['email'] = 'kpap'
......
228 232
        client.set_tokens(mail="kpap@grnet.gr", eppn="kpapeppn",
229 233
                          cn="Kostas Papadimitriou", )
230 234
        r = client.get("/im/login/shibboleth?", follow=True)
231
        self.assertContains(r, messages.ACCOUNT_PENDING_MODERATION)
235
        self.assertContains(r, 'is pending moderation')
232 236
        r = client.get("/im/profile", follow=True)
233 237
        self.assertRedirects(r, 'http://testserver/im/?next=/im/profile')
234 238

  
......
254 258
        # shibboleth logged us in, notice that we use different email
255 259
        client.set_tokens(mail="kpap@shibboleth.gr", eppn="kpapeppn",
256 260
                          cn="Kostas Papadimitriou", )
257
        r = client.get("/im/login/shibboleth?")
258

  
259
        # astakos asks if we want to switch a local account to shibboleth
260
        self.assertContains(r, "Already have an account?")
261
        r = client.get("/im/login/shibboleth?", follow=True)
261 262

  
262 263
        # a new pending user created
263 264
        pending_user = PendingThirdPartyUser.objects.get()
265
        token = pending_user.token
264 266
        self.assertEqual(PendingThirdPartyUser.objects.count(), 1)
265 267
        pending_key = pending_user.token
266 268
        client.reset_tokens()
269
        self.assertRedirects(r, "/im/signup?third_party_token=%s" % token)
267 270

  
268
        # we choose to add shibboleth to an our existing account
269
        # we get redirected to login page with the pending token set
270
        r = client.get('/im/login?key=%s' % pending_key)
271
        post_data = {'password': 'password',
272
                     'username': 'kpap@grnet.gr',
273
                     'key': pending_key}
274
        r = client.post('/im/local', post_data, follow=True)
275
        self.assertRedirects(r, "/im/profile")
276
        self.assertContains(r, messages.AUTH_PROVIDER_ADDED)
271
        form = r.context['form']
272
        signupdata = copy.copy(form.initial)
273
        signupdata['email'] = 'kpap@grnet.gr'
274
        signupdata['third_party_token'] = token
275
        signupdata['provider'] = 'shibboleth'
276
        del signupdata['id']
277 277

  
278
        self.assertTrue(existing_user.has_auth_provider('shibboleth'))
279
        self.assertTrue(existing_user.has_auth_provider('local',
280
                                                        auth_backend='astakos'))
281
        client.logout()
278
        r = client.post("/im/signup", signupdata)
279
        self.assertContains(r, "There is already an account with this email "
280
                               "address")
282 281

  
283
        # check that we cannot assign same third party provide twice
284
        r = client.get('/im/login?key=%s' % pending_key)
285 282
        post_data = {'password': 'password',
286
                     'username': 'kpap@grnet.gr',
287
                     'key': pending_key}
288
        r = self.client.post('/im/local', post_data, follow=True)
289
        self.assertContains(r, messages.AUTH_PROVIDER_ADD_FAILED)
290
        self.client.logout()
283
                     'username': 'kpap@grnet.gr'}
284
        r = client.post('/im/local', post_data, follow=True)
285
        self.assertTrue(r.context['request'].user.is_authenticated())
286
        client.set_tokens(mail="kpap@shibboleth.gr", eppn="kpapeppn",
287
                          cn="Kostas Papadimitriou", )
288
        r = client.get("/im/login/shibboleth?", follow=True)
289
        self.assertContains(r, "enabled for this account")
290
        client.reset_tokens()
291

  
292
        user = existing_user
293
        self.assertTrue(user.has_auth_provider('shibboleth'))
294
        self.assertTrue(user.has_auth_provider('local',
295
                                               auth_backend='astakos'))
291 296
        client.logout()
292 297

  
293 298
        # look Ma, i can login with both my shibboleth and local account
......
311 316
        r = self.client.post('/im/local', post_data, follow=True)
312 317
        self.assertTrue(r.context['request'].user.is_authenticated())
313 318
        self.assertTrue(r.context['request'].user.email == "kpap@grnet.gr")
314
        self.assertRedirects(r, '/im/profile')
319
        self.assertRedirects(r, '/im/landing')
315 320
        self.assertEqual(r.status_code, 200)
316 321

  
317 322
        # cannot add the same eppn
......
322 327
        self.assertTrue(r.status_code, 200)
323 328
        self.assertEquals(existing_user.auth_providers.count(), 2)
324 329

  
325
        # but can add additional eppn
330
        # only one allowed by default
326 331
        client.set_tokens(mail="secondary@shibboleth.gr", eppn="kpapeppn2",
327 332
                          cn="Kostas Papadimitriou", ep_affiliation="affil2")
333
        prov = auth_providers.get_provider('shibboleth')
328 334
        r = client.get("/im/login/shibboleth?", follow=True)
329
        new_provider = existing_user.auth_providers.get(identifier="kpapeppn2")
335
        self.assertContains(r, "Failed to add")
330 336
        self.assertRedirects(r, '/im/profile')
331 337
        self.assertTrue(r.status_code, 200)
332
        self.assertEquals(existing_user.auth_providers.count(), 3)
333
        self.assertEqual(new_provider.affiliation, 'affil2')
338
        self.assertEquals(existing_user.auth_providers.count(), 2)
334 339
        client.logout()
335 340
        client.reset_tokens()
336 341

  
......
343 348
        # lets remove local password
344 349
        user = AstakosUser.objects.get(username="kpap@grnet.gr",
345 350
                                       email="kpap@grnet.gr")
346
        remove_local_url = user.get_provider_remove_url('local')
347
        remove_shibbo_url = user.get_provider_remove_url('shibboleth',
348
                                                         identifier='kpapeppn')
349
        remove_shibbo2_url = user.get_provider_remove_url('shibboleth',
350
                                                         identifier='kpapeppn2')
351
        remove_local_url = user.get_auth_provider('local').get_remove_url
352
        remove_shibbo_url = user.get_auth_provider('shibboleth',
353
                                                   'kpapeppn').get_remove_url
351 354
        client.set_tokens(mail="kpap@shibboleth.gr", eppn="kpapeppn",
352 355
                          cn="Kostas Papadimtriou")
353 356
        r = client.get("/im/login/shibboleth?", follow=True)
......
356 359
        # TODO: this view should use POST
357 360
        r = client.get(remove_local_url)
358 361
        # 2 providers left
359
        self.assertEqual(user.auth_providers.count(), 2)
360
        r = client.get(remove_shibbo2_url)
361
        # 1 provider left
362 362
        self.assertEqual(user.auth_providers.count(), 1)
363 363
        # cannot remove last provider
364 364
        r = client.get(remove_shibbo_url)
......
399 399
                          cn="Kostas Papadimitriou")
400 400
        r = client.get("/im/login/shibboleth?", follow=True)
401 401
        # try to assign existing shibboleth identifier of another user
402
        client.set_tokens(mail="kpap_second@shibboleth.gr", eppn="existingeppn",
403
                          cn="Kostas Papadimitriou")
402
        client.set_tokens(mail="kpap_second@shibboleth.gr",
403
                          eppn="existingeppn", cn="Kostas Papadimitriou")
404 404
        r = client.get("/im/login/shibboleth?", follow=True)
405
        self.assertContains(r, messages.AUTH_PROVIDER_ADD_FAILED)
406
        self.assertContains(r, messages.AUTH_PROVIDER_ADD_EXISTS)
405
        self.assertContains(r, "this account is already assigned")
407 406

  
408 407

  
409 408
class LocalUserTests(TestCase):
......
411 410
    fixtures = ['groups']
412 411

  
413 412
    def setUp(self):
414
        from django.conf import settings
415 413
        settings.ADMINS = (('admin', 'support@cloud.grnet.gr'),)
416 414
        settings.SERVER_EMAIL = 'no-reply@grnet.gr'
415
        self._orig_moderation = astakos_settings.MODERATION_ENABLED
416
        settings.ASTAKOS_MODERATION_ENABLED = True
417

  
418
    def tearDown(self):
419
        settings.ASTAKOS_MODERATION_ENABLED = self._orig_moderation
417 420

  
418 421
    def test_no_moderation(self):
419 422
        # disable moderation
......
422 425
        # create a new user
423 426
        r = self.client.get("/im/signup")
424 427
        self.assertEqual(r.status_code, 200)
425
        data = {'email':'kpap@grnet.gr', 'password1':'password',
426
                'password2':'password', 'first_name': 'Kostas',
428
        data = {'email': 'kpap@grnet.gr', 'password1': 'password',
429
                'password2': 'password', 'first_name': 'Kostas',
427 430
                'last_name': 'Mitroglou', 'provider': 'local'}
428 431
        r = self.client.post("/im/signup", data)
429 432

  
......
442 445

  
443 446
    def test_email_case(self):
444 447
        data = {
445
          'email': 'kPap@grnet.gr',
446
          'password1': '1234',
447
          'password2': '1234'
448
            'email': 'kPap@grnet.gr',
449
            'password1': '1234',
450
            'password2': '1234'
448 451
        }
449 452

  
450 453
        form = forms.LocalUserCreationForm(data)
......
452 455
        user = form.save()
453 456
        form.store_user(user, {})
454 457

  
455
        u = AstakosUser.objects.get(pk=1)
458
        u = AstakosUser.objects.get()
456 459
        self.assertEqual(u.email, 'kPap@grnet.gr')
457 460
        self.assertEqual(u.username, 'kpap@grnet.gr')
458 461
        u.is_active = True
......
468 471
        self.assertTrue(login.is_valid())
469 472

  
470 473
        data = {
471
          'email': 'kpap@grnet.gr',
472
          'password1': '1234',
473
          'password2': '1234'
474
            'email': 'kpap@grnet.gr',
475
            'password1': '1234',
476
            'password2': '1234'
474 477
        }
475 478
        form = forms.LocalUserCreationForm(data)
476 479
        self.assertFalse(form.is_valid())
......
482 485
        # create a user
483 486
        r = self.client.get("/im/signup")
484 487
        self.assertEqual(r.status_code, 200)
485
        data = {'email':'kpap@grnet.gr', 'password1':'password',
486
                'password2':'password', 'first_name': 'Kostas',
488
        data = {'email': 'kpap@grnet.gr', 'password1': 'password',
489
                'password2': 'password', 'first_name': 'Kostas',
487 490
                'last_name': 'Mitroglou', 'provider': 'local'}
488 491
        r = self.client.post("/im/signup", data)
489 492

  
......
493 496
                                       email="kpap@grnet.gr")
494 497
        self.assertEqual(user.username, 'kpap@grnet.gr')
495 498
        self.assertEqual(user.has_auth_provider('local'), True)
496
        self.assertFalse(user.is_active) # not activated
497
        self.assertFalse(user.email_verified) # not verified
498
        self.assertFalse(user.activation_sent) # activation automatically sent
499
        self.assertFalse(user.is_active)  # not activated
500
        self.assertFalse(user.email_verified)  # not verified
501
        self.assertFalse(user.activation_sent)  # activation automatically sent
499 502

  
500 503
        # admin gets notified and activates the user from the command line
501 504
        self.assertEqual(len(get_mailbox('support@cloud.grnet.gr')), 1)
502 505
        r = self.client.post('/im/local', {'username': 'kpap@grnet.gr',
503
                                                 'password': 'password'})
504
        self.assertContains(r, messages.ACCOUNT_PENDING_MODERATION)
506
                                           'password': 'password'})
507
        self.assertContains(r, messages.NOTIFICATION_SENT)
505 508
        functions.send_activation(user)
506 509

  
507 510
        # user activation fields updated and user gets notified via email
......
513 516

  
514 517
        # user forgot she got registered and tries to submit registration
515 518
        # form. Notice the upper case in email
516
        data = {'email':'KPAP@grnet.gr', 'password1':'password',
517
                'password2':'password', 'first_name': 'Kostas',
519
        data = {'email': 'KPAP@grnet.gr', 'password1': 'password',
520
                'password2': 'password', 'first_name': 'Kostas',
518 521
                'last_name': 'Mitroglou', 'provider': 'local'}
519 522
        r = self.client.post("/im/signup", data, follow=True)
520 523
        self.assertRedirects(r, reverse('index'))
521 524
        self.assertContains(r, messages.NOTIFICATION_SENT)
522 525

  
526
        user = AstakosUser.objects.get()
527
        functions.send_activation(user)
528

  
523 529
        # previous user replaced
524
        user = AstakosUser.objects.get(pk=user.pk)
525 530
        self.assertTrue(user.activation_sent)
526 531
        self.assertFalse(user.email_verified)
527 532
        self.assertFalse(user.is_active)
528
        self.assertEqual(len(get_mailbox('kpap@grnet.gr')), 2)
533
        self.assertEqual(len(get_mailbox('KPAP@grnet.gr')), 1)
529 534

  
530 535
        # hmmm, email exists; lets request a password change
531 536
        r = self.client.get('/im/local/password_reset')
532 537
        self.assertEqual(r.status_code, 200)
533
        r = self.client.post('/im/local/password_reset', {'email':
534
                                                          'kpap@grnet.gr'},
535
                            follow=True)
538
        data = {'email': 'kpap@grnet.gr'}
539
        r = self.client.post('/im/local/password_reset', data, follow=True)
536 540
        # she can't because account is not active yet
537
        self.assertContains(r, "doesn't have an associated user account")
541
        self.assertContains(r, 'pending activation')
538 542

  
539
        # moderation is enabled so no automatic activation can be send
540
        r = self.client.get('/im/send/activation/%d' % user.pk)
541
        self.assertEqual(r.status_code, 403)
542
        self.assertEqual(len(get_mailbox('kpap@grnet.gr')), 1)
543
        # moderation is enabled and an activation email has already been sent
544
        # so user can trigger resend of the activation email
545
        r = self.client.get('/im/send/activation/%d' % user.pk, follow=True)
546
        self.assertContains(r, 'has been sent to your email address.')
547
        self.assertEqual(len(get_mailbox('KPAP@grnet.gr')), 2)
543 548

  
544 549
        # also she cannot login
545
        r = self.client.post('/im/local', {'username': 'kpap@grnet.gr',
546
                                                 'password': 'password'})
547
        self.assertContains(r, messages.ACCOUNT_PENDING_ACTIVATION_HELP)
548
        self.assertContains(r, messages.ACCOUNT_PENDING_ACTIVATION)
549
        self.assertNotContains(r, 'Resend activation')
550
        self.assertFalse(r.context['request'].user.is_authenticated())
551
        self.assertFalse('_pithos2_a' in self.client.cookies)
552

  
553
        # same with disabled moderation
554
        astakos_settings.MODERATION_ENABLED = False
555
        r = self.client.post('/im/local/password_reset', {'email':
556
                                                          'kpap@grnet.gr'})
557
        self.assertContains(r, "doesn't have an associated user account")
558
        r = self.client.post('/im/local', {'username': 'kpap@grnet.gr',
559
                                                 'password': 'password'})
560
        self.assertContains(r, messages.ACCOUNT_PENDING_ACTIVATION)
550
        data = {'username': 'kpap@grnet.gr', 'password': 'password'}
551
        r = self.client.post('/im/local', data, follow=True)
561 552
        self.assertContains(r, 'Resend activation')
562 553
        self.assertFalse(r.context['request'].user.is_authenticated())
563 554
        self.assertFalse('_pithos2_a' in self.client.cookies)
564 555

  
565 556
        # user sees the message and resends activation
566
        r = self.client.get('/im/send/activation/%d' % user.pk)
567
        self.assertEqual(len(get_mailbox('kpap@grnet.gr')), 2)
557
        r = self.client.get('/im/send/activation/%d' % user.pk, follow=True)
558
        self.assertEqual(len(get_mailbox('KPAP@grnet.gr')), 3)
568 559

  
569 560
        # switch back moderation setting
570 561
        astakos_settings.MODERATION_ENABLED = True
571 562
        r = self.client.get(user.get_activation_url(), follow=True)
572
        self.assertRedirects(r, "/im/profile")
573
        self.assertContains(r, "kpap@grnet.gr")
574
        self.assertEqual(len(get_mailbox('kpap@grnet.gr')), 3)
563
        self.assertRedirects(r, "/im/landing")
564
        r = self.client.get('/im/profile', follow=True)
565
        self.assertTrue(r.context['request'].user.is_authenticated())
566
        self.assertTrue('_pithos2_a' in self.client.cookies)
567
        self.assertContains(r, "KPAP@grnet.gr")
568
        self.assertEqual(len(get_mailbox('KPAP@grnet.gr')), 4)
575 569

  
576 570
        user = AstakosUser.objects.get(pk=user.pk)
577 571
        # user activated and logged in, token cookie set
578 572
        self.assertTrue(r.context['request'].user.is_authenticated())
579 573
        self.assertTrue('_pithos2_a' in self.client.cookies)
580 574
        cookies = self.client.cookies
581
        self.assertTrue(quote(user.auth_token) in cookies.get('_pithos2_a').value)
575
        self.assertTrue(quote(user.auth_token) in
576
                        cookies.get('_pithos2_a').value)
582 577
        r = self.client.get('/im/logout', follow=True)
583 578
        r = self.client.get('/im/')
584 579
        # user logged out, token cookie removed
585 580
        self.assertFalse(r.context['request'].user.is_authenticated())
586 581
        self.assertFalse(self.client.cookies.get('_pithos2_a').value)
587
        # https://docs.djangoproject.com/en/dev/topics/testing/#persistent-state
582

  
583
        #https://docs.djangoproject.com/en/dev/topics/testing/#persistent-state
588 584
        del self.client.cookies['_pithos2_a']
589 585

  
590 586
        # user can login
591 587
        r = self.client.post('/im/local', {'username': 'kpap@grnet.gr',
592 588
                                           'password': 'password'},
593
                                          follow=True)
589
                             follow=True)
594 590
        self.assertTrue(r.context['request'].user.is_authenticated())
595 591
        self.assertTrue('_pithos2_a' in self.client.cookies)
596 592
        cookies = self.client.cookies
597
        self.assertTrue(quote(user.auth_token) in cookies.get('_pithos2_a').value)
593
        self.assertTrue(quote(user.auth_token) in
594
                        cookies.get('_pithos2_a').value)
598 595
        self.client.get('/im/logout', follow=True)
599 596

  
600 597
        # user forgot password
......
605 602
                                                          'kpap@grnet.gr'})
606 603
        self.assertEqual(r.status_code, 302)
607 604
        # email sent
608
        self.assertEqual(len(get_mailbox('kpap@grnet.gr')), 4)
605
        self.assertEqual(len(get_mailbox('KPAP@grnet.gr')), 5)
609 606

  
610 607
        # user visits change password link
611 608
        r = self.client.get(user.get_password_reset_url())
612 609
        r = self.client.post(user.get_password_reset_url(),
613
                            {'new_password1':'newpass',
614
                             'new_password2':'newpass'})
610
                             {'new_password1': 'newpass',
611
                              'new_password2': 'newpass'})
615 612

  
616 613
        user = AstakosUser.objects.get(pk=user.pk)
617 614
        self.assertNotEqual(old_pass, user.password)
......
637 634
        r = self.client.post('/im/local/password_reset', {'email':
638 635
                                                          'kpap@grnet.gr'})
639 636
        # she can't because account is not active yet
640
        self.assertContains(r, messages.AUTH_PROVIDER_CANNOT_CHANGE_PASSWORD)
637
        self.assertContains(r, "Changing password is not")
638

  
639

  
640
class AuthProviderModules(TestCase):
641

  
642
    def setUp(self):
643
        key = 'ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_LIMIT_POLICY'
644
        self._SETTING = getattr(settings, key, 1)
645
        settings.ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_LIMIT_POLICY = 2
646

  
647
    def tearDown(self):
648
        settings.ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_LIMIT_POLICY = self._SETTING
649

  
650
    def test_create(self):
651
        # this should be wrapped inside a transaction
652
        user = AstakosUser(email="test@test.com")
653
        user.save()
654
        provider = auth_providers.get_provider('shibboleth', user,
655
                                               'test@academia.test')
656
        provider.add_to_user()
657
        user.get_auth_provider('shibboleth', 'test@academia.test')
658
        provider = auth_providers.get_provider('local', user)
659
        provider.add_to_user()
660
        user.get_auth_provider('local')
661

  
662
        settings.ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_CREATE_POLICY = False
663
        user = AstakosUser(email="test2@test.com")
664
        user.save()
665
        provider = auth_providers.get_provider('shibboleth', user,
666
                                               'test@shibboleth.com',
667
                                               **{'info': {'name':
668
                                                                'User Test'}})
669
        self.assertFalse(provider.get_create_policy)
670
        settings.ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_CREATE_POLICY = True
671
        self.assertTrue(provider.get_create_policy)
672
        academic = provider.add_to_user()
673

  
674
    def test_policies(self):
675
        user = get_local_user('kpap@grnet.gr')
676
        user.add_auth_provider('shibboleth', identifier='1234')
677
        user.add_auth_provider('shibboleth', identifier='12345')
678

  
679
        # default limit is 1
680
        local = user.get_auth_provider('local')
681
        self.assertEqual(local.get_add_policy, False)
682

  
683
        settings.ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_LIMIT_POLICY = 3
684
        academic = user.get_auth_provider('shibboleth',
685
                                          identifier='1234')
686
        self.assertEqual(academic.get_add_policy, False)
687
        newacademic = auth_providers.get_provider('shibboleth', user,
688
                                                  identifier='123456')
689
        self.assertEqual(newacademic.get_add_policy, True)
690
        user.add_auth_provider('shibboleth', identifier='123456')
691
        self.assertEqual(academic.get_add_policy, False)
692
        settings.ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_LIMIT_POLICY = 1
693

  
694
    def test_messages(self):
695
        user = get_local_user('kpap@grnet.gr')
696
        user.add_auth_provider('shibboleth', identifier='1234')
697
        user.add_auth_provider('shibboleth', identifier='12345')
698
        provider = auth_providers.get_provider('shibboleth')
699
        self.assertEqual(provider.get_message('title'), 'Academic')
700
        settings.ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_TITLE = 'New title'
701
        # regenerate messages cache
702
        provider = auth_providers.get_provider('shibboleth')
703
        self.assertEqual(provider.get_message('title'), 'New title')
704
        self.assertEqual(provider.get_message('login_title'), 'New title LOGIN')
705
        self.assertEqual(provider.get_login_title_msg, 'New title LOGIN')
706
        self.assertEqual(provider.get_module_icon,
707
                         settings.MEDIA_URL + 'im/auth/icons/shibboleth.png')
708
        self.assertEqual(provider.get_module_medium_icon,
709
                         settings.MEDIA_URL + 'im/auth/icons-medium/shibboleth.png')
710

  
711
        settings.ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_TITLE = None
712
        provider = auth_providers.get_provider('shibboleth', user, '12345')
713
        self.assertEqual(provider.get_method_details_msg,
714
                         'Account: 12345')
715
        provider = auth_providers.get_provider('shibboleth', user, '1234')
716
        self.assertEqual(provider.get_method_details_msg,
717
                         'Account: 1234')
718

  
719
        provider = auth_providers.get_provider('shibboleth', user, '1234')
720
        self.assertEqual(provider.get_not_active_msg,
721
                         "'Academic login' is disabled.")
722

  
723
    def test_templates(self):
724
        user = get_local_user('kpap@grnet.gr')
725
        user.add_auth_provider('shibboleth', identifier='1234')
726
        user.add_auth_provider('shibboleth', identifier='12345')
727

  
728
        provider = auth_providers.get_provider('shibboleth')
729
        self.assertEqual(provider.get_template('login'),
730
                         'im/auth/shibboleth_login.html')
731
        provider = auth_providers.get_provider('google')
732
        self.assertEqual(provider.get_template('login'),
733
                         'im/auth/generic_login.html')
734

  
735

  
641 736

  
642 737
class UserActionsTests(TestCase):
643 738

  
......
704 799
        self.assertEquals(user.email, 'kpap@yahoo.com')
705 800
        self.assertEquals(user.username, 'kpap@yahoo.com')
706 801

  
707

  
708 802
        self.client.logout()
709 803
        r = self.client.post('/im/local?next=' + change2.get_url(),
710 804
                             {'username': 'kpap@grnet.gr',
......
714 808
        self.assertContains(r, "Please enter a correct username and password")
715 809
        self.assertEqual(user.emailchanges.count(), 0)
716 810

  
811

  
812
class TestAuthProvidersAPI(TestCase):
813

  
814
    def setUp(self):
815
        settings.ASTAKOS_IM_MODULES = ['local', 'shibboleth']
816

  
817
    def test_create(self):
818
        from astakos.im import auth_providers as auth
819
        user = AstakosUser.objects.create(email="kpap@grnet.gr")
820
        user2 = AstakosUser.objects.create(email="kpap2@grnet.gr")
821

  
822
        module = 'shibboleth'
823
        identifier = 'SHIB_UUID'
824
        provider_params = {
825
            'affiliation': 'UNIVERSITY',
826
            'info': {'age': 27}
827
        }
828
        provider = auth.get_provider(module, user2, identifier,
829
                                     **provider_params)
830
        provider.add_to_user()
831
        provider = auth.get_provider(module, user, identifier,
832
                                     **provider_params)
833
        provider.add_to_user()
834
        user.email_verified = True
835
        user.save()
836
        self.assertRaises(Exception, provider.add_to_user)
837
        provider = user.get_auth_provider(module, identifier)
838
        self.assertEqual(user.get_auth_provider(
839
            module, identifier)._instance.info.get('age'), 27)
840

  
841
        module = 'local'
842
        identifier = None
843
        provider_params = {'auth_backend': 'ldap', 'info':
844
                          {'office': 'A1'}}
845
        provider = auth.get_provider(module, user, identifier,
846
                                     **provider_params)
847
        provider.add_to_user()
848
        self.assertFalse(provider.get_add_policy)
849
        self.assertRaises(Exception, provider.add_to_user)
850

  
851
        shib = user.get_auth_provider('shibboleth',
852
                                      'SHIB_UUID')
853
        self.assertTrue(shib.get_remove_policy)
854

  
855
        local = user.get_auth_provider('local')
856
        self.assertTrue(local.get_remove_policy)
857

  
858
        local.remove_from_user()
859
        self.assertFalse(shib.get_remove_policy)
860
        self.assertRaises(Exception, shib.remove_from_user)
861

  
862
    def test_policies(self):
863
        group_old, created = Group.objects.get_or_create(name='olduser')
864

  
865
        astakos_settings.MODERATION_ENABLED = True
866
        settings.ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_CREATION_GROUPS_POLICY = \
867
            ['academic-user']
868
        settings.ASTAKOS_AUTH_PROVIDER_GOOGLE_ADD_GROUPS_POLICY = \
869
            ['google-user']
870

  
871
        user = AstakosUser.objects.create(email="kpap@grnet.gr")
872
        user.groups.add(group_old)
873
        user.add_auth_provider('local')
874

  
875
        user2 = AstakosUser.objects.create(email="kpap2@grnet.gr")
876
        user2.add_auth_provider('shibboleth', identifier='shibid')
877

  
878
        user3 = AstakosUser.objects.create(email="kpap3@grnet.gr")
879
        user3.groups.add(group_old)
880
        user3.add_auth_provider('local')
881
        user3.add_auth_provider('shibboleth', identifier='1234')
882

  
883
        self.assertTrue(user2.groups.get(name='academic-user'))
884
        self.assertFalse(user2.groups.filter(name='olduser').count())
885

  
886
        local = auth_providers.get_provider('local')
887
        self.assertTrue(local.get_add_policy)
888

  
889
        academic_group = Group.objects.get(name='academic-user')
890
        AuthProviderPolicyProfile.objects.add_policy('academic', 'shibboleth',
891
                                                     academic_group,
892
                                                     exclusive=True,
893
                                                     add=False,
894
                                                     login=False)
895
        AuthProviderPolicyProfile.objects.add_policy('academic', 'shibboleth',
896
                                                     academic_group,
897
                                                     exclusive=True,
898
                                                     login=False,
899
                                                     add=False)
900
        # no duplicate entry gets created
901
        self.assertEqual(academic_group.authpolicy_profiles.count(), 1)
902

  
903
        self.assertEqual(user2.authpolicy_profiles.count(), 0)
904
        AuthProviderPolicyProfile.objects.add_policy('academic', 'shibboleth',
905
                                                     user2,
906
                                                     remove=False)
907
        self.assertEqual(user2.authpolicy_profiles.count(), 1)
908

  
909
        local = auth_providers.get_provider('local', user2)
910
        google = auth_providers.get_provider('google', user2)
911
        shibboleth = auth_providers.get_provider('shibboleth', user2)
912
        self.assertTrue(shibboleth.get_login_policy)
913
        self.assertFalse(shibboleth.get_remove_policy)
914
        self.assertFalse(local.get_add_policy)
915
        self.assertFalse(local.get_add_policy)
916
        self.assertFalse(google.get_add_policy)
917

  
918
        user2.groups.remove(Group.objects.get(name='academic-user'))
919
        self.assertTrue(local.get_add_policy)
920
        self.assertTrue(google.get_add_policy)
921
        user2.groups.add(Group.objects.get(name='academic-user'))
922

  
923
        AuthProviderPolicyProfile.objects.add_policy('academic', 'shibboleth',
924
                                                     user2,
925
                                                     exclusive=True,
926
                                                     add=True)
927
        self.assertTrue(local.get_add_policy)
928
        self.assertTrue(google.get_add_policy)
929

  
930
        settings.ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_AUTOMODERATE_POLICY = True
931
        self.assertFalse(local.get_automoderate_policy)
932
        self.assertFalse(google.get_automoderate_policy)
933
        self.assertTrue(shibboleth.get_automoderate_policy)
934

  
935
        for s in ['SHIBBOLETH_CREATION_GROUPS_POLICY',
936
                  'GOOGLE_ADD_GROUPS_POLICY']:
937
            delattr(settings, 'ASTAKOS_AUTH_PROVIDER_%s' % s)

Also available in: Unified diff