Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / auth_providers.py @ b1cb2583

History | View | Annotate | Download (22.7 kB)

1 d2633501 Kostas Papadimitriou
# Copyright 2011 GRNET S.A. All rights reserved.
2 d2633501 Kostas Papadimitriou
#
3 d2633501 Kostas Papadimitriou
# Redistribution and use in source and binary forms, with or
4 d2633501 Kostas Papadimitriou
# without modification, are permitted provided that the following
5 d2633501 Kostas Papadimitriou
# conditions are met:
6 d2633501 Kostas Papadimitriou
#
7 d2633501 Kostas Papadimitriou
#   1. Redistributions of source code must retain the above
8 d2633501 Kostas Papadimitriou
#      copyright notice, this list of conditions and the following
9 d2633501 Kostas Papadimitriou
#      disclaimer.
10 d2633501 Kostas Papadimitriou
#
11 d2633501 Kostas Papadimitriou
#   2. Redistributions in binary form must reproduce the above
12 d2633501 Kostas Papadimitriou
#      copyright notice, this list of conditions and the following
13 d2633501 Kostas Papadimitriou
#      disclaimer in the documentation and/or other materials
14 d2633501 Kostas Papadimitriou
#      provided with the distribution.
15 d2633501 Kostas Papadimitriou
#
16 d2633501 Kostas Papadimitriou
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 d2633501 Kostas Papadimitriou
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 d2633501 Kostas Papadimitriou
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 d2633501 Kostas Papadimitriou
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 d2633501 Kostas Papadimitriou
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 d2633501 Kostas Papadimitriou
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 d2633501 Kostas Papadimitriou
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 d2633501 Kostas Papadimitriou
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 d2633501 Kostas Papadimitriou
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 d2633501 Kostas Papadimitriou
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 d2633501 Kostas Papadimitriou
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 d2633501 Kostas Papadimitriou
# POSSIBILITY OF SUCH DAMAGE.
28 d2633501 Kostas Papadimitriou
#
29 d2633501 Kostas Papadimitriou
# The views and conclusions contained in the software and
30 d2633501 Kostas Papadimitriou
# documentation are those of the authors and should not be
31 d2633501 Kostas Papadimitriou
# interpreted as representing official policies, either expressed
32 d2633501 Kostas Papadimitriou
# or implied, of GRNET S.A.
33 d2633501 Kostas Papadimitriou
34 9d20fe23 Kostas Papadimitriou
import copy
35 9d20fe23 Kostas Papadimitriou
import json
36 9d20fe23 Kostas Papadimitriou
37 9d20fe23 Kostas Papadimitriou
from synnefo.lib.ordereddict import OrderedDict
38 d2633501 Kostas Papadimitriou
39 6a80a0ae Kostas Papadimitriou
from django.core.urlresolvers import reverse, NoReverseMatch
40 d2633501 Kostas Papadimitriou
from django.utils.translation import ugettext as _
41 9d20fe23 Kostas Papadimitriou
from django.contrib.auth.models import Group
42 9d20fe23 Kostas Papadimitriou
from django import template
43 d2633501 Kostas Papadimitriou
44 081070a5 Kostas Papadimitriou
from django.conf import settings
45 c4b1a172 Kostas Papadimitriou
46 081070a5 Kostas Papadimitriou
from astakos.im import settings as astakos_settings
47 c4b1a172 Kostas Papadimitriou
from astakos.im import messages as astakos_messages
48 d2633501 Kostas Papadimitriou
49 cbc7a32c Kostas Papadimitriou
from synnefo_branding import utils as branding_utils
50 cbc7a32c Kostas Papadimitriou
51 d2633501 Kostas Papadimitriou
import logging
52 d2633501 Kostas Papadimitriou
53 d2633501 Kostas Papadimitriou
logger = logging.getLogger(__name__)
54 d2633501 Kostas Papadimitriou
55 d2633501 Kostas Papadimitriou
# providers registry
56 6012535a Kostas Papadimitriou
PROVIDERS = {}
57 badcb2a9 Kostas Papadimitriou
REQUIRED_PROVIDERS = {}
58 d2633501 Kostas Papadimitriou
59 9d20fe23 Kostas Papadimitriou
60 3f40ce16 Kostas Papadimitriou
class InvalidProvider(Exception):
61 3f40ce16 Kostas Papadimitriou
    pass
62 3f40ce16 Kostas Papadimitriou
63 3f40ce16 Kostas Papadimitriou
64 d2633501 Kostas Papadimitriou
class AuthProviderBase(type):
65 d2633501 Kostas Papadimitriou
66 d2633501 Kostas Papadimitriou
    def __new__(cls, name, bases, dct):
67 d2633501 Kostas Papadimitriou
        include = False
68 d2633501 Kostas Papadimitriou
        if [b for b in bases if isinstance(b, AuthProviderBase)]:
69 d2633501 Kostas Papadimitriou
            type_id = dct.get('module')
70 d2633501 Kostas Papadimitriou
            if type_id:
71 d2633501 Kostas Papadimitriou
                include = True
72 081070a5 Kostas Papadimitriou
            if type_id in astakos_settings.IM_MODULES:
73 591068ae Kostas Papadimitriou
                if astakos_settings.IM_MODULES.index(type_id) == 0:
74 591068ae Kostas Papadimitriou
                    dct['is_primary'] = True
75 d2633501 Kostas Papadimitriou
                dct['module_enabled'] = True
76 d2633501 Kostas Papadimitriou
77 d2633501 Kostas Papadimitriou
        newcls = super(AuthProviderBase, cls).__new__(cls, name, bases, dct)
78 d2633501 Kostas Papadimitriou
        if include:
79 6012535a Kostas Papadimitriou
            PROVIDERS[type_id] = newcls
80 9d20fe23 Kostas Papadimitriou
            if newcls().get_required_policy:
81 badcb2a9 Kostas Papadimitriou
                REQUIRED_PROVIDERS[type_id] = newcls
82 d2633501 Kostas Papadimitriou
        return newcls
83 d2633501 Kostas Papadimitriou
84 d2633501 Kostas Papadimitriou
85 d2633501 Kostas Papadimitriou
class AuthProvider(object):
86 d2633501 Kostas Papadimitriou
87 d2633501 Kostas Papadimitriou
    __metaclass__ = AuthProviderBase
88 d2633501 Kostas Papadimitriou
89 d2633501 Kostas Papadimitriou
    module = None
90 d2633501 Kostas Papadimitriou
    module_enabled = False
91 591068ae Kostas Papadimitriou
    is_primary = False
92 9d20fe23 Kostas Papadimitriou
93 9d20fe23 Kostas Papadimitriou
    message_tpls = OrderedDict((
94 9d20fe23 Kostas Papadimitriou
        ('title', '{module_title}'),
95 9d20fe23 Kostas Papadimitriou
        ('login_title', '{title} LOGIN'),
96 9d20fe23 Kostas Papadimitriou
        ('method_prompt', '{title} login'),
97 9d20fe23 Kostas Papadimitriou
        ('account_prompt', '{title} account'),
98 9d20fe23 Kostas Papadimitriou
        ('signup_title', '{title}'),
99 9d20fe23 Kostas Papadimitriou
        ('profile_title', '{title}'),
100 9d20fe23 Kostas Papadimitriou
        ('method_details', '{account_prompt}: {identifier}'),
101 9d20fe23 Kostas Papadimitriou
        ('primary_login_prompt', 'Login using '),
102 9d20fe23 Kostas Papadimitriou
        ('required', '{title} is required. You can assign it '
103 9d20fe23 Kostas Papadimitriou
                     'from your profile page'),
104 9d20fe23 Kostas Papadimitriou
        ('login_prompt', ''),
105 9d20fe23 Kostas Papadimitriou
        ('add_prompt', 'Allows you to login using {title}'),
106 9d20fe23 Kostas Papadimitriou
        ('login_extra', ''),
107 9d20fe23 Kostas Papadimitriou
        ('username', '{username}'),
108 cbc7a32c Kostas Papadimitriou
        ('disabled_for_create', 'It seems this is the first time you\'re '
109 cbc7a32c Kostas Papadimitriou
                                'trying to access {service_name}. '
110 cbc7a32c Kostas Papadimitriou
                                'Unfortunately, we are not accepting new '
111 cbc7a32c Kostas Papadimitriou
                                'users at this point.'),
112 9d20fe23 Kostas Papadimitriou
        ('switch_success', 'Account changed successfully.'),
113 9d20fe23 Kostas Papadimitriou
        ('cannot_login', '{title} is not available for login. '
114 9d20fe23 Kostas Papadimitriou
                         'Please use one of your other available methods '
115 9d20fe23 Kostas Papadimitriou
                         'to login ({available_methods_links}'),
116 9d20fe23 Kostas Papadimitriou
117 9d20fe23 Kostas Papadimitriou
        # icons should end with _icon
118 9d20fe23 Kostas Papadimitriou
        ('module_medium_icon', 'im/auth/icons-medium/{module}.png'),
119 9d20fe23 Kostas Papadimitriou
        ('module_icon', 'im/auth/icons/{module}.png'))
120 9d20fe23 Kostas Papadimitriou
    )
121 9d20fe23 Kostas Papadimitriou
122 9d20fe23 Kostas Papadimitriou
    messages = {}
123 9d20fe23 Kostas Papadimitriou
    module_urls = {}
124 9d20fe23 Kostas Papadimitriou
125 564a2292 Kostas Papadimitriou
    remote_authenticate = True
126 564a2292 Kostas Papadimitriou
    remote_logout_url = None
127 d2633501 Kostas Papadimitriou
128 9d20fe23 Kostas Papadimitriou
    # templates
129 9d20fe23 Kostas Papadimitriou
    primary_login_template = 'im/auth/generic_primary_login.html'
130 9d20fe23 Kostas Papadimitriou
    login_template = 'im/auth/generic_login.html'
131 9d20fe23 Kostas Papadimitriou
    signup_template = 'im/signup.html'
132 9d20fe23 Kostas Papadimitriou
    login_prompt_template = 'im/auth/generic_login_prompt.html'
133 9d20fe23 Kostas Papadimitriou
    signup_prompt_template = 'im/auth/signup_prompt.html'
134 9d20fe23 Kostas Papadimitriou
135 9d20fe23 Kostas Papadimitriou
    default_policies = {
136 9d20fe23 Kostas Papadimitriou
        'login': True,
137 9d20fe23 Kostas Papadimitriou
        'create': True,
138 9d20fe23 Kostas Papadimitriou
        'add': True,
139 9d20fe23 Kostas Papadimitriou
        'remove': True,
140 9d20fe23 Kostas Papadimitriou
        'limit': 1,
141 9d20fe23 Kostas Papadimitriou
        'switch': True,
142 9d20fe23 Kostas Papadimitriou
        'add_groups': [],
143 9d20fe23 Kostas Papadimitriou
        'creation_groups': [],
144 9d20fe23 Kostas Papadimitriou
        'required': False,
145 9d20fe23 Kostas Papadimitriou
        'automoderate': not astakos_settings.MODERATION_ENABLED
146 9d20fe23 Kostas Papadimitriou
    }
147 9d20fe23 Kostas Papadimitriou
148 9d20fe23 Kostas Papadimitriou
    policies = {}
149 9d20fe23 Kostas Papadimitriou
150 9d20fe23 Kostas Papadimitriou
    def __init__(self, user=None, identifier=None, **provider_params):
151 9d20fe23 Kostas Papadimitriou
        """
152 9d20fe23 Kostas Papadimitriou
        3 ways to initialize (no args, user, user and identifier).
153 9d20fe23 Kostas Papadimitriou

154 9d20fe23 Kostas Papadimitriou
        no args: Used for anonymous unauthenticated users.
155 9d20fe23 Kostas Papadimitriou
        >>> p = auth_providers.get_provider('local')
156 9d20fe23 Kostas Papadimitriou
        >>> # check that global settings allows us to create a new account
157 9d20fe23 Kostas Papadimitriou
        >>> # using `local` provider.
158 9d20fe23 Kostas Papadimitriou
        >>> print p.is_available_for_create()
159 9d20fe23 Kostas Papadimitriou

160 9d20fe23 Kostas Papadimitriou
        user and identifier: Used to provide details about a user's specific
161 9d20fe23 Kostas Papadimitriou
        login method.
162 97246b51 Kostas Papadimitriou
        >>> p = auth_providers.get_provider('google', user,
163 97246b51 Kostas Papadimitriou
        >>>                                 identifier='1421421')
164 9d20fe23 Kostas Papadimitriou
        >>> # provider (google) details prompt
165 9d20fe23 Kostas Papadimitriou
        >>> print p.get_method_details()
166 9d20fe23 Kostas Papadimitriou
        "Google account: 1421421"
167 9d20fe23 Kostas Papadimitriou
        """
168 9d20fe23 Kostas Papadimitriou
169 9d20fe23 Kostas Papadimitriou
        # handle AnonymousUser instance
170 9d20fe23 Kostas Papadimitriou
        self.user = None
171 9d20fe23 Kostas Papadimitriou
        if user and hasattr(user, 'pk') and user.pk:
172 9d20fe23 Kostas Papadimitriou
            self.user = user
173 c4b1a172 Kostas Papadimitriou
174 9d20fe23 Kostas Papadimitriou
        self.identifier = identifier
175 9d20fe23 Kostas Papadimitriou
        self._instance = None
176 9d20fe23 Kostas Papadimitriou
        if 'instance' in provider_params:
177 9d20fe23 Kostas Papadimitriou
            self._instance = provider_params['instance']
178 9d20fe23 Kostas Papadimitriou
            del provider_params['instance']
179 9d20fe23 Kostas Papadimitriou
180 9d20fe23 Kostas Papadimitriou
        # initialize policies
181 9d20fe23 Kostas Papadimitriou
        self.module_policies = copy.copy(self.default_policies)
182 9d20fe23 Kostas Papadimitriou
        self.module_policies['automoderate'] = not \
183 9d20fe23 Kostas Papadimitriou
            astakos_settings.MODERATION_ENABLED
184 bc8bede2 Kostas Papadimitriou
        for policy, value in self.policies.iteritems():
185 9d20fe23 Kostas Papadimitriou
            setting_key = "%s_POLICY" % policy.upper()
186 9d20fe23 Kostas Papadimitriou
            if self.has_setting(setting_key):
187 9d20fe23 Kostas Papadimitriou
                self.module_policies[policy] = self.get_setting(setting_key)
188 7bb081f5 Kostas Papadimitriou
            else:
189 7bb081f5 Kostas Papadimitriou
                self.module_policies[policy] = value
190 9d20fe23 Kostas Papadimitriou
191 9d20fe23 Kostas Papadimitriou
        # messages cache
192 9d20fe23 Kostas Papadimitriou
        self.message_tpls_compiled = OrderedDict()
193 9d20fe23 Kostas Papadimitriou
194 9d20fe23 Kostas Papadimitriou
        # module specific messages
195 9d20fe23 Kostas Papadimitriou
        self.message_tpls = OrderedDict(self.message_tpls)
196 9d20fe23 Kostas Papadimitriou
        for key, value in self.messages.iteritems():
197 9d20fe23 Kostas Papadimitriou
            self.message_tpls[key] = value
198 9d20fe23 Kostas Papadimitriou
199 9d20fe23 Kostas Papadimitriou
        self._provider_details = provider_params
200 9d20fe23 Kostas Papadimitriou
201 9d20fe23 Kostas Papadimitriou
        self.resolve_available_methods = True
202 9d20fe23 Kostas Papadimitriou
203 9d20fe23 Kostas Papadimitriou
    def get_provider_model(self):
204 9d20fe23 Kostas Papadimitriou
        from astakos.im.models import AstakosUserAuthProvider as AuthProvider
205 9d20fe23 Kostas Papadimitriou
        return AuthProvider
206 9d20fe23 Kostas Papadimitriou
207 9d20fe23 Kostas Papadimitriou
    def remove_from_user(self):
208 9d20fe23 Kostas Papadimitriou
        if not self.get_remove_policy:
209 9d20fe23 Kostas Papadimitriou
            raise Exception("Provider cannot be removed")
210 9d20fe23 Kostas Papadimitriou
211 5d91dccb Kostas Papadimitriou
        for group_name in self.get_add_groups_policy:
212 5d91dccb Kostas Papadimitriou
            group = Group.objects.get(name=group_name)
213 5d91dccb Kostas Papadimitriou
            self.user.groups.remove(group)
214 5d91dccb Kostas Papadimitriou
            self.log('removed from group due to add_groups_policy %s',
215 5d91dccb Kostas Papadimitriou
                     group.name)
216 5d91dccb Kostas Papadimitriou
217 9d20fe23 Kostas Papadimitriou
        self._instance.delete()
218 5d91dccb Kostas Papadimitriou
        self.log('removed')
219 9d20fe23 Kostas Papadimitriou
220 9d20fe23 Kostas Papadimitriou
    def add_to_user(self, **params):
221 9d20fe23 Kostas Papadimitriou
        if self._instance:
222 9d20fe23 Kostas Papadimitriou
            raise Exception("Cannot add an existing provider")
223 9d20fe23 Kostas Papadimitriou
224 9d20fe23 Kostas Papadimitriou
        create = False
225 9d20fe23 Kostas Papadimitriou
        if self.get_user_providers().count() == 0:
226 9d20fe23 Kostas Papadimitriou
            create = True
227 9d20fe23 Kostas Papadimitriou
228 9d20fe23 Kostas Papadimitriou
        if create and not self.get_create_policy:
229 9d20fe23 Kostas Papadimitriou
            raise Exception("Provider not available for create")
230 9d20fe23 Kostas Papadimitriou
231 9d20fe23 Kostas Papadimitriou
        if not self.get_add_policy:
232 9d20fe23 Kostas Papadimitriou
            raise Exception("Provider cannot be added")
233 9d20fe23 Kostas Papadimitriou
234 9d20fe23 Kostas Papadimitriou
        if create:
235 9d20fe23 Kostas Papadimitriou
            for group_name in self.get_creation_groups_policy:
236 9d20fe23 Kostas Papadimitriou
                group, created = Group.objects.get_or_create(name=group_name)
237 9d20fe23 Kostas Papadimitriou
                self.user.groups.add(group)
238 97246b51 Kostas Papadimitriou
                self.log("added to %s group due to creation_groups_policy",
239 97246b51 Kostas Papadimitriou
                         group_name)
240 9d20fe23 Kostas Papadimitriou
241 9d20fe23 Kostas Papadimitriou
        for group_name in self.get_add_groups_policy:
242 9d20fe23 Kostas Papadimitriou
            group, created = Group.objects.get_or_create(name=group_name)
243 9d20fe23 Kostas Papadimitriou
            self.user.groups.add(group)
244 97246b51 Kostas Papadimitriou
            self.log("added to %s group due to add_groups_policy",
245 97246b51 Kostas Papadimitriou
                     group_name)
246 9d20fe23 Kostas Papadimitriou
247 9d20fe23 Kostas Papadimitriou
        if self.identifier:
248 9d20fe23 Kostas Papadimitriou
            pending = self.get_provider_model().objects.unverified(
249 9d20fe23 Kostas Papadimitriou
                self.module, identifier=self.identifier)
250 9d20fe23 Kostas Papadimitriou
251 9d20fe23 Kostas Papadimitriou
            if pending:
252 d7030402 Kostas Papadimitriou
                user = pending._instance.user
253 d7030402 Kostas Papadimitriou
                logger.info("Removing existing unverified user (%r)",
254 d7030402 Kostas Papadimitriou
                            user.log_display)
255 d7030402 Kostas Papadimitriou
                user.delete()
256 9d20fe23 Kostas Papadimitriou
257 9d20fe23 Kostas Papadimitriou
        create_params = {
258 9d20fe23 Kostas Papadimitriou
            'module': self.module,
259 9d20fe23 Kostas Papadimitriou
            'info_data': json.dumps(self.provider_details.get('info', {})),
260 9d20fe23 Kostas Papadimitriou
            'active': True,
261 9d20fe23 Kostas Papadimitriou
            'identifier': self.identifier
262 9d20fe23 Kostas Papadimitriou
        }
263 9d20fe23 Kostas Papadimitriou
        if 'info' in self.provider_details:
264 9d20fe23 Kostas Papadimitriou
            del self.provider_details['info']
265 9d20fe23 Kostas Papadimitriou
266 9d20fe23 Kostas Papadimitriou
        create_params.update(self.provider_details)
267 9d20fe23 Kostas Papadimitriou
        create_params.update(params)
268 97246b51 Kostas Papadimitriou
        create = self.user.auth_providers.create(**create_params)
269 97246b51 Kostas Papadimitriou
        self.log("created %r" % create_params)
270 97246b51 Kostas Papadimitriou
        return create
271 9d20fe23 Kostas Papadimitriou
272 9d20fe23 Kostas Papadimitriou
    def __repr__(self):
273 300ad310 Kostas Papadimitriou
        r = "'%r' module" % self.__class__.__name__
274 9d20fe23 Kostas Papadimitriou
        if self.user:
275 300ad310 Kostas Papadimitriou
            r += ' (user: %r)' % self.user
276 9d20fe23 Kostas Papadimitriou
        if self.identifier:
277 300ad310 Kostas Papadimitriou
            r += '(identifier: %r)' % self.identifier
278 9d20fe23 Kostas Papadimitriou
        return r
279 9d20fe23 Kostas Papadimitriou
280 9d20fe23 Kostas Papadimitriou
    def _message_params(self, **extra_params):
281 9d20fe23 Kostas Papadimitriou
        """
282 9d20fe23 Kostas Papadimitriou
        Retrieve message formating parameters.
283 9d20fe23 Kostas Papadimitriou
        """
284 9d20fe23 Kostas Papadimitriou
        params = {'module': self.module, 'module_title': self.module.title()}
285 9d20fe23 Kostas Papadimitriou
        if self.identifier:
286 9d20fe23 Kostas Papadimitriou
            params['identifier'] = self.identifier
287 c4b1a172 Kostas Papadimitriou
288 9d20fe23 Kostas Papadimitriou
        if self.user:
289 9d20fe23 Kostas Papadimitriou
            for key, val in self.user.__dict__.iteritems():
290 9d20fe23 Kostas Papadimitriou
                params["user_%s" % key.lower()] = val
291 9d20fe23 Kostas Papadimitriou
292 9d20fe23 Kostas Papadimitriou
        if self.provider_details:
293 9d20fe23 Kostas Papadimitriou
            for key, val in self.provider_details.iteritems():
294 9d20fe23 Kostas Papadimitriou
                params["provider_%s" % key.lower()] = val
295 9d20fe23 Kostas Papadimitriou
296 9d20fe23 Kostas Papadimitriou
            if 'info' in self.provider_details:
297 9d20fe23 Kostas Papadimitriou
                if isinstance(self.provider_details['info'], basestring):
298 9d20fe23 Kostas Papadimitriou
                    self.provider_details['info'] = \
299 9d20fe23 Kostas Papadimitriou
                        json.loads(self.provider_details['info'])
300 9d20fe23 Kostas Papadimitriou
                for key, val in self.provider_details['info'].iteritems():
301 cbc7a32c Kostas Papadimitriou
                    params['provider_info_%s' % key.lower()] = val
302 9d20fe23 Kostas Papadimitriou
303 9d20fe23 Kostas Papadimitriou
        # resolve username, handle unexisting defined username key
304 9d20fe23 Kostas Papadimitriou
        if self.user and self.username_key in params:
305 9d20fe23 Kostas Papadimitriou
            params['username'] = params[self.username_key]
306 9d20fe23 Kostas Papadimitriou
        else:
307 9d20fe23 Kostas Papadimitriou
            params['username'] = self.identifier
308 9d20fe23 Kostas Papadimitriou
309 0656aaa7 Giorgos Korfiatis
        branding_params = dict(
310 0656aaa7 Giorgos Korfiatis
            map(lambda k: (k[0].lower(), k[1]),
311 0656aaa7 Giorgos Korfiatis
                branding_utils.get_branding_dict().iteritems()))
312 cbc7a32c Kostas Papadimitriou
        params.update(branding_params)
313 cbc7a32c Kostas Papadimitriou
314 9d20fe23 Kostas Papadimitriou
        if not self.message_tpls_compiled:
315 9d20fe23 Kostas Papadimitriou
            for key, message_tpl in self.message_tpls.iteritems():
316 9d20fe23 Kostas Papadimitriou
                msg = self.messages.get(key, self.message_tpls.get(key))
317 9d20fe23 Kostas Papadimitriou
                override_in_settings = self.get_setting(key)
318 9d20fe23 Kostas Papadimitriou
                if override_in_settings is not None:
319 9d20fe23 Kostas Papadimitriou
                    msg = override_in_settings
320 9d20fe23 Kostas Papadimitriou
                try:
321 9d20fe23 Kostas Papadimitriou
                    self.message_tpls_compiled[key] = msg.format(**params)
322 9d20fe23 Kostas Papadimitriou
                    params.update(self.message_tpls_compiled)
323 9d20fe23 Kostas Papadimitriou
                except KeyError, e:
324 9d20fe23 Kostas Papadimitriou
                    continue
325 9d20fe23 Kostas Papadimitriou
        else:
326 9d20fe23 Kostas Papadimitriou
            params.update(self.message_tpls_compiled)
327 9d20fe23 Kostas Papadimitriou
328 9d20fe23 Kostas Papadimitriou
        for key, value in self.urls.iteritems():
329 9d20fe23 Kostas Papadimitriou
            params['%s_url' % key] = value
330 9d20fe23 Kostas Papadimitriou
331 9d20fe23 Kostas Papadimitriou
        if self.user and self.resolve_available_methods:
332 9d20fe23 Kostas Papadimitriou
            available_providers = self.user.get_enabled_auth_providers()
333 9d20fe23 Kostas Papadimitriou
            for p in available_providers:
334 9d20fe23 Kostas Papadimitriou
                p.resolve_available_methods = False
335 9d20fe23 Kostas Papadimitriou
                if p.module == self.module and p.identifier == self.identifier:
336 9d20fe23 Kostas Papadimitriou
                    available_providers.remove(p)
337 9d20fe23 Kostas Papadimitriou
338 9d20fe23 Kostas Papadimitriou
            get_msg = lambda p: p.get_method_prompt_msg
339 9d20fe23 Kostas Papadimitriou
            params['available_methods'] = \
340 9d20fe23 Kostas Papadimitriou
                ','.join(map(get_msg, available_providers))
341 9d20fe23 Kostas Papadimitriou
342 9d20fe23 Kostas Papadimitriou
            get_msg = lambda p: "<a href='%s'>%s</a>" % \
343 97246b51 Kostas Papadimitriou
                (p.get_login_url, p.get_method_prompt_msg)
344 9d20fe23 Kostas Papadimitriou
345 9d20fe23 Kostas Papadimitriou
            params['available_methods_links'] = \
346 9d20fe23 Kostas Papadimitriou
                ','.join(map(get_msg, available_providers))
347 9d20fe23 Kostas Papadimitriou
348 9d20fe23 Kostas Papadimitriou
        params.update(extra_params)
349 9d20fe23 Kostas Papadimitriou
        return params
350 9d20fe23 Kostas Papadimitriou
351 9d20fe23 Kostas Papadimitriou
    def get_template(self, tpl):
352 9d20fe23 Kostas Papadimitriou
        tpls = ['im/auth/%s_%s.html' % (self.module, tpl),
353 9d20fe23 Kostas Papadimitriou
                getattr(self, '%s_template' % tpl)]
354 9d20fe23 Kostas Papadimitriou
        found = None
355 9d20fe23 Kostas Papadimitriou
        for tpl in tpls:
356 9d20fe23 Kostas Papadimitriou
            try:
357 9d20fe23 Kostas Papadimitriou
                found = template.loader.get_template(tpl)
358 9d20fe23 Kostas Papadimitriou
                return tpl
359 9d20fe23 Kostas Papadimitriou
            except template.TemplateDoesNotExist:
360 9d20fe23 Kostas Papadimitriou
                continue
361 9d20fe23 Kostas Papadimitriou
        if not found:
362 9d20fe23 Kostas Papadimitriou
            raise template.TemplateDoesNotExist
363 9d20fe23 Kostas Papadimitriou
        return tpl
364 9d20fe23 Kostas Papadimitriou
365 9d20fe23 Kostas Papadimitriou
    def get_username(self):
366 9d20fe23 Kostas Papadimitriou
        return self.get_username_msg
367 9d20fe23 Kostas Papadimitriou
368 9d20fe23 Kostas Papadimitriou
    def get_user_providers(self):
369 680c383d Kostas Papadimitriou
        return self.user.auth_providers.active().filter(
370 680c383d Kostas Papadimitriou
            module__in=astakos_settings.IM_MODULES)
371 9d20fe23 Kostas Papadimitriou
372 9d20fe23 Kostas Papadimitriou
    def get_user_module_providers(self):
373 9d20fe23 Kostas Papadimitriou
        return self.user.auth_providers.active().filter(module=self.module)
374 9d20fe23 Kostas Papadimitriou
375 9d20fe23 Kostas Papadimitriou
    def get_existing_providers(self):
376 9d20fe23 Kostas Papadimitriou
        return ""
377 9d20fe23 Kostas Papadimitriou
378 9d20fe23 Kostas Papadimitriou
    def verified_exists(self):
379 9d20fe23 Kostas Papadimitriou
        return self.get_provider_model().objects.verified(
380 9d20fe23 Kostas Papadimitriou
            self.module, identifier=self.identifier)
381 9d20fe23 Kostas Papadimitriou
382 97246b51 Kostas Papadimitriou
    def resolve_policy(self, policy, default=None):
383 9d20fe23 Kostas Papadimitriou
384 9d20fe23 Kostas Papadimitriou
        if policy == 'switch' and default and not self.get_add_policy:
385 9d20fe23 Kostas Papadimitriou
            return not self.get_policy('remove')
386 9d20fe23 Kostas Papadimitriou
387 9d20fe23 Kostas Papadimitriou
        if not self.user:
388 9d20fe23 Kostas Papadimitriou
            return default
389 9d20fe23 Kostas Papadimitriou
390 9d20fe23 Kostas Papadimitriou
        if policy == 'remove' and default is True:
391 9d20fe23 Kostas Papadimitriou
            return self.get_user_providers().count() > 1
392 9d20fe23 Kostas Papadimitriou
393 9d20fe23 Kostas Papadimitriou
        if policy == 'add' and default is True:
394 9d20fe23 Kostas Papadimitriou
            limit = self.get_policy('limit')
395 9d20fe23 Kostas Papadimitriou
            if limit <= self.get_user_module_providers().count():
396 9d20fe23 Kostas Papadimitriou
                return False
397 9d20fe23 Kostas Papadimitriou
398 9d20fe23 Kostas Papadimitriou
            if self.identifier:
399 9d20fe23 Kostas Papadimitriou
                if self.verified_exists():
400 9d20fe23 Kostas Papadimitriou
                    return False
401 9d20fe23 Kostas Papadimitriou
402 9d20fe23 Kostas Papadimitriou
        return default
403 9d20fe23 Kostas Papadimitriou
404 9d20fe23 Kostas Papadimitriou
    def get_user_policies(self):
405 9d20fe23 Kostas Papadimitriou
        from astakos.im.models import AuthProviderPolicyProfile
406 9d20fe23 Kostas Papadimitriou
        return AuthProviderPolicyProfile.objects.for_user(self.user,
407 9d20fe23 Kostas Papadimitriou
                                                          self.module)
408 9d20fe23 Kostas Papadimitriou
409 9d20fe23 Kostas Papadimitriou
    def get_policy(self, policy):
410 9d20fe23 Kostas Papadimitriou
        module_default = self.module_policies.get(policy)
411 9d20fe23 Kostas Papadimitriou
        settings_key = '%s_POLICY' % policy.upper()
412 9d20fe23 Kostas Papadimitriou
        settings_default = self.get_setting(settings_key, module_default)
413 9d20fe23 Kostas Papadimitriou
414 9d20fe23 Kostas Papadimitriou
        if self.user:
415 9d20fe23 Kostas Papadimitriou
            user_policies = self.get_user_policies()
416 9d20fe23 Kostas Papadimitriou
            settings_default = user_policies.get(policy, settings_default)
417 9d20fe23 Kostas Papadimitriou
418 97246b51 Kostas Papadimitriou
        return self.resolve_policy(policy, settings_default)
419 9d20fe23 Kostas Papadimitriou
420 9d20fe23 Kostas Papadimitriou
    def get_message(self, msg, **extra_params):
421 9d20fe23 Kostas Papadimitriou
        """
422 9d20fe23 Kostas Papadimitriou
        Retrieve an auth provider message
423 9d20fe23 Kostas Papadimitriou
        """
424 9d20fe23 Kostas Papadimitriou
        if msg.endswith('_msg'):
425 9d20fe23 Kostas Papadimitriou
            msg = msg.replace('_msg', '')
426 9d20fe23 Kostas Papadimitriou
        params = self._message_params(**extra_params)
427 9d20fe23 Kostas Papadimitriou
428 9d20fe23 Kostas Papadimitriou
        # is message ???
429 9d20fe23 Kostas Papadimitriou
        tpl = self.message_tpls_compiled.get(msg.lower(), None)
430 9d20fe23 Kostas Papadimitriou
        if not tpl:
431 9d20fe23 Kostas Papadimitriou
            msg_key = 'AUTH_PROVIDER_%s' % msg.upper()
432 9d20fe23 Kostas Papadimitriou
            try:
433 9d20fe23 Kostas Papadimitriou
                tpl = getattr(astakos_messages, msg_key)
434 9d20fe23 Kostas Papadimitriou
            except AttributeError, e:
435 9d20fe23 Kostas Papadimitriou
                try:
436 9d20fe23 Kostas Papadimitriou
                    msg_key = msg.upper()
437 9d20fe23 Kostas Papadimitriou
                    tpl = getattr(astakos_messages, msg_key)
438 9d20fe23 Kostas Papadimitriou
                except AttributeError, e:
439 9d20fe23 Kostas Papadimitriou
                    tpl = ''
440 9d20fe23 Kostas Papadimitriou
441 9d20fe23 Kostas Papadimitriou
        in_settings = self.get_setting(msg)
442 9d20fe23 Kostas Papadimitriou
        if in_settings:
443 9d20fe23 Kostas Papadimitriou
            tpl = in_settings
444 9d20fe23 Kostas Papadimitriou
445 9d20fe23 Kostas Papadimitriou
        return tpl.format(**params)
446 dd5f8f4d Kostas Papadimitriou
447 0e79735c Kostas Papadimitriou
    @property
448 9d20fe23 Kostas Papadimitriou
    def urls(self):
449 9d20fe23 Kostas Papadimitriou
        urls = {
450 9d20fe23 Kostas Papadimitriou
            'login': reverse(self.login_view),
451 9d20fe23 Kostas Papadimitriou
            'add': reverse(self.login_view),
452 9d20fe23 Kostas Papadimitriou
            'profile': reverse('edit_profile'),
453 9d20fe23 Kostas Papadimitriou
        }
454 0e79735c Kostas Papadimitriou
        if self.user:
455 9d20fe23 Kostas Papadimitriou
            urls.update({
456 9d20fe23 Kostas Papadimitriou
                'resend_activation': self.user.get_resend_activation_url(),
457 9d20fe23 Kostas Papadimitriou
            })
458 9d20fe23 Kostas Papadimitriou
        if self.identifier and self._instance:
459 9d20fe23 Kostas Papadimitriou
            urls.update({
460 cbc7a32c Kostas Papadimitriou
                'switch': reverse(self.login_view) + '?switch_from=%d' %
461 cbc7a32c Kostas Papadimitriou
                self._instance.pk,
462 9d20fe23 Kostas Papadimitriou
                'remove': reverse('remove_auth_provider',
463 9d20fe23 Kostas Papadimitriou
                                  kwargs={'pk': self._instance.pk})
464 9d20fe23 Kostas Papadimitriou
            })
465 9d20fe23 Kostas Papadimitriou
        urls.update(self.module_urls)
466 9d20fe23 Kostas Papadimitriou
        return urls
467 9d20fe23 Kostas Papadimitriou
468 9d20fe23 Kostas Papadimitriou
    def get_setting_key(self, name):
469 9d20fe23 Kostas Papadimitriou
        return 'ASTAKOS_AUTH_PROVIDER_%s_%s' % (self.module.upper(),
470 9d20fe23 Kostas Papadimitriou
                                                name.upper())
471 9d20fe23 Kostas Papadimitriou
472 9d20fe23 Kostas Papadimitriou
    def get_global_setting_key(self, name):
473 9d20fe23 Kostas Papadimitriou
        return 'ASTAKOS_AUTH_PROVIDERS_%s' % name.upper()
474 9d20fe23 Kostas Papadimitriou
475 9d20fe23 Kostas Papadimitriou
    def has_global_setting(self, name):
476 9d20fe23 Kostas Papadimitriou
        return hasattr(settings, self.get_global_setting_key(name))
477 9d20fe23 Kostas Papadimitriou
478 9d20fe23 Kostas Papadimitriou
    def has_setting(self, name):
479 9d20fe23 Kostas Papadimitriou
        return hasattr(settings, self.get_setting_key(name))
480 0e79735c Kostas Papadimitriou
481 9d20fe23 Kostas Papadimitriou
    def get_setting(self, name, default=None):
482 9d20fe23 Kostas Papadimitriou
        attr = self.get_setting_key(name)
483 9d20fe23 Kostas Papadimitriou
        if not self.has_setting(name):
484 9d20fe23 Kostas Papadimitriou
            return self.get_global_setting(name, default)
485 9d20fe23 Kostas Papadimitriou
        return getattr(settings, attr, default)
486 0e79735c Kostas Papadimitriou
487 9d20fe23 Kostas Papadimitriou
    def get_global_setting(self, name, default=None):
488 9d20fe23 Kostas Papadimitriou
        attr = self.get_global_setting_key(name)
489 9d20fe23 Kostas Papadimitriou
        if not self.has_global_setting(name):
490 9d20fe23 Kostas Papadimitriou
            return default
491 9d20fe23 Kostas Papadimitriou
        return getattr(settings, attr, default)
492 9d20fe23 Kostas Papadimitriou
493 9d20fe23 Kostas Papadimitriou
    @property
494 9d20fe23 Kostas Papadimitriou
    def provider_details(self):
495 9d20fe23 Kostas Papadimitriou
        if self._provider_details:
496 9d20fe23 Kostas Papadimitriou
            return self._provider_details
497 564a2292 Kostas Papadimitriou
498 9d20fe23 Kostas Papadimitriou
        self._provider_details = {}
499 64492c49 Kostas Papadimitriou
500 9d20fe23 Kostas Papadimitriou
        if self._instance:
501 9d20fe23 Kostas Papadimitriou
            self._provider_details = self._instance.__dict__
502 bd0f516a Kostas Papadimitriou
503 9d20fe23 Kostas Papadimitriou
        if self.user and self.identifier:
504 9d20fe23 Kostas Papadimitriou
            if self.identifier:
505 9d20fe23 Kostas Papadimitriou
                try:
506 9d20fe23 Kostas Papadimitriou
                    self._provider_details = \
507 9d20fe23 Kostas Papadimitriou
                        self.user.get_auth_providers().get(
508 9d20fe23 Kostas Papadimitriou
                            module=self.module,
509 9d20fe23 Kostas Papadimitriou
                            identifier=self.identifier).__dict__
510 9d20fe23 Kostas Papadimitriou
                except Exception:
511 9d20fe23 Kostas Papadimitriou
                    return {}
512 9d20fe23 Kostas Papadimitriou
        return self._provider_details
513 d0632ab1 Olga Brani
514 081070a5 Kostas Papadimitriou
    def __getattr__(self, key):
515 081070a5 Kostas Papadimitriou
        if not key.startswith('get_'):
516 6974e526 Kostas Papadimitriou
            return super(AuthProvider, self).__getattribute__(key)
517 081070a5 Kostas Papadimitriou
518 9d20fe23 Kostas Papadimitriou
        key = key.replace('get_', '')
519 9d20fe23 Kostas Papadimitriou
        if key.endswith('_msg'):
520 9d20fe23 Kostas Papadimitriou
            return self.get_message(key)
521 91bbc1a4 Kostas Papadimitriou
522 9d20fe23 Kostas Papadimitriou
        if key.endswith('_policy'):
523 9d20fe23 Kostas Papadimitriou
            return self.get_policy(key.replace('_policy', ''))
524 d2633501 Kostas Papadimitriou
525 9d20fe23 Kostas Papadimitriou
        if key.endswith('_url'):
526 9d20fe23 Kostas Papadimitriou
            key = key.replace('_url', '')
527 9d20fe23 Kostas Papadimitriou
            return self.urls.get(key)
528 e9e692be Kostas Papadimitriou
529 9d20fe23 Kostas Papadimitriou
        if key.endswith('_icon'):
530 9d20fe23 Kostas Papadimitriou
            key = key.replace('_msg', '_icon')
531 9d20fe23 Kostas Papadimitriou
            return settings.MEDIA_URL + self.get_message(key)
532 d2633501 Kostas Papadimitriou
533 9d20fe23 Kostas Papadimitriou
        if key.endswith('_setting'):
534 9d20fe23 Kostas Papadimitriou
            key = key.replace('_setting', '')
535 9d20fe23 Kostas Papadimitriou
            return self.get_message(key)
536 d2633501 Kostas Papadimitriou
537 9d20fe23 Kostas Papadimitriou
        if key.endswith('_template'):
538 9d20fe23 Kostas Papadimitriou
            key = key.replace('_template', '')
539 9d20fe23 Kostas Papadimitriou
            return self.get_template(key)
540 d2633501 Kostas Papadimitriou
541 9d20fe23 Kostas Papadimitriou
        return super(AuthProvider, self).__getattribute__(key)
542 badcb2a9 Kostas Papadimitriou
543 d2633501 Kostas Papadimitriou
    def is_active(self):
544 9d20fe23 Kostas Papadimitriou
        return self.module_enabled
545 d2633501 Kostas Papadimitriou
546 97246b51 Kostas Papadimitriou
    @property
547 97246b51 Kostas Papadimitriou
    def log_display(self):
548 97246b51 Kostas Papadimitriou
        dsp = "%sAuth" % self.module.title()
549 97246b51 Kostas Papadimitriou
        if self.user:
550 97246b51 Kostas Papadimitriou
            dsp += "[%s]" % self.user.log_display
551 97246b51 Kostas Papadimitriou
            if self.identifier:
552 97246b51 Kostas Papadimitriou
                dsp += '[%s]' % self.identifier
553 97246b51 Kostas Papadimitriou
                if self._instance and self._instance.pk:
554 97246b51 Kostas Papadimitriou
                    dsp += '[%d]' % self._instance.pk
555 97246b51 Kostas Papadimitriou
        return dsp
556 97246b51 Kostas Papadimitriou
557 97246b51 Kostas Papadimitriou
    def log(self, msg, *args, **kwargs):
558 97246b51 Kostas Papadimitriou
        level = kwargs.pop('level', logging.INFO)
559 97246b51 Kostas Papadimitriou
        message = '%s: %s' % (self.log_display, msg)
560 97246b51 Kostas Papadimitriou
        logger.log(level, message, *args, **kwargs)
561 97246b51 Kostas Papadimitriou
562 d2633501 Kostas Papadimitriou
563 d2633501 Kostas Papadimitriou
class LocalAuthProvider(AuthProvider):
564 d2633501 Kostas Papadimitriou
    module = 'local'
565 9d20fe23 Kostas Papadimitriou
566 6a80a0ae Kostas Papadimitriou
    login_view = 'login'
567 564a2292 Kostas Papadimitriou
    remote_authenticate = False
568 9d20fe23 Kostas Papadimitriou
    username_key = 'user_email'
569 081070a5 Kostas Papadimitriou
570 9d20fe23 Kostas Papadimitriou
    messages = {
571 9d20fe23 Kostas Papadimitriou
        'title': _('Classic'),
572 9d20fe23 Kostas Papadimitriou
        'login_prompt': _('Classic login (username/password)'),
573 9d20fe23 Kostas Papadimitriou
        'login_success': _('Logged in successfully.'),
574 9d20fe23 Kostas Papadimitriou
        'method_details': 'Username: {username}',
575 9d20fe23 Kostas Papadimitriou
        'logout_success_extra': ' '
576 9d20fe23 Kostas Papadimitriou
    }
577 d2633501 Kostas Papadimitriou
578 bc8bede2 Kostas Papadimitriou
    policies = {
579 7bb081f5 Kostas Papadimitriou
        'limit': 1,
580 7bb081f5 Kostas Papadimitriou
        'switch': False
581 bc8bede2 Kostas Papadimitriou
    }
582 bc8bede2 Kostas Papadimitriou
583 d2633501 Kostas Papadimitriou
    @property
584 9d20fe23 Kostas Papadimitriou
    def urls(self):
585 9d20fe23 Kostas Papadimitriou
        urls = super(LocalAuthProvider, self).urls
586 6a80a0ae Kostas Papadimitriou
587 6a80a0ae Kostas Papadimitriou
        password_change_url = None
588 6a80a0ae Kostas Papadimitriou
        try:
589 6a80a0ae Kostas Papadimitriou
            password_change_url = reverse('password_change')
590 6a80a0ae Kostas Papadimitriou
        except NoReverseMatch:
591 6a80a0ae Kostas Papadimitriou
            pass
592 6a80a0ae Kostas Papadimitriou
593 6a80a0ae Kostas Papadimitriou
        urls['change_password'] = password_change_url
594 9d20fe23 Kostas Papadimitriou
        if self.user:
595 6a80a0ae Kostas Papadimitriou
            urls['add'] = password_change_url
596 9d20fe23 Kostas Papadimitriou
        if self._instance:
597 9d20fe23 Kostas Papadimitriou
            urls.update({
598 9d20fe23 Kostas Papadimitriou
                'remove': reverse('remove_auth_provider',
599 9d20fe23 Kostas Papadimitriou
                                  kwargs={'pk': self._instance.pk})
600 9d20fe23 Kostas Papadimitriou
            })
601 9d20fe23 Kostas Papadimitriou
            if 'switch' in urls:
602 9d20fe23 Kostas Papadimitriou
                del urls['switch']
603 9d20fe23 Kostas Papadimitriou
        return urls
604 9d20fe23 Kostas Papadimitriou
605 9d20fe23 Kostas Papadimitriou
    def remove_from_user(self):
606 9d20fe23 Kostas Papadimitriou
        super(LocalAuthProvider, self).remove_from_user()
607 9d20fe23 Kostas Papadimitriou
        self.user.set_unusable_password()
608 9d20fe23 Kostas Papadimitriou
        self.user.save()
609 d2633501 Kostas Papadimitriou
610 74796dd8 Kostas Papadimitriou
611 d2633501 Kostas Papadimitriou
class ShibbolethAuthProvider(AuthProvider):
612 d2633501 Kostas Papadimitriou
    module = 'shibboleth'
613 70e11eaa Sofia Papagiannaki
    login_view = 'astakos.im.views.target.shibboleth.login'
614 830747d2 Kostas Papadimitriou
    username_key = 'provider_info_eppn'
615 d2633501 Kostas Papadimitriou
616 7bb081f5 Kostas Papadimitriou
    policies = {
617 7bb081f5 Kostas Papadimitriou
        'switch': False
618 7bb081f5 Kostas Papadimitriou
    }
619 7bb081f5 Kostas Papadimitriou
620 9d20fe23 Kostas Papadimitriou
    messages = {
621 9d20fe23 Kostas Papadimitriou
        'title': _('Academic'),
622 6a80a0ae Kostas Papadimitriou
        'method_details': '{account_prompt}: {provider_info_eppn}',
623 9d20fe23 Kostas Papadimitriou
        'login_description': _('If you are a student, professor or researcher'
624 9d20fe23 Kostas Papadimitriou
                               ' you can login using your academic account.'),
625 cbc7a32c Kostas Papadimitriou
        'add_prompt': _('Allows you to login using your Academic '
626 cbc7a32c Kostas Papadimitriou
                        'account'),
627 9d20fe23 Kostas Papadimitriou
        'method_details': 'Account: {username}',
628 cbc7a32c Kostas Papadimitriou
        'logout_success_extra': _('You may still be logged in at your Academic'
629 cbc7a32c Kostas Papadimitriou
                                  ' account though. Consider logging out '
630 cbc7a32c Kostas Papadimitriou
                                  'from there too by closing all browser '
631 cbc7a32c Kostas Papadimitriou
                                  'windows')
632 9d20fe23 Kostas Papadimitriou
    }
633 ca5148f2 Kostas Papadimitriou
634 d2633501 Kostas Papadimitriou
635 c101b32b Kostas Papadimitriou
class TwitterAuthProvider(AuthProvider):
636 c101b32b Kostas Papadimitriou
    module = 'twitter'
637 70e11eaa Sofia Papagiannaki
    login_view = 'astakos.im.views.target.twitter.login'
638 9d20fe23 Kostas Papadimitriou
    username_key = 'provider_info_screen_name'
639 c101b32b Kostas Papadimitriou
640 9d20fe23 Kostas Papadimitriou
    messages = {
641 9d20fe23 Kostas Papadimitriou
        'title': _('Twitter'),
642 9d20fe23 Kostas Papadimitriou
        'method_details': 'Screen name: {username}',
643 9d20fe23 Kostas Papadimitriou
    }
644 c101b32b Kostas Papadimitriou
645 74796dd8 Kostas Papadimitriou
646 74796dd8 Kostas Papadimitriou
class GoogleAuthProvider(AuthProvider):
647 74796dd8 Kostas Papadimitriou
    module = 'google'
648 70e11eaa Sofia Papagiannaki
    login_view = 'astakos.im.views.target.google.login'
649 9d20fe23 Kostas Papadimitriou
    username_key = 'provider_info_email'
650 74796dd8 Kostas Papadimitriou
651 9d20fe23 Kostas Papadimitriou
    messages = {
652 9d20fe23 Kostas Papadimitriou
        'title': _('Google'),
653 9d20fe23 Kostas Papadimitriou
        'method_details': 'Email: {username}',
654 9d20fe23 Kostas Papadimitriou
    }
655 74796dd8 Kostas Papadimitriou
656 74796dd8 Kostas Papadimitriou
657 74796dd8 Kostas Papadimitriou
class LinkedInAuthProvider(AuthProvider):
658 74796dd8 Kostas Papadimitriou
    module = 'linkedin'
659 70e11eaa Sofia Papagiannaki
    login_view = 'astakos.im.views.target.linkedin.login'
660 9d20fe23 Kostas Papadimitriou
    username_key = 'provider_info_email'
661 74796dd8 Kostas Papadimitriou
662 9d20fe23 Kostas Papadimitriou
    messages = {
663 9d20fe23 Kostas Papadimitriou
        'title': _('LinkedIn'),
664 9d20fe23 Kostas Papadimitriou
        'method_details': 'Email: {username}',
665 9d20fe23 Kostas Papadimitriou
    }
666 74796dd8 Kostas Papadimitriou
667 74796dd8 Kostas Papadimitriou
668 9d20fe23 Kostas Papadimitriou
# Utility method
669 9d20fe23 Kostas Papadimitriou
def get_provider(module, user_obj=None, identifier=None, **params):
670 d2633501 Kostas Papadimitriou
    """
671 d2633501 Kostas Papadimitriou
    Return a provider instance from the auth providers registry.
672 d2633501 Kostas Papadimitriou
    """
673 9d20fe23 Kostas Papadimitriou
    if not module in PROVIDERS:
674 3f40ce16 Kostas Papadimitriou
        raise InvalidProvider('Invalid auth provider "%s"' % module)
675 d2633501 Kostas Papadimitriou
676 9d20fe23 Kostas Papadimitriou
    return PROVIDERS.get(module)(user_obj, identifier, **params)