Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / tests / common.py @ 7e24cd42

History | View | Annotate | Download (6.1 kB)

1 1ac3349d Kostas Papadimitriou
# Copyright 2011 GRNET S.A. All rights reserved.
2 1ac3349d Kostas Papadimitriou
#
3 1ac3349d Kostas Papadimitriou
# Redistribution and use in source and binary forms, with or
4 1ac3349d Kostas Papadimitriou
# without modification, are permitted provided that the following
5 1ac3349d Kostas Papadimitriou
# conditions are met:
6 1ac3349d Kostas Papadimitriou
#
7 1ac3349d Kostas Papadimitriou
#   1. Redistributions of source code must retain the above
8 1ac3349d Kostas Papadimitriou
#      copyright notice, this list of conditions and the following
9 1ac3349d Kostas Papadimitriou
#      disclaimer.
10 1ac3349d Kostas Papadimitriou
#
11 1ac3349d Kostas Papadimitriou
#   2. Redistributions in binary form must reproduce the above
12 1ac3349d Kostas Papadimitriou
#      copyright notice, this list of conditions and the following
13 1ac3349d Kostas Papadimitriou
#      disclaimer in the documentation and/or other materials
14 1ac3349d Kostas Papadimitriou
#      provided with the distribution.
15 1ac3349d Kostas Papadimitriou
#
16 1ac3349d Kostas Papadimitriou
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 1ac3349d Kostas Papadimitriou
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 1ac3349d Kostas Papadimitriou
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 1ac3349d Kostas Papadimitriou
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 1ac3349d Kostas Papadimitriou
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 1ac3349d Kostas Papadimitriou
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 1ac3349d Kostas Papadimitriou
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 1ac3349d Kostas Papadimitriou
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 1ac3349d Kostas Papadimitriou
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 1ac3349d Kostas Papadimitriou
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 1ac3349d Kostas Papadimitriou
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 1ac3349d Kostas Papadimitriou
# POSSIBILITY OF SUCH DAMAGE.
28 1ac3349d Kostas Papadimitriou
#
29 1ac3349d Kostas Papadimitriou
# The views and conclusions contained in the software and
30 1ac3349d Kostas Papadimitriou
# documentation are those of the authors and should not be
31 1ac3349d Kostas Papadimitriou
# interpreted as representing official policies, either expressed
32 1ac3349d Kostas Papadimitriou
# or implied, of GRNET S.A.
33 1ac3349d Kostas Papadimitriou
34 1ac3349d Kostas Papadimitriou
from contextlib import contextmanager
35 1ac3349d Kostas Papadimitriou
36 1ac3349d Kostas Papadimitriou
import copy
37 1ac3349d Kostas Papadimitriou
import datetime
38 1ac3349d Kostas Papadimitriou
import functools
39 1ac3349d Kostas Papadimitriou
40 7e24cd42 Giorgos Korfiatis
from snf_django.utils.testing import with_settings, override_settings, \
41 7e24cd42 Giorgos Korfiatis
    assertIn, assertGreater, assertRaises
42 1ac3349d Kostas Papadimitriou
43 1ac3349d Kostas Papadimitriou
from django.test import Client
44 7e24cd42 Giorgos Korfiatis
from django.test import TestCase
45 1ac3349d Kostas Papadimitriou
from django.core import mail
46 1ac3349d Kostas Papadimitriou
from django.http import SimpleCookie, HttpRequest, QueryDict
47 1ac3349d Kostas Papadimitriou
from django.utils.importlib import import_module
48 1ac3349d Kostas Papadimitriou
from django.utils import simplejson as json
49 1ac3349d Kostas Papadimitriou
50 1ac3349d Kostas Papadimitriou
from astakos.im.activation_backends import *
51 70e11eaa Sofia Papagiannaki
from astakos.im.views.target.shibboleth import Tokens as ShibbolethTokens
52 1ac3349d Kostas Papadimitriou
from astakos.im.models import *
53 1ac3349d Kostas Papadimitriou
from astakos.im import functions
54 1ac3349d Kostas Papadimitriou
from astakos.im import settings as astakos_settings
55 1ac3349d Kostas Papadimitriou
from astakos.im import forms
56 1ac3349d Kostas Papadimitriou
from astakos.im import activation_backends
57 1ac3349d Kostas Papadimitriou
58 1ac3349d Kostas Papadimitriou
from urllib import quote
59 1ac3349d Kostas Papadimitriou
from datetime import timedelta
60 1ac3349d Kostas Papadimitriou
61 1ac3349d Kostas Papadimitriou
from astakos.im import messages
62 1ac3349d Kostas Papadimitriou
from astakos.im import auth_providers
63 1ac3349d Kostas Papadimitriou
from astakos.im import quotas
64 bd1f667b Giorgos Korfiatis
from astakos.im import register
65 1ac3349d Kostas Papadimitriou
66 1ac3349d Kostas Papadimitriou
from django.conf import settings
67 1ac3349d Kostas Papadimitriou
68 1ac3349d Kostas Papadimitriou
69 1ac3349d Kostas Papadimitriou
# set some common settings
70 1ac3349d Kostas Papadimitriou
astakos_settings.EMAILCHANGE_ENABLED = True
71 1ac3349d Kostas Papadimitriou
astakos_settings.RECAPTCHA_ENABLED = False
72 1ac3349d Kostas Papadimitriou
73 1ac3349d Kostas Papadimitriou
settings.LOGGING_SETUP['disable_existing_loggers'] = False
74 1ac3349d Kostas Papadimitriou
75 1ac3349d Kostas Papadimitriou
# shortcut decorators to override provider settings
76 1ac3349d Kostas Papadimitriou
# e.g. shibboleth_settings(ENABLED=True) will set
77 1ac3349d Kostas Papadimitriou
# ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_ENABLED = True in global synnefo settings
78 1ac3349d Kostas Papadimitriou
prefixes = {'providers': 'AUTH_PROVIDER_',
79 1ac3349d Kostas Papadimitriou
            'shibboleth': 'ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_',
80 1ac3349d Kostas Papadimitriou
            'local': 'ASTAKOS_AUTH_PROVIDER_LOCAL_'}
81 1ac3349d Kostas Papadimitriou
im_settings = functools.partial(with_settings, astakos_settings)
82 1ac3349d Kostas Papadimitriou
shibboleth_settings = functools.partial(with_settings,
83 1ac3349d Kostas Papadimitriou
                                        settings,
84 1ac3349d Kostas Papadimitriou
                                        prefix=prefixes['shibboleth'])
85 1ac3349d Kostas Papadimitriou
localauth_settings = functools.partial(with_settings, settings,
86 1ac3349d Kostas Papadimitriou
                                       prefix=prefixes['local'])
87 1ac3349d Kostas Papadimitriou
88 1ac3349d Kostas Papadimitriou
89 1ac3349d Kostas Papadimitriou
class AstakosTestClient(Client):
90 1ac3349d Kostas Papadimitriou
    pass
91 1ac3349d Kostas Papadimitriou
92 1ac3349d Kostas Papadimitriou
93 1ac3349d Kostas Papadimitriou
class ShibbolethClient(AstakosTestClient):
94 1ac3349d Kostas Papadimitriou
    """
95 1ac3349d Kostas Papadimitriou
    A shibboleth agnostic client.
96 1ac3349d Kostas Papadimitriou
    """
97 1ac3349d Kostas Papadimitriou
    VALID_TOKENS = filter(lambda x: not x.startswith("_"),
98 1ac3349d Kostas Papadimitriou
                          dir(ShibbolethTokens))
99 1ac3349d Kostas Papadimitriou
100 1ac3349d Kostas Papadimitriou
    def __init__(self, *args, **kwargs):
101 1ac3349d Kostas Papadimitriou
        self.tokens = kwargs.pop('tokens', {})
102 1ac3349d Kostas Papadimitriou
        super(ShibbolethClient, self).__init__(*args, **kwargs)
103 1ac3349d Kostas Papadimitriou
104 1ac3349d Kostas Papadimitriou
    def set_tokens(self, **kwargs):
105 1ac3349d Kostas Papadimitriou
        for key, value in kwargs.iteritems():
106 1ac3349d Kostas Papadimitriou
            key = 'SHIB_%s' % key.upper()
107 1ac3349d Kostas Papadimitriou
            if not key in self.VALID_TOKENS:
108 1ac3349d Kostas Papadimitriou
                raise Exception('Invalid shibboleth token')
109 1ac3349d Kostas Papadimitriou
110 1ac3349d Kostas Papadimitriou
            self.tokens[key] = value
111 1ac3349d Kostas Papadimitriou
112 1ac3349d Kostas Papadimitriou
    def unset_tokens(self, *keys):
113 1ac3349d Kostas Papadimitriou
        for key in keys:
114 1ac3349d Kostas Papadimitriou
            key = 'SHIB_%s' % param.upper()
115 1ac3349d Kostas Papadimitriou
            if key in self.tokens:
116 1ac3349d Kostas Papadimitriou
                del self.tokens[key]
117 1ac3349d Kostas Papadimitriou
118 1ac3349d Kostas Papadimitriou
    def reset_tokens(self):
119 1ac3349d Kostas Papadimitriou
        self.tokens = {}
120 1ac3349d Kostas Papadimitriou
121 1ac3349d Kostas Papadimitriou
    def get_http_token(self, key):
122 1ac3349d Kostas Papadimitriou
        http_header = getattr(ShibbolethTokens, key)
123 1ac3349d Kostas Papadimitriou
        return http_header
124 1ac3349d Kostas Papadimitriou
125 1ac3349d Kostas Papadimitriou
    def request(self, **request):
126 1ac3349d Kostas Papadimitriou
        """
127 1ac3349d Kostas Papadimitriou
        Transform valid shibboleth tokens to http headers
128 1ac3349d Kostas Papadimitriou
        """
129 1ac3349d Kostas Papadimitriou
        for token, value in self.tokens.iteritems():
130 1ac3349d Kostas Papadimitriou
            request[self.get_http_token(token)] = value
131 1ac3349d Kostas Papadimitriou
132 1ac3349d Kostas Papadimitriou
        for param in request.keys():
133 1ac3349d Kostas Papadimitriou
            key = 'SHIB_%s' % param.upper()
134 1ac3349d Kostas Papadimitriou
            if key in self.VALID_TOKENS:
135 1ac3349d Kostas Papadimitriou
                request[self.get_http_token(key)] = request[param]
136 1ac3349d Kostas Papadimitriou
                del request[param]
137 1ac3349d Kostas Papadimitriou
138 1ac3349d Kostas Papadimitriou
        return super(ShibbolethClient, self).request(**request)
139 1ac3349d Kostas Papadimitriou
140 1ac3349d Kostas Papadimitriou
141 1ac3349d Kostas Papadimitriou
def get_user_client(username, password="password"):
142 1ac3349d Kostas Papadimitriou
    client = Client()
143 1ac3349d Kostas Papadimitriou
    client.login(username=username, password=password)
144 1ac3349d Kostas Papadimitriou
    return client
145 1ac3349d Kostas Papadimitriou
146 1ac3349d Kostas Papadimitriou
147 1ac3349d Kostas Papadimitriou
def get_local_user(username, **kwargs):
148 1ac3349d Kostas Papadimitriou
        try:
149 1ac3349d Kostas Papadimitriou
            return AstakosUser.objects.get(email=username)
150 1ac3349d Kostas Papadimitriou
        except:
151 1ac3349d Kostas Papadimitriou
            user_params = {
152 1ac3349d Kostas Papadimitriou
                'username': username,
153 1ac3349d Kostas Papadimitriou
                'email': username,
154 1ac3349d Kostas Papadimitriou
                'is_active': True,
155 1ac3349d Kostas Papadimitriou
                'activation_sent': datetime.now(),
156 1ac3349d Kostas Papadimitriou
                'email_verified': True
157 1ac3349d Kostas Papadimitriou
            }
158 1ac3349d Kostas Papadimitriou
            user_params.update(kwargs)
159 1ac3349d Kostas Papadimitriou
            user = AstakosUser(**user_params)
160 1ac3349d Kostas Papadimitriou
            user.set_password(kwargs.get('password', 'password'))
161 1ac3349d Kostas Papadimitriou
            user.renew_verification_code()
162 1ac3349d Kostas Papadimitriou
            user.save()
163 1ac3349d Kostas Papadimitriou
            user.add_auth_provider('local', auth_backend='astakos')
164 1ac3349d Kostas Papadimitriou
            if kwargs.get('is_active', True):
165 1ac3349d Kostas Papadimitriou
                user.is_active = True
166 1ac3349d Kostas Papadimitriou
            else:
167 1ac3349d Kostas Papadimitriou
                user.is_active = False
168 1ac3349d Kostas Papadimitriou
            user.save()
169 1ac3349d Kostas Papadimitriou
            return user
170 1ac3349d Kostas Papadimitriou
171 1ac3349d Kostas Papadimitriou
172 1ac3349d Kostas Papadimitriou
def get_mailbox(email):
173 1ac3349d Kostas Papadimitriou
    mails = []
174 1ac3349d Kostas Papadimitriou
    for sent_email in mail.outbox:
175 1ac3349d Kostas Papadimitriou
        for recipient in sent_email.recipients():
176 1ac3349d Kostas Papadimitriou
            if email in recipient:
177 1ac3349d Kostas Papadimitriou
                mails.append(sent_email)
178 1ac3349d Kostas Papadimitriou
    return mails
179 630e6b6d Kostas Papadimitriou
180 630e6b6d Kostas Papadimitriou
181 630e6b6d Kostas Papadimitriou
def reverse_with_next(next_reverse, base_reverse='login'):
182 630e6b6d Kostas Papadimitriou
    return reverse(base_reverse) + '?next=%s' % reverse(next_reverse)