Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / tests.py @ 93a77d30

History | View | Annotate | Download (70.5 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 478ece6c Kostas Papadimitriou
from contextlib import contextmanager
34 d2633501 Kostas Papadimitriou
35 9d20fe23 Kostas Papadimitriou
import copy
36 d2633501 Kostas Papadimitriou
import datetime
37 478ece6c Kostas Papadimitriou
import functools
38 478ece6c Kostas Papadimitriou
39 aba462a2 Giorgos Korfiatis
from snf_django.utils.testing import with_settings, override_settings, assertIn
40 d2633501 Kostas Papadimitriou
41 d2633501 Kostas Papadimitriou
from django.test import TestCase, Client
42 d2633501 Kostas Papadimitriou
from django.core import mail
43 478ece6c Kostas Papadimitriou
from django.http import SimpleCookie, HttpRequest, QueryDict
44 478ece6c Kostas Papadimitriou
from django.utils.importlib import import_module
45 c80722ce Giorgos Korfiatis
from django.utils import simplejson as json
46 d2633501 Kostas Papadimitriou
47 9d20fe23 Kostas Papadimitriou
from astakos.im.activation_backends import *
48 d2633501 Kostas Papadimitriou
from astakos.im.target.shibboleth import Tokens as ShibbolethTokens
49 d2633501 Kostas Papadimitriou
from astakos.im.models import *
50 d2633501 Kostas Papadimitriou
from astakos.im import functions
51 d2633501 Kostas Papadimitriou
from astakos.im import settings as astakos_settings
52 e5966bd9 Kostas Papadimitriou
from astakos.im import forms
53 d2633501 Kostas Papadimitriou
54 d2633501 Kostas Papadimitriou
from urllib import quote
55 450c7fb0 Kostas Papadimitriou
from datetime import timedelta
56 d2633501 Kostas Papadimitriou
57 2e90e3ec Kostas Papadimitriou
from astakos.im import messages
58 9d20fe23 Kostas Papadimitriou
from astakos.im import auth_providers
59 450c7fb0 Kostas Papadimitriou
from astakos.im import quotas
60 c80722ce Giorgos Korfiatis
from astakos.im import resources
61 450c7fb0 Kostas Papadimitriou
62 478ece6c Kostas Papadimitriou
from django.conf import settings
63 2e90e3ec Kostas Papadimitriou
64 34a76cdb Kostas Papadimitriou
65 478ece6c Kostas Papadimitriou
# set some common settings
66 34a76cdb Kostas Papadimitriou
astakos_settings.EMAILCHANGE_ENABLED = True
67 478ece6c Kostas Papadimitriou
astakos_settings.RECAPTCHA_ENABLED = False
68 478ece6c Kostas Papadimitriou
69 478ece6c Kostas Papadimitriou
settings.LOGGING_SETUP['disable_existing_loggers'] = False
70 34a76cdb Kostas Papadimitriou
71 0a7a4104 Kostas Papadimitriou
# shortcut decorators to override provider settings
72 0a7a4104 Kostas Papadimitriou
# e.g. shibboleth_settings(ENABLED=True) will set
73 0a7a4104 Kostas Papadimitriou
# ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_ENABLED = True in global synnefo settings
74 0a7a4104 Kostas Papadimitriou
prefixes = {'providers': 'AUTH_PROVIDER_',
75 0a7a4104 Kostas Papadimitriou
            'shibboleth': 'ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_',
76 0a7a4104 Kostas Papadimitriou
            'local': 'ASTAKOS_AUTH_PROVIDER_LOCAL_'}
77 450c7fb0 Kostas Papadimitriou
im_settings = functools.partial(with_settings, astakos_settings)
78 478ece6c Kostas Papadimitriou
shibboleth_settings = functools.partial(with_settings,
79 0a7a4104 Kostas Papadimitriou
                                        settings,
80 478ece6c Kostas Papadimitriou
                                        prefix=prefixes['shibboleth'])
81 0a7a4104 Kostas Papadimitriou
localauth_settings = functools.partial(with_settings, settings,
82 478ece6c Kostas Papadimitriou
                                       prefix=prefixes['local'])
83 478ece6c Kostas Papadimitriou
84 0a7a4104 Kostas Papadimitriou
85 478ece6c Kostas Papadimitriou
class AstakosTestClient(Client):
86 478ece6c Kostas Papadimitriou
    pass
87 478ece6c Kostas Papadimitriou
88 0a7a4104 Kostas Papadimitriou
89 478ece6c Kostas Papadimitriou
class ShibbolethClient(AstakosTestClient):
90 d2633501 Kostas Papadimitriou
    """
91 d2633501 Kostas Papadimitriou
    A shibboleth agnostic client.
92 d2633501 Kostas Papadimitriou
    """
93 9d20fe23 Kostas Papadimitriou
    VALID_TOKENS = filter(lambda x: not x.startswith("_"),
94 9d20fe23 Kostas Papadimitriou
                          dir(ShibbolethTokens))
95 d2633501 Kostas Papadimitriou
96 d2633501 Kostas Papadimitriou
    def __init__(self, *args, **kwargs):
97 d2633501 Kostas Papadimitriou
        self.tokens = kwargs.pop('tokens', {})
98 d2633501 Kostas Papadimitriou
        super(ShibbolethClient, self).__init__(*args, **kwargs)
99 d2633501 Kostas Papadimitriou
100 d2633501 Kostas Papadimitriou
    def set_tokens(self, **kwargs):
101 d2633501 Kostas Papadimitriou
        for key, value in kwargs.iteritems():
102 d2633501 Kostas Papadimitriou
            key = 'SHIB_%s' % key.upper()
103 d2633501 Kostas Papadimitriou
            if not key in self.VALID_TOKENS:
104 d2633501 Kostas Papadimitriou
                raise Exception('Invalid shibboleth token')
105 d2633501 Kostas Papadimitriou
106 d2633501 Kostas Papadimitriou
            self.tokens[key] = value
107 d2633501 Kostas Papadimitriou
108 d2633501 Kostas Papadimitriou
    def unset_tokens(self, *keys):
109 d2633501 Kostas Papadimitriou
        for key in keys:
110 d2633501 Kostas Papadimitriou
            key = 'SHIB_%s' % param.upper()
111 d2633501 Kostas Papadimitriou
            if key in self.tokens:
112 d2633501 Kostas Papadimitriou
                del self.tokens[key]
113 d2633501 Kostas Papadimitriou
114 d2633501 Kostas Papadimitriou
    def reset_tokens(self):
115 d2633501 Kostas Papadimitriou
        self.tokens = {}
116 d2633501 Kostas Papadimitriou
117 d2633501 Kostas Papadimitriou
    def get_http_token(self, key):
118 d2633501 Kostas Papadimitriou
        http_header = getattr(ShibbolethTokens, key)
119 d2633501 Kostas Papadimitriou
        return http_header
120 d2633501 Kostas Papadimitriou
121 d2633501 Kostas Papadimitriou
    def request(self, **request):
122 d2633501 Kostas Papadimitriou
        """
123 d2633501 Kostas Papadimitriou
        Transform valid shibboleth tokens to http headers
124 d2633501 Kostas Papadimitriou
        """
125 d2633501 Kostas Papadimitriou
        for token, value in self.tokens.iteritems():
126 d2633501 Kostas Papadimitriou
            request[self.get_http_token(token)] = value
127 d2633501 Kostas Papadimitriou
128 d2633501 Kostas Papadimitriou
        for param in request.keys():
129 d2633501 Kostas Papadimitriou
            key = 'SHIB_%s' % param.upper()
130 d2633501 Kostas Papadimitriou
            if key in self.VALID_TOKENS:
131 d2633501 Kostas Papadimitriou
                request[self.get_http_token(key)] = request[param]
132 d2633501 Kostas Papadimitriou
                del request[param]
133 d2633501 Kostas Papadimitriou
134 d2633501 Kostas Papadimitriou
        return super(ShibbolethClient, self).request(**request)
135 d2633501 Kostas Papadimitriou
136 d2633501 Kostas Papadimitriou
137 450c7fb0 Kostas Papadimitriou
def get_user_client(username, password="password"):
138 450c7fb0 Kostas Papadimitriou
    client = Client()
139 450c7fb0 Kostas Papadimitriou
    client.login(username=username, password=password)
140 450c7fb0 Kostas Papadimitriou
    return client
141 450c7fb0 Kostas Papadimitriou
142 450c7fb0 Kostas Papadimitriou
143 d2633501 Kostas Papadimitriou
def get_local_user(username, **kwargs):
144 d2633501 Kostas Papadimitriou
        try:
145 d2633501 Kostas Papadimitriou
            return AstakosUser.objects.get(email=username)
146 d2633501 Kostas Papadimitriou
        except:
147 d2633501 Kostas Papadimitriou
            user_params = {
148 d2633501 Kostas Papadimitriou
                'username': username,
149 d2633501 Kostas Papadimitriou
                'email': username,
150 d2633501 Kostas Papadimitriou
                'is_active': True,
151 d2633501 Kostas Papadimitriou
                'activation_sent': datetime.now(),
152 d2633501 Kostas Papadimitriou
                'email_verified': True,
153 d2633501 Kostas Papadimitriou
                'provider': 'local'
154 d2633501 Kostas Papadimitriou
            }
155 d2633501 Kostas Papadimitriou
            user_params.update(kwargs)
156 d2633501 Kostas Papadimitriou
            user = AstakosUser(**user_params)
157 d2633501 Kostas Papadimitriou
            user.set_password(kwargs.get('password', 'password'))
158 d2633501 Kostas Papadimitriou
            user.save()
159 d2633501 Kostas Papadimitriou
            user.add_auth_provider('local', auth_backend='astakos')
160 d2633501 Kostas Papadimitriou
            if kwargs.get('is_active', True):
161 d2633501 Kostas Papadimitriou
                user.is_active = True
162 d2633501 Kostas Papadimitriou
            else:
163 d2633501 Kostas Papadimitriou
                user.is_active = False
164 d2633501 Kostas Papadimitriou
            user.save()
165 d2633501 Kostas Papadimitriou
            return user
166 d2633501 Kostas Papadimitriou
167 d2633501 Kostas Papadimitriou
168 d2633501 Kostas Papadimitriou
def get_mailbox(email):
169 d2633501 Kostas Papadimitriou
    mails = []
170 d2633501 Kostas Papadimitriou
    for sent_email in mail.outbox:
171 d2633501 Kostas Papadimitriou
        for recipient in sent_email.recipients():
172 d2633501 Kostas Papadimitriou
            if email in recipient:
173 d2633501 Kostas Papadimitriou
                mails.append(sent_email)
174 d2633501 Kostas Papadimitriou
    return mails
175 d2633501 Kostas Papadimitriou
176 d2633501 Kostas Papadimitriou
177 d2633501 Kostas Papadimitriou
class ShibbolethTests(TestCase):
178 d2633501 Kostas Papadimitriou
    """
179 d2633501 Kostas Papadimitriou
    Testing shibboleth authentication.
180 d2633501 Kostas Papadimitriou
    """
181 d2633501 Kostas Papadimitriou
182 d2633501 Kostas Papadimitriou
    fixtures = ['groups']
183 d2633501 Kostas Papadimitriou
184 d2633501 Kostas Papadimitriou
    def setUp(self):
185 d2633501 Kostas Papadimitriou
        self.client = ShibbolethClient()
186 9d20fe23 Kostas Papadimitriou
        astakos_settings.IM_MODULES = ['local', 'shibboleth']
187 9d20fe23 Kostas Papadimitriou
        astakos_settings.MODERATION_ENABLED = True
188 d2633501 Kostas Papadimitriou
189 0a7a4104 Kostas Papadimitriou
    @im_settings(FORCE_PROFILE_UPDATE=False)
190 d2633501 Kostas Papadimitriou
    def test_create_account(self):
191 ba50648c Kostas Papadimitriou
192 d2633501 Kostas Papadimitriou
        client = ShibbolethClient()
193 d2633501 Kostas Papadimitriou
194 d2633501 Kostas Papadimitriou
        # shibboleth views validation
195 d2633501 Kostas Papadimitriou
        # eepn required
196 d2633501 Kostas Papadimitriou
        r = client.get('/im/login/shibboleth?', follow=True)
197 e24d0e0d Kostas Papadimitriou
        self.assertContains(r, messages.SHIBBOLETH_MISSING_EPPN % {
198 e24d0e0d Kostas Papadimitriou
            'domain': astakos_settings.BASEURL,
199 31bc3a62 Kostas Papadimitriou
            'contact_email': settings.CONTACT_EMAIL
200 e24d0e0d Kostas Papadimitriou
        })
201 d2633501 Kostas Papadimitriou
        client.set_tokens(eppn="kpapeppn")
202 ba50648c Kostas Papadimitriou
203 31fdafa8 Kostas Papadimitriou
        astakos_settings.SHIBBOLETH_REQUIRE_NAME_INFO = True
204 d2633501 Kostas Papadimitriou
        # shibboleth user info required
205 d2633501 Kostas Papadimitriou
        r = client.get('/im/login/shibboleth?', follow=True)
206 2e90e3ec Kostas Papadimitriou
        self.assertContains(r, messages.SHIBBOLETH_MISSING_NAME)
207 31fdafa8 Kostas Papadimitriou
        astakos_settings.SHIBBOLETH_REQUIRE_NAME_INFO = False
208 d2633501 Kostas Papadimitriou
209 d2633501 Kostas Papadimitriou
        # shibboleth logged us in
210 e5966bd9 Kostas Papadimitriou
        client.set_tokens(mail="kpap@grnet.gr", eppn="kpapeppn",
211 e5966bd9 Kostas Papadimitriou
                          cn="Kostas Papadimitriou",
212 ba50648c Kostas Papadimitriou
                          ep_affiliation="Test Affiliation")
213 f47ecf6b Kostas Papadimitriou
        r = client.get('/im/login/shibboleth?', follow=True)
214 9d20fe23 Kostas Papadimitriou
        token = PendingThirdPartyUser.objects.get().token
215 9d20fe23 Kostas Papadimitriou
        self.assertRedirects(r, '/im/signup?third_party_token=%s' % token)
216 ba50648c Kostas Papadimitriou
        self.assertEqual(r.status_code, 200)
217 d2633501 Kostas Papadimitriou
218 d2633501 Kostas Papadimitriou
        # a new pending user created
219 d2633501 Kostas Papadimitriou
        pending_user = PendingThirdPartyUser.objects.get(
220 d2633501 Kostas Papadimitriou
            third_party_identifier="kpapeppn")
221 d2633501 Kostas Papadimitriou
        self.assertEqual(PendingThirdPartyUser.objects.count(), 1)
222 ba50648c Kostas Papadimitriou
        # keep the token for future use
223 d2633501 Kostas Papadimitriou
        token = pending_user.token
224 d2633501 Kostas Papadimitriou
        # from now on no shibboleth headers are sent to the server
225 d2633501 Kostas Papadimitriou
        client.reset_tokens()
226 d2633501 Kostas Papadimitriou
227 ba50648c Kostas Papadimitriou
        # this is the old way, it should fail, to avoid pending user take over
228 d2633501 Kostas Papadimitriou
        r = client.get('/im/shibboleth/signup/%s' % pending_user.username)
229 d2633501 Kostas Papadimitriou
        self.assertEqual(r.status_code, 404)
230 d2633501 Kostas Papadimitriou
231 9d20fe23 Kostas Papadimitriou
        # this is the signup unique url associated with the pending user
232 9d20fe23 Kostas Papadimitriou
        # created
233 ba50648c Kostas Papadimitriou
        r = client.get('/im/signup/?third_party_token=%s' % token)
234 9d20fe23 Kostas Papadimitriou
        identifier = pending_user.third_party_identifier
235 9d20fe23 Kostas Papadimitriou
        post_data = {'third_party_identifier': identifier,
236 d2633501 Kostas Papadimitriou
                     'first_name': 'Kostas',
237 d2633501 Kostas Papadimitriou
                     'third_party_token': token,
238 d2633501 Kostas Papadimitriou
                     'last_name': 'Mitroglou',
239 9d20fe23 Kostas Papadimitriou
                     'provider': 'shibboleth'}
240 ba50648c Kostas Papadimitriou
241 0a7a4104 Kostas Papadimitriou
        signup_url = reverse('signup')
242 0a7a4104 Kostas Papadimitriou
243 ba50648c Kostas Papadimitriou
        # invlid email
244 ba50648c Kostas Papadimitriou
        post_data['email'] = 'kpap'
245 0a7a4104 Kostas Papadimitriou
        r = client.post(signup_url, post_data)
246 8ab484ea Kostas Papadimitriou
        self.assertContains(r, token)
247 ba50648c Kostas Papadimitriou
248 ba50648c Kostas Papadimitriou
        # existing email
249 ba50648c Kostas Papadimitriou
        existing_user = get_local_user('test@test.com')
250 ba50648c Kostas Papadimitriou
        post_data['email'] = 'test@test.com'
251 0a7a4104 Kostas Papadimitriou
        r = client.post(signup_url, post_data)
252 ba50648c Kostas Papadimitriou
        self.assertContains(r, messages.EMAIL_USED)
253 ba50648c Kostas Papadimitriou
        existing_user.delete()
254 ba50648c Kostas Papadimitriou
255 ba50648c Kostas Papadimitriou
        # and finally a valid signup
256 8ab484ea Kostas Papadimitriou
        post_data['email'] = 'kpap@grnet.gr'
257 0a7a4104 Kostas Papadimitriou
        r = client.post(signup_url, post_data, follow=True)
258 e5966bd9 Kostas Papadimitriou
        self.assertContains(r, messages.NOTIFICATION_SENT)
259 ba50648c Kostas Papadimitriou
260 ba50648c Kostas Papadimitriou
        # everything is ok in our db
261 d2633501 Kostas Papadimitriou
        self.assertEqual(AstakosUser.objects.count(), 1)
262 d2633501 Kostas Papadimitriou
        self.assertEqual(AstakosUserAuthProvider.objects.count(), 1)
263 ba50648c Kostas Papadimitriou
        self.assertEqual(PendingThirdPartyUser.objects.count(), 0)
264 d2633501 Kostas Papadimitriou
265 ba50648c Kostas Papadimitriou
        # provider info stored
266 ba50648c Kostas Papadimitriou
        provider = AstakosUserAuthProvider.objects.get(module="shibboleth")
267 ba50648c Kostas Papadimitriou
        self.assertEqual(provider.affiliation, 'Test Affiliation')
268 ba50648c Kostas Papadimitriou
        self.assertEqual(provider.info, {u'email': u'kpap@grnet.gr',
269 e5966bd9 Kostas Papadimitriou
                                         u'eppn': u'kpapeppn',
270 e5966bd9 Kostas Papadimitriou
                                         u'name': u'Kostas Papadimitriou'})
271 d2633501 Kostas Papadimitriou
272 ba50648c Kostas Papadimitriou
        # lets login (not activated yet)
273 e5966bd9 Kostas Papadimitriou
        client.set_tokens(mail="kpap@grnet.gr", eppn="kpapeppn",
274 e5966bd9 Kostas Papadimitriou
                          cn="Kostas Papadimitriou", )
275 d2633501 Kostas Papadimitriou
        r = client.get("/im/login/shibboleth?", follow=True)
276 9d20fe23 Kostas Papadimitriou
        self.assertContains(r, 'is pending moderation')
277 d2633501 Kostas Papadimitriou
278 ba50648c Kostas Papadimitriou
        # admin activates our user
279 ba50648c Kostas Papadimitriou
        u = AstakosUser.objects.get(username="kpap@grnet.gr")
280 d2633501 Kostas Papadimitriou
        functions.activate(u)
281 d2633501 Kostas Papadimitriou
        self.assertEqual(u.is_active, True)
282 d2633501 Kostas Papadimitriou
283 ba50648c Kostas Papadimitriou
        # we see our profile
284 ba50648c Kostas Papadimitriou
        r = client.get("/im/login/shibboleth?", follow=True)
285 478ece6c Kostas Papadimitriou
        self.assertRedirects(r, '/im/landing')
286 ba50648c Kostas Papadimitriou
        self.assertEqual(r.status_code, 200)
287 d2633501 Kostas Papadimitriou
288 d2633501 Kostas Papadimitriou
    def test_existing(self):
289 ba50648c Kostas Papadimitriou
        """
290 ba50648c Kostas Papadimitriou
        Test adding of third party login to an existing account
291 ba50648c Kostas Papadimitriou
        """
292 ba50648c Kostas Papadimitriou
293 ba50648c Kostas Papadimitriou
        # this is our existing user
294 d2633501 Kostas Papadimitriou
        existing_user = get_local_user('kpap@grnet.gr')
295 478ece6c Kostas Papadimitriou
        existing_inactive = get_local_user('kpap-inactive@grnet.gr')
296 478ece6c Kostas Papadimitriou
        existing_inactive.is_active = False
297 478ece6c Kostas Papadimitriou
        existing_inactive.save()
298 478ece6c Kostas Papadimitriou
299 478ece6c Kostas Papadimitriou
        existing_unverified = get_local_user('kpap-unverified@grnet.gr')
300 478ece6c Kostas Papadimitriou
        existing_unverified.is_active = False
301 478ece6c Kostas Papadimitriou
        existing_unverified.activation_sent = None
302 478ece6c Kostas Papadimitriou
        existing_unverified.email_verified = False
303 478ece6c Kostas Papadimitriou
        existing_unverified.is_verified = False
304 478ece6c Kostas Papadimitriou
        existing_unverified.save()
305 d2633501 Kostas Papadimitriou
306 d2633501 Kostas Papadimitriou
        client = ShibbolethClient()
307 d2633501 Kostas Papadimitriou
        # shibboleth logged us in, notice that we use different email
308 e5966bd9 Kostas Papadimitriou
        client.set_tokens(mail="kpap@shibboleth.gr", eppn="kpapeppn",
309 e5966bd9 Kostas Papadimitriou
                          cn="Kostas Papadimitriou", )
310 9d20fe23 Kostas Papadimitriou
        r = client.get("/im/login/shibboleth?", follow=True)
311 d2633501 Kostas Papadimitriou
312 d2633501 Kostas Papadimitriou
        # a new pending user created
313 d2633501 Kostas Papadimitriou
        pending_user = PendingThirdPartyUser.objects.get()
314 9d20fe23 Kostas Papadimitriou
        token = pending_user.token
315 d2633501 Kostas Papadimitriou
        self.assertEqual(PendingThirdPartyUser.objects.count(), 1)
316 d2633501 Kostas Papadimitriou
        pending_key = pending_user.token
317 d2633501 Kostas Papadimitriou
        client.reset_tokens()
318 9d20fe23 Kostas Papadimitriou
        self.assertRedirects(r, "/im/signup?third_party_token=%s" % token)
319 d2633501 Kostas Papadimitriou
320 2a88057d Christos Stavrakakis
        form = r.context['login_form']
321 9d20fe23 Kostas Papadimitriou
        signupdata = copy.copy(form.initial)
322 9d20fe23 Kostas Papadimitriou
        signupdata['email'] = 'kpap@grnet.gr'
323 9d20fe23 Kostas Papadimitriou
        signupdata['third_party_token'] = token
324 9d20fe23 Kostas Papadimitriou
        signupdata['provider'] = 'shibboleth'
325 2a88057d Christos Stavrakakis
        signupdata.pop('id', None)
326 d2633501 Kostas Papadimitriou
327 478ece6c Kostas Papadimitriou
        # the email exists to another user
328 478ece6c Kostas Papadimitriou
        r = client.post("/im/signup", signupdata)
329 478ece6c Kostas Papadimitriou
        self.assertContains(r, "There is already an account with this email "
330 478ece6c Kostas Papadimitriou
                               "address")
331 478ece6c Kostas Papadimitriou
        # change the case, still cannot create
332 478ece6c Kostas Papadimitriou
        signupdata['email'] = 'KPAP@grnet.GR'
333 478ece6c Kostas Papadimitriou
        r = client.post("/im/signup", signupdata)
334 478ece6c Kostas Papadimitriou
        self.assertContains(r, "There is already an account with this email "
335 478ece6c Kostas Papadimitriou
                               "address")
336 478ece6c Kostas Papadimitriou
        # inactive user
337 478ece6c Kostas Papadimitriou
        signupdata['email'] = 'KPAP-inactive@grnet.GR'
338 9d20fe23 Kostas Papadimitriou
        r = client.post("/im/signup", signupdata)
339 9d20fe23 Kostas Papadimitriou
        self.assertContains(r, "There is already an account with this email "
340 9d20fe23 Kostas Papadimitriou
                               "address")
341 d2633501 Kostas Papadimitriou
342 478ece6c Kostas Papadimitriou
        # unverified user, this should pass, old entry will be deleted
343 478ece6c Kostas Papadimitriou
        signupdata['email'] = 'KAPAP-unverified@grnet.GR'
344 478ece6c Kostas Papadimitriou
        r = client.post("/im/signup", signupdata)
345 478ece6c Kostas Papadimitriou
346 d2633501 Kostas Papadimitriou
        post_data = {'password': 'password',
347 9d20fe23 Kostas Papadimitriou
                     'username': 'kpap@grnet.gr'}
348 9d20fe23 Kostas Papadimitriou
        r = client.post('/im/local', post_data, follow=True)
349 9d20fe23 Kostas Papadimitriou
        self.assertTrue(r.context['request'].user.is_authenticated())
350 9d20fe23 Kostas Papadimitriou
        client.set_tokens(mail="kpap@shibboleth.gr", eppn="kpapeppn",
351 9d20fe23 Kostas Papadimitriou
                          cn="Kostas Papadimitriou", )
352 9d20fe23 Kostas Papadimitriou
        r = client.get("/im/login/shibboleth?", follow=True)
353 9d20fe23 Kostas Papadimitriou
        self.assertContains(r, "enabled for this account")
354 9d20fe23 Kostas Papadimitriou
        client.reset_tokens()
355 9d20fe23 Kostas Papadimitriou
356 9d20fe23 Kostas Papadimitriou
        user = existing_user
357 9d20fe23 Kostas Papadimitriou
        self.assertTrue(user.has_auth_provider('shibboleth'))
358 9d20fe23 Kostas Papadimitriou
        self.assertTrue(user.has_auth_provider('local',
359 9d20fe23 Kostas Papadimitriou
                                               auth_backend='astakos'))
360 d2633501 Kostas Papadimitriou
        client.logout()
361 d2633501 Kostas Papadimitriou
362 d2633501 Kostas Papadimitriou
        # look Ma, i can login with both my shibboleth and local account
363 e5966bd9 Kostas Papadimitriou
        client.set_tokens(mail="kpap@shibboleth.gr", eppn="kpapeppn",
364 e5966bd9 Kostas Papadimitriou
                          cn="Kostas Papadimitriou")
365 d2633501 Kostas Papadimitriou
        r = client.get("/im/login/shibboleth?", follow=True)
366 d2633501 Kostas Papadimitriou
        self.assertTrue(r.context['request'].user.is_authenticated())
367 d2633501 Kostas Papadimitriou
        self.assertTrue(r.context['request'].user.email == "kpap@grnet.gr")
368 478ece6c Kostas Papadimitriou
        self.assertRedirects(r, '/im/landing')
369 ba50648c Kostas Papadimitriou
        self.assertEqual(r.status_code, 200)
370 d2633501 Kostas Papadimitriou
        client.logout()
371 d2633501 Kostas Papadimitriou
        client.reset_tokens()
372 ba50648c Kostas Papadimitriou
373 ba50648c Kostas Papadimitriou
        # logged out
374 d2633501 Kostas Papadimitriou
        r = client.get("/im/profile", follow=True)
375 d2633501 Kostas Papadimitriou
        self.assertFalse(r.context['request'].user.is_authenticated())
376 d2633501 Kostas Papadimitriou
377 ba50648c Kostas Papadimitriou
        # login with local account also works
378 d2633501 Kostas Papadimitriou
        post_data = {'password': 'password',
379 d2633501 Kostas Papadimitriou
                     'username': 'kpap@grnet.gr'}
380 d2633501 Kostas Papadimitriou
        r = self.client.post('/im/local', post_data, follow=True)
381 d2633501 Kostas Papadimitriou
        self.assertTrue(r.context['request'].user.is_authenticated())
382 ba50648c Kostas Papadimitriou
        self.assertTrue(r.context['request'].user.email == "kpap@grnet.gr")
383 9d20fe23 Kostas Papadimitriou
        self.assertRedirects(r, '/im/landing')
384 ba50648c Kostas Papadimitriou
        self.assertEqual(r.status_code, 200)
385 d2633501 Kostas Papadimitriou
386 ba50648c Kostas Papadimitriou
        # cannot add the same eppn
387 e5966bd9 Kostas Papadimitriou
        client.set_tokens(mail="secondary@shibboleth.gr", eppn="kpapeppn",
388 e5966bd9 Kostas Papadimitriou
                          cn="Kostas Papadimitriou", )
389 d2633501 Kostas Papadimitriou
        r = client.get("/im/login/shibboleth?", follow=True)
390 478ece6c Kostas Papadimitriou
        self.assertRedirects(r, '/im/landing')
391 ba50648c Kostas Papadimitriou
        self.assertTrue(r.status_code, 200)
392 ba50648c Kostas Papadimitriou
        self.assertEquals(existing_user.auth_providers.count(), 2)
393 d2633501 Kostas Papadimitriou
394 9d20fe23 Kostas Papadimitriou
        # only one allowed by default
395 ba50648c Kostas Papadimitriou
        client.set_tokens(mail="secondary@shibboleth.gr", eppn="kpapeppn2",
396 e5966bd9 Kostas Papadimitriou
                          cn="Kostas Papadimitriou", ep_affiliation="affil2")
397 9d20fe23 Kostas Papadimitriou
        prov = auth_providers.get_provider('shibboleth')
398 ba50648c Kostas Papadimitriou
        r = client.get("/im/login/shibboleth?", follow=True)
399 9d20fe23 Kostas Papadimitriou
        self.assertContains(r, "Failed to add")
400 ba50648c Kostas Papadimitriou
        self.assertRedirects(r, '/im/profile')
401 ba50648c Kostas Papadimitriou
        self.assertTrue(r.status_code, 200)
402 9d20fe23 Kostas Papadimitriou
        self.assertEquals(existing_user.auth_providers.count(), 2)
403 d2633501 Kostas Papadimitriou
        client.logout()
404 ba50648c Kostas Papadimitriou
        client.reset_tokens()
405 ba50648c Kostas Papadimitriou
406 ba50648c Kostas Papadimitriou
        # cannot login with another eppn
407 e5966bd9 Kostas Papadimitriou
        client.set_tokens(mail="kpap@grnet.gr", eppn="kpapeppninvalid",
408 e5966bd9 Kostas Papadimitriou
                          cn="Kostas Papadimitriou")
409 d2633501 Kostas Papadimitriou
        r = client.get("/im/login/shibboleth?", follow=True)
410 d2633501 Kostas Papadimitriou
        self.assertFalse(r.context['request'].user.is_authenticated())
411 d2633501 Kostas Papadimitriou
412 478ece6c Kostas Papadimitriou
        # cannot
413 478ece6c Kostas Papadimitriou
414 f432088a Kostas Papadimitriou
        # lets remove local password
415 f432088a Kostas Papadimitriou
        user = AstakosUser.objects.get(username="kpap@grnet.gr",
416 f432088a Kostas Papadimitriou
                                       email="kpap@grnet.gr")
417 9d20fe23 Kostas Papadimitriou
        remove_local_url = user.get_auth_provider('local').get_remove_url
418 9d20fe23 Kostas Papadimitriou
        remove_shibbo_url = user.get_auth_provider('shibboleth',
419 9d20fe23 Kostas Papadimitriou
                                                   'kpapeppn').get_remove_url
420 e5966bd9 Kostas Papadimitriou
        client.set_tokens(mail="kpap@shibboleth.gr", eppn="kpapeppn",
421 e5966bd9 Kostas Papadimitriou
                          cn="Kostas Papadimtriou")
422 f432088a Kostas Papadimitriou
        r = client.get("/im/login/shibboleth?", follow=True)
423 f432088a Kostas Papadimitriou
        client.reset_tokens()
424 ba50648c Kostas Papadimitriou
425 ba50648c Kostas Papadimitriou
        # TODO: this view should use POST
426 ba50648c Kostas Papadimitriou
        r = client.get(remove_local_url)
427 ba50648c Kostas Papadimitriou
        # 2 providers left
428 f432088a Kostas Papadimitriou
        self.assertEqual(user.auth_providers.count(), 1)
429 ba50648c Kostas Papadimitriou
        # cannot remove last provider
430 ba50648c Kostas Papadimitriou
        r = client.get(remove_shibbo_url)
431 f432088a Kostas Papadimitriou
        self.assertEqual(r.status_code, 403)
432 f432088a Kostas Papadimitriou
        self.client.logout()
433 ba50648c Kostas Papadimitriou
434 ba50648c Kostas Papadimitriou
        # cannot login using local credentials (notice we use another client)
435 f432088a Kostas Papadimitriou
        post_data = {'password': 'password',
436 f432088a Kostas Papadimitriou
                     'username': 'kpap@grnet.gr'}
437 f432088a Kostas Papadimitriou
        r = self.client.post('/im/local', post_data, follow=True)
438 f432088a Kostas Papadimitriou
        self.assertFalse(r.context['request'].user.is_authenticated())
439 f432088a Kostas Papadimitriou
440 ba50648c Kostas Papadimitriou
        # we can reenable the local provider by setting a password
441 f432088a Kostas Papadimitriou
        r = client.get("/im/password_change", follow=True)
442 0a7a4104 Kostas Papadimitriou
        r = client.post("/im/password_change", {'new_password1': '111',
443 f432088a Kostas Papadimitriou
                                                'new_password2': '111'},
444 f432088a Kostas Papadimitriou
                        follow=True)
445 f432088a Kostas Papadimitriou
        user = r.context['request'].user
446 f432088a Kostas Papadimitriou
        self.assertTrue(user.has_auth_provider('local'))
447 f432088a Kostas Papadimitriou
        self.assertTrue(user.has_auth_provider('shibboleth'))
448 f432088a Kostas Papadimitriou
        self.assertTrue(user.check_password('111'))
449 f432088a Kostas Papadimitriou
        self.assertTrue(user.has_usable_password())
450 f432088a Kostas Papadimitriou
        self.client.logout()
451 ba50648c Kostas Papadimitriou
452 ba50648c Kostas Papadimitriou
        # now we can login
453 f432088a Kostas Papadimitriou
        post_data = {'password': '111',
454 f432088a Kostas Papadimitriou
                     'username': 'kpap@grnet.gr'}
455 f432088a Kostas Papadimitriou
        r = self.client.post('/im/local', post_data, follow=True)
456 f432088a Kostas Papadimitriou
        self.assertTrue(r.context['request'].user.is_authenticated())
457 f432088a Kostas Papadimitriou
458 ba50648c Kostas Papadimitriou
        client.reset_tokens()
459 f432088a Kostas Papadimitriou
460 ba50648c Kostas Papadimitriou
        # we cannot take over another shibboleth identifier
461 f432088a Kostas Papadimitriou
        user2 = get_local_user('another@grnet.gr')
462 f432088a Kostas Papadimitriou
        user2.add_auth_provider('shibboleth', identifier='existingeppn')
463 ba50648c Kostas Papadimitriou
        # login
464 e5966bd9 Kostas Papadimitriou
        client.set_tokens(mail="kpap@shibboleth.gr", eppn="kpapeppn",
465 e5966bd9 Kostas Papadimitriou
                          cn="Kostas Papadimitriou")
466 f432088a Kostas Papadimitriou
        r = client.get("/im/login/shibboleth?", follow=True)
467 ba50648c Kostas Papadimitriou
        # try to assign existing shibboleth identifier of another user
468 9d20fe23 Kostas Papadimitriou
        client.set_tokens(mail="kpap_second@shibboleth.gr",
469 9d20fe23 Kostas Papadimitriou
                          eppn="existingeppn", cn="Kostas Papadimitriou")
470 f432088a Kostas Papadimitriou
        r = client.get("/im/login/shibboleth?", follow=True)
471 9d20fe23 Kostas Papadimitriou
        self.assertContains(r, "this account is already assigned")
472 2e90e3ec Kostas Papadimitriou
473 d2633501 Kostas Papadimitriou
474 478ece6c Kostas Papadimitriou
class TestLocal(TestCase):
475 d2633501 Kostas Papadimitriou
476 d2633501 Kostas Papadimitriou
    fixtures = ['groups']
477 d2633501 Kostas Papadimitriou
478 2e90e3ec Kostas Papadimitriou
    def setUp(self):
479 2e90e3ec Kostas Papadimitriou
        settings.ADMINS = (('admin', 'support@cloud.grnet.gr'),)
480 2e90e3ec Kostas Papadimitriou
        settings.SERVER_EMAIL = 'no-reply@grnet.gr'
481 9d20fe23 Kostas Papadimitriou
        self._orig_moderation = astakos_settings.MODERATION_ENABLED
482 9d20fe23 Kostas Papadimitriou
        settings.ASTAKOS_MODERATION_ENABLED = True
483 9d20fe23 Kostas Papadimitriou
484 9d20fe23 Kostas Papadimitriou
    def tearDown(self):
485 9d20fe23 Kostas Papadimitriou
        settings.ASTAKOS_MODERATION_ENABLED = self._orig_moderation
486 2e90e3ec Kostas Papadimitriou
487 7233d542 Kostas Papadimitriou
    def test_no_moderation(self):
488 ba50648c Kostas Papadimitriou
        # disable moderation
489 7233d542 Kostas Papadimitriou
        astakos_settings.MODERATION_ENABLED = False
490 ba50648c Kostas Papadimitriou
491 ba50648c Kostas Papadimitriou
        # create a new user
492 7233d542 Kostas Papadimitriou
        r = self.client.get("/im/signup")
493 7233d542 Kostas Papadimitriou
        self.assertEqual(r.status_code, 200)
494 9d20fe23 Kostas Papadimitriou
        data = {'email': 'kpap@grnet.gr', 'password1': 'password',
495 9d20fe23 Kostas Papadimitriou
                'password2': 'password', 'first_name': 'Kostas',
496 7233d542 Kostas Papadimitriou
                'last_name': 'Mitroglou', 'provider': 'local'}
497 7233d542 Kostas Papadimitriou
        r = self.client.post("/im/signup", data)
498 ba50648c Kostas Papadimitriou
499 ba50648c Kostas Papadimitriou
        # user created
500 7233d542 Kostas Papadimitriou
        self.assertEqual(AstakosUser.objects.count(), 1)
501 7233d542 Kostas Papadimitriou
        user = AstakosUser.objects.get(username="kpap@grnet.gr",
502 7233d542 Kostas Papadimitriou
                                       email="kpap@grnet.gr")
503 7233d542 Kostas Papadimitriou
        self.assertEqual(user.username, 'kpap@grnet.gr')
504 7233d542 Kostas Papadimitriou
        self.assertEqual(user.has_auth_provider('local'), True)
505 7233d542 Kostas Papadimitriou
        self.assertFalse(user.is_active)
506 7233d542 Kostas Papadimitriou
507 ba50648c Kostas Papadimitriou
        # user (but not admin) gets notified
508 7233d542 Kostas Papadimitriou
        self.assertEqual(len(get_mailbox('support@cloud.grnet.gr')), 0)
509 7233d542 Kostas Papadimitriou
        self.assertEqual(len(get_mailbox('kpap@grnet.gr')), 1)
510 7233d542 Kostas Papadimitriou
        astakos_settings.MODERATION_ENABLED = True
511 d2633501 Kostas Papadimitriou
512 e5966bd9 Kostas Papadimitriou
    def test_email_case(self):
513 e5966bd9 Kostas Papadimitriou
        data = {
514 9d20fe23 Kostas Papadimitriou
            'email': 'kPap@grnet.gr',
515 9d20fe23 Kostas Papadimitriou
            'password1': '1234',
516 9d20fe23 Kostas Papadimitriou
            'password2': '1234'
517 e5966bd9 Kostas Papadimitriou
        }
518 e5966bd9 Kostas Papadimitriou
519 e5966bd9 Kostas Papadimitriou
        form = forms.LocalUserCreationForm(data)
520 e5966bd9 Kostas Papadimitriou
        self.assertTrue(form.is_valid())
521 e5966bd9 Kostas Papadimitriou
        user = form.save()
522 e5966bd9 Kostas Papadimitriou
        form.store_user(user, {})
523 e5966bd9 Kostas Papadimitriou
524 9d20fe23 Kostas Papadimitriou
        u = AstakosUser.objects.get()
525 e5966bd9 Kostas Papadimitriou
        self.assertEqual(u.email, 'kPap@grnet.gr')
526 e5966bd9 Kostas Papadimitriou
        self.assertEqual(u.username, 'kpap@grnet.gr')
527 e5966bd9 Kostas Papadimitriou
        u.is_active = True
528 e5966bd9 Kostas Papadimitriou
        u.email_verified = True
529 e5966bd9 Kostas Papadimitriou
        u.save()
530 e5966bd9 Kostas Papadimitriou
531 e5966bd9 Kostas Papadimitriou
        data = {'username': 'kpap@grnet.gr', 'password': '1234'}
532 e5966bd9 Kostas Papadimitriou
        login = forms.LoginForm(data=data)
533 e5966bd9 Kostas Papadimitriou
        self.assertTrue(login.is_valid())
534 e5966bd9 Kostas Papadimitriou
535 e5966bd9 Kostas Papadimitriou
        data = {'username': 'KpaP@grnet.gr', 'password': '1234'}
536 e5966bd9 Kostas Papadimitriou
        login = forms.LoginForm(data=data)
537 e5966bd9 Kostas Papadimitriou
        self.assertTrue(login.is_valid())
538 e5966bd9 Kostas Papadimitriou
539 e5966bd9 Kostas Papadimitriou
        data = {
540 9d20fe23 Kostas Papadimitriou
            'email': 'kpap@grnet.gr',
541 9d20fe23 Kostas Papadimitriou
            'password1': '1234',
542 9d20fe23 Kostas Papadimitriou
            'password2': '1234'
543 e5966bd9 Kostas Papadimitriou
        }
544 e5966bd9 Kostas Papadimitriou
        form = forms.LocalUserCreationForm(data)
545 e5966bd9 Kostas Papadimitriou
        self.assertFalse(form.is_valid())
546 e5966bd9 Kostas Papadimitriou
547 0a7a4104 Kostas Papadimitriou
    @im_settings(HELPDESK=(('support', 'support@synnefo.org'),))
548 0a7a4104 Kostas Papadimitriou
    @im_settings(FORCE_PROFILE_UPDATE=False)
549 d2633501 Kostas Papadimitriou
    def test_local_provider(self):
550 19a992e3 Kostas Papadimitriou
        self.helpdesk_email = astakos_settings.HELPDESK[0][1]
551 ba50648c Kostas Papadimitriou
        # enable moderation
552 7233d542 Kostas Papadimitriou
        astakos_settings.MODERATION_ENABLED = True
553 ba50648c Kostas Papadimitriou
554 ba50648c Kostas Papadimitriou
        # create a user
555 d2633501 Kostas Papadimitriou
        r = self.client.get("/im/signup")
556 d2633501 Kostas Papadimitriou
        self.assertEqual(r.status_code, 200)
557 9d20fe23 Kostas Papadimitriou
        data = {'email': 'kpap@grnet.gr', 'password1': 'password',
558 9d20fe23 Kostas Papadimitriou
                'password2': 'password', 'first_name': 'Kostas',
559 d2633501 Kostas Papadimitriou
                'last_name': 'Mitroglou', 'provider': 'local'}
560 d2633501 Kostas Papadimitriou
        r = self.client.post("/im/signup", data)
561 ba50648c Kostas Papadimitriou
562 ba50648c Kostas Papadimitriou
        # user created
563 d2633501 Kostas Papadimitriou
        self.assertEqual(AstakosUser.objects.count(), 1)
564 d2633501 Kostas Papadimitriou
        user = AstakosUser.objects.get(username="kpap@grnet.gr",
565 d2633501 Kostas Papadimitriou
                                       email="kpap@grnet.gr")
566 d2633501 Kostas Papadimitriou
        self.assertEqual(user.username, 'kpap@grnet.gr')
567 d2633501 Kostas Papadimitriou
        self.assertEqual(user.has_auth_provider('local'), True)
568 9d20fe23 Kostas Papadimitriou
        self.assertFalse(user.is_active)  # not activated
569 9d20fe23 Kostas Papadimitriou
        self.assertFalse(user.email_verified)  # not verified
570 9d20fe23 Kostas Papadimitriou
        self.assertFalse(user.activation_sent)  # activation automatically sent
571 d2633501 Kostas Papadimitriou
572 ba50648c Kostas Papadimitriou
        # admin gets notified and activates the user from the command line
573 19a992e3 Kostas Papadimitriou
        self.assertEqual(len(get_mailbox(self.helpdesk_email)), 1)
574 31fdafa8 Kostas Papadimitriou
        r = self.client.post('/im/local', {'username': 'kpap@grnet.gr',
575 9d20fe23 Kostas Papadimitriou
                                           'password': 'password'})
576 9d20fe23 Kostas Papadimitriou
        self.assertContains(r, messages.NOTIFICATION_SENT)
577 d2633501 Kostas Papadimitriou
        functions.send_activation(user)
578 d2633501 Kostas Papadimitriou
579 ba50648c Kostas Papadimitriou
        # user activation fields updated and user gets notified via email
580 d2633501 Kostas Papadimitriou
        user = AstakosUser.objects.get(pk=user.pk)
581 d2633501 Kostas Papadimitriou
        self.assertTrue(user.activation_sent)
582 d2633501 Kostas Papadimitriou
        self.assertFalse(user.email_verified)
583 f47ecf6b Kostas Papadimitriou
        self.assertFalse(user.is_active)
584 d2633501 Kostas Papadimitriou
        self.assertEqual(len(get_mailbox('kpap@grnet.gr')), 1)
585 d2633501 Kostas Papadimitriou
586 d2633501 Kostas Papadimitriou
        # user forgot she got registered and tries to submit registration
587 d2633501 Kostas Papadimitriou
        # form. Notice the upper case in email
588 9d20fe23 Kostas Papadimitriou
        data = {'email': 'KPAP@grnet.gr', 'password1': 'password',
589 9d20fe23 Kostas Papadimitriou
                'password2': 'password', 'first_name': 'Kostas',
590 d2633501 Kostas Papadimitriou
                'last_name': 'Mitroglou', 'provider': 'local'}
591 564a2292 Kostas Papadimitriou
        r = self.client.post("/im/signup", data, follow=True)
592 564a2292 Kostas Papadimitriou
        self.assertRedirects(r, reverse('index'))
593 564a2292 Kostas Papadimitriou
        self.assertContains(r, messages.NOTIFICATION_SENT)
594 564a2292 Kostas Papadimitriou
595 9d20fe23 Kostas Papadimitriou
        user = AstakosUser.objects.get()
596 9d20fe23 Kostas Papadimitriou
        functions.send_activation(user)
597 9d20fe23 Kostas Papadimitriou
598 564a2292 Kostas Papadimitriou
        # previous user replaced
599 564a2292 Kostas Papadimitriou
        self.assertTrue(user.activation_sent)
600 564a2292 Kostas Papadimitriou
        self.assertFalse(user.email_verified)
601 564a2292 Kostas Papadimitriou
        self.assertFalse(user.is_active)
602 9d20fe23 Kostas Papadimitriou
        self.assertEqual(len(get_mailbox('KPAP@grnet.gr')), 1)
603 d2633501 Kostas Papadimitriou
604 f47ecf6b Kostas Papadimitriou
        # hmmm, email exists; lets request a password change
605 d2633501 Kostas Papadimitriou
        r = self.client.get('/im/local/password_reset')
606 d2633501 Kostas Papadimitriou
        self.assertEqual(r.status_code, 200)
607 9d20fe23 Kostas Papadimitriou
        data = {'email': 'kpap@grnet.gr'}
608 9d20fe23 Kostas Papadimitriou
        r = self.client.post('/im/local/password_reset', data, follow=True)
609 d2633501 Kostas Papadimitriou
        # she can't because account is not active yet
610 9d20fe23 Kostas Papadimitriou
        self.assertContains(r, 'pending activation')
611 d2633501 Kostas Papadimitriou
612 9d20fe23 Kostas Papadimitriou
        # moderation is enabled and an activation email has already been sent
613 9d20fe23 Kostas Papadimitriou
        # so user can trigger resend of the activation email
614 9d20fe23 Kostas Papadimitriou
        r = self.client.get('/im/send/activation/%d' % user.pk, follow=True)
615 9d20fe23 Kostas Papadimitriou
        self.assertContains(r, 'has been sent to your email address.')
616 9d20fe23 Kostas Papadimitriou
        self.assertEqual(len(get_mailbox('KPAP@grnet.gr')), 2)
617 ba50648c Kostas Papadimitriou
618 d2633501 Kostas Papadimitriou
        # also she cannot login
619 9d20fe23 Kostas Papadimitriou
        data = {'username': 'kpap@grnet.gr', 'password': 'password'}
620 9d20fe23 Kostas Papadimitriou
        r = self.client.post('/im/local', data, follow=True)
621 d2633501 Kostas Papadimitriou
        self.assertContains(r, 'Resend activation')
622 d2633501 Kostas Papadimitriou
        self.assertFalse(r.context['request'].user.is_authenticated())
623 d2633501 Kostas Papadimitriou
        self.assertFalse('_pithos2_a' in self.client.cookies)
624 ba50648c Kostas Papadimitriou
625 d2633501 Kostas Papadimitriou
        # user sees the message and resends activation
626 9d20fe23 Kostas Papadimitriou
        r = self.client.get('/im/send/activation/%d' % user.pk, follow=True)
627 9d20fe23 Kostas Papadimitriou
        self.assertEqual(len(get_mailbox('KPAP@grnet.gr')), 3)
628 d2633501 Kostas Papadimitriou
629 d2633501 Kostas Papadimitriou
        # switch back moderation setting
630 d2633501 Kostas Papadimitriou
        astakos_settings.MODERATION_ENABLED = True
631 d2633501 Kostas Papadimitriou
        r = self.client.get(user.get_activation_url(), follow=True)
632 9d20fe23 Kostas Papadimitriou
        self.assertRedirects(r, "/im/landing")
633 9d20fe23 Kostas Papadimitriou
        r = self.client.get('/im/profile', follow=True)
634 9d20fe23 Kostas Papadimitriou
        self.assertTrue(r.context['request'].user.is_authenticated())
635 9d20fe23 Kostas Papadimitriou
        self.assertTrue('_pithos2_a' in self.client.cookies)
636 9d20fe23 Kostas Papadimitriou
        self.assertContains(r, "KPAP@grnet.gr")
637 9d20fe23 Kostas Papadimitriou
        self.assertEqual(len(get_mailbox('KPAP@grnet.gr')), 4)
638 d2633501 Kostas Papadimitriou
639 d2633501 Kostas Papadimitriou
        user = AstakosUser.objects.get(pk=user.pk)
640 d2633501 Kostas Papadimitriou
        # user activated and logged in, token cookie set
641 d2633501 Kostas Papadimitriou
        self.assertTrue(r.context['request'].user.is_authenticated())
642 d2633501 Kostas Papadimitriou
        self.assertTrue('_pithos2_a' in self.client.cookies)
643 d2633501 Kostas Papadimitriou
        cookies = self.client.cookies
644 9d20fe23 Kostas Papadimitriou
        self.assertTrue(quote(user.auth_token) in
645 9d20fe23 Kostas Papadimitriou
                        cookies.get('_pithos2_a').value)
646 d2633501 Kostas Papadimitriou
        r = self.client.get('/im/logout', follow=True)
647 d2633501 Kostas Papadimitriou
        r = self.client.get('/im/')
648 d2633501 Kostas Papadimitriou
        # user logged out, token cookie removed
649 d2633501 Kostas Papadimitriou
        self.assertFalse(r.context['request'].user.is_authenticated())
650 d2633501 Kostas Papadimitriou
        self.assertFalse(self.client.cookies.get('_pithos2_a').value)
651 9d20fe23 Kostas Papadimitriou
652 9d20fe23 Kostas Papadimitriou
        #https://docs.djangoproject.com/en/dev/topics/testing/#persistent-state
653 d2633501 Kostas Papadimitriou
        del self.client.cookies['_pithos2_a']
654 d2633501 Kostas Papadimitriou
655 d2633501 Kostas Papadimitriou
        # user can login
656 d2633501 Kostas Papadimitriou
        r = self.client.post('/im/local', {'username': 'kpap@grnet.gr',
657 d2633501 Kostas Papadimitriou
                                           'password': 'password'},
658 9d20fe23 Kostas Papadimitriou
                             follow=True)
659 d2633501 Kostas Papadimitriou
        self.assertTrue(r.context['request'].user.is_authenticated())
660 d2633501 Kostas Papadimitriou
        self.assertTrue('_pithos2_a' in self.client.cookies)
661 d2633501 Kostas Papadimitriou
        cookies = self.client.cookies
662 9d20fe23 Kostas Papadimitriou
        self.assertTrue(quote(user.auth_token) in
663 9d20fe23 Kostas Papadimitriou
                        cookies.get('_pithos2_a').value)
664 d2633501 Kostas Papadimitriou
        self.client.get('/im/logout', follow=True)
665 d2633501 Kostas Papadimitriou
666 d2633501 Kostas Papadimitriou
        # user forgot password
667 d2633501 Kostas Papadimitriou
        old_pass = user.password
668 d2633501 Kostas Papadimitriou
        r = self.client.get('/im/local/password_reset')
669 d2633501 Kostas Papadimitriou
        self.assertEqual(r.status_code, 200)
670 d2633501 Kostas Papadimitriou
        r = self.client.post('/im/local/password_reset', {'email':
671 d2633501 Kostas Papadimitriou
                                                          'kpap@grnet.gr'})
672 d2633501 Kostas Papadimitriou
        self.assertEqual(r.status_code, 302)
673 d2633501 Kostas Papadimitriou
        # email sent
674 9d20fe23 Kostas Papadimitriou
        self.assertEqual(len(get_mailbox('KPAP@grnet.gr')), 5)
675 d2633501 Kostas Papadimitriou
676 d2633501 Kostas Papadimitriou
        # user visits change password link
677 95150b7d Christos Stavrakakis
        # "Refresh" user because created url is based on last_login timestamp
678 126f6a55 Christos Stavrakakis
        user = AstakosUser.objects.get(pk=user.pk)
679 d2633501 Kostas Papadimitriou
        r = self.client.get(user.get_password_reset_url())
680 d2633501 Kostas Papadimitriou
        r = self.client.post(user.get_password_reset_url(),
681 9d20fe23 Kostas Papadimitriou
                             {'new_password1': 'newpass',
682 9d20fe23 Kostas Papadimitriou
                              'new_password2': 'newpass'})
683 d2633501 Kostas Papadimitriou
684 d2633501 Kostas Papadimitriou
        user = AstakosUser.objects.get(pk=user.pk)
685 d2633501 Kostas Papadimitriou
        self.assertNotEqual(old_pass, user.password)
686 d2633501 Kostas Papadimitriou
687 d2633501 Kostas Papadimitriou
        # old pass is not usable
688 d2633501 Kostas Papadimitriou
        r = self.client.post('/im/local', {'username': 'kpap@grnet.gr',
689 d2633501 Kostas Papadimitriou
                                           'password': 'password'})
690 31fdafa8 Kostas Papadimitriou
        self.assertContains(r, 'Please enter a correct username and password')
691 d2633501 Kostas Papadimitriou
        r = self.client.post('/im/local', {'username': 'kpap@grnet.gr',
692 d2633501 Kostas Papadimitriou
                                           'password': 'newpass'},
693 478ece6c Kostas Papadimitriou
                             follow=True)
694 d2633501 Kostas Papadimitriou
        self.assertTrue(r.context['request'].user.is_authenticated())
695 d2633501 Kostas Papadimitriou
        self.client.logout()
696 d2633501 Kostas Papadimitriou
697 d2633501 Kostas Papadimitriou
        # tests of special local backends
698 d2633501 Kostas Papadimitriou
        user = AstakosUser.objects.get(pk=user.pk)
699 d2633501 Kostas Papadimitriou
        user.auth_providers.filter(module='local').update(auth_backend='ldap')
700 d2633501 Kostas Papadimitriou
        user.save()
701 d2633501 Kostas Papadimitriou
702 d2633501 Kostas Papadimitriou
        # non astakos local backends do not support password reset
703 d2633501 Kostas Papadimitriou
        r = self.client.get('/im/local/password_reset')
704 d2633501 Kostas Papadimitriou
        self.assertEqual(r.status_code, 200)
705 d2633501 Kostas Papadimitriou
        r = self.client.post('/im/local/password_reset', {'email':
706 d2633501 Kostas Papadimitriou
                                                          'kpap@grnet.gr'})
707 d2633501 Kostas Papadimitriou
        # she can't because account is not active yet
708 9d20fe23 Kostas Papadimitriou
        self.assertContains(r, "Changing password is not")
709 9d20fe23 Kostas Papadimitriou
710 9d20fe23 Kostas Papadimitriou
711 34a76cdb Kostas Papadimitriou
class UserActionsTests(TestCase):
712 34a76cdb Kostas Papadimitriou
713 34a76cdb Kostas Papadimitriou
    def test_email_change(self):
714 34a76cdb Kostas Papadimitriou
        # to test existing email validation
715 478ece6c Kostas Papadimitriou
        get_local_user('existing@grnet.gr')
716 34a76cdb Kostas Papadimitriou
717 34a76cdb Kostas Papadimitriou
        # local user
718 34a76cdb Kostas Papadimitriou
        user = get_local_user('kpap@grnet.gr')
719 34a76cdb Kostas Papadimitriou
720 34a76cdb Kostas Papadimitriou
        # login as kpap
721 34a76cdb Kostas Papadimitriou
        self.client.login(username='kpap@grnet.gr', password='password')
722 34a76cdb Kostas Papadimitriou
        r = self.client.get('/im/profile', follow=True)
723 34a76cdb Kostas Papadimitriou
        user = r.context['request'].user
724 34a76cdb Kostas Papadimitriou
        self.assertTrue(user.is_authenticated())
725 34a76cdb Kostas Papadimitriou
726 34a76cdb Kostas Papadimitriou
        # change email is enabled
727 34a76cdb Kostas Papadimitriou
        r = self.client.get('/im/email_change')
728 34a76cdb Kostas Papadimitriou
        self.assertEqual(r.status_code, 200)
729 34a76cdb Kostas Papadimitriou
        self.assertFalse(user.email_change_is_pending())
730 34a76cdb Kostas Papadimitriou
731 34a76cdb Kostas Papadimitriou
        # request email change to an existing email fails
732 34a76cdb Kostas Papadimitriou
        data = {'new_email_address': 'existing@grnet.gr'}
733 34a76cdb Kostas Papadimitriou
        r = self.client.post('/im/email_change', data)
734 34a76cdb Kostas Papadimitriou
        self.assertContains(r, messages.EMAIL_USED)
735 34a76cdb Kostas Papadimitriou
736 34a76cdb Kostas Papadimitriou
        # proper email change
737 34a76cdb Kostas Papadimitriou
        data = {'new_email_address': 'kpap@gmail.com'}
738 34a76cdb Kostas Papadimitriou
        r = self.client.post('/im/email_change', data, follow=True)
739 34a76cdb Kostas Papadimitriou
        self.assertRedirects(r, '/im/profile')
740 34a76cdb Kostas Papadimitriou
        self.assertContains(r, messages.EMAIL_CHANGE_REGISTERED)
741 34a76cdb Kostas Papadimitriou
        change1 = EmailChange.objects.get()
742 34a76cdb Kostas Papadimitriou
743 34a76cdb Kostas Papadimitriou
        # user sees a warning
744 34a76cdb Kostas Papadimitriou
        r = self.client.get('/im/email_change')
745 34a76cdb Kostas Papadimitriou
        self.assertEqual(r.status_code, 200)
746 34a76cdb Kostas Papadimitriou
        self.assertContains(r, messages.PENDING_EMAIL_CHANGE_REQUEST)
747 34a76cdb Kostas Papadimitriou
        self.assertTrue(user.email_change_is_pending())
748 34a76cdb Kostas Papadimitriou
749 34a76cdb Kostas Papadimitriou
        # link was sent
750 34a76cdb Kostas Papadimitriou
        self.assertEqual(len(get_mailbox('kpap@grnet.gr')), 0)
751 34a76cdb Kostas Papadimitriou
        self.assertEqual(len(get_mailbox('kpap@gmail.com')), 1)
752 34a76cdb Kostas Papadimitriou
753 34a76cdb Kostas Papadimitriou
        # proper email change
754 34a76cdb Kostas Papadimitriou
        data = {'new_email_address': 'kpap@yahoo.com'}
755 34a76cdb Kostas Papadimitriou
        r = self.client.post('/im/email_change', data, follow=True)
756 34a76cdb Kostas Papadimitriou
        self.assertRedirects(r, '/im/profile')
757 34a76cdb Kostas Papadimitriou
        self.assertContains(r, messages.EMAIL_CHANGE_REGISTERED)
758 34a76cdb Kostas Papadimitriou
        self.assertEqual(len(get_mailbox('kpap@grnet.gr')), 0)
759 34a76cdb Kostas Papadimitriou
        self.assertEqual(len(get_mailbox('kpap@yahoo.com')), 1)
760 34a76cdb Kostas Papadimitriou
        change2 = EmailChange.objects.get()
761 34a76cdb Kostas Papadimitriou
762 34a76cdb Kostas Papadimitriou
        r = self.client.get(change1.get_url())
763 34a76cdb Kostas Papadimitriou
        self.assertEquals(r.status_code, 302)
764 34a76cdb Kostas Papadimitriou
        self.client.logout()
765 34a76cdb Kostas Papadimitriou
766 34a76cdb Kostas Papadimitriou
        r = self.client.post('/im/local?next=' + change2.get_url(),
767 34a76cdb Kostas Papadimitriou
                             {'username': 'kpap@grnet.gr',
768 34a76cdb Kostas Papadimitriou
                              'password': 'password',
769 34a76cdb Kostas Papadimitriou
                              'next': change2.get_url()},
770 34a76cdb Kostas Papadimitriou
                             follow=True)
771 34a76cdb Kostas Papadimitriou
        self.assertRedirects(r, '/im/profile')
772 34a76cdb Kostas Papadimitriou
        user = r.context['request'].user
773 34a76cdb Kostas Papadimitriou
        self.assertEquals(user.email, 'kpap@yahoo.com')
774 34a76cdb Kostas Papadimitriou
        self.assertEquals(user.username, 'kpap@yahoo.com')
775 34a76cdb Kostas Papadimitriou
776 34a76cdb Kostas Papadimitriou
        self.client.logout()
777 34a76cdb Kostas Papadimitriou
        r = self.client.post('/im/local?next=' + change2.get_url(),
778 34a76cdb Kostas Papadimitriou
                             {'username': 'kpap@grnet.gr',
779 34a76cdb Kostas Papadimitriou
                              'password': 'password',
780 34a76cdb Kostas Papadimitriou
                              'next': change2.get_url()},
781 34a76cdb Kostas Papadimitriou
                             follow=True)
782 34a76cdb Kostas Papadimitriou
        self.assertContains(r, "Please enter a correct username and password")
783 34a76cdb Kostas Papadimitriou
        self.assertEqual(user.emailchanges.count(), 0)
784 34a76cdb Kostas Papadimitriou
785 9d20fe23 Kostas Papadimitriou
786 478ece6c Kostas Papadimitriou
class TestAuthProviderViews(TestCase):
787 478ece6c Kostas Papadimitriou
788 478ece6c Kostas Papadimitriou
    @shibboleth_settings(CREATION_GROUPS_POLICY=['academic-login'])
789 478ece6c Kostas Papadimitriou
    @shibboleth_settings(AUTOMODERATE_POLICY=True)
790 478ece6c Kostas Papadimitriou
    @im_settings(IM_MODULES=['shibboleth', 'local'])
791 478ece6c Kostas Papadimitriou
    @im_settings(MODERATION_ENABLED=True)
792 0a7a4104 Kostas Papadimitriou
    @im_settings(FORCE_PROFILE_UPDATE=False)
793 478ece6c Kostas Papadimitriou
    def test_user(self):
794 478ece6c Kostas Papadimitriou
        Profile = AuthProviderPolicyProfile
795 478ece6c Kostas Papadimitriou
        Pending = PendingThirdPartyUser
796 478ece6c Kostas Papadimitriou
        User = AstakosUser
797 478ece6c Kostas Papadimitriou
798 0a7a4104 Kostas Papadimitriou
        User.objects.create(email="newuser@grnet.gr")
799 0a7a4104 Kostas Papadimitriou
        get_local_user("olduser@grnet.gr")
800 478ece6c Kostas Papadimitriou
        cl_olduser = ShibbolethClient()
801 0a7a4104 Kostas Papadimitriou
        get_local_user("olduser2@grnet.gr")
802 0a7a4104 Kostas Papadimitriou
        ShibbolethClient()
803 478ece6c Kostas Papadimitriou
        cl_newuser = ShibbolethClient()
804 478ece6c Kostas Papadimitriou
        cl_newuser2 = Client()
805 478ece6c Kostas Papadimitriou
806 478ece6c Kostas Papadimitriou
        academic_group, created = Group.objects.get_or_create(
807 478ece6c Kostas Papadimitriou
            name='academic-login')
808 478ece6c Kostas Papadimitriou
        academic_users = academic_group.user_set
809 478ece6c Kostas Papadimitriou
        assert created
810 478ece6c Kostas Papadimitriou
        policy_only_academic = Profile.objects.add_policy('academic_strict',
811 478ece6c Kostas Papadimitriou
                                                          'shibboleth',
812 478ece6c Kostas Papadimitriou
                                                          academic_group,
813 478ece6c Kostas Papadimitriou
                                                          exclusive=True,
814 478ece6c Kostas Papadimitriou
                                                          login=False,
815 478ece6c Kostas Papadimitriou
                                                          add=False)
816 478ece6c Kostas Papadimitriou
817 478ece6c Kostas Papadimitriou
818 478ece6c Kostas Papadimitriou
        # new academic user
819 478ece6c Kostas Papadimitriou
        self.assertFalse(academic_users.filter(email='newuser@grnet.gr'))
820 478ece6c Kostas Papadimitriou
        cl_newuser.set_tokens(eppn="newusereppn")
821 478ece6c Kostas Papadimitriou
        r = cl_newuser.get('/im/login/shibboleth?', follow=True)
822 478ece6c Kostas Papadimitriou
        pending = Pending.objects.get()
823 478ece6c Kostas Papadimitriou
        identifier = pending.third_party_identifier
824 478ece6c Kostas Papadimitriou
        signup_data = {'third_party_identifier': identifier,
825 478ece6c Kostas Papadimitriou
                       'first_name': 'Academic',
826 478ece6c Kostas Papadimitriou
                       'third_party_token': pending.token,
827 478ece6c Kostas Papadimitriou
                       'last_name': 'New User',
828 478ece6c Kostas Papadimitriou
                       'provider': 'shibboleth'}
829 478ece6c Kostas Papadimitriou
        r = cl_newuser.post('/im/signup', signup_data)
830 478ece6c Kostas Papadimitriou
        self.assertContains(r, "This field is required", )
831 478ece6c Kostas Papadimitriou
        signup_data['email'] = 'olduser@grnet.gr'
832 478ece6c Kostas Papadimitriou
        r = cl_newuser.post('/im/signup', signup_data)
833 478ece6c Kostas Papadimitriou
        self.assertContains(r, "already an account with this email", )
834 478ece6c Kostas Papadimitriou
        signup_data['email'] = 'newuser@grnet.gr'
835 478ece6c Kostas Papadimitriou
        r = cl_newuser.post('/im/signup', signup_data, follow=True)
836 478ece6c Kostas Papadimitriou
        r = cl_newuser.post('/im/signup', signup_data, follow=True)
837 478ece6c Kostas Papadimitriou
        self.assertEqual(r.status_code, 404)
838 478ece6c Kostas Papadimitriou
        newuser = User.objects.get(email="newuser@grnet.gr")
839 478ece6c Kostas Papadimitriou
        activation_link = newuser.get_activation_url()
840 478ece6c Kostas Papadimitriou
        self.assertTrue(academic_users.get(email='newuser@grnet.gr'))
841 478ece6c Kostas Papadimitriou
842 478ece6c Kostas Papadimitriou
        # new non-academic user
843 478ece6c Kostas Papadimitriou
        signup_data = {'first_name': 'Non Academic',
844 478ece6c Kostas Papadimitriou
                       'last_name': 'New User',
845 478ece6c Kostas Papadimitriou
                       'provider': 'local',
846 478ece6c Kostas Papadimitriou
                       'password1': 'password',
847 478ece6c Kostas Papadimitriou
                       'password2': 'password'}
848 478ece6c Kostas Papadimitriou
        signup_data['email'] = 'olduser@grnet.gr'
849 478ece6c Kostas Papadimitriou
        r = cl_newuser2.post('/im/signup', signup_data)
850 478ece6c Kostas Papadimitriou
        self.assertContains(r, 'There is already an account with this '
851 478ece6c Kostas Papadimitriou
                               'email address')
852 478ece6c Kostas Papadimitriou
        signup_data['email'] = 'newuser@grnet.gr'
853 478ece6c Kostas Papadimitriou
        r = cl_newuser2.post('/im/signup/', signup_data)
854 478ece6c Kostas Papadimitriou
        self.assertFalse(academic_users.filter(email='newuser@grnet.gr'))
855 478ece6c Kostas Papadimitriou
        r = self.client.get(activation_link, follow=True)
856 478ece6c Kostas Papadimitriou
        self.assertEqual(r.status_code, 400)
857 478ece6c Kostas Papadimitriou
        newuser = User.objects.get(email="newuser@grnet.gr")
858 478ece6c Kostas Papadimitriou
        self.assertFalse(newuser.activation_sent)
859 478ece6c Kostas Papadimitriou
        r = self.client.get(newuser.get_activation_url(), follow=True)
860 478ece6c Kostas Papadimitriou
        self.assertContains(r, "pending moderation")
861 478ece6c Kostas Papadimitriou
862 478ece6c Kostas Papadimitriou
        self.assertFalse(academic_users.filter(email='newuser@grnet.gr'))
863 478ece6c Kostas Papadimitriou
        r = cl_newuser.get('/im/login/shibboleth?', follow=True)
864 478ece6c Kostas Papadimitriou
        pending = Pending.objects.get()
865 478ece6c Kostas Papadimitriou
        identifier = pending.third_party_identifier
866 478ece6c Kostas Papadimitriou
        signup_data = {'third_party_identifier': identifier,
867 478ece6c Kostas Papadimitriou
                       'first_name': 'Academic',
868 478ece6c Kostas Papadimitriou
                       'third_party_token': pending.token,
869 478ece6c Kostas Papadimitriou
                       'last_name': 'New User',
870 478ece6c Kostas Papadimitriou
                       'provider': 'shibboleth'}
871 478ece6c Kostas Papadimitriou
        signup_data['email'] = 'newuser@grnet.gr'
872 478ece6c Kostas Papadimitriou
        r = cl_newuser.post('/im/signup', signup_data)
873 478ece6c Kostas Papadimitriou
        newuser = User.objects.get(email="newuser@grnet.gr")
874 478ece6c Kostas Papadimitriou
        self.assertTrue(newuser.activation_sent)
875 478ece6c Kostas Papadimitriou
        activation_link = newuser.get_activation_url()
876 478ece6c Kostas Papadimitriou
        self.assertTrue(academic_users.get(email='newuser@grnet.gr'))
877 478ece6c Kostas Papadimitriou
        r = cl_newuser.get(newuser.get_activation_url(), follow=True)
878 478ece6c Kostas Papadimitriou
        self.assertRedirects(r, '/im/landing')
879 478ece6c Kostas Papadimitriou
        newuser = User.objects.get(email="newuser@grnet.gr")
880 478ece6c Kostas Papadimitriou
        self.assertEqual(newuser.is_active, True)
881 478ece6c Kostas Papadimitriou
        self.assertEqual(newuser.email_verified, True)
882 478ece6c Kostas Papadimitriou
        cl_newuser.logout()
883 478ece6c Kostas Papadimitriou
884 478ece6c Kostas Papadimitriou
        # cannot reactivate if suspended
885 478ece6c Kostas Papadimitriou
        newuser.is_active = False
886 478ece6c Kostas Papadimitriou
        newuser.save()
887 478ece6c Kostas Papadimitriou
        r = cl_newuser.get(newuser.get_activation_url())
888 478ece6c Kostas Papadimitriou
        newuser = User.objects.get(email="newuser@grnet.gr")
889 478ece6c Kostas Papadimitriou
        self.assertFalse(newuser.is_active)
890 478ece6c Kostas Papadimitriou
891 478ece6c Kostas Papadimitriou
        # release suspension
892 478ece6c Kostas Papadimitriou
        newuser.is_active = True
893 478ece6c Kostas Papadimitriou
        newuser.save()
894 478ece6c Kostas Papadimitriou
895 478ece6c Kostas Papadimitriou
        cl_newuser.get('/im/login/shibboleth?', follow=True)
896 478ece6c Kostas Papadimitriou
        local = auth.get_provider('local', newuser)
897 478ece6c Kostas Papadimitriou
        self.assertEqual(local.get_add_policy, False)
898 478ece6c Kostas Papadimitriou
        self.assertEqual(local.get_login_policy, False)
899 478ece6c Kostas Papadimitriou
        r = cl_newuser.get(local.get_add_url, follow=True)
900 478ece6c Kostas Papadimitriou
        self.assertRedirects(r, '/im/profile')
901 478ece6c Kostas Papadimitriou
        self.assertContains(r, 'disabled for your')
902 478ece6c Kostas Papadimitriou
903 478ece6c Kostas Papadimitriou
        cl_olduser.login(username='olduser@grnet.gr', password="password")
904 478ece6c Kostas Papadimitriou
        r = cl_olduser.get('/im/profile', follow=True)
905 478ece6c Kostas Papadimitriou
        self.assertEqual(r.status_code, 200)
906 478ece6c Kostas Papadimitriou
        r = cl_olduser.get('/im/login/shibboleth?', follow=True)
907 478ece6c Kostas Papadimitriou
        self.assertContains(r, 'Your request is missing a unique token')
908 478ece6c Kostas Papadimitriou
        cl_olduser.set_tokens(eppn="newusereppn")
909 478ece6c Kostas Papadimitriou
        r = cl_olduser.get('/im/login/shibboleth?', follow=True)
910 478ece6c Kostas Papadimitriou
        self.assertContains(r, 'is already assigned to another user')
911 478ece6c Kostas Papadimitriou
        cl_olduser.set_tokens(eppn="oldusereppn")
912 478ece6c Kostas Papadimitriou
        r = cl_olduser.get('/im/login/shibboleth?', follow=True)
913 478ece6c Kostas Papadimitriou
        self.assertContains(r, 'Academic login enabled for this account')
914 478ece6c Kostas Papadimitriou
915 478ece6c Kostas Papadimitriou
        user = User.objects.get(email="olduser@grnet.gr")
916 478ece6c Kostas Papadimitriou
        shib_provider = user.get_auth_provider('shibboleth', 'oldusereppn')
917 478ece6c Kostas Papadimitriou
        local_provider = user.get_auth_provider('local')
918 478ece6c Kostas Papadimitriou
        self.assertEqual(shib_provider.get_remove_policy, True)
919 478ece6c Kostas Papadimitriou
        self.assertEqual(local_provider.get_remove_policy, True)
920 478ece6c Kostas Papadimitriou
921 478ece6c Kostas Papadimitriou
922 478ece6c Kostas Papadimitriou
        policy_only_academic = Profile.objects.add_policy('academic_strict2',
923 478ece6c Kostas Papadimitriou
                                                          'shibboleth',
924 478ece6c Kostas Papadimitriou
                                                          academic_group,
925 478ece6c Kostas Papadimitriou
                                                          remove=False)
926 478ece6c Kostas Papadimitriou
        user.groups.add(academic_group)
927 478ece6c Kostas Papadimitriou
        shib_provider = user.get_auth_provider('shibboleth', 'oldusereppn')
928 478ece6c Kostas Papadimitriou
        local_provider = user.get_auth_provider('local')
929 478ece6c Kostas Papadimitriou
        self.assertEqual(shib_provider.get_remove_policy, False)
930 478ece6c Kostas Papadimitriou
        self.assertEqual(local_provider.get_remove_policy, True)
931 478ece6c Kostas Papadimitriou
        self.assertEqual(local_provider.get_login_policy, False)
932 478ece6c Kostas Papadimitriou
933 478ece6c Kostas Papadimitriou
        cl_olduser.logout()
934 478ece6c Kostas Papadimitriou
        login_data = {'username': 'olduser@grnet.gr', 'password': 'password'}
935 478ece6c Kostas Papadimitriou
        r = cl_olduser.post('/im/local', login_data, follow=True)
936 478ece6c Kostas Papadimitriou
        self.assertContains(r, "href='/im/login/shibboleth'>Academic login")
937 9d20fe23 Kostas Papadimitriou
938 9d20fe23 Kostas Papadimitriou
939 478ece6c Kostas Papadimitriou
class TestAuthProvidersAPI(TestCase):
940 478ece6c Kostas Papadimitriou
    """
941 478ece6c Kostas Papadimitriou
    Test auth_providers module API
942 478ece6c Kostas Papadimitriou
    """
943 478ece6c Kostas Papadimitriou
944 478ece6c Kostas Papadimitriou
    @im_settings(IM_MODULES=['local', 'shibboleth'])
945 9d20fe23 Kostas Papadimitriou
    def test_create(self):
946 9d20fe23 Kostas Papadimitriou
        user = AstakosUser.objects.create(email="kpap@grnet.gr")
947 9d20fe23 Kostas Papadimitriou
        user2 = AstakosUser.objects.create(email="kpap2@grnet.gr")
948 9d20fe23 Kostas Papadimitriou
949 9d20fe23 Kostas Papadimitriou
        module = 'shibboleth'
950 9d20fe23 Kostas Papadimitriou
        identifier = 'SHIB_UUID'
951 9d20fe23 Kostas Papadimitriou
        provider_params = {
952 9d20fe23 Kostas Papadimitriou
            'affiliation': 'UNIVERSITY',
953 9d20fe23 Kostas Papadimitriou
            'info': {'age': 27}
954 9d20fe23 Kostas Papadimitriou
        }
955 9d20fe23 Kostas Papadimitriou
        provider = auth.get_provider(module, user2, identifier,
956 9d20fe23 Kostas Papadimitriou
                                     **provider_params)
957 9d20fe23 Kostas Papadimitriou
        provider.add_to_user()
958 9d20fe23 Kostas Papadimitriou
        provider = auth.get_provider(module, user, identifier,
959 9d20fe23 Kostas Papadimitriou
                                     **provider_params)
960 9d20fe23 Kostas Papadimitriou
        provider.add_to_user()
961 9d20fe23 Kostas Papadimitriou
        user.email_verified = True
962 9d20fe23 Kostas Papadimitriou
        user.save()
963 9d20fe23 Kostas Papadimitriou
        self.assertRaises(Exception, provider.add_to_user)
964 9d20fe23 Kostas Papadimitriou
        provider = user.get_auth_provider(module, identifier)
965 9d20fe23 Kostas Papadimitriou
        self.assertEqual(user.get_auth_provider(
966 9d20fe23 Kostas Papadimitriou
            module, identifier)._instance.info.get('age'), 27)
967 9d20fe23 Kostas Papadimitriou
968 9d20fe23 Kostas Papadimitriou
        module = 'local'
969 9d20fe23 Kostas Papadimitriou
        identifier = None
970 9d20fe23 Kostas Papadimitriou
        provider_params = {'auth_backend': 'ldap', 'info':
971 9d20fe23 Kostas Papadimitriou
                          {'office': 'A1'}}
972 9d20fe23 Kostas Papadimitriou
        provider = auth.get_provider(module, user, identifier,
973 9d20fe23 Kostas Papadimitriou
                                     **provider_params)
974 9d20fe23 Kostas Papadimitriou
        provider.add_to_user()
975 9d20fe23 Kostas Papadimitriou
        self.assertFalse(provider.get_add_policy)
976 9d20fe23 Kostas Papadimitriou
        self.assertRaises(Exception, provider.add_to_user)
977 9d20fe23 Kostas Papadimitriou
978 9d20fe23 Kostas Papadimitriou
        shib = user.get_auth_provider('shibboleth',
979 9d20fe23 Kostas Papadimitriou
                                      'SHIB_UUID')
980 9d20fe23 Kostas Papadimitriou
        self.assertTrue(shib.get_remove_policy)
981 9d20fe23 Kostas Papadimitriou
982 9d20fe23 Kostas Papadimitriou
        local = user.get_auth_provider('local')
983 9d20fe23 Kostas Papadimitriou
        self.assertTrue(local.get_remove_policy)
984 9d20fe23 Kostas Papadimitriou
985 9d20fe23 Kostas Papadimitriou
        local.remove_from_user()
986 9d20fe23 Kostas Papadimitriou
        self.assertFalse(shib.get_remove_policy)
987 9d20fe23 Kostas Papadimitriou
        self.assertRaises(Exception, shib.remove_from_user)
988 9d20fe23 Kostas Papadimitriou
989 478ece6c Kostas Papadimitriou
        provider = user.get_auth_providers()[0]
990 478ece6c Kostas Papadimitriou
        self.assertRaises(Exception, provider.add_to_user)
991 478ece6c Kostas Papadimitriou
992 478ece6c Kostas Papadimitriou
    @im_settings(IM_MODULES=['local', 'shibboleth'])
993 478ece6c Kostas Papadimitriou
    @shibboleth_settings(ADD_GROUPS_POLICY=['group1', 'group2'])
994 478ece6c Kostas Papadimitriou
    @shibboleth_settings(CREATION_GROUPS_POLICY=['group-create', 'group1',
995 478ece6c Kostas Papadimitriou
                                                 'group2'])
996 478ece6c Kostas Papadimitriou
    @localauth_settings(ADD_GROUPS_POLICY=['localgroup'])
997 478ece6c Kostas Papadimitriou
    @localauth_settings(CREATION_GROUPS_POLICY=['localgroup-create',
998 478ece6c Kostas Papadimitriou
                                                'group-create'])
999 478ece6c Kostas Papadimitriou
    def test_add_groups(self):
1000 478ece6c Kostas Papadimitriou
        user = AstakosUser.objects.create(email="kpap@grnet.gr")
1001 478ece6c Kostas Papadimitriou
        provider = auth.get_provider('shibboleth', user, 'test123')
1002 478ece6c Kostas Papadimitriou
        provider.add_to_user()
1003 478ece6c Kostas Papadimitriou
        user = AstakosUser.objects.get()
1004 2a88057d Christos Stavrakakis
        self.assertEqual(sorted(user.groups.values_list('name', flat=True)),
1005 2a88057d Christos Stavrakakis
                         sorted([u'group1', u'group2', u'group-create']))
1006 478ece6c Kostas Papadimitriou
1007 478ece6c Kostas Papadimitriou
        local = auth.get_provider('local', user)
1008 478ece6c Kostas Papadimitriou
        local.add_to_user()
1009 478ece6c Kostas Papadimitriou
        provider = user.get_auth_provider('shibboleth')
1010 478ece6c Kostas Papadimitriou
        self.assertEqual(provider.get_add_groups_policy, ['group1', 'group2'])
1011 478ece6c Kostas Papadimitriou
        provider.remove_from_user()
1012 478ece6c Kostas Papadimitriou
        user = AstakosUser.objects.get()
1013 478ece6c Kostas Papadimitriou
        self.assertEqual(len(user.get_auth_providers()), 1)
1014 2a88057d Christos Stavrakakis
        self.assertEqual(sorted(user.groups.values_list('name', flat=True)),
1015 2a88057d Christos Stavrakakis
                         sorted([u'group-create', u'localgroup']))
1016 478ece6c Kostas Papadimitriou
1017 478ece6c Kostas Papadimitriou
        local = user.get_auth_provider('local')
1018 478ece6c Kostas Papadimitriou
        self.assertRaises(Exception, local.remove_from_user)
1019 478ece6c Kostas Papadimitriou
        provider = auth.get_provider('shibboleth', user, 'test123')
1020 478ece6c Kostas Papadimitriou
        provider.add_to_user()
1021 478ece6c Kostas Papadimitriou
        user = AstakosUser.objects.get()
1022 2a88057d Christos Stavrakakis
        self.assertEqual(sorted(user.groups.values_list('name', flat=True)),
1023 2a88057d Christos Stavrakakis
                         sorted([u'group-create', u'group1', u'group2',
1024 2a88057d Christos Stavrakakis
                                 u'localgroup']))
1025 478ece6c Kostas Papadimitriou
1026 478ece6c Kostas Papadimitriou
    @im_settings(IM_MODULES=['local', 'shibboleth'])
1027 9d20fe23 Kostas Papadimitriou
    def test_policies(self):
1028 9d20fe23 Kostas Papadimitriou
        group_old, created = Group.objects.get_or_create(name='olduser')
1029 9d20fe23 Kostas Papadimitriou
1030 9d20fe23 Kostas Papadimitriou
        astakos_settings.MODERATION_ENABLED = True
1031 9d20fe23 Kostas Papadimitriou
        settings.ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_CREATION_GROUPS_POLICY = \
1032 9d20fe23 Kostas Papadimitriou
            ['academic-user']
1033 9d20fe23 Kostas Papadimitriou
        settings.ASTAKOS_AUTH_PROVIDER_GOOGLE_ADD_GROUPS_POLICY = \
1034 9d20fe23 Kostas Papadimitriou
            ['google-user']
1035 9d20fe23 Kostas Papadimitriou
1036 9d20fe23 Kostas Papadimitriou
        user = AstakosUser.objects.create(email="kpap@grnet.gr")
1037 9d20fe23 Kostas Papadimitriou
        user.groups.add(group_old)
1038 9d20fe23 Kostas Papadimitriou
        user.add_auth_provider('local')
1039 9d20fe23 Kostas Papadimitriou
1040 9d20fe23 Kostas Papadimitriou
        user2 = AstakosUser.objects.create(email="kpap2@grnet.gr")
1041 9d20fe23 Kostas Papadimitriou
        user2.add_auth_provider('shibboleth', identifier='shibid')
1042 9d20fe23 Kostas Papadimitriou
1043 9d20fe23 Kostas Papadimitriou
        user3 = AstakosUser.objects.create(email="kpap3@grnet.gr")
1044 9d20fe23 Kostas Papadimitriou
        user3.groups.add(group_old)
1045 9d20fe23 Kostas Papadimitriou
        user3.add_auth_provider('local')
1046 9d20fe23 Kostas Papadimitriou
        user3.add_auth_provider('shibboleth', identifier='1234')
1047 9d20fe23 Kostas Papadimitriou
1048 9d20fe23 Kostas Papadimitriou
        self.assertTrue(user2.groups.get(name='academic-user'))
1049 9d20fe23 Kostas Papadimitriou
        self.assertFalse(user2.groups.filter(name='olduser').count())
1050 9d20fe23 Kostas Papadimitriou
1051 9d20fe23 Kostas Papadimitriou
        local = auth_providers.get_provider('local')
1052 9d20fe23 Kostas Papadimitriou
        self.assertTrue(local.get_add_policy)
1053 9d20fe23 Kostas Papadimitriou
1054 9d20fe23 Kostas Papadimitriou
        academic_group = Group.objects.get(name='academic-user')
1055 9d20fe23 Kostas Papadimitriou
        AuthProviderPolicyProfile.objects.add_policy('academic', 'shibboleth',
1056 9d20fe23 Kostas Papadimitriou
                                                     academic_group,
1057 9d20fe23 Kostas Papadimitriou
                                                     exclusive=True,
1058 9d20fe23 Kostas Papadimitriou
                                                     add=False,
1059 9d20fe23 Kostas Papadimitriou
                                                     login=False)
1060 9d20fe23 Kostas Papadimitriou
        AuthProviderPolicyProfile.objects.add_policy('academic', 'shibboleth',
1061 9d20fe23 Kostas Papadimitriou
                                                     academic_group,
1062 9d20fe23 Kostas Papadimitriou
                                                     exclusive=True,
1063 9d20fe23 Kostas Papadimitriou
                                                     login=False,
1064 9d20fe23 Kostas Papadimitriou
                                                     add=False)
1065 9d20fe23 Kostas Papadimitriou
        # no duplicate entry gets created
1066 9d20fe23 Kostas Papadimitriou
        self.assertEqual(academic_group.authpolicy_profiles.count(), 1)
1067 9d20fe23 Kostas Papadimitriou
1068 9d20fe23 Kostas Papadimitriou
        self.assertEqual(user2.authpolicy_profiles.count(), 0)
1069 9d20fe23 Kostas Papadimitriou
        AuthProviderPolicyProfile.objects.add_policy('academic', 'shibboleth',
1070 9d20fe23 Kostas Papadimitriou
                                                     user2,
1071 9d20fe23 Kostas Papadimitriou
                                                     remove=False)
1072 9d20fe23 Kostas Papadimitriou
        self.assertEqual(user2.authpolicy_profiles.count(), 1)
1073 9d20fe23 Kostas Papadimitriou
1074 9d20fe23 Kostas Papadimitriou
        local = auth_providers.get_provider('local', user2)
1075 9d20fe23 Kostas Papadimitriou
        google = auth_providers.get_provider('google', user2)
1076 9d20fe23 Kostas Papadimitriou
        shibboleth = auth_providers.get_provider('shibboleth', user2)
1077 9d20fe23 Kostas Papadimitriou
        self.assertTrue(shibboleth.get_login_policy)
1078 9d20fe23 Kostas Papadimitriou
        self.assertFalse(shibboleth.get_remove_policy)
1079 9d20fe23 Kostas Papadimitriou
        self.assertFalse(local.get_add_policy)
1080 9d20fe23 Kostas Papadimitriou
        self.assertFalse(local.get_add_policy)
1081 9d20fe23 Kostas Papadimitriou
        self.assertFalse(google.get_add_policy)
1082 9d20fe23 Kostas Papadimitriou
1083 9d20fe23 Kostas Papadimitriou
        user2.groups.remove(Group.objects.get(name='academic-user'))
1084 9d20fe23 Kostas Papadimitriou
        self.assertTrue(local.get_add_policy)
1085 9d20fe23 Kostas Papadimitriou
        self.assertTrue(google.get_add_policy)
1086 9d20fe23 Kostas Papadimitriou
        user2.groups.add(Group.objects.get(name='academic-user'))
1087 9d20fe23 Kostas Papadimitriou
1088 9d20fe23 Kostas Papadimitriou
        AuthProviderPolicyProfile.objects.add_policy('academic', 'shibboleth',
1089 9d20fe23 Kostas Papadimitriou
                                                     user2,
1090 9d20fe23 Kostas Papadimitriou
                                                     exclusive=True,
1091 9d20fe23 Kostas Papadimitriou
                                                     add=True)
1092 9d20fe23 Kostas Papadimitriou
        self.assertTrue(local.get_add_policy)
1093 9d20fe23 Kostas Papadimitriou
        self.assertTrue(google.get_add_policy)
1094 9d20fe23 Kostas Papadimitriou
1095 9d20fe23 Kostas Papadimitriou
        settings.ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_AUTOMODERATE_POLICY = True
1096 9d20fe23 Kostas Papadimitriou
        self.assertFalse(local.get_automoderate_policy)
1097 9d20fe23 Kostas Papadimitriou
        self.assertFalse(google.get_automoderate_policy)
1098 9d20fe23 Kostas Papadimitriou
        self.assertTrue(shibboleth.get_automoderate_policy)
1099 9d20fe23 Kostas Papadimitriou
1100 9d20fe23 Kostas Papadimitriou
        for s in ['SHIBBOLETH_CREATION_GROUPS_POLICY',
1101 9d20fe23 Kostas Papadimitriou
                  'GOOGLE_ADD_GROUPS_POLICY']:
1102 9d20fe23 Kostas Papadimitriou
            delattr(settings, 'ASTAKOS_AUTH_PROVIDER_%s' % s)
1103 478ece6c Kostas Papadimitriou
1104 478ece6c Kostas Papadimitriou
1105 478ece6c Kostas Papadimitriou
    @shibboleth_settings(CREATE_POLICY=True)
1106 478ece6c Kostas Papadimitriou
    @im_settings(IM_MODULES=['local', 'shibboleth'])
1107 478ece6c Kostas Papadimitriou
    def test_create_http(self):
1108 478ece6c Kostas Papadimitriou
        # this should be wrapped inside a transaction
1109 478ece6c Kostas Papadimitriou
        user = AstakosUser(email="test@test.com")
1110 478ece6c Kostas Papadimitriou
        user.save()
1111 478ece6c Kostas Papadimitriou
        provider = auth_providers.get_provider('shibboleth', user,
1112 478ece6c Kostas Papadimitriou
                                               'test@academia.test')
1113 478ece6c Kostas Papadimitriou
        provider.add_to_user()
1114 478ece6c Kostas Papadimitriou
        user.get_auth_provider('shibboleth', 'test@academia.test')
1115 478ece6c Kostas Papadimitriou
        provider = auth_providers.get_provider('local', user)
1116 478ece6c Kostas Papadimitriou
        provider.add_to_user()
1117 478ece6c Kostas Papadimitriou
        user.get_auth_provider('local')
1118 478ece6c Kostas Papadimitriou
1119 478ece6c Kostas Papadimitriou
        settings.ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_CREATE_POLICY = False
1120 478ece6c Kostas Papadimitriou
        user = AstakosUser(email="test2@test.com")
1121 478ece6c Kostas Papadimitriou
        user.save()
1122 478ece6c Kostas Papadimitriou
        provider = auth_providers.get_provider('shibboleth', user,
1123 478ece6c Kostas Papadimitriou
                                               'test@shibboleth.com',
1124 478ece6c Kostas Papadimitriou
                                               **{'info': {'name':
1125 478ece6c Kostas Papadimitriou
                                                                'User Test'}})
1126 478ece6c Kostas Papadimitriou
        self.assertFalse(provider.get_create_policy)
1127 478ece6c Kostas Papadimitriou
        settings.ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_CREATE_POLICY = True
1128 478ece6c Kostas Papadimitriou
        self.assertTrue(provider.get_create_policy)
1129 478ece6c Kostas Papadimitriou
        academic = provider.add_to_user()
1130 478ece6c Kostas Papadimitriou
1131 478ece6c Kostas Papadimitriou
    @im_settings(IM_MODULES=['local', 'shibboleth'])
1132 478ece6c Kostas Papadimitriou
    @shibboleth_settings(LIMIT_POLICY=2)
1133 478ece6c Kostas Papadimitriou
    def test_policies(self):
1134 478ece6c Kostas Papadimitriou
        user = get_local_user('kpap@grnet.gr')
1135 478ece6c Kostas Papadimitriou
        user.add_auth_provider('shibboleth', identifier='1234')
1136 478ece6c Kostas Papadimitriou
        user.add_auth_provider('shibboleth', identifier='12345')
1137 478ece6c Kostas Papadimitriou
1138 478ece6c Kostas Papadimitriou
        # default limit is 1
1139 478ece6c Kostas Papadimitriou
        local = user.get_auth_provider('local')
1140 478ece6c Kostas Papadimitriou
        self.assertEqual(local.get_add_policy, False)
1141 478ece6c Kostas Papadimitriou
1142 478ece6c Kostas Papadimitriou
        settings.ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_LIMIT_POLICY = 3
1143 478ece6c Kostas Papadimitriou
        academic = user.get_auth_provider('shibboleth',
1144 478ece6c Kostas Papadimitriou
                                          identifier='1234')
1145 478ece6c Kostas Papadimitriou
        self.assertEqual(academic.get_add_policy, False)
1146 478ece6c Kostas Papadimitriou
        newacademic = auth_providers.get_provider('shibboleth', user,
1147 478ece6c Kostas Papadimitriou
                                                  identifier='123456')
1148 478ece6c Kostas Papadimitriou
        self.assertEqual(newacademic.get_add_policy, True)
1149 478ece6c Kostas Papadimitriou
        user.add_auth_provider('shibboleth', identifier='123456')
1150 478ece6c Kostas Papadimitriou
        self.assertEqual(academic.get_add_policy, False)
1151 478ece6c Kostas Papadimitriou
        settings.ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_LIMIT_POLICY = 1
1152 478ece6c Kostas Papadimitriou
1153 478ece6c Kostas Papadimitriou
    @im_settings(IM_MODULES=['local', 'shibboleth'])
1154 478ece6c Kostas Papadimitriou
    @shibboleth_settings(LIMIT_POLICY=2)
1155 478ece6c Kostas Papadimitriou
    def test_messages(self):
1156 478ece6c Kostas Papadimitriou
        user = get_local_user('kpap@grnet.gr')
1157 478ece6c Kostas Papadimitriou
        user.add_auth_provider('shibboleth', identifier='1234')
1158 478ece6c Kostas Papadimitriou
        user.add_auth_provider('shibboleth', identifier='12345')
1159 478ece6c Kostas Papadimitriou
        provider = auth_providers.get_provider('shibboleth')
1160 478ece6c Kostas Papadimitriou
        self.assertEqual(provider.get_message('title'), 'Academic')
1161 478ece6c Kostas Papadimitriou
        settings.ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_TITLE = 'New title'
1162 478ece6c Kostas Papadimitriou
        # regenerate messages cache
1163 478ece6c Kostas Papadimitriou
        provider = auth_providers.get_provider('shibboleth')
1164 478ece6c Kostas Papadimitriou
        self.assertEqual(provider.get_message('title'), 'New title')
1165 478ece6c Kostas Papadimitriou
        self.assertEqual(provider.get_message('login_title'),
1166 478ece6c Kostas Papadimitriou
                         'New title LOGIN')
1167 478ece6c Kostas Papadimitriou
        self.assertEqual(provider.get_login_title_msg, 'New title LOGIN')
1168 478ece6c Kostas Papadimitriou
        self.assertEqual(provider.get_module_icon,
1169 478ece6c Kostas Papadimitriou
                         settings.MEDIA_URL + 'im/auth/icons/shibboleth.png')
1170 478ece6c Kostas Papadimitriou
        self.assertEqual(provider.get_module_medium_icon,
1171 478ece6c Kostas Papadimitriou
                         settings.MEDIA_URL +
1172 478ece6c Kostas Papadimitriou
                         'im/auth/icons-medium/shibboleth.png')
1173 478ece6c Kostas Papadimitriou
1174 478ece6c Kostas Papadimitriou
        settings.ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_TITLE = None
1175 478ece6c Kostas Papadimitriou
        provider = auth_providers.get_provider('shibboleth', user, '12345')
1176 478ece6c Kostas Papadimitriou
        self.assertEqual(provider.get_method_details_msg,
1177 478ece6c Kostas Papadimitriou
                         'Account: 12345')
1178 478ece6c Kostas Papadimitriou
        provider = auth_providers.get_provider('shibboleth', user, '1234')
1179 478ece6c Kostas Papadimitriou
        self.assertEqual(provider.get_method_details_msg,
1180 478ece6c Kostas Papadimitriou
                         'Account: 1234')
1181 478ece6c Kostas Papadimitriou
1182 478ece6c Kostas Papadimitriou
        provider = auth_providers.get_provider('shibboleth', user, '1234')
1183 478ece6c Kostas Papadimitriou
        self.assertEqual(provider.get_not_active_msg,
1184 478ece6c Kostas Papadimitriou
                         "'Academic login' is disabled.")
1185 478ece6c Kostas Papadimitriou
1186 478ece6c Kostas Papadimitriou
    @im_settings(IM_MODULES=['local', 'shibboleth'])
1187 478ece6c Kostas Papadimitriou
    @shibboleth_settings(LIMIT_POLICY=2)
1188 478ece6c Kostas Papadimitriou
    def test_templates(self):
1189 478ece6c Kostas Papadimitriou
        user = get_local_user('kpap@grnet.gr')
1190 478ece6c Kostas Papadimitriou
        user.add_auth_provider('shibboleth', identifier='1234')
1191 478ece6c Kostas Papadimitriou
        user.add_auth_provider('shibboleth', identifier='12345')
1192 478ece6c Kostas Papadimitriou
1193 478ece6c Kostas Papadimitriou
        provider = auth_providers.get_provider('shibboleth')
1194 478ece6c Kostas Papadimitriou
        self.assertEqual(provider.get_template('login'),
1195 478ece6c Kostas Papadimitriou
                         'im/auth/shibboleth_login.html')
1196 478ece6c Kostas Papadimitriou
        provider = auth_providers.get_provider('google')
1197 478ece6c Kostas Papadimitriou
        self.assertEqual(provider.get_template('login'),
1198 478ece6c Kostas Papadimitriou
                         'im/auth/generic_login.html')
1199 478ece6c Kostas Papadimitriou
1200 478ece6c Kostas Papadimitriou
1201 450c7fb0 Kostas Papadimitriou
class TestProjects(TestCase):
1202 450c7fb0 Kostas Papadimitriou
    """
1203 450c7fb0 Kostas Papadimitriou
    Test projects.
1204 450c7fb0 Kostas Papadimitriou
    """
1205 450c7fb0 Kostas Papadimitriou
    def setUp(self):
1206 ba886e03 Kostas Papadimitriou
        # astakos resources
1207 ba886e03 Kostas Papadimitriou
        self.astakos_service = Service.objects.create(name="astakos",
1208 ba886e03 Kostas Papadimitriou
                                                      api_url="/astakos/api/")
1209 ba886e03 Kostas Papadimitriou
        self.resource = Resource.objects.create(name="astakos.pending_app",
1210 ba886e03 Kostas Papadimitriou
                                                uplimit=0,
1211 37d59b27 Kostas Papadimitriou
                                                allow_in_projects=False,
1212 ba886e03 Kostas Papadimitriou
                                                service=self.astakos_service)
1213 ba886e03 Kostas Papadimitriou
1214 ba886e03 Kostas Papadimitriou
        # custom service resources
1215 450c7fb0 Kostas Papadimitriou
        self.service = Service.objects.create(name="service1",
1216 450c7fb0 Kostas Papadimitriou
                                              api_url="http://service.api")
1217 450c7fb0 Kostas Papadimitriou
        self.resource = Resource.objects.create(name="service1.resource",
1218 0a7a4104 Kostas Papadimitriou
                                                uplimit=100,
1219 0a7a4104 Kostas Papadimitriou
                                                service=self.service)
1220 450c7fb0 Kostas Papadimitriou
        self.admin = get_local_user("projects-admin@synnefo.org")
1221 450c7fb0 Kostas Papadimitriou
        self.admin.uuid = 'uuid1'
1222 450c7fb0 Kostas Papadimitriou
        self.admin.save()
1223 450c7fb0 Kostas Papadimitriou
1224 450c7fb0 Kostas Papadimitriou
        self.user = get_local_user("user@synnefo.org")
1225 450c7fb0 Kostas Papadimitriou
        self.member = get_local_user("member@synnefo.org")
1226 450c7fb0 Kostas Papadimitriou
        self.member2 = get_local_user("member2@synnefo.org")
1227 450c7fb0 Kostas Papadimitriou
1228 450c7fb0 Kostas Papadimitriou
        self.admin_client = get_user_client("projects-admin@synnefo.org")
1229 450c7fb0 Kostas Papadimitriou
        self.user_client = get_user_client("user@synnefo.org")
1230 450c7fb0 Kostas Papadimitriou
        self.member_client = get_user_client("member@synnefo.org")
1231 450c7fb0 Kostas Papadimitriou
        self.member2_client = get_user_client("member2@synnefo.org")
1232 450c7fb0 Kostas Papadimitriou
1233 ba886e03 Kostas Papadimitriou
        quotas.qh_sync_users(AstakosUser.objects.all())
1234 ba886e03 Kostas Papadimitriou
1235 ba886e03 Kostas Papadimitriou
    @im_settings(PROJECT_ADMINS=['uuid1'])
1236 450c7fb0 Kostas Papadimitriou
    def test_application_limit(self):
1237 450c7fb0 Kostas Papadimitriou
        # user cannot create a project
1238 450c7fb0 Kostas Papadimitriou
        r = self.user_client.get(reverse('project_add'), follow=True)
1239 450c7fb0 Kostas Papadimitriou
        self.assertRedirects(r, reverse('project_list'))
1240 450c7fb0 Kostas Papadimitriou
        self.assertContains(r, "You are not allowed to create a new project")
1241 450c7fb0 Kostas Papadimitriou
1242 450c7fb0 Kostas Papadimitriou
        # but admin can
1243 450c7fb0 Kostas Papadimitriou
        r = self.admin_client.get(reverse('project_add'), follow=True)
1244 450c7fb0 Kostas Papadimitriou
        self.assertRedirects(r, reverse('project_add'))
1245 450c7fb0 Kostas Papadimitriou
1246 ba886e03 Kostas Papadimitriou
    @im_settings(PROJECT_ADMINS=['uuid1'])
1247 37d59b27 Kostas Papadimitriou
    def test_allow_in_project(self):
1248 37d59b27 Kostas Papadimitriou
        dfrom = datetime.now()
1249 37d59b27 Kostas Papadimitriou
        dto = datetime.now() + timedelta(days=30)
1250 37d59b27 Kostas Papadimitriou
1251 37d59b27 Kostas Papadimitriou
        # astakos.pending_uplimit allow_in_project flag is False
1252 37d59b27 Kostas Papadimitriou
        # we shouldn't be able to create a project application using this
1253 37d59b27 Kostas Papadimitriou
        # resource.
1254 37d59b27 Kostas Papadimitriou
        application_data = {
1255 37d59b27 Kostas Papadimitriou
            'name': 'project.synnefo.org',
1256 37d59b27 Kostas Papadimitriou
            'homepage': 'https://www.synnefo.org',
1257 37d59b27 Kostas Papadimitriou
            'start_date': dfrom.strftime("%Y-%m-%d"),
1258 37d59b27 Kostas Papadimitriou
            'end_date': dto.strftime("%Y-%m-%d"),
1259 37d59b27 Kostas Papadimitriou
            'member_join_policy': 2,
1260 37d59b27 Kostas Papadimitriou
            'member_leave_policy': 1,
1261 37d59b27 Kostas Papadimitriou
            'service1.resource_uplimit': 100,
1262 37d59b27 Kostas Papadimitriou
            'is_selected_service1.resource': "1",
1263 37d59b27 Kostas Papadimitriou
            'astakos.pending_app_uplimit': 100,
1264 37d59b27 Kostas Papadimitriou
            'is_selected_accounts': "1",
1265 37d59b27 Kostas Papadimitriou
            'user': self.user.pk
1266 37d59b27 Kostas Papadimitriou
        }
1267 37d59b27 Kostas Papadimitriou
        form = forms.ProjectApplicationForm(data=application_data)
1268 37d59b27 Kostas Papadimitriou
        # form is invalid
1269 37d59b27 Kostas Papadimitriou
        self.assertEqual(form.is_valid(), False)
1270 37d59b27 Kostas Papadimitriou
1271 37d59b27 Kostas Papadimitriou
        del application_data['astakos.pending_app_uplimit']
1272 37d59b27 Kostas Papadimitriou
        del application_data['is_selected_accounts']
1273 37d59b27 Kostas Papadimitriou
        form = forms.ProjectApplicationForm(data=application_data)
1274 37d59b27 Kostas Papadimitriou
        self.assertEqual(form.is_valid(), True)
1275 37d59b27 Kostas Papadimitriou
1276 37d59b27 Kostas Papadimitriou
    @im_settings(PROJECT_ADMINS=['uuid1'])
1277 450c7fb0 Kostas Papadimitriou
    def test_applications(self):
1278 ba886e03 Kostas Papadimitriou
        # let user have 2 pending applications
1279 764d99c4 Giorgos Korfiatis
        quotas.add_base_quota(self.user, 'astakos.pending_app', 2)
1280 ba886e03 Kostas Papadimitriou
1281 450c7fb0 Kostas Papadimitriou
        r = self.user_client.get(reverse('project_add'), follow=True)
1282 450c7fb0 Kostas Papadimitriou
        self.assertRedirects(r, reverse('project_add'))
1283 450c7fb0 Kostas Papadimitriou
1284 450c7fb0 Kostas Papadimitriou
        # user fills the project application form
1285 450c7fb0 Kostas Papadimitriou
        post_url = reverse('project_add') + '?verify=1'
1286 450c7fb0 Kostas Papadimitriou
        dfrom = datetime.now()
1287 450c7fb0 Kostas Papadimitriou
        dto = datetime.now() + timedelta(days=30)
1288 450c7fb0 Kostas Papadimitriou
        application_data = {
1289 450c7fb0 Kostas Papadimitriou
            'name': 'project.synnefo.org',
1290 450c7fb0 Kostas Papadimitriou
            'homepage': 'https://www.synnefo.org',
1291 450c7fb0 Kostas Papadimitriou
            'start_date': dfrom.strftime("%Y-%m-%d"),
1292 450c7fb0 Kostas Papadimitriou
            'end_date': dto.strftime("%Y-%m-%d"),
1293 450c7fb0 Kostas Papadimitriou
            'member_join_policy': 2,
1294 450c7fb0 Kostas Papadimitriou
            'member_leave_policy': 1,
1295 450c7fb0 Kostas Papadimitriou
            'service1.resource_uplimit': 100,
1296 37d59b27 Kostas Papadimitriou
            'is_selected_service1.resource': "1",
1297 450c7fb0 Kostas Papadimitriou
            'user': self.user.pk
1298 450c7fb0 Kostas Papadimitriou
        }
1299 450c7fb0 Kostas Papadimitriou
        r = self.user_client.post(post_url, data=application_data, follow=True)
1300 450c7fb0 Kostas Papadimitriou
        self.assertEqual(r.status_code, 200)
1301 450c7fb0 Kostas Papadimitriou
        self.assertEqual(r.context['form'].is_valid(), True)
1302 450c7fb0 Kostas Papadimitriou
1303 450c7fb0 Kostas Papadimitriou
        # confirm request
1304 450c7fb0 Kostas Papadimitriou
        post_url = reverse('project_add') + '?verify=0&edit=0'
1305 450c7fb0 Kostas Papadimitriou
        r = self.user_client.post(post_url, data=application_data, follow=True)
1306 450c7fb0 Kostas Papadimitriou
        self.assertContains(r, "The project application has been received")
1307 450c7fb0 Kostas Papadimitriou
        self.assertRedirects(r, reverse('project_list'))
1308 450c7fb0 Kostas Papadimitriou
        self.assertEqual(ProjectApplication.objects.count(), 1)
1309 450c7fb0 Kostas Papadimitriou
        app1_id = ProjectApplication.objects.filter().order_by('pk')[0].pk
1310 450c7fb0 Kostas Papadimitriou
1311 450c7fb0 Kostas Papadimitriou
        # create another one
1312 450c7fb0 Kostas Papadimitriou
        application_data['name'] = 'project2.synnefo.org'
1313 450c7fb0 Kostas Papadimitriou
        r = self.user_client.post(post_url, data=application_data, follow=True)
1314 450c7fb0 Kostas Papadimitriou
        app2_id = ProjectApplication.objects.filter().order_by('pk')[1].pk
1315 450c7fb0 Kostas Papadimitriou
1316 450c7fb0 Kostas Papadimitriou
        # no more applications (LIMIT is 2)
1317 450c7fb0 Kostas Papadimitriou
        r = self.user_client.get(reverse('project_add'), follow=True)
1318 450c7fb0 Kostas Papadimitriou
        self.assertRedirects(r, reverse('project_list'))
1319 450c7fb0 Kostas Papadimitriou
        self.assertContains(r, "You are not allowed to create a new project")
1320 450c7fb0 Kostas Papadimitriou
1321 450c7fb0 Kostas Papadimitriou
        # login
1322 450c7fb0 Kostas Papadimitriou
        self.admin_client.get(reverse("edit_profile"))
1323 450c7fb0 Kostas Papadimitriou
        # admin approves
1324 450c7fb0 Kostas Papadimitriou
        r = self.admin_client.post(reverse('project_app_approve',
1325 450c7fb0 Kostas Papadimitriou
                                           kwargs={'application_id': app1_id}),
1326 450c7fb0 Kostas Papadimitriou
                                   follow=True)
1327 450c7fb0 Kostas Papadimitriou
        self.assertEqual(r.status_code, 200)
1328 450c7fb0 Kostas Papadimitriou
1329 450c7fb0 Kostas Papadimitriou
        # project created
1330 450c7fb0 Kostas Papadimitriou
        self.assertEqual(Project.objects.count(), 1)
1331 450c7fb0 Kostas Papadimitriou
1332 450c7fb0 Kostas Papadimitriou
        # login
1333 450c7fb0 Kostas Papadimitriou
        self.member_client.get(reverse("edit_profile"))
1334 450c7fb0 Kostas Papadimitriou
        # cannot join app2 (not approved yet)
1335 450c7fb0 Kostas Papadimitriou
        join_url = reverse("project_join", kwargs={'chain_id': app2_id})
1336 450c7fb0 Kostas Papadimitriou
        r = self.member_client.post(join_url, follow=True)
1337 450c7fb0 Kostas Papadimitriou
        self.assertEqual(r.status_code, 403)
1338 450c7fb0 Kostas Papadimitriou
1339 450c7fb0 Kostas Papadimitriou
        # can join app1
1340 450c7fb0 Kostas Papadimitriou
        self.member_client.get(reverse("edit_profile"))
1341 450c7fb0 Kostas Papadimitriou
        join_url = reverse("project_join", kwargs={'chain_id': app1_id})
1342 450c7fb0 Kostas Papadimitriou
        r = self.member_client.post(join_url, follow=True)
1343 450c7fb0 Kostas Papadimitriou
        self.assertEqual(r.status_code, 200)
1344 450c7fb0 Kostas Papadimitriou
1345 5dcf6618 Giorgos Korfiatis
        memberships = ProjectMembership.objects.all()
1346 5dcf6618 Giorgos Korfiatis
        self.assertEqual(len(memberships), 1)
1347 5dcf6618 Giorgos Korfiatis
        memb_id = memberships[0].id
1348 450c7fb0 Kostas Papadimitriou
1349 450c7fb0 Kostas Papadimitriou
        reject_member_url = reverse('project_reject_member',
1350 2a88057d Christos Stavrakakis
                                    kwargs={'chain_id': app1_id, 'memb_id':
1351 5dcf6618 Giorgos Korfiatis
                                            memb_id})
1352 450c7fb0 Kostas Papadimitriou
        accept_member_url = reverse('project_accept_member',
1353 2a88057d Christos Stavrakakis
                                    kwargs={'chain_id': app1_id, 'memb_id':
1354 5dcf6618 Giorgos Korfiatis
                                            memb_id})
1355 450c7fb0 Kostas Papadimitriou
1356 450c7fb0 Kostas Papadimitriou
        # only project owner is allowed to reject
1357 450c7fb0 Kostas Papadimitriou
        r = self.member_client.post(reject_member_url, follow=True)
1358 450c7fb0 Kostas Papadimitriou
        self.assertContains(r, "You do not have the permissions")
1359 450c7fb0 Kostas Papadimitriou
        self.assertEqual(r.status_code, 200)
1360 450c7fb0 Kostas Papadimitriou
1361 450c7fb0 Kostas Papadimitriou
        # user (owns project) rejects membership
1362 450c7fb0 Kostas Papadimitriou
        r = self.user_client.post(reject_member_url, follow=True)
1363 450c7fb0 Kostas Papadimitriou
        self.assertEqual(ProjectMembership.objects.count(), 0)
1364 450c7fb0 Kostas Papadimitriou
1365 450c7fb0 Kostas Papadimitriou
        # user rejoins
1366 450c7fb0 Kostas Papadimitriou
        self.member_client.get(reverse("edit_profile"))
1367 450c7fb0 Kostas Papadimitriou
        join_url = reverse("project_join", kwargs={'chain_id': app1_id})
1368 450c7fb0 Kostas Papadimitriou
        r = self.member_client.post(join_url, follow=True)
1369 450c7fb0 Kostas Papadimitriou
        self.assertEqual(r.status_code, 200)
1370 450c7fb0 Kostas Papadimitriou
        self.assertEqual(ProjectMembership.objects.count(), 1)
1371 450c7fb0 Kostas Papadimitriou
1372 450c7fb0 Kostas Papadimitriou
        # user (owns project) accepts membership
1373 450c7fb0 Kostas Papadimitriou
        r = self.user_client.post(accept_member_url, follow=True)
1374 450c7fb0 Kostas Papadimitriou
        self.assertEqual(ProjectMembership.objects.count(), 1)
1375 450c7fb0 Kostas Papadimitriou
        membership = ProjectMembership.objects.get()
1376 450c7fb0 Kostas Papadimitriou
        self.assertEqual(membership.state, ProjectMembership.ACCEPTED)
1377 450c7fb0 Kostas Papadimitriou
1378 450c7fb0 Kostas Papadimitriou
        user_quotas = quotas.get_users_quotas([self.member])
1379 450c7fb0 Kostas Papadimitriou
        resource = 'service1.resource'
1380 450c7fb0 Kostas Papadimitriou
        newlimit = user_quotas[self.member.uuid]['system'][resource]['limit']
1381 450c7fb0 Kostas Papadimitriou
        # 100 from initial uplimit + 100 from project
1382 450c7fb0 Kostas Papadimitriou
        self.assertEqual(newlimit, 200)
1383 450c7fb0 Kostas Papadimitriou
1384 450c7fb0 Kostas Papadimitriou
        remove_member_url = reverse('project_remove_member',
1385 2a88057d Christos Stavrakakis
                                    kwargs={'chain_id': app1_id, 'memb_id':
1386 5dcf6618 Giorgos Korfiatis
                                            membership.id})
1387 450c7fb0 Kostas Papadimitriou
        r = self.user_client.post(remove_member_url, follow=True)
1388 450c7fb0 Kostas Papadimitriou
        self.assertEqual(r.status_code, 200)
1389 450c7fb0 Kostas Papadimitriou
1390 450c7fb0 Kostas Papadimitriou
        user_quotas = quotas.get_users_quotas([self.member])
1391 450c7fb0 Kostas Papadimitriou
        resource = 'service1.resource'
1392 450c7fb0 Kostas Papadimitriou
        newlimit = user_quotas[self.member.uuid]['system'][resource]['limit']
1393 450c7fb0 Kostas Papadimitriou
        # 200 - 100 from project
1394 450c7fb0 Kostas Papadimitriou
        self.assertEqual(newlimit, 100)
1395 c80722ce Giorgos Korfiatis
1396 c80722ce Giorgos Korfiatis
1397 c80722ce Giorgos Korfiatis
ROOT = '/astakos/api/'
1398 c80722ce Giorgos Korfiatis
u = lambda url: ROOT + url
1399 c80722ce Giorgos Korfiatis
1400 c80722ce Giorgos Korfiatis
1401 c80722ce Giorgos Korfiatis
class QuotaAPITest(TestCase):
1402 c80722ce Giorgos Korfiatis
    def test_0(self):
1403 c80722ce Giorgos Korfiatis
        client = Client()
1404 c80722ce Giorgos Korfiatis
        # custom service resources
1405 c80722ce Giorgos Korfiatis
        service1 = Service.objects.create(
1406 c80722ce Giorgos Korfiatis
            name="service1", api_url="http://service1.api")
1407 c80722ce Giorgos Korfiatis
        resource11 = {"name": "service1.resource11",
1408 c80722ce Giorgos Korfiatis
                      "desc": "resource11 desc",
1409 c80722ce Giorgos Korfiatis
                      "allow_in_projects": True}
1410 c80722ce Giorgos Korfiatis
        r, _ = resources.add_resource(service1, resource11)
1411 c80722ce Giorgos Korfiatis
        resources.update_resource(r, 100)
1412 c80722ce Giorgos Korfiatis
        resource12 = {"name": "service1.resource12",
1413 c80722ce Giorgos Korfiatis
                      "desc": "resource11 desc",
1414 c80722ce Giorgos Korfiatis
                      "unit": "bytes"}
1415 c80722ce Giorgos Korfiatis
        r, _ = resources.add_resource(service1, resource12)
1416 c80722ce Giorgos Korfiatis
        resources.update_resource(r, 1024)
1417 c80722ce Giorgos Korfiatis
1418 c80722ce Giorgos Korfiatis
        # create user
1419 c80722ce Giorgos Korfiatis
        user = get_local_user('test@grnet.gr')
1420 e336910f Giorgos Korfiatis
        quotas.qh_sync_user(user)
1421 c80722ce Giorgos Korfiatis
1422 c80722ce Giorgos Korfiatis
        # create another service
1423 c80722ce Giorgos Korfiatis
        service2 = Service.objects.create(
1424 c80722ce Giorgos Korfiatis
            name="service2", api_url="http://service2.api")
1425 c80722ce Giorgos Korfiatis
        resource21 = {"name": "service2.resource21",
1426 c80722ce Giorgos Korfiatis
                      "desc": "resource11 desc",
1427 c80722ce Giorgos Korfiatis
                      "allow_in_projects": False}
1428 c80722ce Giorgos Korfiatis
        r, _ = resources.add_resource(service2, resource21)
1429 c80722ce Giorgos Korfiatis
        resources.update_resource(r, 3)
1430 c80722ce Giorgos Korfiatis
1431 c80722ce Giorgos Korfiatis
        resource_names = [r['name'] for r in
1432 c80722ce Giorgos Korfiatis
                          [resource11, resource12, resource21]]
1433 c80722ce Giorgos Korfiatis
1434 c80722ce Giorgos Korfiatis
        # get resources
1435 93a77d30 Giorgos Korfiatis
        r = client.get(u('resources'))
1436 c80722ce Giorgos Korfiatis
        self.assertEqual(r.status_code, 200)
1437 c80722ce Giorgos Korfiatis
        body = json.loads(r.content)
1438 c80722ce Giorgos Korfiatis
        for name in resource_names:
1439 aba462a2 Giorgos Korfiatis
            assertIn(name, body)
1440 c80722ce Giorgos Korfiatis
1441 c80722ce Giorgos Korfiatis
        # get quota
1442 93a77d30 Giorgos Korfiatis
        r = client.get(u('quotas'))
1443 c80722ce Giorgos Korfiatis
        self.assertEqual(r.status_code, 401)
1444 c80722ce Giorgos Korfiatis
1445 c80722ce Giorgos Korfiatis
        headers = {'HTTP_X_AUTH_TOKEN': user.auth_token}
1446 93a77d30 Giorgos Korfiatis
        r = client.get(u('quotas/'), **headers)
1447 c80722ce Giorgos Korfiatis
        self.assertEqual(r.status_code, 200)
1448 c80722ce Giorgos Korfiatis
        body = json.loads(r.content)
1449 c80722ce Giorgos Korfiatis
        system_quota = body['system']
1450 aba462a2 Giorgos Korfiatis
        assertIn('system', body)
1451 c80722ce Giorgos Korfiatis
        for name in resource_names:
1452 aba462a2 Giorgos Korfiatis
            assertIn(name, system_quota)
1453 c80722ce Giorgos Korfiatis
1454 93a77d30 Giorgos Korfiatis
        r = client.get(u('service_quotas'))
1455 c80722ce Giorgos Korfiatis
        self.assertEqual(r.status_code, 401)
1456 c80722ce Giorgos Korfiatis
1457 c80722ce Giorgos Korfiatis
        s1_headers = {'HTTP_X_AUTH_TOKEN': service1.auth_token}
1458 93a77d30 Giorgos Korfiatis
        r = client.get(u('service_quotas'), **s1_headers)
1459 c80722ce Giorgos Korfiatis
        self.assertEqual(r.status_code, 200)
1460 c80722ce Giorgos Korfiatis
        body = json.loads(r.content)
1461 aba462a2 Giorgos Korfiatis
        assertIn(user.uuid, body)
1462 c80722ce Giorgos Korfiatis
1463 93a77d30 Giorgos Korfiatis
        r = client.get(u('commissions'), **s1_headers)
1464 c80722ce Giorgos Korfiatis
        self.assertEqual(r.status_code, 200)
1465 c80722ce Giorgos Korfiatis
        body = json.loads(r.content)
1466 c80722ce Giorgos Korfiatis
        self.assertEqual(body, [])
1467 c80722ce Giorgos Korfiatis
1468 c80722ce Giorgos Korfiatis
        # issue some commissions
1469 c80722ce Giorgos Korfiatis
        commission_request = {
1470 c80722ce Giorgos Korfiatis
            "force": False,
1471 c80722ce Giorgos Korfiatis
            "auto_accept": False,
1472 c80722ce Giorgos Korfiatis
            "name": "my commission",
1473 c80722ce Giorgos Korfiatis
            "provisions": [
1474 c80722ce Giorgos Korfiatis
                {
1475 c80722ce Giorgos Korfiatis
                    "holder": user.uuid,
1476 c80722ce Giorgos Korfiatis
                    "source": "system",
1477 c80722ce Giorgos Korfiatis
                    "resource": resource11['name'],
1478 c80722ce Giorgos Korfiatis
                    "quantity": 1
1479 c80722ce Giorgos Korfiatis
                },
1480 c80722ce Giorgos Korfiatis
                {
1481 c80722ce Giorgos Korfiatis
                    "holder": user.uuid,
1482 c80722ce Giorgos Korfiatis
                    "source": "system",
1483 c80722ce Giorgos Korfiatis
                    "resource": resource12['name'],
1484 c80722ce Giorgos Korfiatis
                    "quantity": 30000
1485 c80722ce Giorgos Korfiatis
                }]}
1486 c80722ce Giorgos Korfiatis
1487 c80722ce Giorgos Korfiatis
        post_data = json.dumps(commission_request)
1488 c80722ce Giorgos Korfiatis
        r = client.post(u('commissions'), post_data,
1489 c80722ce Giorgos Korfiatis
                        content_type='application/json', **s1_headers)
1490 c80722ce Giorgos Korfiatis
        self.assertEqual(r.status_code, 413)
1491 c80722ce Giorgos Korfiatis
1492 c80722ce Giorgos Korfiatis
        commission_request = {
1493 c80722ce Giorgos Korfiatis
            "force": False,
1494 c80722ce Giorgos Korfiatis
            "auto_accept": False,
1495 c80722ce Giorgos Korfiatis
            "name": "my commission",
1496 c80722ce Giorgos Korfiatis
            "provisions": [
1497 c80722ce Giorgos Korfiatis
                {
1498 c80722ce Giorgos Korfiatis
                    "holder": user.uuid,
1499 c80722ce Giorgos Korfiatis
                    "source": "system",
1500 c80722ce Giorgos Korfiatis
                    "resource": resource11['name'],
1501 c80722ce Giorgos Korfiatis
                    "quantity": 1
1502 c80722ce Giorgos Korfiatis
                },
1503 c80722ce Giorgos Korfiatis
                {
1504 c80722ce Giorgos Korfiatis
                    "holder": user.uuid,
1505 c80722ce Giorgos Korfiatis
                    "source": "system",
1506 c80722ce Giorgos Korfiatis
                    "resource": resource12['name'],
1507 c80722ce Giorgos Korfiatis
                    "quantity": 100
1508 c80722ce Giorgos Korfiatis
                }]}
1509 c80722ce Giorgos Korfiatis
1510 c80722ce Giorgos Korfiatis
        post_data = json.dumps(commission_request)
1511 c80722ce Giorgos Korfiatis
        r = client.post(u('commissions'), post_data,
1512 c80722ce Giorgos Korfiatis
                        content_type='application/json', **s1_headers)
1513 c80722ce Giorgos Korfiatis
        self.assertEqual(r.status_code, 201)
1514 c80722ce Giorgos Korfiatis
        body = json.loads(r.content)
1515 c80722ce Giorgos Korfiatis
        serial = body['serial']
1516 c80722ce Giorgos Korfiatis
        self.assertEqual(serial, 1)
1517 c80722ce Giorgos Korfiatis
1518 c80722ce Giorgos Korfiatis
        post_data = json.dumps(commission_request)
1519 c80722ce Giorgos Korfiatis
        r = client.post(u('commissions'), post_data,
1520 c80722ce Giorgos Korfiatis
                        content_type='application/json', **s1_headers)
1521 c80722ce Giorgos Korfiatis
        self.assertEqual(r.status_code, 201)
1522 c80722ce Giorgos Korfiatis
        body = json.loads(r.content)
1523 c80722ce Giorgos Korfiatis
        self.assertEqual(body['serial'], 2)
1524 c80722ce Giorgos Korfiatis
1525 c80722ce Giorgos Korfiatis
        post_data = json.dumps(commission_request)
1526 c80722ce Giorgos Korfiatis
        r = client.post(u('commissions'), post_data,
1527 c80722ce Giorgos Korfiatis
                        content_type='application/json', **s1_headers)
1528 c80722ce Giorgos Korfiatis
        self.assertEqual(r.status_code, 201)
1529 c80722ce Giorgos Korfiatis
        body = json.loads(r.content)
1530 c80722ce Giorgos Korfiatis
        self.assertEqual(body['serial'], 3)
1531 c80722ce Giorgos Korfiatis
1532 93a77d30 Giorgos Korfiatis
        r = client.get(u('commissions'), **s1_headers)
1533 c80722ce Giorgos Korfiatis
        self.assertEqual(r.status_code, 200)
1534 c80722ce Giorgos Korfiatis
        body = json.loads(r.content)
1535 c80722ce Giorgos Korfiatis
        self.assertEqual(body, [1, 2, 3])
1536 c80722ce Giorgos Korfiatis
1537 93a77d30 Giorgos Korfiatis
        r = client.get(u('commissions/' + str(serial)), **s1_headers)
1538 c80722ce Giorgos Korfiatis
        self.assertEqual(r.status_code, 200)
1539 c80722ce Giorgos Korfiatis
        body = json.loads(r.content)
1540 c80722ce Giorgos Korfiatis
        self.assertEqual(body['serial'], serial)
1541 aba462a2 Giorgos Korfiatis
        assertIn('issue_time', body)
1542 c80722ce Giorgos Korfiatis
        self.assertEqual(body['provisions'], commission_request['provisions'])
1543 c80722ce Giorgos Korfiatis
        self.assertEqual(body['name'], commission_request['name'])
1544 c80722ce Giorgos Korfiatis
1545 93a77d30 Giorgos Korfiatis
        r = client.get(u('service_quotas?user=' + user.uuid), **s1_headers)
1546 c80722ce Giorgos Korfiatis
        self.assertEqual(r.status_code, 200)
1547 c80722ce Giorgos Korfiatis
        body = json.loads(r.content)
1548 c80722ce Giorgos Korfiatis
        user_quota = body[user.uuid]
1549 c80722ce Giorgos Korfiatis
        system_quota = user_quota['system']
1550 c80722ce Giorgos Korfiatis
        r11 = system_quota[resource11['name']]
1551 c80722ce Giorgos Korfiatis
        self.assertEqual(r11['usage'], 3)
1552 c80722ce Giorgos Korfiatis
        self.assertEqual(r11['pending'], 3)
1553 c80722ce Giorgos Korfiatis
1554 c80722ce Giorgos Korfiatis
        # resolve pending commissions
1555 c80722ce Giorgos Korfiatis
        resolve_data = {
1556 c80722ce Giorgos Korfiatis
            "accept": [1, 3],
1557 c80722ce Giorgos Korfiatis
            "reject": [2, 3, 4],
1558 c80722ce Giorgos Korfiatis
        }
1559 c80722ce Giorgos Korfiatis
        post_data = json.dumps(resolve_data)
1560 c80722ce Giorgos Korfiatis
1561 c80722ce Giorgos Korfiatis
        r = client.post(u('commissions/action'), post_data,
1562 c80722ce Giorgos Korfiatis
                        content_type='application/json', **s1_headers)
1563 c80722ce Giorgos Korfiatis
        self.assertEqual(r.status_code, 200)
1564 c80722ce Giorgos Korfiatis
        body = json.loads(r.content)
1565 c80722ce Giorgos Korfiatis
        self.assertEqual(body['accepted'], [1])
1566 c80722ce Giorgos Korfiatis
        self.assertEqual(body['rejected'], [2])
1567 c80722ce Giorgos Korfiatis
        failed = body['failed']
1568 c80722ce Giorgos Korfiatis
        self.assertEqual(len(failed), 2)
1569 c80722ce Giorgos Korfiatis
1570 93a77d30 Giorgos Korfiatis
        r = client.get(u('commissions/' + str(serial)), **s1_headers)
1571 c80722ce Giorgos Korfiatis
        self.assertEqual(r.status_code, 404)
1572 c80722ce Giorgos Korfiatis
1573 c80722ce Giorgos Korfiatis
        # auto accept
1574 c80722ce Giorgos Korfiatis
        commission_request = {
1575 c80722ce Giorgos Korfiatis
            "auto_accept": True,
1576 c80722ce Giorgos Korfiatis
            "name": "my commission",
1577 c80722ce Giorgos Korfiatis
            "provisions": [
1578 c80722ce Giorgos Korfiatis
                {
1579 c80722ce Giorgos Korfiatis
                    "holder": user.uuid,
1580 c80722ce Giorgos Korfiatis
                    "source": "system",
1581 c80722ce Giorgos Korfiatis
                    "resource": resource11['name'],
1582 c80722ce Giorgos Korfiatis
                    "quantity": 1
1583 c80722ce Giorgos Korfiatis
                },
1584 c80722ce Giorgos Korfiatis
                {
1585 c80722ce Giorgos Korfiatis
                    "holder": user.uuid,
1586 c80722ce Giorgos Korfiatis
                    "source": "system",
1587 c80722ce Giorgos Korfiatis
                    "resource": resource12['name'],
1588 c80722ce Giorgos Korfiatis
                    "quantity": 100
1589 c80722ce Giorgos Korfiatis
                }]}
1590 c80722ce Giorgos Korfiatis
1591 c80722ce Giorgos Korfiatis
        post_data = json.dumps(commission_request)
1592 c80722ce Giorgos Korfiatis
        r = client.post(u('commissions'), post_data,
1593 c80722ce Giorgos Korfiatis
                        content_type='application/json', **s1_headers)
1594 c80722ce Giorgos Korfiatis
        self.assertEqual(r.status_code, 201)
1595 c80722ce Giorgos Korfiatis
        body = json.loads(r.content)
1596 c80722ce Giorgos Korfiatis
        serial = body['serial']
1597 c80722ce Giorgos Korfiatis
        self.assertEqual(serial, 4)
1598 c80722ce Giorgos Korfiatis
1599 93a77d30 Giorgos Korfiatis
        r = client.get(u('commissions/' + str(serial)), **s1_headers)
1600 c80722ce Giorgos Korfiatis
        self.assertEqual(r.status_code, 404)
1601 c80722ce Giorgos Korfiatis
1602 c80722ce Giorgos Korfiatis
        # malformed
1603 c80722ce Giorgos Korfiatis
        commission_request = {
1604 c80722ce Giorgos Korfiatis
            "auto_accept": True,
1605 c80722ce Giorgos Korfiatis
            "name": "my commission",
1606 c80722ce Giorgos Korfiatis
            "provisions": [
1607 c80722ce Giorgos Korfiatis
                {
1608 c80722ce Giorgos Korfiatis
                    "holder": user.uuid,
1609 c80722ce Giorgos Korfiatis
                    "source": "system",
1610 c80722ce Giorgos Korfiatis
                    "resource": resource11['name'],
1611 c80722ce Giorgos Korfiatis
                }
1612 c80722ce Giorgos Korfiatis
            ]}
1613 c80722ce Giorgos Korfiatis
1614 c80722ce Giorgos Korfiatis
        post_data = json.dumps(commission_request)
1615 c80722ce Giorgos Korfiatis
        r = client.post(u('commissions'), post_data,
1616 c80722ce Giorgos Korfiatis
                        content_type='application/json', **s1_headers)
1617 c80722ce Giorgos Korfiatis
        self.assertEqual(r.status_code, 400)
1618 c80722ce Giorgos Korfiatis
1619 c80722ce Giorgos Korfiatis
        commission_request = {
1620 c80722ce Giorgos Korfiatis
            "auto_accept": True,
1621 c80722ce Giorgos Korfiatis
            "name": "my commission",
1622 c80722ce Giorgos Korfiatis
            "provisions": "dummy"}
1623 c80722ce Giorgos Korfiatis
1624 c80722ce Giorgos Korfiatis
        post_data = json.dumps(commission_request)
1625 c80722ce Giorgos Korfiatis
        r = client.post(u('commissions'), post_data,
1626 c80722ce Giorgos Korfiatis
                        content_type='application/json', **s1_headers)
1627 c80722ce Giorgos Korfiatis
        self.assertEqual(r.status_code, 400)
1628 c80722ce Giorgos Korfiatis
1629 c80722ce Giorgos Korfiatis
        r = client.post(u('commissions'), commission_request,
1630 c80722ce Giorgos Korfiatis
                        content_type='application/json', **s1_headers)
1631 c80722ce Giorgos Korfiatis
        self.assertEqual(r.status_code, 400)
1632 c80722ce Giorgos Korfiatis
1633 c80722ce Giorgos Korfiatis
        # no holding
1634 c80722ce Giorgos Korfiatis
        commission_request = {
1635 c80722ce Giorgos Korfiatis
            "auto_accept": True,
1636 c80722ce Giorgos Korfiatis
            "name": "my commission",
1637 c80722ce Giorgos Korfiatis
            "provisions": [
1638 c80722ce Giorgos Korfiatis
                {
1639 c80722ce Giorgos Korfiatis
                    "holder": user.uuid,
1640 c80722ce Giorgos Korfiatis
                    "source": "system",
1641 c80722ce Giorgos Korfiatis
                    "resource": "non existent",
1642 c80722ce Giorgos Korfiatis
                    "quantity": 1
1643 c80722ce Giorgos Korfiatis
                },
1644 c80722ce Giorgos Korfiatis
                {
1645 c80722ce Giorgos Korfiatis
                    "holder": user.uuid,
1646 c80722ce Giorgos Korfiatis
                    "source": "system",
1647 c80722ce Giorgos Korfiatis
                    "resource": resource12['name'],
1648 c80722ce Giorgos Korfiatis
                    "quantity": 100
1649 c80722ce Giorgos Korfiatis
                }]}
1650 c80722ce Giorgos Korfiatis
1651 c80722ce Giorgos Korfiatis
        post_data = json.dumps(commission_request)
1652 c80722ce Giorgos Korfiatis
        r = client.post(u('commissions'), post_data,
1653 c80722ce Giorgos Korfiatis
                        content_type='application/json', **s1_headers)
1654 c80722ce Giorgos Korfiatis
        self.assertEqual(r.status_code, 404)
1655 c80722ce Giorgos Korfiatis
1656 c80722ce Giorgos Korfiatis
        # release
1657 c80722ce Giorgos Korfiatis
        commission_request = {
1658 c80722ce Giorgos Korfiatis
            "provisions": [
1659 c80722ce Giorgos Korfiatis
                {
1660 c80722ce Giorgos Korfiatis
                    "holder": user.uuid,
1661 c80722ce Giorgos Korfiatis
                    "source": "system",
1662 c80722ce Giorgos Korfiatis
                    "resource": resource11['name'],
1663 c80722ce Giorgos Korfiatis
                    "quantity": -1
1664 c80722ce Giorgos Korfiatis
                }
1665 c80722ce Giorgos Korfiatis
            ]}
1666 c80722ce Giorgos Korfiatis
1667 c80722ce Giorgos Korfiatis
        post_data = json.dumps(commission_request)
1668 c80722ce Giorgos Korfiatis
        r = client.post(u('commissions'), post_data,
1669 c80722ce Giorgos Korfiatis
                        content_type='application/json', **s1_headers)
1670 c80722ce Giorgos Korfiatis
        self.assertEqual(r.status_code, 201)
1671 c80722ce Giorgos Korfiatis
        body = json.loads(r.content)
1672 c80722ce Giorgos Korfiatis
        serial = body['serial']
1673 c80722ce Giorgos Korfiatis
1674 c80722ce Giorgos Korfiatis
        accept_data = {'accept': ""}
1675 c80722ce Giorgos Korfiatis
        post_data = json.dumps(accept_data)
1676 c80722ce Giorgos Korfiatis
        r = client.post(u('commissions/' + str(serial) + '/action'), post_data,
1677 c80722ce Giorgos Korfiatis
                        content_type='application/json', **s1_headers)
1678 c80722ce Giorgos Korfiatis
        self.assertEqual(r.status_code, 200)
1679 c80722ce Giorgos Korfiatis
1680 c80722ce Giorgos Korfiatis
        reject_data = {'reject': ""}
1681 c80722ce Giorgos Korfiatis
        post_data = json.dumps(accept_data)
1682 c80722ce Giorgos Korfiatis
        r = client.post(u('commissions/' + str(serial) + '/action'), post_data,
1683 c80722ce Giorgos Korfiatis
                        content_type='application/json', **s1_headers)
1684 c80722ce Giorgos Korfiatis
        self.assertEqual(r.status_code, 404)
1685 c80722ce Giorgos Korfiatis
1686 c80722ce Giorgos Korfiatis
        # force
1687 c80722ce Giorgos Korfiatis
        commission_request = {
1688 c80722ce Giorgos Korfiatis
            "force": True,
1689 c80722ce Giorgos Korfiatis
            "provisions": [
1690 c80722ce Giorgos Korfiatis
                {
1691 c80722ce Giorgos Korfiatis
                    "holder": user.uuid,
1692 c80722ce Giorgos Korfiatis
                    "source": "system",
1693 c80722ce Giorgos Korfiatis
                    "resource": resource11['name'],
1694 c80722ce Giorgos Korfiatis
                    "quantity": 100
1695 c80722ce Giorgos Korfiatis
                }]}
1696 c80722ce Giorgos Korfiatis
1697 c80722ce Giorgos Korfiatis
        post_data = json.dumps(commission_request)
1698 c80722ce Giorgos Korfiatis
        r = client.post(u('commissions'), post_data,
1699 c80722ce Giorgos Korfiatis
                        content_type='application/json', **s1_headers)
1700 c80722ce Giorgos Korfiatis
        self.assertEqual(r.status_code, 201)
1701 c80722ce Giorgos Korfiatis
        body = json.loads(r.content)
1702 c80722ce Giorgos Korfiatis
1703 c80722ce Giorgos Korfiatis
        r = client.get(u('quotas'), **headers)
1704 c80722ce Giorgos Korfiatis
        self.assertEqual(r.status_code, 200)
1705 c80722ce Giorgos Korfiatis
        body = json.loads(r.content)
1706 c80722ce Giorgos Korfiatis
        system_quota = body['system']
1707 c80722ce Giorgos Korfiatis
        r11 = system_quota[resource11['name']]
1708 c80722ce Giorgos Korfiatis
        self.assertEqual(r11['usage'], 102)
1709 c80722ce Giorgos Korfiatis
        self.assertEqual(r11['pending'], 101)