Statistics
| Branch: | Tag: | Revision:

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

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