Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / tests / auth.py @ 5bc77346

History | View | Annotate | Download (63 kB)

1 a661dfb2 Kostas Papadimitriou
# -*- coding: utf-8 -*-
2 d2633501 Kostas Papadimitriou
# Copyright 2011 GRNET S.A. All rights reserved.
3 d2633501 Kostas Papadimitriou
#
4 d2633501 Kostas Papadimitriou
# Redistribution and use in source and binary forms, with or
5 d2633501 Kostas Papadimitriou
# without modification, are permitted provided that the following
6 d2633501 Kostas Papadimitriou
# conditions are met:
7 d2633501 Kostas Papadimitriou
#
8 d2633501 Kostas Papadimitriou
#   1. Redistributions of source code must retain the above
9 d2633501 Kostas Papadimitriou
#      copyright notice, this list of conditions and the following
10 d2633501 Kostas Papadimitriou
#      disclaimer.
11 d2633501 Kostas Papadimitriou
#
12 d2633501 Kostas Papadimitriou
#   2. Redistributions in binary form must reproduce the above
13 d2633501 Kostas Papadimitriou
#      copyright notice, this list of conditions and the following
14 d2633501 Kostas Papadimitriou
#      disclaimer in the documentation and/or other materials
15 d2633501 Kostas Papadimitriou
#      provided with the distribution.
16 d2633501 Kostas Papadimitriou
#
17 d2633501 Kostas Papadimitriou
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
18 d2633501 Kostas Papadimitriou
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 d2633501 Kostas Papadimitriou
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 d2633501 Kostas Papadimitriou
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
21 d2633501 Kostas Papadimitriou
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 d2633501 Kostas Papadimitriou
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 d2633501 Kostas Papadimitriou
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
24 d2633501 Kostas Papadimitriou
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25 d2633501 Kostas Papadimitriou
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 d2633501 Kostas Papadimitriou
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27 d2633501 Kostas Papadimitriou
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 d2633501 Kostas Papadimitriou
# POSSIBILITY OF SUCH DAMAGE.
29 d2633501 Kostas Papadimitriou
#
30 d2633501 Kostas Papadimitriou
# The views and conclusions contained in the software and
31 d2633501 Kostas Papadimitriou
# documentation are those of the authors and should not be
32 d2633501 Kostas Papadimitriou
# interpreted as representing official policies, either expressed
33 d2633501 Kostas Papadimitriou
# or implied, of GRNET S.A.
34 d2633501 Kostas Papadimitriou
35 5b65fb47 Kostas Papadimitriou
import urlparse
36 5b65fb47 Kostas Papadimitriou
import urllib
37 5b65fb47 Kostas Papadimitriou
38 1ac3349d Kostas Papadimitriou
from astakos.im.tests.common import *
39 d2633501 Kostas Papadimitriou
40 5f28aa14 Kostas Papadimitriou
ui_url = lambda url: '/' + astakos_settings.BASE_PATH + '/ui/%s' % url
41 5f28aa14 Kostas Papadimitriou
42 d2633501 Kostas Papadimitriou
43 d2633501 Kostas Papadimitriou
class ShibbolethTests(TestCase):
44 d2633501 Kostas Papadimitriou
    """
45 d2633501 Kostas Papadimitriou
    Testing shibboleth authentication.
46 d2633501 Kostas Papadimitriou
    """
47 d2633501 Kostas Papadimitriou
48 d2633501 Kostas Papadimitriou
    def setUp(self):
49 d2633501 Kostas Papadimitriou
        self.client = ShibbolethClient()
50 9d20fe23 Kostas Papadimitriou
        astakos_settings.IM_MODULES = ['local', 'shibboleth']
51 9d20fe23 Kostas Papadimitriou
        astakos_settings.MODERATION_ENABLED = True
52 d2633501 Kostas Papadimitriou
53 baa9073a Kostas Papadimitriou
    def tearDown(self):
54 baa9073a Kostas Papadimitriou
        AstakosUser.objects.all().delete()
55 baa9073a Kostas Papadimitriou
56 0a7a4104 Kostas Papadimitriou
    @im_settings(FORCE_PROFILE_UPDATE=False)
57 d2633501 Kostas Papadimitriou
    def test_create_account(self):
58 ba50648c Kostas Papadimitriou
59 d2633501 Kostas Papadimitriou
        client = ShibbolethClient()
60 d2633501 Kostas Papadimitriou
61 d2633501 Kostas Papadimitriou
        # shibboleth views validation
62 d2633501 Kostas Papadimitriou
        # eepn required
63 5f28aa14 Kostas Papadimitriou
        r = client.get(ui_url('login/shibboleth?'), follow=True)
64 6a80a0ae Kostas Papadimitriou
        self.assertContains(r, messages.SHIBBOLETH_MISSING_USER_ID % {
65 a248ebbb Kostas Papadimitriou
            'domain': astakos_settings.BASE_HOST,
66 31bc3a62 Kostas Papadimitriou
            'contact_email': settings.CONTACT_EMAIL
67 e24d0e0d Kostas Papadimitriou
        })
68 6a80a0ae Kostas Papadimitriou
        client.set_tokens(remote_user="kpapeppn", eppn="kpapeppn")
69 ba50648c Kostas Papadimitriou
70 31fdafa8 Kostas Papadimitriou
        astakos_settings.SHIBBOLETH_REQUIRE_NAME_INFO = True
71 d2633501 Kostas Papadimitriou
        # shibboleth user info required
72 5f28aa14 Kostas Papadimitriou
        r = client.get(ui_url('login/shibboleth?'), follow=True)
73 2e90e3ec Kostas Papadimitriou
        self.assertContains(r, messages.SHIBBOLETH_MISSING_NAME)
74 31fdafa8 Kostas Papadimitriou
        astakos_settings.SHIBBOLETH_REQUIRE_NAME_INFO = False
75 d2633501 Kostas Papadimitriou
76 d2633501 Kostas Papadimitriou
        # shibboleth logged us in
77 6a80a0ae Kostas Papadimitriou
        client.set_tokens(mail="kpap@synnefo.org", remote_user="kpapeppn",
78 e5966bd9 Kostas Papadimitriou
                          cn="Kostas Papadimitriou",
79 ba50648c Kostas Papadimitriou
                          ep_affiliation="Test Affiliation")
80 5f28aa14 Kostas Papadimitriou
        r = client.get(ui_url('login/shibboleth?'), follow=True)
81 9d20fe23 Kostas Papadimitriou
        token = PendingThirdPartyUser.objects.get().token
82 5f28aa14 Kostas Papadimitriou
        self.assertRedirects(r, ui_url('signup?third_party_token=%s' % token))
83 ba50648c Kostas Papadimitriou
        self.assertEqual(r.status_code, 200)
84 d2633501 Kostas Papadimitriou
85 d2633501 Kostas Papadimitriou
        # a new pending user created
86 d2633501 Kostas Papadimitriou
        pending_user = PendingThirdPartyUser.objects.get(
87 d2633501 Kostas Papadimitriou
            third_party_identifier="kpapeppn")
88 d2633501 Kostas Papadimitriou
        self.assertEqual(PendingThirdPartyUser.objects.count(), 1)
89 ba50648c Kostas Papadimitriou
        # keep the token for future use
90 d2633501 Kostas Papadimitriou
        token = pending_user.token
91 d2633501 Kostas Papadimitriou
        # from now on no shibboleth headers are sent to the server
92 d2633501 Kostas Papadimitriou
        client.reset_tokens()
93 d2633501 Kostas Papadimitriou
94 ba50648c Kostas Papadimitriou
        # this is the old way, it should fail, to avoid pending user take over
95 5f28aa14 Kostas Papadimitriou
        r = client.get(ui_url('shibboleth/signup/%s' % pending_user.username))
96 d2633501 Kostas Papadimitriou
        self.assertEqual(r.status_code, 404)
97 d2633501 Kostas Papadimitriou
98 9d20fe23 Kostas Papadimitriou
        # this is the signup unique url associated with the pending user
99 9d20fe23 Kostas Papadimitriou
        # created
100 5f28aa14 Kostas Papadimitriou
        r = client.get(ui_url('signup/?third_party_token=%s' % token))
101 9d20fe23 Kostas Papadimitriou
        identifier = pending_user.third_party_identifier
102 9d20fe23 Kostas Papadimitriou
        post_data = {'third_party_identifier': identifier,
103 d2633501 Kostas Papadimitriou
                     'first_name': 'Kostas',
104 d2633501 Kostas Papadimitriou
                     'third_party_token': token,
105 d2633501 Kostas Papadimitriou
                     'last_name': 'Mitroglou',
106 9d20fe23 Kostas Papadimitriou
                     'provider': 'shibboleth'}
107 ba50648c Kostas Papadimitriou
108 0a7a4104 Kostas Papadimitriou
        signup_url = reverse('signup')
109 0a7a4104 Kostas Papadimitriou
110 ba50648c Kostas Papadimitriou
        # invlid email
111 ba50648c Kostas Papadimitriou
        post_data['email'] = 'kpap'
112 0a7a4104 Kostas Papadimitriou
        r = client.post(signup_url, post_data)
113 8ab484ea Kostas Papadimitriou
        self.assertContains(r, token)
114 ba50648c Kostas Papadimitriou
115 ba50648c Kostas Papadimitriou
        # existing email
116 ba50648c Kostas Papadimitriou
        existing_user = get_local_user('test@test.com')
117 ba50648c Kostas Papadimitriou
        post_data['email'] = 'test@test.com'
118 0a7a4104 Kostas Papadimitriou
        r = client.post(signup_url, post_data)
119 ba50648c Kostas Papadimitriou
        self.assertContains(r, messages.EMAIL_USED)
120 ba50648c Kostas Papadimitriou
        existing_user.delete()
121 ba50648c Kostas Papadimitriou
122 ba50648c Kostas Papadimitriou
        # and finally a valid signup
123 e7cb4085 Kostas Papadimitriou
        post_data['email'] = 'kpap@synnefo.org'
124 0a7a4104 Kostas Papadimitriou
        r = client.post(signup_url, post_data, follow=True)
125 e7cb4085 Kostas Papadimitriou
        self.assertContains(r, messages.VERIFICATION_SENT)
126 ba50648c Kostas Papadimitriou
127 e7cb4085 Kostas Papadimitriou
        # entires commited as expected
128 d2633501 Kostas Papadimitriou
        self.assertEqual(AstakosUser.objects.count(), 1)
129 d2633501 Kostas Papadimitriou
        self.assertEqual(AstakosUserAuthProvider.objects.count(), 1)
130 ba50648c Kostas Papadimitriou
        self.assertEqual(PendingThirdPartyUser.objects.count(), 0)
131 d2633501 Kostas Papadimitriou
132 ba50648c Kostas Papadimitriou
        # provider info stored
133 ba50648c Kostas Papadimitriou
        provider = AstakosUserAuthProvider.objects.get(module="shibboleth")
134 ba50648c Kostas Papadimitriou
        self.assertEqual(provider.affiliation, 'Test Affiliation')
135 830747d2 Kostas Papadimitriou
        self.assertEqual(provider.info['email'], u'kpap@synnefo.org')
136 830747d2 Kostas Papadimitriou
        self.assertEqual(provider.info['eppn'], u'kpapeppn')
137 830747d2 Kostas Papadimitriou
        self.assertEqual(provider.info['name'], u'Kostas Papadimitriou')
138 830747d2 Kostas Papadimitriou
        self.assertTrue('headers' in provider.info)
139 d2633501 Kostas Papadimitriou
140 e7cb4085 Kostas Papadimitriou
        # login (not activated yet)
141 6a80a0ae Kostas Papadimitriou
        client.set_tokens(mail="kpap@synnefo.org", remote_user="kpapeppn",
142 830747d2 Kostas Papadimitriou
                          cn="Kostas Papadimitriou")
143 5f28aa14 Kostas Papadimitriou
        r = client.get(ui_url("login/shibboleth?"), follow=True)
144 9d20fe23 Kostas Papadimitriou
        self.assertContains(r, 'is pending moderation')
145 d2633501 Kostas Papadimitriou
146 e7cb4085 Kostas Papadimitriou
        # admin activates the user
147 e7cb4085 Kostas Papadimitriou
        u = AstakosUser.objects.get(username="kpap@synnefo.org")
148 e7cb4085 Kostas Papadimitriou
        backend = activation_backends.get_backend()
149 e7cb4085 Kostas Papadimitriou
        activation_result = backend.verify_user(u, u.verification_code)
150 e7cb4085 Kostas Papadimitriou
        activation_result = backend.accept_user(u)
151 e7cb4085 Kostas Papadimitriou
        self.assertFalse(activation_result.is_error())
152 e7cb4085 Kostas Papadimitriou
        backend.send_result_notifications(activation_result, u)
153 d2633501 Kostas Papadimitriou
        self.assertEqual(u.is_active, True)
154 d2633501 Kostas Papadimitriou
155 ba50648c Kostas Papadimitriou
        # we see our profile
156 5f28aa14 Kostas Papadimitriou
        r = client.get(ui_url("login/shibboleth?"), follow=True)
157 5f28aa14 Kostas Papadimitriou
        self.assertRedirects(r, ui_url('landing'))
158 ba50648c Kostas Papadimitriou
        self.assertEqual(r.status_code, 200)
159 d2633501 Kostas Papadimitriou
160 d2633501 Kostas Papadimitriou
    def test_existing(self):
161 ba50648c Kostas Papadimitriou
        """
162 ba50648c Kostas Papadimitriou
        Test adding of third party login to an existing account
163 ba50648c Kostas Papadimitriou
        """
164 ba50648c Kostas Papadimitriou
165 ba50648c Kostas Papadimitriou
        # this is our existing user
166 e7cb4085 Kostas Papadimitriou
        existing_user = get_local_user('kpap@synnefo.org')
167 e7cb4085 Kostas Papadimitriou
        existing_inactive = get_local_user('kpap-inactive@synnefo.org')
168 478ece6c Kostas Papadimitriou
        existing_inactive.is_active = False
169 478ece6c Kostas Papadimitriou
        existing_inactive.save()
170 478ece6c Kostas Papadimitriou
171 e7cb4085 Kostas Papadimitriou
        existing_unverified = get_local_user('kpap-unverified@synnefo.org')
172 478ece6c Kostas Papadimitriou
        existing_unverified.is_active = False
173 478ece6c Kostas Papadimitriou
        existing_unverified.activation_sent = None
174 478ece6c Kostas Papadimitriou
        existing_unverified.email_verified = False
175 478ece6c Kostas Papadimitriou
        existing_unverified.is_verified = False
176 478ece6c Kostas Papadimitriou
        existing_unverified.save()
177 d2633501 Kostas Papadimitriou
178 d2633501 Kostas Papadimitriou
        client = ShibbolethClient()
179 d2633501 Kostas Papadimitriou
        # shibboleth logged us in, notice that we use different email
180 6a80a0ae Kostas Papadimitriou
        client.set_tokens(mail="kpap@shibboleth.gr", remote_user="kpapeppn",
181 e5966bd9 Kostas Papadimitriou
                          cn="Kostas Papadimitriou", )
182 5f28aa14 Kostas Papadimitriou
        r = client.get(ui_url("login/shibboleth?"), follow=True)
183 d2633501 Kostas Papadimitriou
184 d2633501 Kostas Papadimitriou
        # a new pending user created
185 d2633501 Kostas Papadimitriou
        pending_user = PendingThirdPartyUser.objects.get()
186 9d20fe23 Kostas Papadimitriou
        token = pending_user.token
187 d2633501 Kostas Papadimitriou
        self.assertEqual(PendingThirdPartyUser.objects.count(), 1)
188 d2633501 Kostas Papadimitriou
        pending_key = pending_user.token
189 d2633501 Kostas Papadimitriou
        client.reset_tokens()
190 5f28aa14 Kostas Papadimitriou
        self.assertRedirects(r, ui_url("signup?third_party_token=%s" % token))
191 d2633501 Kostas Papadimitriou
192 e585664e Christos Stavrakakis
        form = r.context['login_form']
193 9d20fe23 Kostas Papadimitriou
        signupdata = copy.copy(form.initial)
194 e7cb4085 Kostas Papadimitriou
        signupdata['email'] = 'kpap@synnefo.org'
195 9d20fe23 Kostas Papadimitriou
        signupdata['third_party_token'] = token
196 9d20fe23 Kostas Papadimitriou
        signupdata['provider'] = 'shibboleth'
197 2a88057d Christos Stavrakakis
        signupdata.pop('id', None)
198 d2633501 Kostas Papadimitriou
199 478ece6c Kostas Papadimitriou
        # the email exists to another user
200 5f28aa14 Kostas Papadimitriou
        r = client.post(ui_url("signup"), signupdata)
201 478ece6c Kostas Papadimitriou
        self.assertContains(r, "There is already an account with this email "
202 478ece6c Kostas Papadimitriou
                               "address")
203 478ece6c Kostas Papadimitriou
        # change the case, still cannot create
204 e7cb4085 Kostas Papadimitriou
        signupdata['email'] = 'KPAP@synnefo.org'
205 5f28aa14 Kostas Papadimitriou
        r = client.post(ui_url("signup"), signupdata)
206 478ece6c Kostas Papadimitriou
        self.assertContains(r, "There is already an account with this email "
207 478ece6c Kostas Papadimitriou
                               "address")
208 478ece6c Kostas Papadimitriou
        # inactive user
209 e7cb4085 Kostas Papadimitriou
        signupdata['email'] = 'KPAP-inactive@synnefo.org'
210 5f28aa14 Kostas Papadimitriou
        r = client.post(ui_url("signup"), signupdata)
211 9d20fe23 Kostas Papadimitriou
        self.assertContains(r, "There is already an account with this email "
212 9d20fe23 Kostas Papadimitriou
                               "address")
213 d2633501 Kostas Papadimitriou
214 478ece6c Kostas Papadimitriou
        # unverified user, this should pass, old entry will be deleted
215 e7cb4085 Kostas Papadimitriou
        signupdata['email'] = 'KAPAP-unverified@synnefo.org'
216 5f28aa14 Kostas Papadimitriou
        r = client.post(ui_url("signup"), signupdata)
217 478ece6c Kostas Papadimitriou
218 d2633501 Kostas Papadimitriou
        post_data = {'password': 'password',
219 e7cb4085 Kostas Papadimitriou
                     'username': 'kpap@synnefo.org'}
220 5f28aa14 Kostas Papadimitriou
        r = client.post(ui_url('local'), post_data, follow=True)
221 9d20fe23 Kostas Papadimitriou
        self.assertTrue(r.context['request'].user.is_authenticated())
222 6a80a0ae Kostas Papadimitriou
        client.set_tokens(mail="kpap@shibboleth.gr", remote_user="kpapeppn",
223 9d20fe23 Kostas Papadimitriou
                          cn="Kostas Papadimitriou", )
224 5f28aa14 Kostas Papadimitriou
        r = client.get(ui_url("login/shibboleth?"), follow=True)
225 9d20fe23 Kostas Papadimitriou
        self.assertContains(r, "enabled for this account")
226 9d20fe23 Kostas Papadimitriou
        client.reset_tokens()
227 9d20fe23 Kostas Papadimitriou
228 9d20fe23 Kostas Papadimitriou
        user = existing_user
229 9d20fe23 Kostas Papadimitriou
        self.assertTrue(user.has_auth_provider('shibboleth'))
230 9d20fe23 Kostas Papadimitriou
        self.assertTrue(user.has_auth_provider('local',
231 9d20fe23 Kostas Papadimitriou
                                               auth_backend='astakos'))
232 d2633501 Kostas Papadimitriou
        client.logout()
233 d2633501 Kostas Papadimitriou
234 d2633501 Kostas Papadimitriou
        # look Ma, i can login with both my shibboleth and local account
235 6a80a0ae Kostas Papadimitriou
        client.set_tokens(mail="kpap@shibboleth.gr", remote_user="kpapeppn",
236 e5966bd9 Kostas Papadimitriou
                          cn="Kostas Papadimitriou")
237 5f28aa14 Kostas Papadimitriou
        r = client.get(ui_url("login/shibboleth?"), follow=True)
238 d2633501 Kostas Papadimitriou
        self.assertTrue(r.context['request'].user.is_authenticated())
239 e7cb4085 Kostas Papadimitriou
        self.assertTrue(r.context['request'].user.email == "kpap@synnefo.org")
240 5f28aa14 Kostas Papadimitriou
        self.assertRedirects(r, ui_url('landing'))
241 ba50648c Kostas Papadimitriou
        self.assertEqual(r.status_code, 200)
242 d2633501 Kostas Papadimitriou
        client.logout()
243 d2633501 Kostas Papadimitriou
        client.reset_tokens()
244 ba50648c Kostas Papadimitriou
245 ba50648c Kostas Papadimitriou
        # logged out
246 5f28aa14 Kostas Papadimitriou
        r = client.get(ui_url("profile"), follow=True)
247 d2633501 Kostas Papadimitriou
        self.assertFalse(r.context['request'].user.is_authenticated())
248 d2633501 Kostas Papadimitriou
249 ba50648c Kostas Papadimitriou
        # login with local account also works
250 d2633501 Kostas Papadimitriou
        post_data = {'password': 'password',
251 e7cb4085 Kostas Papadimitriou
                     'username': 'kpap@synnefo.org'}
252 5f28aa14 Kostas Papadimitriou
        r = self.client.post(ui_url('local'), post_data, follow=True)
253 d2633501 Kostas Papadimitriou
        self.assertTrue(r.context['request'].user.is_authenticated())
254 e7cb4085 Kostas Papadimitriou
        self.assertTrue(r.context['request'].user.email == "kpap@synnefo.org")
255 5f28aa14 Kostas Papadimitriou
        self.assertRedirects(r, ui_url('landing'))
256 ba50648c Kostas Papadimitriou
        self.assertEqual(r.status_code, 200)
257 d2633501 Kostas Papadimitriou
258 ba50648c Kostas Papadimitriou
        # cannot add the same eppn
259 5bc77346 Giorgos Korfiatis
        client.set_tokens(mail="secondary@shibboleth.gr",
260 5bc77346 Giorgos Korfiatis
                          remote_user="kpapeppn",
261 e5966bd9 Kostas Papadimitriou
                          cn="Kostas Papadimitriou", )
262 5f28aa14 Kostas Papadimitriou
        r = client.get(ui_url("login/shibboleth?"), follow=True)
263 5f28aa14 Kostas Papadimitriou
        self.assertRedirects(r, ui_url('landing'))
264 ba50648c Kostas Papadimitriou
        self.assertTrue(r.status_code, 200)
265 ba50648c Kostas Papadimitriou
        self.assertEquals(existing_user.auth_providers.count(), 2)
266 d2633501 Kostas Papadimitriou
267 9d20fe23 Kostas Papadimitriou
        # only one allowed by default
268 5bc77346 Giorgos Korfiatis
        client.set_tokens(mail="secondary@shibboleth.gr",
269 5bc77346 Giorgos Korfiatis
                          remote_user="kpapeppn2",
270 e5966bd9 Kostas Papadimitriou
                          cn="Kostas Papadimitriou", ep_affiliation="affil2")
271 9d20fe23 Kostas Papadimitriou
        prov = auth_providers.get_provider('shibboleth')
272 5f28aa14 Kostas Papadimitriou
        r = client.get(ui_url("login/shibboleth?"), follow=True)
273 9d20fe23 Kostas Papadimitriou
        self.assertContains(r, "Failed to add")
274 5f28aa14 Kostas Papadimitriou
        self.assertRedirects(r, ui_url('profile'))
275 ba50648c Kostas Papadimitriou
        self.assertTrue(r.status_code, 200)
276 9d20fe23 Kostas Papadimitriou
        self.assertEquals(existing_user.auth_providers.count(), 2)
277 d2633501 Kostas Papadimitriou
        client.logout()
278 ba50648c Kostas Papadimitriou
        client.reset_tokens()
279 ba50648c Kostas Papadimitriou
280 ba50648c Kostas Papadimitriou
        # cannot login with another eppn
281 5bc77346 Giorgos Korfiatis
        client.set_tokens(mail="kpap@synnefo.org",
282 5bc77346 Giorgos Korfiatis
                          remote_user="kpapeppninvalid",
283 e5966bd9 Kostas Papadimitriou
                          cn="Kostas Papadimitriou")
284 5f28aa14 Kostas Papadimitriou
        r = client.get(ui_url("login/shibboleth?"), follow=True)
285 d2633501 Kostas Papadimitriou
        self.assertFalse(r.context['request'].user.is_authenticated())
286 d2633501 Kostas Papadimitriou
287 478ece6c Kostas Papadimitriou
        # cannot
288 478ece6c Kostas Papadimitriou
289 f432088a Kostas Papadimitriou
        # lets remove local password
290 e7cb4085 Kostas Papadimitriou
        user = AstakosUser.objects.get(username="kpap@synnefo.org",
291 e7cb4085 Kostas Papadimitriou
                                       email="kpap@synnefo.org")
292 9d20fe23 Kostas Papadimitriou
        remove_local_url = user.get_auth_provider('local').get_remove_url
293 9d20fe23 Kostas Papadimitriou
        remove_shibbo_url = user.get_auth_provider('shibboleth',
294 9d20fe23 Kostas Papadimitriou
                                                   'kpapeppn').get_remove_url
295 6a80a0ae Kostas Papadimitriou
        client.set_tokens(mail="kpap@shibboleth.gr", remote_user="kpapeppn",
296 e5966bd9 Kostas Papadimitriou
                          cn="Kostas Papadimtriou")
297 5f28aa14 Kostas Papadimitriou
        r = client.get(ui_url("login/shibboleth?"), follow=True)
298 f432088a Kostas Papadimitriou
        client.reset_tokens()
299 ba50648c Kostas Papadimitriou
300 17138f12 Kostas Papadimitriou
        # only POST is allowed (for CSRF protection)
301 17138f12 Kostas Papadimitriou
        r = client.get(remove_local_url, follow=True)
302 17138f12 Kostas Papadimitriou
        self.assertEqual(r.status_code, 405)
303 17138f12 Kostas Papadimitriou
304 17138f12 Kostas Papadimitriou
        r = client.post(remove_local_url, follow=True)
305 ba50648c Kostas Papadimitriou
        # 2 providers left
306 f432088a Kostas Papadimitriou
        self.assertEqual(user.auth_providers.count(), 1)
307 ba50648c Kostas Papadimitriou
        # cannot remove last provider
308 17138f12 Kostas Papadimitriou
        r = client.post(remove_shibbo_url)
309 f432088a Kostas Papadimitriou
        self.assertEqual(r.status_code, 403)
310 f432088a Kostas Papadimitriou
        self.client.logout()
311 ba50648c Kostas Papadimitriou
312 ba50648c Kostas Papadimitriou
        # cannot login using local credentials (notice we use another client)
313 f432088a Kostas Papadimitriou
        post_data = {'password': 'password',
314 e7cb4085 Kostas Papadimitriou
                     'username': 'kpap@synnefo.org'}
315 5f28aa14 Kostas Papadimitriou
        r = self.client.post(ui_url('local'), post_data, follow=True)
316 f432088a Kostas Papadimitriou
        self.assertFalse(r.context['request'].user.is_authenticated())
317 f432088a Kostas Papadimitriou
318 ba50648c Kostas Papadimitriou
        # we can reenable the local provider by setting a password
319 5f28aa14 Kostas Papadimitriou
        r = client.get(ui_url("password_change"), follow=True)
320 5f28aa14 Kostas Papadimitriou
        r = client.post(ui_url("password_change"), {'new_password1': '111',
321 8fb8d0cf Giorgos Korfiatis
                                                    'new_password2': '111'},
322 f432088a Kostas Papadimitriou
                        follow=True)
323 f432088a Kostas Papadimitriou
        user = r.context['request'].user
324 f432088a Kostas Papadimitriou
        self.assertTrue(user.has_auth_provider('local'))
325 f432088a Kostas Papadimitriou
        self.assertTrue(user.has_auth_provider('shibboleth'))
326 f432088a Kostas Papadimitriou
        self.assertTrue(user.check_password('111'))
327 f432088a Kostas Papadimitriou
        self.assertTrue(user.has_usable_password())
328 36f1eabb Kostas Papadimitriou
329 36f1eabb Kostas Papadimitriou
        # change password via profile form
330 36f1eabb Kostas Papadimitriou
        r = client.post(ui_url("profile"), {
331 36f1eabb Kostas Papadimitriou
            'old_password': '111',
332 36f1eabb Kostas Papadimitriou
            'new_password': '',
333 36f1eabb Kostas Papadimitriou
            'new_password2': '',
334 36f1eabb Kostas Papadimitriou
            'change_password': 'on',
335 36f1eabb Kostas Papadimitriou
        }, follow=False)
336 36f1eabb Kostas Papadimitriou
        self.assertEqual(r.status_code, 200)
337 36f1eabb Kostas Papadimitriou
        self.assertFalse(r.context['profile_form'].is_valid())
338 36f1eabb Kostas Papadimitriou
339 f432088a Kostas Papadimitriou
        self.client.logout()
340 ba50648c Kostas Papadimitriou
341 ba50648c Kostas Papadimitriou
        # now we can login
342 f432088a Kostas Papadimitriou
        post_data = {'password': '111',
343 e7cb4085 Kostas Papadimitriou
                     'username': 'kpap@synnefo.org'}
344 5f28aa14 Kostas Papadimitriou
        r = self.client.post(ui_url('local'), post_data, follow=True)
345 f432088a Kostas Papadimitriou
        self.assertTrue(r.context['request'].user.is_authenticated())
346 f432088a Kostas Papadimitriou
347 ba50648c Kostas Papadimitriou
        client.reset_tokens()
348 f432088a Kostas Papadimitriou
349 ba50648c Kostas Papadimitriou
        # we cannot take over another shibboleth identifier
350 e7cb4085 Kostas Papadimitriou
        user2 = get_local_user('another@synnefo.org')
351 f432088a Kostas Papadimitriou
        user2.add_auth_provider('shibboleth', identifier='existingeppn')
352 ba50648c Kostas Papadimitriou
        # login
353 6a80a0ae Kostas Papadimitriou
        client.set_tokens(mail="kpap@shibboleth.gr", remote_user="kpapeppn",
354 e5966bd9 Kostas Papadimitriou
                          cn="Kostas Papadimitriou")
355 5f28aa14 Kostas Papadimitriou
        r = client.get(ui_url("login/shibboleth?"), follow=True)
356 ba50648c Kostas Papadimitriou
        # try to assign existing shibboleth identifier of another user
357 9d20fe23 Kostas Papadimitriou
        client.set_tokens(mail="kpap_second@shibboleth.gr",
358 5bc77346 Giorgos Korfiatis
                          remote_user="existingeppn",
359 5bc77346 Giorgos Korfiatis
                          cn="Kostas Papadimitriou")
360 5f28aa14 Kostas Papadimitriou
        r = client.get(ui_url("login/shibboleth?"), follow=True)
361 c34abd9c Kostas Papadimitriou
        self.assertContains(r, "is already in use")
362 2e90e3ec Kostas Papadimitriou
363 d2633501 Kostas Papadimitriou
364 478ece6c Kostas Papadimitriou
class TestLocal(TestCase):
365 d2633501 Kostas Papadimitriou
366 2e90e3ec Kostas Papadimitriou
    def setUp(self):
367 e7cb4085 Kostas Papadimitriou
        settings.ADMINS = (('admin', 'support@cloud.synnefo.org'),)
368 e7cb4085 Kostas Papadimitriou
        settings.SERVER_EMAIL = 'no-reply@synnefo.org'
369 9d20fe23 Kostas Papadimitriou
        self._orig_moderation = astakos_settings.MODERATION_ENABLED
370 9d20fe23 Kostas Papadimitriou
        settings.ASTAKOS_MODERATION_ENABLED = True
371 9d20fe23 Kostas Papadimitriou
372 9d20fe23 Kostas Papadimitriou
    def tearDown(self):
373 9d20fe23 Kostas Papadimitriou
        settings.ASTAKOS_MODERATION_ENABLED = self._orig_moderation
374 baa9073a Kostas Papadimitriou
        AstakosUser.objects.all().delete()
375 2e90e3ec Kostas Papadimitriou
376 a661dfb2 Kostas Papadimitriou
    @im_settings(RECAPTCHA_ENABLED=True, RATELIMIT_RETRIES_ALLOWED=3)
377 a661dfb2 Kostas Papadimitriou
    def test_login_ratelimit(self):
378 6a80a0ae Kostas Papadimitriou
        from django.core.cache import cache
379 b8633f0c Kostas Papadimitriou
        cache.clear()
380 6a80a0ae Kostas Papadimitriou
381 a661dfb2 Kostas Papadimitriou
        credentials = {'username': 'γιού τι έφ', 'password': 'password'}
382 a661dfb2 Kostas Papadimitriou
        r = self.client.post(ui_url('local'), credentials, follow=True)
383 a661dfb2 Kostas Papadimitriou
        fields = r.context['login_form'].fields.keyOrder
384 a661dfb2 Kostas Papadimitriou
        self.assertFalse('recaptcha_challenge_field' in fields)
385 a661dfb2 Kostas Papadimitriou
        r = self.client.post(ui_url('local'), credentials, follow=True)
386 a661dfb2 Kostas Papadimitriou
        fields = r.context['login_form'].fields.keyOrder
387 a661dfb2 Kostas Papadimitriou
        self.assertFalse('recaptcha_challenge_field' in fields)
388 a661dfb2 Kostas Papadimitriou
        r = self.client.post(ui_url('local'), credentials, follow=True)
389 a661dfb2 Kostas Papadimitriou
        fields = r.context['login_form'].fields.keyOrder
390 a661dfb2 Kostas Papadimitriou
        self.assertTrue('recaptcha_challenge_field' in fields)
391 3407774b Kostas Papadimitriou
        r = self.client.post(ui_url('local'), follow=True)
392 3407774b Kostas Papadimitriou
        fields = r.context['login_form'].fields.keyOrder
393 3407774b Kostas Papadimitriou
        self.assertTrue('recaptcha_challenge_field' in fields)
394 a661dfb2 Kostas Papadimitriou
395 7233d542 Kostas Papadimitriou
    def test_no_moderation(self):
396 ba50648c Kostas Papadimitriou
        # disable moderation
397 7233d542 Kostas Papadimitriou
        astakos_settings.MODERATION_ENABLED = False
398 ba50648c Kostas Papadimitriou
399 ba50648c Kostas Papadimitriou
        # create a new user
400 5f28aa14 Kostas Papadimitriou
        r = self.client.get(ui_url("signup"))
401 7233d542 Kostas Papadimitriou
        self.assertEqual(r.status_code, 200)
402 e7cb4085 Kostas Papadimitriou
        data = {'email': 'kpap@synnefo.org', 'password1': 'password',
403 9d20fe23 Kostas Papadimitriou
                'password2': 'password', 'first_name': 'Kostas',
404 7233d542 Kostas Papadimitriou
                'last_name': 'Mitroglou', 'provider': 'local'}
405 5f28aa14 Kostas Papadimitriou
        r = self.client.post(ui_url("signup"), data)
406 ba50648c Kostas Papadimitriou
407 ba50648c Kostas Papadimitriou
        # user created
408 7233d542 Kostas Papadimitriou
        self.assertEqual(AstakosUser.objects.count(), 1)
409 e7cb4085 Kostas Papadimitriou
        user = AstakosUser.objects.get(username="kpap@synnefo.org",
410 e7cb4085 Kostas Papadimitriou
                                       email="kpap@synnefo.org")
411 e7cb4085 Kostas Papadimitriou
        self.assertEqual(user.username, 'kpap@synnefo.org')
412 7233d542 Kostas Papadimitriou
        self.assertEqual(user.has_auth_provider('local'), True)
413 7233d542 Kostas Papadimitriou
        self.assertFalse(user.is_active)
414 7233d542 Kostas Papadimitriou
415 ba50648c Kostas Papadimitriou
        # user (but not admin) gets notified
416 e7cb4085 Kostas Papadimitriou
        self.assertEqual(len(get_mailbox('support@cloud.synnefo.org')), 0)
417 e7cb4085 Kostas Papadimitriou
        self.assertEqual(len(get_mailbox('kpap@synnefo.org')), 1)
418 7233d542 Kostas Papadimitriou
        astakos_settings.MODERATION_ENABLED = True
419 d2633501 Kostas Papadimitriou
420 e5966bd9 Kostas Papadimitriou
    def test_email_case(self):
421 e5966bd9 Kostas Papadimitriou
        data = {
422 e7cb4085 Kostas Papadimitriou
            'email': 'kPap@synnefo.org',
423 9d20fe23 Kostas Papadimitriou
            'password1': '1234',
424 9d20fe23 Kostas Papadimitriou
            'password2': '1234'
425 e5966bd9 Kostas Papadimitriou
        }
426 e5966bd9 Kostas Papadimitriou
427 e5966bd9 Kostas Papadimitriou
        form = forms.LocalUserCreationForm(data)
428 e5966bd9 Kostas Papadimitriou
        self.assertTrue(form.is_valid())
429 e5966bd9 Kostas Papadimitriou
        user = form.save()
430 e5966bd9 Kostas Papadimitriou
        form.store_user(user, {})
431 e5966bd9 Kostas Papadimitriou
432 9d20fe23 Kostas Papadimitriou
        u = AstakosUser.objects.get()
433 e7cb4085 Kostas Papadimitriou
        self.assertEqual(u.email, 'kPap@synnefo.org')
434 e7cb4085 Kostas Papadimitriou
        self.assertEqual(u.username, 'kpap@synnefo.org')
435 e5966bd9 Kostas Papadimitriou
        u.is_active = True
436 e5966bd9 Kostas Papadimitriou
        u.email_verified = True
437 e5966bd9 Kostas Papadimitriou
        u.save()
438 e5966bd9 Kostas Papadimitriou
439 e7cb4085 Kostas Papadimitriou
        data = {'username': 'kpap@synnefo.org', 'password': '1234'}
440 e5966bd9 Kostas Papadimitriou
        login = forms.LoginForm(data=data)
441 e5966bd9 Kostas Papadimitriou
        self.assertTrue(login.is_valid())
442 e5966bd9 Kostas Papadimitriou
443 e7cb4085 Kostas Papadimitriou
        data = {'username': 'KpaP@synnefo.org', 'password': '1234'}
444 e5966bd9 Kostas Papadimitriou
        login = forms.LoginForm(data=data)
445 e5966bd9 Kostas Papadimitriou
        self.assertTrue(login.is_valid())
446 e5966bd9 Kostas Papadimitriou
447 e5966bd9 Kostas Papadimitriou
        data = {
448 e7cb4085 Kostas Papadimitriou
            'email': 'kpap@synnefo.org',
449 9d20fe23 Kostas Papadimitriou
            'password1': '1234',
450 9d20fe23 Kostas Papadimitriou
            'password2': '1234'
451 e5966bd9 Kostas Papadimitriou
        }
452 e5966bd9 Kostas Papadimitriou
        form = forms.LocalUserCreationForm(data)
453 e5966bd9 Kostas Papadimitriou
        self.assertFalse(form.is_valid())
454 e5966bd9 Kostas Papadimitriou
455 ba27316a Kostas Papadimitriou
    @im_settings(HELPDESK=(('support', 'support@synnefo.org'),),
456 e7cb4085 Kostas Papadimitriou
                 FORCE_PROFILE_UPDATE=False, MODERATION_ENABLED=True)
457 d2633501 Kostas Papadimitriou
    def test_local_provider(self):
458 19a992e3 Kostas Papadimitriou
        self.helpdesk_email = astakos_settings.HELPDESK[0][1]
459 ba50648c Kostas Papadimitriou
460 ba50648c Kostas Papadimitriou
        # create a user
461 5f28aa14 Kostas Papadimitriou
        r = self.client.get(ui_url("signup"))
462 d2633501 Kostas Papadimitriou
        self.assertEqual(r.status_code, 200)
463 e7cb4085 Kostas Papadimitriou
        data = {'email': 'kpap@synnefo.org', 'password1': 'password',
464 9d20fe23 Kostas Papadimitriou
                'password2': 'password', 'first_name': 'Kostas',
465 d2633501 Kostas Papadimitriou
                'last_name': 'Mitroglou', 'provider': 'local'}
466 5f28aa14 Kostas Papadimitriou
        r = self.client.post(ui_url("signup"), data)
467 ba50648c Kostas Papadimitriou
468 ba50648c Kostas Papadimitriou
        # user created
469 d2633501 Kostas Papadimitriou
        self.assertEqual(AstakosUser.objects.count(), 1)
470 e7cb4085 Kostas Papadimitriou
        user = AstakosUser.objects.get(username="kpap@synnefo.org",
471 e7cb4085 Kostas Papadimitriou
                                       email="kpap@synnefo.org")
472 e7cb4085 Kostas Papadimitriou
        self.assertEqual(user.username, 'kpap@synnefo.org')
473 d2633501 Kostas Papadimitriou
        self.assertEqual(user.has_auth_provider('local'), True)
474 9d20fe23 Kostas Papadimitriou
        self.assertFalse(user.is_active)  # not activated
475 9d20fe23 Kostas Papadimitriou
        self.assertFalse(user.email_verified)  # not verified
476 e7cb4085 Kostas Papadimitriou
        self.assertTrue(user.activation_sent)  # activation automatically sent
477 e7cb4085 Kostas Papadimitriou
        self.assertFalse(user.moderated)
478 e7cb4085 Kostas Papadimitriou
        self.assertFalse(user.email_verified)
479 d2633501 Kostas Papadimitriou
480 ba50648c Kostas Papadimitriou
        # admin gets notified and activates the user from the command line
481 e7cb4085 Kostas Papadimitriou
        self.assertEqual(len(get_mailbox('kpap@synnefo.org')), 1)
482 5f28aa14 Kostas Papadimitriou
        r = self.client.post(ui_url('local'), {'username': 'kpap@synnefo.org',
483 8fb8d0cf Giorgos Korfiatis
                                               'password': 'password'},
484 e7cb4085 Kostas Papadimitriou
                             follow=True)
485 e7cb4085 Kostas Papadimitriou
        self.assertContains(r, messages.VERIFICATION_SENT)
486 e7cb4085 Kostas Papadimitriou
        backend = activation_backends.get_backend()
487 e7cb4085 Kostas Papadimitriou
488 e7cb4085 Kostas Papadimitriou
        user = AstakosUser.objects.get(username="kpap@synnefo.org")
489 e7cb4085 Kostas Papadimitriou
        backend.send_user_verification_email(user)
490 d2633501 Kostas Papadimitriou
491 ba50648c Kostas Papadimitriou
        # user activation fields updated and user gets notified via email
492 d2633501 Kostas Papadimitriou
        user = AstakosUser.objects.get(pk=user.pk)
493 d2633501 Kostas Papadimitriou
        self.assertTrue(user.activation_sent)
494 d2633501 Kostas Papadimitriou
        self.assertFalse(user.email_verified)
495 f47ecf6b Kostas Papadimitriou
        self.assertFalse(user.is_active)
496 e7cb4085 Kostas Papadimitriou
        self.assertEqual(len(get_mailbox('kpap@synnefo.org')), 2)
497 d2633501 Kostas Papadimitriou
498 d2633501 Kostas Papadimitriou
        # user forgot she got registered and tries to submit registration
499 d2633501 Kostas Papadimitriou
        # form. Notice the upper case in email
500 e7cb4085 Kostas Papadimitriou
        data = {'email': 'KPAP@synnefo.org', 'password1': 'password',
501 9d20fe23 Kostas Papadimitriou
                'password2': 'password', 'first_name': 'Kostas',
502 d2633501 Kostas Papadimitriou
                'last_name': 'Mitroglou', 'provider': 'local'}
503 5f28aa14 Kostas Papadimitriou
        r = self.client.post(ui_url("signup"), data, follow=True)
504 1ecda536 Kostas Papadimitriou
        self.assertRedirects(r, reverse('login'))
505 e7cb4085 Kostas Papadimitriou
        self.assertContains(r, messages.VERIFICATION_SENT)
506 564a2292 Kostas Papadimitriou
507 9d20fe23 Kostas Papadimitriou
        user = AstakosUser.objects.get()
508 564a2292 Kostas Papadimitriou
        # previous user replaced
509 564a2292 Kostas Papadimitriou
        self.assertTrue(user.activation_sent)
510 564a2292 Kostas Papadimitriou
        self.assertFalse(user.email_verified)
511 564a2292 Kostas Papadimitriou
        self.assertFalse(user.is_active)
512 e7cb4085 Kostas Papadimitriou
        self.assertEqual(len(get_mailbox('KPAP@synnefo.org')), 1)
513 d2633501 Kostas Papadimitriou
514 f47ecf6b Kostas Papadimitriou
        # hmmm, email exists; lets request a password change
515 5f28aa14 Kostas Papadimitriou
        r = self.client.get(ui_url('local/password_reset'))
516 d2633501 Kostas Papadimitriou
        self.assertEqual(r.status_code, 200)
517 e7cb4085 Kostas Papadimitriou
        data = {'email': 'kpap@synnefo.org'}
518 5f28aa14 Kostas Papadimitriou
        r = self.client.post(ui_url('local/password_reset'), data, follow=True)
519 d2633501 Kostas Papadimitriou
        # she can't because account is not active yet
520 9d20fe23 Kostas Papadimitriou
        self.assertContains(r, 'pending activation')
521 d2633501 Kostas Papadimitriou
522 9d20fe23 Kostas Papadimitriou
        # moderation is enabled and an activation email has already been sent
523 9d20fe23 Kostas Papadimitriou
        # so user can trigger resend of the activation email
524 5f28aa14 Kostas Papadimitriou
        r = self.client.get(ui_url('send/activation/%d' % user.pk),
525 5f28aa14 Kostas Papadimitriou
                            follow=True)
526 9d20fe23 Kostas Papadimitriou
        self.assertContains(r, 'has been sent to your email address.')
527 e7cb4085 Kostas Papadimitriou
        self.assertEqual(len(get_mailbox('KPAP@synnefo.org')), 2)
528 ba50648c Kostas Papadimitriou
529 d2633501 Kostas Papadimitriou
        # also she cannot login
530 e7cb4085 Kostas Papadimitriou
        data = {'username': 'kpap@synnefo.org', 'password': 'password'}
531 5f28aa14 Kostas Papadimitriou
        r = self.client.post(ui_url('local'), data, follow=True)
532 d2633501 Kostas Papadimitriou
        self.assertContains(r, 'Resend activation')
533 d2633501 Kostas Papadimitriou
        self.assertFalse(r.context['request'].user.is_authenticated())
534 d2633501 Kostas Papadimitriou
        self.assertFalse('_pithos2_a' in self.client.cookies)
535 ba50648c Kostas Papadimitriou
536 d2633501 Kostas Papadimitriou
        # user sees the message and resends activation
537 5f28aa14 Kostas Papadimitriou
        r = self.client.get(ui_url('send/activation/%d' % user.pk),
538 5f28aa14 Kostas Papadimitriou
                            follow=True)
539 e7cb4085 Kostas Papadimitriou
        self.assertEqual(len(get_mailbox('KPAP@synnefo.org')), 3)
540 d2633501 Kostas Papadimitriou
541 e7cb4085 Kostas Papadimitriou
        # logged in user cannot activate another account
542 e7cb4085 Kostas Papadimitriou
        tmp_user = get_local_user("test_existing_user@synnefo.org")
543 e7cb4085 Kostas Papadimitriou
        tmp_client = Client()
544 e7cb4085 Kostas Papadimitriou
        tmp_client.login(username="test_existing_user@synnefo.org",
545 e7cb4085 Kostas Papadimitriou
                         password="password")
546 e7cb4085 Kostas Papadimitriou
        r = tmp_client.get(user.get_activation_url(), follow=True)
547 e7cb4085 Kostas Papadimitriou
        self.assertContains(r, messages.LOGGED_IN_WARNING)
548 e7cb4085 Kostas Papadimitriou
549 e7cb4085 Kostas Papadimitriou
        r = self.client.get(user.get_activation_url(), follow=True)
550 e7cb4085 Kostas Papadimitriou
        # previous code got invalidated
551 e7cb4085 Kostas Papadimitriou
        self.assertEqual(r.status_code, 404)
552 e7cb4085 Kostas Papadimitriou
553 e7cb4085 Kostas Papadimitriou
        user = AstakosUser.objects.get(pk=user.pk)
554 e7cb4085 Kostas Papadimitriou
        self.assertEqual(len(get_mailbox(self.helpdesk_email)), 0)
555 d2633501 Kostas Papadimitriou
        r = self.client.get(user.get_activation_url(), follow=True)
556 1ecda536 Kostas Papadimitriou
        self.assertRedirects(r, reverse('login'))
557 e7cb4085 Kostas Papadimitriou
        # user sees that account is pending approval from admins
558 e7cb4085 Kostas Papadimitriou
        self.assertContains(r, messages.NOTIFICATION_SENT)
559 e7cb4085 Kostas Papadimitriou
        self.assertEqual(len(get_mailbox(self.helpdesk_email)), 1)
560 e7cb4085 Kostas Papadimitriou
561 e7cb4085 Kostas Papadimitriou
        user = AstakosUser.objects.get(email="KPAP@synnefo.org")
562 e7cb4085 Kostas Papadimitriou
        result = backend.handle_moderation(user)
563 e7cb4085 Kostas Papadimitriou
        backend.send_result_notifications(result, user)
564 e7cb4085 Kostas Papadimitriou
        self.assertEqual(len(get_mailbox('KPAP@synnefo.org')), 4)
565 e7cb4085 Kostas Papadimitriou
        self.assertEqual(len(get_mailbox(self.helpdesk_email)), 2)
566 e7cb4085 Kostas Papadimitriou
567 e7cb4085 Kostas Papadimitriou
        user = AstakosUser.objects.get(email="KPAP@synnefo.org")
568 5f28aa14 Kostas Papadimitriou
        r = self.client.get(ui_url('profile'), follow=True)
569 e7cb4085 Kostas Papadimitriou
        self.assertFalse(r.context['request'].user.is_authenticated())
570 e7cb4085 Kostas Papadimitriou
        self.assertFalse('_pithos2_a' in self.client.cookies)
571 e7cb4085 Kostas Papadimitriou
        self.assertEqual(len(get_mailbox('KPAP@synnefo.org')), 4)
572 d2633501 Kostas Papadimitriou
573 d2633501 Kostas Papadimitriou
        user = AstakosUser.objects.get(pk=user.pk)
574 5f28aa14 Kostas Papadimitriou
        r = self.client.post(ui_url('local'), {'username': 'kpap@synnefo.org',
575 5f28aa14 Kostas Papadimitriou
                                               'password': 'password'},
576 e7cb4085 Kostas Papadimitriou
                             follow=True)
577 d2633501 Kostas Papadimitriou
        # user activated and logged in, token cookie set
578 d2633501 Kostas Papadimitriou
        self.assertTrue(r.context['request'].user.is_authenticated())
579 d2633501 Kostas Papadimitriou
        self.assertTrue('_pithos2_a' in self.client.cookies)
580 d2633501 Kostas Papadimitriou
        cookies = self.client.cookies
581 9d20fe23 Kostas Papadimitriou
        self.assertTrue(quote(user.auth_token) in
582 9d20fe23 Kostas Papadimitriou
                        cookies.get('_pithos2_a').value)
583 5f28aa14 Kostas Papadimitriou
        r = self.client.get(ui_url('logout'), follow=True)
584 1ecda536 Kostas Papadimitriou
        r = self.client.get(ui_url(''), follow=True)
585 1ecda536 Kostas Papadimitriou
        self.assertRedirects(r, ui_url('login'))
586 d2633501 Kostas Papadimitriou
        # user logged out, token cookie removed
587 d2633501 Kostas Papadimitriou
        self.assertFalse(r.context['request'].user.is_authenticated())
588 d2633501 Kostas Papadimitriou
        self.assertFalse(self.client.cookies.get('_pithos2_a').value)
589 9d20fe23 Kostas Papadimitriou
590 9d20fe23 Kostas Papadimitriou
        #https://docs.djangoproject.com/en/dev/topics/testing/#persistent-state
591 d2633501 Kostas Papadimitriou
        del self.client.cookies['_pithos2_a']
592 d2633501 Kostas Papadimitriou
593 d2633501 Kostas Papadimitriou
        # user can login
594 5f28aa14 Kostas Papadimitriou
        r = self.client.post(ui_url('local'), {'username': 'kpap@synnefo.org',
595 5f28aa14 Kostas Papadimitriou
                                               'password': 'password'},
596 9d20fe23 Kostas Papadimitriou
                             follow=True)
597 d2633501 Kostas Papadimitriou
        self.assertTrue(r.context['request'].user.is_authenticated())
598 d2633501 Kostas Papadimitriou
        self.assertTrue('_pithos2_a' in self.client.cookies)
599 d2633501 Kostas Papadimitriou
        cookies = self.client.cookies
600 9d20fe23 Kostas Papadimitriou
        self.assertTrue(quote(user.auth_token) in
601 9d20fe23 Kostas Papadimitriou
                        cookies.get('_pithos2_a').value)
602 5f28aa14 Kostas Papadimitriou
        self.client.get(ui_url('logout'), follow=True)
603 d2633501 Kostas Papadimitriou
604 d2633501 Kostas Papadimitriou
        # user forgot password
605 d2633501 Kostas Papadimitriou
        old_pass = user.password
606 5f28aa14 Kostas Papadimitriou
        r = self.client.get(ui_url('local/password_reset'))
607 d2633501 Kostas Papadimitriou
        self.assertEqual(r.status_code, 200)
608 5f28aa14 Kostas Papadimitriou
        r = self.client.post(ui_url('local/password_reset'),
609 5f28aa14 Kostas Papadimitriou
                             {'email': 'kpap@synnefo.org'})
610 d2633501 Kostas Papadimitriou
        self.assertEqual(r.status_code, 302)
611 d2633501 Kostas Papadimitriou
        # email sent
612 e7cb4085 Kostas Papadimitriou
        self.assertEqual(len(get_mailbox('KPAP@synnefo.org')), 5)
613 d2633501 Kostas Papadimitriou
614 d2633501 Kostas Papadimitriou
        # user visits change password link
615 126f6a55 Christos Stavrakakis
        user = AstakosUser.objects.get(pk=user.pk)
616 d2633501 Kostas Papadimitriou
        r = self.client.get(user.get_password_reset_url())
617 d2633501 Kostas Papadimitriou
        r = self.client.post(user.get_password_reset_url(),
618 9d20fe23 Kostas Papadimitriou
                             {'new_password1': 'newpass',
619 9d20fe23 Kostas Papadimitriou
                              'new_password2': 'newpass'})
620 d2633501 Kostas Papadimitriou
621 d2633501 Kostas Papadimitriou
        user = AstakosUser.objects.get(pk=user.pk)
622 d2633501 Kostas Papadimitriou
        self.assertNotEqual(old_pass, user.password)
623 d2633501 Kostas Papadimitriou
624 d2633501 Kostas Papadimitriou
        # old pass is not usable
625 5f28aa14 Kostas Papadimitriou
        r = self.client.post(ui_url('local'), {'username': 'kpap@synnefo.org',
626 5f28aa14 Kostas Papadimitriou
                                               'password': 'password'})
627 31fdafa8 Kostas Papadimitriou
        self.assertContains(r, 'Please enter a correct username and password')
628 5f28aa14 Kostas Papadimitriou
        r = self.client.post(ui_url('local'), {'username': 'kpap@synnefo.org',
629 5f28aa14 Kostas Papadimitriou
                                               'password': 'newpass'},
630 478ece6c Kostas Papadimitriou
                             follow=True)
631 d2633501 Kostas Papadimitriou
        self.assertTrue(r.context['request'].user.is_authenticated())
632 d2633501 Kostas Papadimitriou
        self.client.logout()
633 d2633501 Kostas Papadimitriou
634 d2633501 Kostas Papadimitriou
        # tests of special local backends
635 d2633501 Kostas Papadimitriou
        user = AstakosUser.objects.get(pk=user.pk)
636 d2633501 Kostas Papadimitriou
        user.auth_providers.filter(module='local').update(auth_backend='ldap')
637 d2633501 Kostas Papadimitriou
        user.save()
638 d2633501 Kostas Papadimitriou
639 d2633501 Kostas Papadimitriou
        # non astakos local backends do not support password reset
640 5f28aa14 Kostas Papadimitriou
        r = self.client.get(ui_url('local/password_reset'))
641 d2633501 Kostas Papadimitriou
        self.assertEqual(r.status_code, 200)
642 5f28aa14 Kostas Papadimitriou
        r = self.client.post(ui_url('local/password_reset'),
643 5f28aa14 Kostas Papadimitriou
                             {'email': 'kpap@synnefo.org'})
644 d2633501 Kostas Papadimitriou
        # she can't because account is not active yet
645 9d20fe23 Kostas Papadimitriou
        self.assertContains(r, "Changing password is not")
646 9d20fe23 Kostas Papadimitriou
647 9d20fe23 Kostas Papadimitriou
648 34a76cdb Kostas Papadimitriou
class UserActionsTests(TestCase):
649 34a76cdb Kostas Papadimitriou
650 34a76cdb Kostas Papadimitriou
    def test_email_change(self):
651 34a76cdb Kostas Papadimitriou
        # to test existing email validation
652 e7cb4085 Kostas Papadimitriou
        get_local_user('existing@synnefo.org')
653 34a76cdb Kostas Papadimitriou
654 34a76cdb Kostas Papadimitriou
        # local user
655 e7cb4085 Kostas Papadimitriou
        user = get_local_user('kpap@synnefo.org')
656 34a76cdb Kostas Papadimitriou
657 34a76cdb Kostas Papadimitriou
        # login as kpap
658 e7cb4085 Kostas Papadimitriou
        self.client.login(username='kpap@synnefo.org', password='password')
659 5f28aa14 Kostas Papadimitriou
        r = self.client.get(ui_url('profile'), follow=True)
660 34a76cdb Kostas Papadimitriou
        user = r.context['request'].user
661 34a76cdb Kostas Papadimitriou
        self.assertTrue(user.is_authenticated())
662 34a76cdb Kostas Papadimitriou
663 34a76cdb Kostas Papadimitriou
        # change email is enabled
664 5f28aa14 Kostas Papadimitriou
        r = self.client.get(ui_url('email_change'))
665 34a76cdb Kostas Papadimitriou
        self.assertEqual(r.status_code, 200)
666 34a76cdb Kostas Papadimitriou
        self.assertFalse(user.email_change_is_pending())
667 34a76cdb Kostas Papadimitriou
668 34a76cdb Kostas Papadimitriou
        # request email change to an existing email fails
669 e7cb4085 Kostas Papadimitriou
        data = {'new_email_address': 'existing@synnefo.org'}
670 5f28aa14 Kostas Papadimitriou
        r = self.client.post(ui_url('email_change'), data)
671 34a76cdb Kostas Papadimitriou
        self.assertContains(r, messages.EMAIL_USED)
672 34a76cdb Kostas Papadimitriou
673 34a76cdb Kostas Papadimitriou
        # proper email change
674 34a76cdb Kostas Papadimitriou
        data = {'new_email_address': 'kpap@gmail.com'}
675 5f28aa14 Kostas Papadimitriou
        r = self.client.post(ui_url('email_change'), data, follow=True)
676 5f28aa14 Kostas Papadimitriou
        self.assertRedirects(r, ui_url('profile'))
677 34a76cdb Kostas Papadimitriou
        self.assertContains(r, messages.EMAIL_CHANGE_REGISTERED)
678 34a76cdb Kostas Papadimitriou
        change1 = EmailChange.objects.get()
679 34a76cdb Kostas Papadimitriou
680 34a76cdb Kostas Papadimitriou
        # user sees a warning
681 5f28aa14 Kostas Papadimitriou
        r = self.client.get(ui_url('email_change'))
682 34a76cdb Kostas Papadimitriou
        self.assertEqual(r.status_code, 200)
683 34a76cdb Kostas Papadimitriou
        self.assertContains(r, messages.PENDING_EMAIL_CHANGE_REQUEST)
684 34a76cdb Kostas Papadimitriou
        self.assertTrue(user.email_change_is_pending())
685 34a76cdb Kostas Papadimitriou
686 34a76cdb Kostas Papadimitriou
        # link was sent
687 e7cb4085 Kostas Papadimitriou
        self.assertEqual(len(get_mailbox('kpap@synnefo.org')), 0)
688 34a76cdb Kostas Papadimitriou
        self.assertEqual(len(get_mailbox('kpap@gmail.com')), 1)
689 34a76cdb Kostas Papadimitriou
690 34a76cdb Kostas Papadimitriou
        # proper email change
691 34a76cdb Kostas Papadimitriou
        data = {'new_email_address': 'kpap@yahoo.com'}
692 5f28aa14 Kostas Papadimitriou
        r = self.client.post(ui_url('email_change'), data, follow=True)
693 5f28aa14 Kostas Papadimitriou
        self.assertRedirects(r, ui_url('profile'))
694 34a76cdb Kostas Papadimitriou
        self.assertContains(r, messages.EMAIL_CHANGE_REGISTERED)
695 e7cb4085 Kostas Papadimitriou
        self.assertEqual(len(get_mailbox('kpap@synnefo.org')), 0)
696 34a76cdb Kostas Papadimitriou
        self.assertEqual(len(get_mailbox('kpap@yahoo.com')), 1)
697 34a76cdb Kostas Papadimitriou
        change2 = EmailChange.objects.get()
698 34a76cdb Kostas Papadimitriou
699 34a76cdb Kostas Papadimitriou
        r = self.client.get(change1.get_url())
700 0b817216 Kostas Papadimitriou
        self.assertEquals(r.status_code, 404)
701 34a76cdb Kostas Papadimitriou
        self.client.logout()
702 34a76cdb Kostas Papadimitriou
703 0b817216 Kostas Papadimitriou
        invalid_client = Client()
704 5f28aa14 Kostas Papadimitriou
        r = invalid_client.post(ui_url('local?'),
705 0b817216 Kostas Papadimitriou
                                {'username': 'existing@synnefo.org',
706 0b817216 Kostas Papadimitriou
                                 'password': 'password'})
707 0b817216 Kostas Papadimitriou
        r = invalid_client.get(change2.get_url(), follow=True)
708 0b817216 Kostas Papadimitriou
        self.assertEquals(r.status_code, 403)
709 0b817216 Kostas Papadimitriou
710 5f28aa14 Kostas Papadimitriou
        r = self.client.post(ui_url('local?next=' + change2.get_url()),
711 e7cb4085 Kostas Papadimitriou
                             {'username': 'kpap@synnefo.org',
712 34a76cdb Kostas Papadimitriou
                              'password': 'password',
713 34a76cdb Kostas Papadimitriou
                              'next': change2.get_url()},
714 34a76cdb Kostas Papadimitriou
                             follow=True)
715 5f28aa14 Kostas Papadimitriou
        self.assertRedirects(r, ui_url('profile'))
716 34a76cdb Kostas Papadimitriou
        user = r.context['request'].user
717 34a76cdb Kostas Papadimitriou
        self.assertEquals(user.email, 'kpap@yahoo.com')
718 34a76cdb Kostas Papadimitriou
        self.assertEquals(user.username, 'kpap@yahoo.com')
719 34a76cdb Kostas Papadimitriou
720 34a76cdb Kostas Papadimitriou
        self.client.logout()
721 5f28aa14 Kostas Papadimitriou
        r = self.client.post(ui_url('local?next=' + change2.get_url()),
722 e7cb4085 Kostas Papadimitriou
                             {'username': 'kpap@synnefo.org',
723 34a76cdb Kostas Papadimitriou
                              'password': 'password',
724 34a76cdb Kostas Papadimitriou
                              'next': change2.get_url()},
725 34a76cdb Kostas Papadimitriou
                             follow=True)
726 34a76cdb Kostas Papadimitriou
        self.assertContains(r, "Please enter a correct username and password")
727 34a76cdb Kostas Papadimitriou
        self.assertEqual(user.emailchanges.count(), 0)
728 34a76cdb Kostas Papadimitriou
729 5f28aa14 Kostas Papadimitriou
        AstakosUser.objects.all().delete()
730 5f28aa14 Kostas Papadimitriou
        Group.objects.all().delete()
731 5f28aa14 Kostas Papadimitriou
732 9d20fe23 Kostas Papadimitriou
733 6a80a0ae Kostas Papadimitriou
TEST_TARGETED_ID1 = \
734 6a80a0ae Kostas Papadimitriou
    "https://idp.synnefo.org/idp/shibboleth!ZWxhIHJlIGVsYSByZSBlbGEgcmU="
735 6a80a0ae Kostas Papadimitriou
TEST_TARGETED_ID2 = \
736 6a80a0ae Kostas Papadimitriou
    "https://idp.synnefo.org/idp/shibboleth!ZGUgc2UgeGFsYXNlLi4uLi4uLg=="
737 6a80a0ae Kostas Papadimitriou
TEST_TARGETED_ID3 = \
738 6a80a0ae Kostas Papadimitriou
    "https://idp.synnefo.org/idp/shibboleth!"
739 6a80a0ae Kostas Papadimitriou
740 6a80a0ae Kostas Papadimitriou
741 478ece6c Kostas Papadimitriou
class TestAuthProviderViews(TestCase):
742 478ece6c Kostas Papadimitriou
743 baa9073a Kostas Papadimitriou
    def tearDown(self):
744 baa9073a Kostas Papadimitriou
        AstakosUser.objects.all().delete()
745 baa9073a Kostas Papadimitriou
746 6a80a0ae Kostas Papadimitriou
    @im_settings(IM_MODULES=['shibboleth'], MODERATION_ENABLED=False,
747 6a80a0ae Kostas Papadimitriou
                 SHIBBOLETH_MIGRATE_EPPN=True)
748 6a80a0ae Kostas Papadimitriou
    def migrate_to_remote_id(self):
749 6a80a0ae Kostas Papadimitriou
        eppn_user = get_local_user("eppn@synnefo.org")
750 6a80a0ae Kostas Papadimitriou
        tid_user = get_local_user("tid@synnefo.org")
751 6a80a0ae Kostas Papadimitriou
        eppn_user.add_auth_provider('shibboleth', 'EPPN')
752 6a80a0ae Kostas Papadimitriou
        tid_user.add_auth_provider('shibboleth', TEST_TARGETED_ID1)
753 6a80a0ae Kostas Papadimitriou
754 6a80a0ae Kostas Papadimitriou
        get_user = lambda r: r.context['request'].user
755 6a80a0ae Kostas Papadimitriou
756 6a80a0ae Kostas Papadimitriou
        client = ShibbolethClient()
757 6a80a0ae Kostas Papadimitriou
        client.set_tokens(eppn="EPPN", remote_user=TEST_TARGETED_ID2)
758 6a80a0ae Kostas Papadimitriou
        r = client.get(ui_url('login/shibboleth?'), follow=True)
759 6a80a0ae Kostas Papadimitriou
        self.assertTrue(get_user(r).is_authenticated())
760 6a80a0ae Kostas Papadimitriou
        self.assertEqual(eppn_user.get_auth_provider('shibboleth').identifier,
761 6a80a0ae Kostas Papadimitriou
                         TEST_TARGETED_ID2)
762 6a80a0ae Kostas Papadimitriou
763 6a80a0ae Kostas Papadimitriou
        client = ShibbolethClient()
764 6a80a0ae Kostas Papadimitriou
        client.set_tokens(eppn="EPPN", remote_user=TEST_TARGETED_ID1)
765 6a80a0ae Kostas Papadimitriou
        r = client.get(ui_url('login/shibboleth?'), follow=True)
766 6a80a0ae Kostas Papadimitriou
        self.assertTrue(get_user(r).is_authenticated())
767 6a80a0ae Kostas Papadimitriou
        self.assertEqual(tid_user.get_auth_provider('shibboleth').identifier,
768 6a80a0ae Kostas Papadimitriou
                         TEST_TARGETED_ID1)
769 6a80a0ae Kostas Papadimitriou
770 ba27316a Kostas Papadimitriou
    @shibboleth_settings(CREATION_GROUPS_POLICY=['academic-login'],
771 ba27316a Kostas Papadimitriou
                         AUTOMODERATE_POLICY=True)
772 ba27316a Kostas Papadimitriou
    @im_settings(IM_MODULES=['shibboleth', 'local'], MODERATION_ENABLED=True,
773 ba27316a Kostas Papadimitriou
                 FORCE_PROFILE_UPDATE=False)
774 478ece6c Kostas Papadimitriou
    def test_user(self):
775 478ece6c Kostas Papadimitriou
        Profile = AuthProviderPolicyProfile
776 478ece6c Kostas Papadimitriou
        Pending = PendingThirdPartyUser
777 478ece6c Kostas Papadimitriou
        User = AstakosUser
778 478ece6c Kostas Papadimitriou
779 e7cb4085 Kostas Papadimitriou
        User.objects.create(email="newuser@synnefo.org")
780 e7cb4085 Kostas Papadimitriou
        get_local_user("olduser@synnefo.org")
781 478ece6c Kostas Papadimitriou
        cl_olduser = ShibbolethClient()
782 e7cb4085 Kostas Papadimitriou
        get_local_user("olduser2@synnefo.org")
783 0a7a4104 Kostas Papadimitriou
        ShibbolethClient()
784 478ece6c Kostas Papadimitriou
        cl_newuser = ShibbolethClient()
785 478ece6c Kostas Papadimitriou
        cl_newuser2 = Client()
786 478ece6c Kostas Papadimitriou
787 478ece6c Kostas Papadimitriou
        academic_group, created = Group.objects.get_or_create(
788 478ece6c Kostas Papadimitriou
            name='academic-login')
789 478ece6c Kostas Papadimitriou
        academic_users = academic_group.user_set
790 478ece6c Kostas Papadimitriou
        assert created
791 478ece6c Kostas Papadimitriou
        policy_only_academic = Profile.objects.add_policy('academic_strict',
792 478ece6c Kostas Papadimitriou
                                                          'shibboleth',
793 478ece6c Kostas Papadimitriou
                                                          academic_group,
794 478ece6c Kostas Papadimitriou
                                                          exclusive=True,
795 478ece6c Kostas Papadimitriou
                                                          login=False,
796 478ece6c Kostas Papadimitriou
                                                          add=False)
797 478ece6c Kostas Papadimitriou
798 478ece6c Kostas Papadimitriou
        # new academic user
799 e7cb4085 Kostas Papadimitriou
        self.assertFalse(academic_users.filter(email='newuser@synnefo.org'))
800 5bc77346 Giorgos Korfiatis
        cl_newuser.set_tokens(remote_user="newusereppn",
801 5bc77346 Giorgos Korfiatis
                              mail="newuser@synnefo.org",
802 c1f65a1e Kostas Papadimitriou
                              surname="Lastname")
803 5f28aa14 Kostas Papadimitriou
        r = cl_newuser.get(ui_url('login/shibboleth?'), follow=True)
804 c1f65a1e Kostas Papadimitriou
        initial = r.context['signup_form'].initial
805 478ece6c Kostas Papadimitriou
        pending = Pending.objects.get()
806 c1f65a1e Kostas Papadimitriou
        self.assertEqual(initial.get('last_name'), 'Lastname')
807 c1f65a1e Kostas Papadimitriou
        self.assertEqual(initial.get('email'), 'newuser@synnefo.org')
808 478ece6c Kostas Papadimitriou
        identifier = pending.third_party_identifier
809 478ece6c Kostas Papadimitriou
        signup_data = {'third_party_identifier': identifier,
810 478ece6c Kostas Papadimitriou
                       'first_name': 'Academic',
811 478ece6c Kostas Papadimitriou
                       'third_party_token': pending.token,
812 478ece6c Kostas Papadimitriou
                       'last_name': 'New User',
813 478ece6c Kostas Papadimitriou
                       'provider': 'shibboleth'}
814 5f28aa14 Kostas Papadimitriou
        r = cl_newuser.post(ui_url('signup'), signup_data)
815 478ece6c Kostas Papadimitriou
        self.assertContains(r, "This field is required", )
816 e7cb4085 Kostas Papadimitriou
        signup_data['email'] = 'olduser@synnefo.org'
817 5f28aa14 Kostas Papadimitriou
        r = cl_newuser.post(ui_url('signup'), signup_data)
818 478ece6c Kostas Papadimitriou
        self.assertContains(r, "already an account with this email", )
819 e7cb4085 Kostas Papadimitriou
        signup_data['email'] = 'newuser@synnefo.org'
820 5f28aa14 Kostas Papadimitriou
        r = cl_newuser.post(ui_url('signup'), signup_data, follow=True)
821 5f28aa14 Kostas Papadimitriou
        r = cl_newuser.post(ui_url('signup'), signup_data, follow=True)
822 478ece6c Kostas Papadimitriou
        self.assertEqual(r.status_code, 404)
823 e7cb4085 Kostas Papadimitriou
        newuser = User.objects.get(email="newuser@synnefo.org")
824 478ece6c Kostas Papadimitriou
        activation_link = newuser.get_activation_url()
825 e7cb4085 Kostas Papadimitriou
        self.assertTrue(academic_users.get(email='newuser@synnefo.org'))
826 478ece6c Kostas Papadimitriou
827 478ece6c Kostas Papadimitriou
        # new non-academic user
828 478ece6c Kostas Papadimitriou
        signup_data = {'first_name': 'Non Academic',
829 478ece6c Kostas Papadimitriou
                       'last_name': 'New User',
830 478ece6c Kostas Papadimitriou
                       'provider': 'local',
831 478ece6c Kostas Papadimitriou
                       'password1': 'password',
832 478ece6c Kostas Papadimitriou
                       'password2': 'password'}
833 e7cb4085 Kostas Papadimitriou
        signup_data['email'] = 'olduser@synnefo.org'
834 5f28aa14 Kostas Papadimitriou
        r = cl_newuser2.post(ui_url('signup'), signup_data)
835 478ece6c Kostas Papadimitriou
        self.assertContains(r, 'There is already an account with this '
836 478ece6c Kostas Papadimitriou
                               'email address')
837 e7cb4085 Kostas Papadimitriou
        signup_data['email'] = 'newuser@synnefo.org'
838 5f28aa14 Kostas Papadimitriou
        r = cl_newuser2.post(ui_url('signup/'), signup_data)
839 e7cb4085 Kostas Papadimitriou
        self.assertFalse(academic_users.filter(email='newuser@synnefo.org'))
840 478ece6c Kostas Papadimitriou
        r = self.client.get(activation_link, follow=True)
841 e7cb4085 Kostas Papadimitriou
        self.assertEqual(r.status_code, 404)
842 e7cb4085 Kostas Papadimitriou
        newuser = User.objects.get(email="newuser@synnefo.org")
843 e7cb4085 Kostas Papadimitriou
        self.assertTrue(newuser.activation_sent)
844 478ece6c Kostas Papadimitriou
845 e7cb4085 Kostas Papadimitriou
        # activation sent, user didn't open verification url so additional
846 e7cb4085 Kostas Papadimitriou
        # registrations invalidate the previous signups.
847 e7cb4085 Kostas Papadimitriou
        self.assertFalse(academic_users.filter(email='newuser@synnefo.org'))
848 5f28aa14 Kostas Papadimitriou
        r = cl_newuser.get(ui_url('login/shibboleth?'), follow=True)
849 478ece6c Kostas Papadimitriou
        pending = Pending.objects.get()
850 478ece6c Kostas Papadimitriou
        identifier = pending.third_party_identifier
851 478ece6c Kostas Papadimitriou
        signup_data = {'third_party_identifier': identifier,
852 478ece6c Kostas Papadimitriou
                       'first_name': 'Academic',
853 478ece6c Kostas Papadimitriou
                       'third_party_token': pending.token,
854 478ece6c Kostas Papadimitriou
                       'last_name': 'New User',
855 478ece6c Kostas Papadimitriou
                       'provider': 'shibboleth'}
856 e7cb4085 Kostas Papadimitriou
        signup_data['email'] = 'newuser@synnefo.org'
857 5f28aa14 Kostas Papadimitriou
        r = cl_newuser.post(ui_url('signup'), signup_data)
858 e7cb4085 Kostas Papadimitriou
        self.assertEqual(r.status_code, 302)
859 e7cb4085 Kostas Papadimitriou
        newuser = User.objects.get(email="newuser@synnefo.org")
860 478ece6c Kostas Papadimitriou
        self.assertTrue(newuser.activation_sent)
861 478ece6c Kostas Papadimitriou
        activation_link = newuser.get_activation_url()
862 e7cb4085 Kostas Papadimitriou
        self.assertTrue(academic_users.get(email='newuser@synnefo.org'))
863 478ece6c Kostas Papadimitriou
        r = cl_newuser.get(newuser.get_activation_url(), follow=True)
864 5f28aa14 Kostas Papadimitriou
        self.assertRedirects(r, ui_url('landing'))
865 e7cb4085 Kostas Papadimitriou
        newuser = User.objects.get(email="newuser@synnefo.org")
866 478ece6c Kostas Papadimitriou
        self.assertEqual(newuser.is_active, True)
867 478ece6c Kostas Papadimitriou
        self.assertEqual(newuser.email_verified, True)
868 478ece6c Kostas Papadimitriou
        cl_newuser.logout()
869 478ece6c Kostas Papadimitriou
870 478ece6c Kostas Papadimitriou
        # cannot reactivate if suspended
871 478ece6c Kostas Papadimitriou
        newuser.is_active = False
872 478ece6c Kostas Papadimitriou
        newuser.save()
873 478ece6c Kostas Papadimitriou
        r = cl_newuser.get(newuser.get_activation_url())
874 e7cb4085 Kostas Papadimitriou
        newuser = User.objects.get(email="newuser@synnefo.org")
875 478ece6c Kostas Papadimitriou
        self.assertFalse(newuser.is_active)
876 478ece6c Kostas Papadimitriou
877 478ece6c Kostas Papadimitriou
        # release suspension
878 478ece6c Kostas Papadimitriou
        newuser.is_active = True
879 478ece6c Kostas Papadimitriou
        newuser.save()
880 478ece6c Kostas Papadimitriou
881 5f28aa14 Kostas Papadimitriou
        cl_newuser.get(ui_url('login/shibboleth?'), follow=True)
882 478ece6c Kostas Papadimitriou
        local = auth.get_provider('local', newuser)
883 478ece6c Kostas Papadimitriou
        self.assertEqual(local.get_add_policy, False)
884 478ece6c Kostas Papadimitriou
        self.assertEqual(local.get_login_policy, False)
885 478ece6c Kostas Papadimitriou
        r = cl_newuser.get(local.get_add_url, follow=True)
886 5f28aa14 Kostas Papadimitriou
        self.assertRedirects(r, ui_url('profile'))
887 478ece6c Kostas Papadimitriou
        self.assertContains(r, 'disabled for your')
888 478ece6c Kostas Papadimitriou
889 e7cb4085 Kostas Papadimitriou
        cl_olduser.login(username='olduser@synnefo.org', password="password")
890 5f28aa14 Kostas Papadimitriou
        r = cl_olduser.get(ui_url('profile'), follow=True)
891 478ece6c Kostas Papadimitriou
        self.assertEqual(r.status_code, 200)
892 5f28aa14 Kostas Papadimitriou
        r = cl_olduser.get(ui_url('login/shibboleth?'), follow=True)
893 478ece6c Kostas Papadimitriou
        self.assertContains(r, 'Your request is missing a unique token')
894 6a80a0ae Kostas Papadimitriou
        cl_olduser.set_tokens(remote_user="newusereppn")
895 5f28aa14 Kostas Papadimitriou
        r = cl_olduser.get(ui_url('login/shibboleth?'), follow=True)
896 c34abd9c Kostas Papadimitriou
        self.assertContains(r, 'already in use')
897 6a80a0ae Kostas Papadimitriou
        cl_olduser.set_tokens(remote_user="oldusereppn")
898 5f28aa14 Kostas Papadimitriou
        r = cl_olduser.get(ui_url('login/shibboleth?'), follow=True)
899 478ece6c Kostas Papadimitriou
        self.assertContains(r, 'Academic login enabled for this account')
900 478ece6c Kostas Papadimitriou
901 e7cb4085 Kostas Papadimitriou
        user = User.objects.get(email="olduser@synnefo.org")
902 478ece6c Kostas Papadimitriou
        shib_provider = user.get_auth_provider('shibboleth', 'oldusereppn')
903 478ece6c Kostas Papadimitriou
        local_provider = user.get_auth_provider('local')
904 478ece6c Kostas Papadimitriou
        self.assertEqual(shib_provider.get_remove_policy, True)
905 478ece6c Kostas Papadimitriou
        self.assertEqual(local_provider.get_remove_policy, True)
906 478ece6c Kostas Papadimitriou
907 478ece6c Kostas Papadimitriou
        policy_only_academic = Profile.objects.add_policy('academic_strict2',
908 478ece6c Kostas Papadimitriou
                                                          'shibboleth',
909 478ece6c Kostas Papadimitriou
                                                          academic_group,
910 478ece6c Kostas Papadimitriou
                                                          remove=False)
911 478ece6c Kostas Papadimitriou
        user.groups.add(academic_group)
912 478ece6c Kostas Papadimitriou
        shib_provider = user.get_auth_provider('shibboleth', 'oldusereppn')
913 478ece6c Kostas Papadimitriou
        local_provider = user.get_auth_provider('local')
914 478ece6c Kostas Papadimitriou
        self.assertEqual(shib_provider.get_remove_policy, False)
915 478ece6c Kostas Papadimitriou
        self.assertEqual(local_provider.get_remove_policy, True)
916 478ece6c Kostas Papadimitriou
        self.assertEqual(local_provider.get_login_policy, False)
917 478ece6c Kostas Papadimitriou
918 478ece6c Kostas Papadimitriou
        cl_olduser.logout()
919 0b817216 Kostas Papadimitriou
        login_data = {'username': 'olduser@synnefo.org',
920 0b817216 Kostas Papadimitriou
                      'password': 'password'}
921 5f28aa14 Kostas Papadimitriou
        r = cl_olduser.post(ui_url('local'), login_data, follow=True)
922 5f28aa14 Kostas Papadimitriou
        self.assertContains(r, "login/shibboleth'>Academic login")
923 39e16ecc Kostas Papadimitriou
        Group.objects.all().delete()
924 9d20fe23 Kostas Papadimitriou
925 9d20fe23 Kostas Papadimitriou
926 478ece6c Kostas Papadimitriou
class TestAuthProvidersAPI(TestCase):
927 478ece6c Kostas Papadimitriou
    """
928 478ece6c Kostas Papadimitriou
    Test auth_providers module API
929 478ece6c Kostas Papadimitriou
    """
930 478ece6c Kostas Papadimitriou
931 c34abd9c Kostas Papadimitriou
    def tearDown(self):
932 c34abd9c Kostas Papadimitriou
        Group.objects.all().delete()
933 c34abd9c Kostas Papadimitriou
934 478ece6c Kostas Papadimitriou
    @im_settings(IM_MODULES=['local', 'shibboleth'])
935 9d20fe23 Kostas Papadimitriou
    def test_create(self):
936 e7cb4085 Kostas Papadimitriou
        user = AstakosUser.objects.create(email="kpap@synnefo.org")
937 e7cb4085 Kostas Papadimitriou
        user2 = AstakosUser.objects.create(email="kpap2@synnefo.org")
938 9d20fe23 Kostas Papadimitriou
939 9d20fe23 Kostas Papadimitriou
        module = 'shibboleth'
940 9d20fe23 Kostas Papadimitriou
        identifier = 'SHIB_UUID'
941 9d20fe23 Kostas Papadimitriou
        provider_params = {
942 9d20fe23 Kostas Papadimitriou
            'affiliation': 'UNIVERSITY',
943 9d20fe23 Kostas Papadimitriou
            'info': {'age': 27}
944 9d20fe23 Kostas Papadimitriou
        }
945 9d20fe23 Kostas Papadimitriou
        provider = auth.get_provider(module, user2, identifier,
946 9d20fe23 Kostas Papadimitriou
                                     **provider_params)
947 9d20fe23 Kostas Papadimitriou
        provider.add_to_user()
948 9d20fe23 Kostas Papadimitriou
        provider = auth.get_provider(module, user, identifier,
949 9d20fe23 Kostas Papadimitriou
                                     **provider_params)
950 9d20fe23 Kostas Papadimitriou
        provider.add_to_user()
951 9d20fe23 Kostas Papadimitriou
        user.email_verified = True
952 9d20fe23 Kostas Papadimitriou
        user.save()
953 9d20fe23 Kostas Papadimitriou
        self.assertRaises(Exception, provider.add_to_user)
954 9d20fe23 Kostas Papadimitriou
        provider = user.get_auth_provider(module, identifier)
955 9d20fe23 Kostas Papadimitriou
        self.assertEqual(user.get_auth_provider(
956 9d20fe23 Kostas Papadimitriou
            module, identifier)._instance.info.get('age'), 27)
957 9d20fe23 Kostas Papadimitriou
958 9d20fe23 Kostas Papadimitriou
        module = 'local'
959 9d20fe23 Kostas Papadimitriou
        identifier = None
960 9d20fe23 Kostas Papadimitriou
        provider_params = {'auth_backend': 'ldap', 'info':
961 9d20fe23 Kostas Papadimitriou
                          {'office': 'A1'}}
962 9d20fe23 Kostas Papadimitriou
        provider = auth.get_provider(module, user, identifier,
963 9d20fe23 Kostas Papadimitriou
                                     **provider_params)
964 9d20fe23 Kostas Papadimitriou
        provider.add_to_user()
965 9d20fe23 Kostas Papadimitriou
        self.assertFalse(provider.get_add_policy)
966 9d20fe23 Kostas Papadimitriou
        self.assertRaises(Exception, provider.add_to_user)
967 9d20fe23 Kostas Papadimitriou
968 9d20fe23 Kostas Papadimitriou
        shib = user.get_auth_provider('shibboleth',
969 9d20fe23 Kostas Papadimitriou
                                      'SHIB_UUID')
970 9d20fe23 Kostas Papadimitriou
        self.assertTrue(shib.get_remove_policy)
971 9d20fe23 Kostas Papadimitriou
972 9d20fe23 Kostas Papadimitriou
        local = user.get_auth_provider('local')
973 9d20fe23 Kostas Papadimitriou
        self.assertTrue(local.get_remove_policy)
974 9d20fe23 Kostas Papadimitriou
975 9d20fe23 Kostas Papadimitriou
        local.remove_from_user()
976 9d20fe23 Kostas Papadimitriou
        self.assertFalse(shib.get_remove_policy)
977 9d20fe23 Kostas Papadimitriou
        self.assertRaises(Exception, shib.remove_from_user)
978 9d20fe23 Kostas Papadimitriou
979 478ece6c Kostas Papadimitriou
        provider = user.get_auth_providers()[0]
980 478ece6c Kostas Papadimitriou
        self.assertRaises(Exception, provider.add_to_user)
981 478ece6c Kostas Papadimitriou
982 478ece6c Kostas Papadimitriou
    @im_settings(IM_MODULES=['local', 'shibboleth'])
983 ba27316a Kostas Papadimitriou
    @shibboleth_settings(ADD_GROUPS_POLICY=['group1', 'group2'],
984 ba27316a Kostas Papadimitriou
                         CREATION_GROUPS_POLICY=['group-create', 'group1',
985 478ece6c Kostas Papadimitriou
                                                 'group2'])
986 ba27316a Kostas Papadimitriou
    @localauth_settings(ADD_GROUPS_POLICY=['localgroup'],
987 ba27316a Kostas Papadimitriou
                        CREATION_GROUPS_POLICY=['localgroup-create',
988 478ece6c Kostas Papadimitriou
                                                'group-create'])
989 478ece6c Kostas Papadimitriou
    def test_add_groups(self):
990 e7cb4085 Kostas Papadimitriou
        user = AstakosUser.objects.create(email="kpap@synnefo.org")
991 478ece6c Kostas Papadimitriou
        provider = auth.get_provider('shibboleth', user, 'test123')
992 478ece6c Kostas Papadimitriou
        provider.add_to_user()
993 478ece6c Kostas Papadimitriou
        user = AstakosUser.objects.get()
994 2a88057d Christos Stavrakakis
        self.assertEqual(sorted(user.groups.values_list('name', flat=True)),
995 8fb8d0cf Giorgos Korfiatis
                         sorted([u'group1', u'group2', u'group-create']))
996 478ece6c Kostas Papadimitriou
997 478ece6c Kostas Papadimitriou
        local = auth.get_provider('local', user)
998 478ece6c Kostas Papadimitriou
        local.add_to_user()
999 478ece6c Kostas Papadimitriou
        provider = user.get_auth_provider('shibboleth')
1000 478ece6c Kostas Papadimitriou
        self.assertEqual(provider.get_add_groups_policy, ['group1', 'group2'])
1001 478ece6c Kostas Papadimitriou
        provider.remove_from_user()
1002 478ece6c Kostas Papadimitriou
        user = AstakosUser.objects.get()
1003 478ece6c Kostas Papadimitriou
        self.assertEqual(len(user.get_auth_providers()), 1)
1004 2a88057d Christos Stavrakakis
        self.assertEqual(sorted(user.groups.values_list('name', flat=True)),
1005 8fb8d0cf Giorgos Korfiatis
                         sorted([u'group-create', u'localgroup']))
1006 478ece6c Kostas Papadimitriou
1007 478ece6c Kostas Papadimitriou
        local = user.get_auth_provider('local')
1008 478ece6c Kostas Papadimitriou
        self.assertRaises(Exception, local.remove_from_user)
1009 478ece6c Kostas Papadimitriou
        provider = auth.get_provider('shibboleth', user, 'test123')
1010 478ece6c Kostas Papadimitriou
        provider.add_to_user()
1011 478ece6c Kostas Papadimitriou
        user = AstakosUser.objects.get()
1012 2a88057d Christos Stavrakakis
        self.assertEqual(sorted(user.groups.values_list('name', flat=True)),
1013 8fb8d0cf Giorgos Korfiatis
                         sorted([u'group-create', u'group1', u'group2',
1014 8fb8d0cf Giorgos Korfiatis
                                 u'localgroup']))
1015 39e16ecc Kostas Papadimitriou
        Group.objects.all().delete()
1016 e7cb4085 Kostas Papadimitriou
1017 478ece6c Kostas Papadimitriou
    @im_settings(IM_MODULES=['local', 'shibboleth'])
1018 9d20fe23 Kostas Papadimitriou
    def test_policies(self):
1019 9d20fe23 Kostas Papadimitriou
        group_old, created = Group.objects.get_or_create(name='olduser')
1020 9d20fe23 Kostas Papadimitriou
1021 9d20fe23 Kostas Papadimitriou
        astakos_settings.MODERATION_ENABLED = True
1022 9d20fe23 Kostas Papadimitriou
        settings.ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_CREATION_GROUPS_POLICY = \
1023 9d20fe23 Kostas Papadimitriou
            ['academic-user']
1024 9d20fe23 Kostas Papadimitriou
        settings.ASTAKOS_AUTH_PROVIDER_GOOGLE_ADD_GROUPS_POLICY = \
1025 9d20fe23 Kostas Papadimitriou
            ['google-user']
1026 9d20fe23 Kostas Papadimitriou
1027 e7cb4085 Kostas Papadimitriou
        user = AstakosUser.objects.create(email="kpap@synnefo.org")
1028 9d20fe23 Kostas Papadimitriou
        user.groups.add(group_old)
1029 9d20fe23 Kostas Papadimitriou
        user.add_auth_provider('local')
1030 9d20fe23 Kostas Papadimitriou
1031 e7cb4085 Kostas Papadimitriou
        user2 = AstakosUser.objects.create(email="kpap2@synnefo.org")
1032 9d20fe23 Kostas Papadimitriou
        user2.add_auth_provider('shibboleth', identifier='shibid')
1033 9d20fe23 Kostas Papadimitriou
1034 e7cb4085 Kostas Papadimitriou
        user3 = AstakosUser.objects.create(email="kpap3@synnefo.org")
1035 9d20fe23 Kostas Papadimitriou
        user3.groups.add(group_old)
1036 9d20fe23 Kostas Papadimitriou
        user3.add_auth_provider('local')
1037 9d20fe23 Kostas Papadimitriou
        user3.add_auth_provider('shibboleth', identifier='1234')
1038 9d20fe23 Kostas Papadimitriou
1039 9d20fe23 Kostas Papadimitriou
        self.assertTrue(user2.groups.get(name='academic-user'))
1040 9d20fe23 Kostas Papadimitriou
        self.assertFalse(user2.groups.filter(name='olduser').count())
1041 9d20fe23 Kostas Papadimitriou
1042 9d20fe23 Kostas Papadimitriou
        local = auth_providers.get_provider('local')
1043 9d20fe23 Kostas Papadimitriou
        self.assertTrue(local.get_add_policy)
1044 9d20fe23 Kostas Papadimitriou
1045 9d20fe23 Kostas Papadimitriou
        academic_group = Group.objects.get(name='academic-user')
1046 9d20fe23 Kostas Papadimitriou
        AuthProviderPolicyProfile.objects.add_policy('academic', 'shibboleth',
1047 9d20fe23 Kostas Papadimitriou
                                                     academic_group,
1048 9d20fe23 Kostas Papadimitriou
                                                     exclusive=True,
1049 9d20fe23 Kostas Papadimitriou
                                                     add=False,
1050 9d20fe23 Kostas Papadimitriou
                                                     login=False)
1051 9d20fe23 Kostas Papadimitriou
        AuthProviderPolicyProfile.objects.add_policy('academic', 'shibboleth',
1052 9d20fe23 Kostas Papadimitriou
                                                     academic_group,
1053 9d20fe23 Kostas Papadimitriou
                                                     exclusive=True,
1054 9d20fe23 Kostas Papadimitriou
                                                     login=False,
1055 9d20fe23 Kostas Papadimitriou
                                                     add=False)
1056 9d20fe23 Kostas Papadimitriou
        # no duplicate entry gets created
1057 9d20fe23 Kostas Papadimitriou
        self.assertEqual(academic_group.authpolicy_profiles.count(), 1)
1058 9d20fe23 Kostas Papadimitriou
1059 9d20fe23 Kostas Papadimitriou
        self.assertEqual(user2.authpolicy_profiles.count(), 0)
1060 9d20fe23 Kostas Papadimitriou
        AuthProviderPolicyProfile.objects.add_policy('academic', 'shibboleth',
1061 9d20fe23 Kostas Papadimitriou
                                                     user2,
1062 9d20fe23 Kostas Papadimitriou
                                                     remove=False)
1063 9d20fe23 Kostas Papadimitriou
        self.assertEqual(user2.authpolicy_profiles.count(), 1)
1064 9d20fe23 Kostas Papadimitriou
1065 9d20fe23 Kostas Papadimitriou
        local = auth_providers.get_provider('local', user2)
1066 9d20fe23 Kostas Papadimitriou
        google = auth_providers.get_provider('google', user2)
1067 9d20fe23 Kostas Papadimitriou
        shibboleth = auth_providers.get_provider('shibboleth', user2)
1068 9d20fe23 Kostas Papadimitriou
        self.assertTrue(shibboleth.get_login_policy)
1069 9d20fe23 Kostas Papadimitriou
        self.assertFalse(shibboleth.get_remove_policy)
1070 9d20fe23 Kostas Papadimitriou
        self.assertFalse(local.get_add_policy)
1071 9d20fe23 Kostas Papadimitriou
        self.assertFalse(local.get_add_policy)
1072 9d20fe23 Kostas Papadimitriou
        self.assertFalse(google.get_add_policy)
1073 9d20fe23 Kostas Papadimitriou
1074 9d20fe23 Kostas Papadimitriou
        user2.groups.remove(Group.objects.get(name='academic-user'))
1075 9d20fe23 Kostas Papadimitriou
        self.assertTrue(local.get_add_policy)
1076 9d20fe23 Kostas Papadimitriou
        self.assertTrue(google.get_add_policy)
1077 9d20fe23 Kostas Papadimitriou
        user2.groups.add(Group.objects.get(name='academic-user'))
1078 9d20fe23 Kostas Papadimitriou
1079 9d20fe23 Kostas Papadimitriou
        AuthProviderPolicyProfile.objects.add_policy('academic', 'shibboleth',
1080 9d20fe23 Kostas Papadimitriou
                                                     user2,
1081 9d20fe23 Kostas Papadimitriou
                                                     exclusive=True,
1082 9d20fe23 Kostas Papadimitriou
                                                     add=True)
1083 9d20fe23 Kostas Papadimitriou
        self.assertTrue(local.get_add_policy)
1084 9d20fe23 Kostas Papadimitriou
        self.assertTrue(google.get_add_policy)
1085 9d20fe23 Kostas Papadimitriou
1086 9d20fe23 Kostas Papadimitriou
        settings.ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_AUTOMODERATE_POLICY = True
1087 9d20fe23 Kostas Papadimitriou
        self.assertFalse(local.get_automoderate_policy)
1088 9d20fe23 Kostas Papadimitriou
        self.assertFalse(google.get_automoderate_policy)
1089 9d20fe23 Kostas Papadimitriou
        self.assertTrue(shibboleth.get_automoderate_policy)
1090 9d20fe23 Kostas Papadimitriou
1091 9d20fe23 Kostas Papadimitriou
        for s in ['SHIBBOLETH_CREATION_GROUPS_POLICY',
1092 9d20fe23 Kostas Papadimitriou
                  'GOOGLE_ADD_GROUPS_POLICY']:
1093 9d20fe23 Kostas Papadimitriou
            delattr(settings, 'ASTAKOS_AUTH_PROVIDER_%s' % s)
1094 478ece6c Kostas Papadimitriou
1095 478ece6c Kostas Papadimitriou
    @shibboleth_settings(CREATE_POLICY=True)
1096 478ece6c Kostas Papadimitriou
    @im_settings(IM_MODULES=['local', 'shibboleth'])
1097 478ece6c Kostas Papadimitriou
    def test_create_http(self):
1098 478ece6c Kostas Papadimitriou
        # this should be wrapped inside a transaction
1099 478ece6c Kostas Papadimitriou
        user = AstakosUser(email="test@test.com")
1100 478ece6c Kostas Papadimitriou
        user.save()
1101 478ece6c Kostas Papadimitriou
        provider = auth_providers.get_provider('shibboleth', user,
1102 478ece6c Kostas Papadimitriou
                                               'test@academia.test')
1103 478ece6c Kostas Papadimitriou
        provider.add_to_user()
1104 478ece6c Kostas Papadimitriou
        user.get_auth_provider('shibboleth', 'test@academia.test')
1105 478ece6c Kostas Papadimitriou
        provider = auth_providers.get_provider('local', user)
1106 478ece6c Kostas Papadimitriou
        provider.add_to_user()
1107 478ece6c Kostas Papadimitriou
        user.get_auth_provider('local')
1108 478ece6c Kostas Papadimitriou
1109 478ece6c Kostas Papadimitriou
        settings.ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_CREATE_POLICY = False
1110 478ece6c Kostas Papadimitriou
        user = AstakosUser(email="test2@test.com")
1111 478ece6c Kostas Papadimitriou
        user.save()
1112 478ece6c Kostas Papadimitriou
        provider = auth_providers.get_provider('shibboleth', user,
1113 478ece6c Kostas Papadimitriou
                                               'test@shibboleth.com',
1114 478ece6c Kostas Papadimitriou
                                               **{'info': {'name':
1115 8fb8d0cf Giorgos Korfiatis
                                                           'User Test'}})
1116 478ece6c Kostas Papadimitriou
        self.assertFalse(provider.get_create_policy)
1117 478ece6c Kostas Papadimitriou
        settings.ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_CREATE_POLICY = True
1118 478ece6c Kostas Papadimitriou
        self.assertTrue(provider.get_create_policy)
1119 478ece6c Kostas Papadimitriou
        academic = provider.add_to_user()
1120 478ece6c Kostas Papadimitriou
1121 478ece6c Kostas Papadimitriou
    @im_settings(IM_MODULES=['local', 'shibboleth'])
1122 478ece6c Kostas Papadimitriou
    @shibboleth_settings(LIMIT_POLICY=2)
1123 478ece6c Kostas Papadimitriou
    def test_policies(self):
1124 e7cb4085 Kostas Papadimitriou
        user = get_local_user('kpap@synnefo.org')
1125 478ece6c Kostas Papadimitriou
        user.add_auth_provider('shibboleth', identifier='1234')
1126 478ece6c Kostas Papadimitriou
        user.add_auth_provider('shibboleth', identifier='12345')
1127 478ece6c Kostas Papadimitriou
1128 478ece6c Kostas Papadimitriou
        # default limit is 1
1129 478ece6c Kostas Papadimitriou
        local = user.get_auth_provider('local')
1130 478ece6c Kostas Papadimitriou
        self.assertEqual(local.get_add_policy, False)
1131 478ece6c Kostas Papadimitriou
1132 478ece6c Kostas Papadimitriou
        settings.ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_LIMIT_POLICY = 3
1133 478ece6c Kostas Papadimitriou
        academic = user.get_auth_provider('shibboleth',
1134 478ece6c Kostas Papadimitriou
                                          identifier='1234')
1135 478ece6c Kostas Papadimitriou
        self.assertEqual(academic.get_add_policy, False)
1136 478ece6c Kostas Papadimitriou
        newacademic = auth_providers.get_provider('shibboleth', user,
1137 478ece6c Kostas Papadimitriou
                                                  identifier='123456')
1138 478ece6c Kostas Papadimitriou
        self.assertEqual(newacademic.get_add_policy, True)
1139 478ece6c Kostas Papadimitriou
        user.add_auth_provider('shibboleth', identifier='123456')
1140 478ece6c Kostas Papadimitriou
        self.assertEqual(academic.get_add_policy, False)
1141 478ece6c Kostas Papadimitriou
        settings.ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_LIMIT_POLICY = 1
1142 478ece6c Kostas Papadimitriou
1143 478ece6c Kostas Papadimitriou
    @im_settings(IM_MODULES=['local', 'shibboleth'])
1144 478ece6c Kostas Papadimitriou
    @shibboleth_settings(LIMIT_POLICY=2)
1145 478ece6c Kostas Papadimitriou
    def test_messages(self):
1146 e7cb4085 Kostas Papadimitriou
        user = get_local_user('kpap@synnefo.org')
1147 478ece6c Kostas Papadimitriou
        user.add_auth_provider('shibboleth', identifier='1234')
1148 478ece6c Kostas Papadimitriou
        user.add_auth_provider('shibboleth', identifier='12345')
1149 478ece6c Kostas Papadimitriou
        provider = auth_providers.get_provider('shibboleth')
1150 478ece6c Kostas Papadimitriou
        self.assertEqual(provider.get_message('title'), 'Academic')
1151 478ece6c Kostas Papadimitriou
        settings.ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_TITLE = 'New title'
1152 478ece6c Kostas Papadimitriou
        # regenerate messages cache
1153 478ece6c Kostas Papadimitriou
        provider = auth_providers.get_provider('shibboleth')
1154 478ece6c Kostas Papadimitriou
        self.assertEqual(provider.get_message('title'), 'New title')
1155 478ece6c Kostas Papadimitriou
        self.assertEqual(provider.get_message('login_title'),
1156 478ece6c Kostas Papadimitriou
                         'New title LOGIN')
1157 478ece6c Kostas Papadimitriou
        self.assertEqual(provider.get_login_title_msg, 'New title LOGIN')
1158 478ece6c Kostas Papadimitriou
        self.assertEqual(provider.get_module_icon,
1159 478ece6c Kostas Papadimitriou
                         settings.MEDIA_URL + 'im/auth/icons/shibboleth.png')
1160 478ece6c Kostas Papadimitriou
        self.assertEqual(provider.get_module_medium_icon,
1161 478ece6c Kostas Papadimitriou
                         settings.MEDIA_URL +
1162 478ece6c Kostas Papadimitriou
                         'im/auth/icons-medium/shibboleth.png')
1163 478ece6c Kostas Papadimitriou
1164 478ece6c Kostas Papadimitriou
        settings.ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_TITLE = None
1165 478ece6c Kostas Papadimitriou
        provider = auth_providers.get_provider('shibboleth', user, '12345')
1166 478ece6c Kostas Papadimitriou
        self.assertEqual(provider.get_method_details_msg,
1167 478ece6c Kostas Papadimitriou
                         'Account: 12345')
1168 478ece6c Kostas Papadimitriou
        provider = auth_providers.get_provider('shibboleth', user, '1234')
1169 478ece6c Kostas Papadimitriou
        self.assertEqual(provider.get_method_details_msg,
1170 478ece6c Kostas Papadimitriou
                         'Account: 1234')
1171 478ece6c Kostas Papadimitriou
1172 478ece6c Kostas Papadimitriou
        provider = auth_providers.get_provider('shibboleth', user, '1234')
1173 478ece6c Kostas Papadimitriou
        self.assertEqual(provider.get_not_active_msg,
1174 478ece6c Kostas Papadimitriou
                         "'Academic login' is disabled.")
1175 478ece6c Kostas Papadimitriou
1176 478ece6c Kostas Papadimitriou
    @im_settings(IM_MODULES=['local', 'shibboleth'])
1177 478ece6c Kostas Papadimitriou
    @shibboleth_settings(LIMIT_POLICY=2)
1178 478ece6c Kostas Papadimitriou
    def test_templates(self):
1179 e7cb4085 Kostas Papadimitriou
        user = get_local_user('kpap@synnefo.org')
1180 478ece6c Kostas Papadimitriou
        user.add_auth_provider('shibboleth', identifier='1234')
1181 478ece6c Kostas Papadimitriou
        user.add_auth_provider('shibboleth', identifier='12345')
1182 478ece6c Kostas Papadimitriou
1183 478ece6c Kostas Papadimitriou
        provider = auth_providers.get_provider('shibboleth')
1184 478ece6c Kostas Papadimitriou
        self.assertEqual(provider.get_template('login'),
1185 478ece6c Kostas Papadimitriou
                         'im/auth/shibboleth_login.html')
1186 478ece6c Kostas Papadimitriou
        provider = auth_providers.get_provider('google')
1187 478ece6c Kostas Papadimitriou
        self.assertEqual(provider.get_template('login'),
1188 478ece6c Kostas Papadimitriou
                         'im/auth/generic_login.html')
1189 478ece6c Kostas Papadimitriou
1190 478ece6c Kostas Papadimitriou
1191 e7cb4085 Kostas Papadimitriou
class TestActivationBackend(TestCase):
1192 e7cb4085 Kostas Papadimitriou
1193 e7cb4085 Kostas Papadimitriou
    def setUp(self):
1194 e7cb4085 Kostas Papadimitriou
        # dummy call to pass through logging middleware
1195 5f28aa14 Kostas Papadimitriou
        self.client.get(ui_url(''))
1196 e7cb4085 Kostas Papadimitriou
1197 e7cb4085 Kostas Papadimitriou
    @im_settings(RE_USER_EMAIL_PATTERNS=['.*@synnefo.org'])
1198 e7cb4085 Kostas Papadimitriou
    @shibboleth_settings(AUTOMODERATE_POLICY=True)
1199 e7cb4085 Kostas Papadimitriou
    def test_policies(self):
1200 e7cb4085 Kostas Papadimitriou
        backend = activation_backends.get_backend()
1201 e7cb4085 Kostas Papadimitriou
1202 e7cb4085 Kostas Papadimitriou
        # email matches RE_USER_EMAIL_PATTERNS
1203 e7cb4085 Kostas Papadimitriou
        user1 = get_local_user('kpap@synnefo.org', moderated=False,
1204 e7cb4085 Kostas Papadimitriou
                               is_active=False, email_verified=False)
1205 e7cb4085 Kostas Papadimitriou
        backend.handle_verification(user1, user1.verification_code)
1206 e7cb4085 Kostas Papadimitriou
        self.assertEqual(user1.accepted_policy, 'email')
1207 e7cb4085 Kostas Papadimitriou
1208 e7cb4085 Kostas Papadimitriou
        # manually moderated
1209 e7cb4085 Kostas Papadimitriou
        user2 = get_local_user('kpap@synnefo-bad.org', moderated=False,
1210 e7cb4085 Kostas Papadimitriou
                               is_active=False, email_verified=False)
1211 e7cb4085 Kostas Papadimitriou
1212 e7cb4085 Kostas Papadimitriou
        backend.handle_verification(user2, user2.verification_code)
1213 e7cb4085 Kostas Papadimitriou
        self.assertEqual(user2.moderated, False)
1214 e7cb4085 Kostas Papadimitriou
        backend.handle_moderation(user2)
1215 e7cb4085 Kostas Papadimitriou
        self.assertEqual(user2.moderated, True)
1216 e7cb4085 Kostas Papadimitriou
        self.assertEqual(user2.accepted_policy, 'manual')
1217 e7cb4085 Kostas Papadimitriou
1218 e7cb4085 Kostas Papadimitriou
        # autoaccept due to provider automoderate policy
1219 e7cb4085 Kostas Papadimitriou
        user3 = get_local_user('kpap2@synnefo-bad.org', moderated=False,
1220 e7cb4085 Kostas Papadimitriou
                               is_active=False, email_verified=False)
1221 e7cb4085 Kostas Papadimitriou
        user3.auth_providers.all().delete()
1222 e7cb4085 Kostas Papadimitriou
        user3.add_auth_provider('shibboleth', identifier='shib123')
1223 e7cb4085 Kostas Papadimitriou
        backend.handle_verification(user3, user3.verification_code)
1224 e7cb4085 Kostas Papadimitriou
        self.assertEqual(user3.moderated, True)
1225 e7cb4085 Kostas Papadimitriou
        self.assertEqual(user3.accepted_policy, 'auth_provider_shibboleth')
1226 e7cb4085 Kostas Papadimitriou
1227 e7cb4085 Kostas Papadimitriou
    @im_settings(MODERATION_ENABLED=False,
1228 e7cb4085 Kostas Papadimitriou
                 MANAGERS=(('Manager',
1229 e7cb4085 Kostas Papadimitriou
                            'manager@synnefo.org'),),
1230 e7cb4085 Kostas Papadimitriou
                 HELPDESK=(('Helpdesk',
1231 e7cb4085 Kostas Papadimitriou
                            'helpdesk@synnefo.org'),),
1232 e7cb4085 Kostas Papadimitriou
                 ADMINS=(('Admin', 'admin@synnefo.org'), ))
1233 e7cb4085 Kostas Papadimitriou
    def test_without_moderation(self):
1234 e7cb4085 Kostas Papadimitriou
        backend = activation_backends.get_backend()
1235 e7cb4085 Kostas Papadimitriou
        form = backend.get_signup_form('local')
1236 e7cb4085 Kostas Papadimitriou
        self.assertTrue(isinstance(form, forms.LocalUserCreationForm))
1237 e7cb4085 Kostas Papadimitriou
1238 e7cb4085 Kostas Papadimitriou
        user_data = {
1239 e7cb4085 Kostas Papadimitriou
            'email': 'kpap@synnefo.org',
1240 e7cb4085 Kostas Papadimitriou
            'first_name': 'Kostas Papas',
1241 e7cb4085 Kostas Papadimitriou
            'password1': '123',
1242 e7cb4085 Kostas Papadimitriou
            'password2': '123'
1243 e7cb4085 Kostas Papadimitriou
        }
1244 e7cb4085 Kostas Papadimitriou
        form = backend.get_signup_form('local', user_data)
1245 e7cb4085 Kostas Papadimitriou
        user = form.save(commit=False)
1246 e7cb4085 Kostas Papadimitriou
        form.store_user(user)
1247 e7cb4085 Kostas Papadimitriou
        self.assertEqual(user.is_active, False)
1248 e7cb4085 Kostas Papadimitriou
        self.assertEqual(user.email_verified, False)
1249 e7cb4085 Kostas Papadimitriou
1250 e7cb4085 Kostas Papadimitriou
        # step one, registration
1251 e7cb4085 Kostas Papadimitriou
        result = backend.handle_registration(user)
1252 e7cb4085 Kostas Papadimitriou
        user = AstakosUser.objects.get()
1253 e7cb4085 Kostas Papadimitriou
        self.assertEqual(user.is_active, False)
1254 e7cb4085 Kostas Papadimitriou
        self.assertEqual(user.email_verified, False)
1255 e7cb4085 Kostas Papadimitriou
        self.assertTrue(user.verification_code)
1256 e7cb4085 Kostas Papadimitriou
        self.assertEqual(result.status, backend.Result.PENDING_VERIFICATION)
1257 e7cb4085 Kostas Papadimitriou
        backend.send_result_notifications(result, user)
1258 e7cb4085 Kostas Papadimitriou
        self.assertEqual(len(get_mailbox('kpap@synnefo.org')), 1)
1259 e7cb4085 Kostas Papadimitriou
        self.assertEqual(len(mail.outbox), 1)
1260 e7cb4085 Kostas Papadimitriou
1261 e7cb4085 Kostas Papadimitriou
        # step two, verify email (automatically
1262 e7cb4085 Kostas Papadimitriou
        # moderates/accepts user, since moderation is disabled)
1263 e7cb4085 Kostas Papadimitriou
        user = AstakosUser.objects.get()
1264 e7cb4085 Kostas Papadimitriou
        valid_code = user.verification_code
1265 e7cb4085 Kostas Papadimitriou
1266 e7cb4085 Kostas Papadimitriou
        # test invalid code
1267 e7cb4085 Kostas Papadimitriou
        result = backend.handle_verification(user, valid_code)
1268 e7cb4085 Kostas Papadimitriou
        backend.send_result_notifications(result, user)
1269 e7cb4085 Kostas Papadimitriou
        self.assertEqual(len(get_mailbox('manager@synnefo.org')), 1)
1270 e7cb4085 Kostas Papadimitriou
        self.assertEqual(len(get_mailbox('helpdesk@synnefo.org')), 1)
1271 e7cb4085 Kostas Papadimitriou
        self.assertEqual(len(get_mailbox('admin@synnefo.org')), 1)
1272 e7cb4085 Kostas Papadimitriou
        # verification + activated + greeting = 3
1273 e7cb4085 Kostas Papadimitriou
        self.assertEqual(len(mail.outbox), 3)
1274 e7cb4085 Kostas Papadimitriou
        user = AstakosUser.objects.get()
1275 e7cb4085 Kostas Papadimitriou
        self.assertEqual(user.is_active, True)
1276 e7cb4085 Kostas Papadimitriou
        self.assertEqual(user.moderated, True)
1277 e7cb4085 Kostas Papadimitriou
        self.assertTrue(user.moderated_at)
1278 e7cb4085 Kostas Papadimitriou
        self.assertEqual(user.email_verified, True)
1279 e7cb4085 Kostas Papadimitriou
        self.assertTrue(user.activation_sent)
1280 e7cb4085 Kostas Papadimitriou
1281 e7cb4085 Kostas Papadimitriou
    @im_settings(MODERATION_ENABLED=True,
1282 e7cb4085 Kostas Papadimitriou
                 MANAGERS=(('Manager',
1283 e7cb4085 Kostas Papadimitriou
                            'manager@synnefo.org'),),
1284 e7cb4085 Kostas Papadimitriou
                 HELPDESK=(('Helpdesk',
1285 e7cb4085 Kostas Papadimitriou
                            'helpdesk@synnefo.org'),),
1286 e7cb4085 Kostas Papadimitriou
                 ADMINS=(('Admin', 'admin@synnefo.org'), ))
1287 e7cb4085 Kostas Papadimitriou
    def test_with_moderation(self):
1288 e7cb4085 Kostas Papadimitriou
1289 e7cb4085 Kostas Papadimitriou
        backend = activation_backends.get_backend()
1290 e7cb4085 Kostas Papadimitriou
        form = backend.get_signup_form('local')
1291 e7cb4085 Kostas Papadimitriou
        self.assertTrue(isinstance(form, forms.LocalUserCreationForm))
1292 e7cb4085 Kostas Papadimitriou
1293 e7cb4085 Kostas Papadimitriou
        user_data = {
1294 e7cb4085 Kostas Papadimitriou
            'email': 'kpap@synnefo.org',
1295 e7cb4085 Kostas Papadimitriou
            'first_name': 'Kostas Papas',
1296 e7cb4085 Kostas Papadimitriou
            'password1': '123',
1297 e7cb4085 Kostas Papadimitriou
            'password2': '123'
1298 e7cb4085 Kostas Papadimitriou
        }
1299 e7cb4085 Kostas Papadimitriou
        form = backend.get_signup_form(provider='local',
1300 e7cb4085 Kostas Papadimitriou
                                       initial_data=user_data)
1301 e7cb4085 Kostas Papadimitriou
        user = form.save(commit=False)
1302 e7cb4085 Kostas Papadimitriou
        form.store_user(user)
1303 e7cb4085 Kostas Papadimitriou
        self.assertEqual(user.is_active, False)
1304 e7cb4085 Kostas Papadimitriou
        self.assertEqual(user.email_verified, False)
1305 e7cb4085 Kostas Papadimitriou
1306 e7cb4085 Kostas Papadimitriou
        # step one, registration
1307 e7cb4085 Kostas Papadimitriou
        result = backend.handle_registration(user)
1308 e7cb4085 Kostas Papadimitriou
        user = AstakosUser.objects.get()
1309 e7cb4085 Kostas Papadimitriou
        self.assertEqual(user.is_active, False)
1310 e7cb4085 Kostas Papadimitriou
        self.assertEqual(user.email_verified, False)
1311 e7cb4085 Kostas Papadimitriou
        self.assertTrue(user.verification_code)
1312 e7cb4085 Kostas Papadimitriou
        self.assertEqual(result.status, backend.Result.PENDING_VERIFICATION)
1313 e7cb4085 Kostas Papadimitriou
        backend.send_result_notifications(result, user)
1314 e7cb4085 Kostas Papadimitriou
        self.assertEqual(len(get_mailbox('kpap@synnefo.org')), 1)
1315 e7cb4085 Kostas Papadimitriou
        self.assertEqual(len(mail.outbox), 1)
1316 e7cb4085 Kostas Papadimitriou
1317 e7cb4085 Kostas Papadimitriou
        # step two, verifying email
1318 e7cb4085 Kostas Papadimitriou
        user = AstakosUser.objects.get()
1319 e7cb4085 Kostas Papadimitriou
        valid_code = user.verification_code
1320 e7cb4085 Kostas Papadimitriou
        invalid_code = user.verification_code + 'invalid'
1321 e7cb4085 Kostas Papadimitriou
1322 e7cb4085 Kostas Papadimitriou
        # test invalid code
1323 e7cb4085 Kostas Papadimitriou
        result = backend.handle_verification(user, invalid_code)
1324 e7cb4085 Kostas Papadimitriou
        self.assertEqual(result.status, backend.Result.ERROR)
1325 e7cb4085 Kostas Papadimitriou
        backend.send_result_notifications(result, user)
1326 e7cb4085 Kostas Papadimitriou
        user = AstakosUser.objects.get()
1327 e7cb4085 Kostas Papadimitriou
        self.assertEqual(user.is_active, False)
1328 e7cb4085 Kostas Papadimitriou
        self.assertEqual(user.moderated, False)
1329 e7cb4085 Kostas Papadimitriou
        self.assertEqual(user.moderated_at, None)
1330 e7cb4085 Kostas Papadimitriou
        self.assertEqual(user.email_verified, False)
1331 e7cb4085 Kostas Papadimitriou
        self.assertTrue(user.activation_sent)
1332 e7cb4085 Kostas Papadimitriou
1333 e7cb4085 Kostas Papadimitriou
        # test valid code
1334 e7cb4085 Kostas Papadimitriou
        user = AstakosUser.objects.get()
1335 e7cb4085 Kostas Papadimitriou
        result = backend.handle_verification(user, valid_code)
1336 e7cb4085 Kostas Papadimitriou
        backend.send_result_notifications(result, user)
1337 e7cb4085 Kostas Papadimitriou
        self.assertEqual(len(get_mailbox('manager@synnefo.org')), 1)
1338 e7cb4085 Kostas Papadimitriou
        self.assertEqual(len(get_mailbox('helpdesk@synnefo.org')), 1)
1339 e7cb4085 Kostas Papadimitriou
        self.assertEqual(len(get_mailbox('admin@synnefo.org')), 1)
1340 e7cb4085 Kostas Papadimitriou
        self.assertEqual(len(mail.outbox), 2)
1341 e7cb4085 Kostas Papadimitriou
        user = AstakosUser.objects.get()
1342 e7cb4085 Kostas Papadimitriou
        self.assertEqual(user.moderated, False)
1343 e7cb4085 Kostas Papadimitriou
        self.assertEqual(user.moderated_at, None)
1344 e7cb4085 Kostas Papadimitriou
        self.assertEqual(user.email_verified, True)
1345 e7cb4085 Kostas Papadimitriou
        self.assertTrue(user.activation_sent)
1346 e7cb4085 Kostas Papadimitriou
1347 e7cb4085 Kostas Papadimitriou
        # test code reuse
1348 e7cb4085 Kostas Papadimitriou
        result = backend.handle_verification(user, valid_code)
1349 e7cb4085 Kostas Papadimitriou
        self.assertEqual(result.status, backend.Result.ERROR)
1350 e7cb4085 Kostas Papadimitriou
        user = AstakosUser.objects.get()
1351 e7cb4085 Kostas Papadimitriou
        self.assertEqual(user.is_active, False)
1352 e7cb4085 Kostas Papadimitriou
        self.assertEqual(user.moderated, False)
1353 e7cb4085 Kostas Papadimitriou
        self.assertEqual(user.moderated_at, None)
1354 e7cb4085 Kostas Papadimitriou
        self.assertEqual(user.email_verified, True)
1355 e7cb4085 Kostas Papadimitriou
        self.assertTrue(user.activation_sent)
1356 e7cb4085 Kostas Papadimitriou
1357 e7cb4085 Kostas Papadimitriou
        # valid code on verified user
1358 e7cb4085 Kostas Papadimitriou
        user = AstakosUser.objects.get()
1359 e7cb4085 Kostas Papadimitriou
        valid_code = user.verification_code
1360 e7cb4085 Kostas Papadimitriou
        result = backend.handle_verification(user, valid_code)
1361 e7cb4085 Kostas Papadimitriou
        self.assertEqual(result.status, backend.Result.ERROR)
1362 e7cb4085 Kostas Papadimitriou
1363 e7cb4085 Kostas Papadimitriou
        # step three, moderation user
1364 e7cb4085 Kostas Papadimitriou
        user = AstakosUser.objects.get()
1365 e7cb4085 Kostas Papadimitriou
        result = backend.handle_moderation(user)
1366 e7cb4085 Kostas Papadimitriou
        backend.send_result_notifications(result, user)
1367 e7cb4085 Kostas Papadimitriou
1368 e7cb4085 Kostas Papadimitriou
        user = AstakosUser.objects.get()
1369 e7cb4085 Kostas Papadimitriou
        self.assertEqual(user.is_active, True)
1370 e7cb4085 Kostas Papadimitriou
        self.assertEqual(user.moderated, True)
1371 e7cb4085 Kostas Papadimitriou
        self.assertTrue(user.moderated_at)
1372 e7cb4085 Kostas Papadimitriou
        self.assertEqual(user.email_verified, True)
1373 e7cb4085 Kostas Papadimitriou
        self.assertTrue(user.activation_sent)
1374 5b65fb47 Kostas Papadimitriou
1375 5b65fb47 Kostas Papadimitriou
1376 5b65fb47 Kostas Papadimitriou
class TestWebloginRedirect(TestCase):
1377 5b65fb47 Kostas Papadimitriou
1378 5b65fb47 Kostas Papadimitriou
    @with_settings(settings, COOKIE_DOMAIN='.astakos.synnefo.org')
1379 5b65fb47 Kostas Papadimitriou
    def test_restricts_domains(self):
1380 5b65fb47 Kostas Papadimitriou
        get_local_user('user1@synnefo.org')
1381 5b65fb47 Kostas Papadimitriou
1382 5b65fb47 Kostas Papadimitriou
        # next url construct helpers
1383 5b65fb47 Kostas Papadimitriou
        weblogin = lambda nxt: reverse('weblogin') + '?next=%s' % nxt
1384 5b65fb47 Kostas Papadimitriou
        weblogin_quoted = lambda nxt: reverse('weblogin') + '?next=%s' % \
1385 5b65fb47 Kostas Papadimitriou
            urllib.quote_plus(nxt)
1386 5b65fb47 Kostas Papadimitriou
1387 5b65fb47 Kostas Papadimitriou
        # common cases
1388 5b65fb47 Kostas Papadimitriou
        invalid_domain = weblogin("https://www.invaliddomain.synnefo.org")
1389 5b65fb47 Kostas Papadimitriou
        invalid_scheme = weblogin("customscheme://localhost")
1390 5b65fb47 Kostas Papadimitriou
        invalid_scheme_with_valid_domain = \
1391 8fb8d0cf Giorgos Korfiatis
            weblogin("http://www.invaliddomain.com")
1392 5b65fb47 Kostas Papadimitriou
        valid_scheme = weblogin("pithos://localhost/")
1393 5b65fb47 Kostas Papadimitriou
        # to be used in assertRedirects
1394 5b65fb47 Kostas Papadimitriou
        valid_scheme_quoted = weblogin_quoted("pithos://localhost/")
1395 5b65fb47 Kostas Papadimitriou
1396 5b65fb47 Kostas Papadimitriou
        # not authenticated, redirects to login which contains next param with
1397 5b65fb47 Kostas Papadimitriou
        # additional nested quoted next params
1398 5b65fb47 Kostas Papadimitriou
        r = self.client.get(valid_scheme, follow=True)
1399 1ecda536 Kostas Papadimitriou
        login_redirect = reverse('login') + '?next=' + \
1400 5b65fb47 Kostas Papadimitriou
            urllib.quote_plus("http://testserver" + valid_scheme_quoted)
1401 5b65fb47 Kostas Papadimitriou
        self.assertRedirects(r, login_redirect)
1402 5b65fb47 Kostas Papadimitriou
1403 5b65fb47 Kostas Papadimitriou
        # authenticate client
1404 5b65fb47 Kostas Papadimitriou
        self.client.login(username="user1@synnefo.org", password="password")
1405 5b65fb47 Kostas Papadimitriou
1406 5b65fb47 Kostas Papadimitriou
        # valid scheme
1407 5b65fb47 Kostas Papadimitriou
        r = self.client.get(valid_scheme, follow=True)
1408 5b65fb47 Kostas Papadimitriou
        url = r.redirect_chain[1][0]
1409 5b65fb47 Kostas Papadimitriou
        # scheme preserved
1410 5b65fb47 Kostas Papadimitriou
        self.assertTrue(url.startswith('pithos://localhost/'))
1411 5b65fb47 Kostas Papadimitriou
        # redirect contains token param
1412 28a890d3 Kostas Papadimitriou
        params = urlparse.urlparse(url.replace('pithos', 'https'),
1413 28a890d3 Kostas Papadimitriou
                                   scheme='https').query
1414 5b65fb47 Kostas Papadimitriou
        params = urlparse.parse_qs(params)
1415 5b65fb47 Kostas Papadimitriou
        self.assertEqual(params['token'][0],
1416 5b65fb47 Kostas Papadimitriou
                         AstakosUser.objects.get().auth_token)
1417 5b65fb47 Kostas Papadimitriou
        # does not contain uuid
1418 387eee94 Kostas Papadimitriou
        # reverted for 0.14.2 to support old pithos desktop clients
1419 387eee94 Kostas Papadimitriou
        #self.assertFalse('uuid' in params)
1420 5b65fb47 Kostas Papadimitriou
1421 5b65fb47 Kostas Papadimitriou
        # invalid cases
1422 5b65fb47 Kostas Papadimitriou
        r = self.client.get(invalid_scheme, follow=True)
1423 5b65fb47 Kostas Papadimitriou
        self.assertEqual(r.status_code, 403)
1424 5b65fb47 Kostas Papadimitriou
1425 5b65fb47 Kostas Papadimitriou
        r = self.client.get(invalid_scheme_with_valid_domain, follow=True)
1426 5b65fb47 Kostas Papadimitriou
        self.assertEqual(r.status_code, 403)
1427 5b65fb47 Kostas Papadimitriou
1428 5b65fb47 Kostas Papadimitriou
        r = self.client.get(invalid_domain, follow=True)
1429 5b65fb47 Kostas Papadimitriou
        self.assertEqual(r.status_code, 403)