Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (68.8 kB)

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