Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (57.4 kB)

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