Statistics
| Branch: | Tag: | Revision:

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

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