Statistics
| Branch: | Tag: | Revision:

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

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