Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (21.6 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 d2633501 Kostas Papadimitriou
from django.core.urlresolvers import reverse
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 d2633501 Kostas Papadimitriou
import logging
50 d2633501 Kostas Papadimitriou
51 d2633501 Kostas Papadimitriou
logger = logging.getLogger(__name__)
52 d2633501 Kostas Papadimitriou
53 d2633501 Kostas Papadimitriou
# providers registry
54 6012535a Kostas Papadimitriou
PROVIDERS = {}
55 badcb2a9 Kostas Papadimitriou
REQUIRED_PROVIDERS = {}
56 d2633501 Kostas Papadimitriou
57 9d20fe23 Kostas Papadimitriou
58 d2633501 Kostas Papadimitriou
class AuthProviderBase(type):
59 d2633501 Kostas Papadimitriou
60 d2633501 Kostas Papadimitriou
    def __new__(cls, name, bases, dct):
61 d2633501 Kostas Papadimitriou
        include = False
62 d2633501 Kostas Papadimitriou
        if [b for b in bases if isinstance(b, AuthProviderBase)]:
63 d2633501 Kostas Papadimitriou
            type_id = dct.get('module')
64 d2633501 Kostas Papadimitriou
            if type_id:
65 d2633501 Kostas Papadimitriou
                include = True
66 081070a5 Kostas Papadimitriou
            if type_id in astakos_settings.IM_MODULES:
67 591068ae Kostas Papadimitriou
                if astakos_settings.IM_MODULES.index(type_id) == 0:
68 591068ae Kostas Papadimitriou
                    dct['is_primary'] = True
69 d2633501 Kostas Papadimitriou
                dct['module_enabled'] = True
70 d2633501 Kostas Papadimitriou
71 d2633501 Kostas Papadimitriou
        newcls = super(AuthProviderBase, cls).__new__(cls, name, bases, dct)
72 d2633501 Kostas Papadimitriou
        if include:
73 6012535a Kostas Papadimitriou
            PROVIDERS[type_id] = newcls
74 9d20fe23 Kostas Papadimitriou
            if newcls().get_required_policy:
75 badcb2a9 Kostas Papadimitriou
                REQUIRED_PROVIDERS[type_id] = newcls
76 d2633501 Kostas Papadimitriou
        return newcls
77 d2633501 Kostas Papadimitriou
78 d2633501 Kostas Papadimitriou
79 d2633501 Kostas Papadimitriou
class AuthProvider(object):
80 d2633501 Kostas Papadimitriou
81 d2633501 Kostas Papadimitriou
    __metaclass__ = AuthProviderBase
82 d2633501 Kostas Papadimitriou
83 d2633501 Kostas Papadimitriou
    module = None
84 d2633501 Kostas Papadimitriou
    module_enabled = False
85 591068ae Kostas Papadimitriou
    is_primary = False
86 9d20fe23 Kostas Papadimitriou
87 9d20fe23 Kostas Papadimitriou
    message_tpls = OrderedDict((
88 9d20fe23 Kostas Papadimitriou
        ('title', '{module_title}'),
89 9d20fe23 Kostas Papadimitriou
        ('login_title', '{title} LOGIN'),
90 9d20fe23 Kostas Papadimitriou
        ('method_prompt', '{title} login'),
91 9d20fe23 Kostas Papadimitriou
        ('account_prompt', '{title} account'),
92 9d20fe23 Kostas Papadimitriou
        ('signup_title', '{title}'),
93 9d20fe23 Kostas Papadimitriou
        ('profile_title', '{title}'),
94 9d20fe23 Kostas Papadimitriou
        ('method_details', '{account_prompt}: {identifier}'),
95 9d20fe23 Kostas Papadimitriou
        ('primary_login_prompt', 'Login using '),
96 9d20fe23 Kostas Papadimitriou
        ('required', '{title} is required. You can assign it '
97 9d20fe23 Kostas Papadimitriou
                     'from your profile page'),
98 9d20fe23 Kostas Papadimitriou
        ('login_prompt', ''),
99 9d20fe23 Kostas Papadimitriou
        ('add_prompt', 'Allows you to login using {title}'),
100 9d20fe23 Kostas Papadimitriou
        ('login_extra', ''),
101 9d20fe23 Kostas Papadimitriou
        ('username', '{username}'),
102 9d20fe23 Kostas Papadimitriou
        ('disabled_for_create', '{title} is not available for signup.'),
103 9d20fe23 Kostas Papadimitriou
        ('switch_success', 'Account changed successfully.'),
104 9d20fe23 Kostas Papadimitriou
        ('cannot_login', '{title} is not available for login. '
105 9d20fe23 Kostas Papadimitriou
                         'Please use one of your other available methods '
106 9d20fe23 Kostas Papadimitriou
                         'to login ({available_methods_links}'),
107 9d20fe23 Kostas Papadimitriou
108 9d20fe23 Kostas Papadimitriou
        # icons should end with _icon
109 9d20fe23 Kostas Papadimitriou
        ('module_medium_icon', 'im/auth/icons-medium/{module}.png'),
110 9d20fe23 Kostas Papadimitriou
        ('module_icon', 'im/auth/icons/{module}.png'))
111 9d20fe23 Kostas Papadimitriou
    )
112 9d20fe23 Kostas Papadimitriou
113 9d20fe23 Kostas Papadimitriou
    messages = {}
114 9d20fe23 Kostas Papadimitriou
    module_urls = {}
115 9d20fe23 Kostas Papadimitriou
116 564a2292 Kostas Papadimitriou
    remote_authenticate = True
117 564a2292 Kostas Papadimitriou
    remote_logout_url = None
118 d2633501 Kostas Papadimitriou
119 9d20fe23 Kostas Papadimitriou
    # templates
120 9d20fe23 Kostas Papadimitriou
    primary_login_template = 'im/auth/generic_primary_login.html'
121 9d20fe23 Kostas Papadimitriou
    login_template = 'im/auth/generic_login.html'
122 9d20fe23 Kostas Papadimitriou
    signup_template = 'im/signup.html'
123 9d20fe23 Kostas Papadimitriou
    login_prompt_template = 'im/auth/generic_login_prompt.html'
124 9d20fe23 Kostas Papadimitriou
    signup_prompt_template = 'im/auth/signup_prompt.html'
125 9d20fe23 Kostas Papadimitriou
126 9d20fe23 Kostas Papadimitriou
    default_policies = {
127 9d20fe23 Kostas Papadimitriou
        'login': True,
128 9d20fe23 Kostas Papadimitriou
        'create': True,
129 9d20fe23 Kostas Papadimitriou
        'add': True,
130 9d20fe23 Kostas Papadimitriou
        'remove': True,
131 9d20fe23 Kostas Papadimitriou
        'limit': 1,
132 9d20fe23 Kostas Papadimitriou
        'switch': True,
133 9d20fe23 Kostas Papadimitriou
        'add_groups': [],
134 9d20fe23 Kostas Papadimitriou
        'creation_groups': [],
135 9d20fe23 Kostas Papadimitriou
        'required': False,
136 9d20fe23 Kostas Papadimitriou
        'automoderate': not astakos_settings.MODERATION_ENABLED
137 9d20fe23 Kostas Papadimitriou
    }
138 9d20fe23 Kostas Papadimitriou
139 9d20fe23 Kostas Papadimitriou
    policies = {}
140 9d20fe23 Kostas Papadimitriou
141 9d20fe23 Kostas Papadimitriou
    def __init__(self, user=None, identifier=None, **provider_params):
142 9d20fe23 Kostas Papadimitriou
        """
143 9d20fe23 Kostas Papadimitriou
        3 ways to initialize (no args, user, user and identifier).
144 9d20fe23 Kostas Papadimitriou

145 9d20fe23 Kostas Papadimitriou
        no args: Used for anonymous unauthenticated users.
146 9d20fe23 Kostas Papadimitriou
        >>> p = auth_providers.get_provider('local')
147 9d20fe23 Kostas Papadimitriou
        >>> # check that global settings allows us to create a new account
148 9d20fe23 Kostas Papadimitriou
        >>> # using `local` provider.
149 9d20fe23 Kostas Papadimitriou
        >>> print p.is_available_for_create()
150 9d20fe23 Kostas Papadimitriou

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