1
|
|
|
''' |
2
|
|
|
A Python Social (PSA) authentication backend. |
3
|
|
|
|
4
|
|
|
It performs no authentication by itself, but believes in auth information that is |
5
|
|
|
stored by a separate view in the *session*. |
6
|
|
|
|
7
|
|
|
This is used for performing the authentication in an independent view, |
8
|
|
|
but managing the database and user creation still in PSA. |
9
|
|
|
|
10
|
|
|
Since PSA really wants to do all login views by itself, |
11
|
|
|
the separate auth view needs to redirect to '/login/passthrough/' |
12
|
|
|
after storing all data in the session variable SESSION_VAR. |
13
|
|
|
The keys can be seen in get_user_details(). |
14
|
|
|
|
15
|
|
|
After the redirect, everything works as usual in Python Social, |
16
|
|
|
with the only exception that the auth_url redirect is no longer needed. |
17
|
|
|
''' |
18
|
|
|
|
19
|
|
|
from social_core.backends.base import BaseAuth |
20
|
|
|
from django.core.exceptions import PermissionDenied |
21
|
|
|
from opensubmit import settings |
22
|
|
|
|
23
|
|
|
SESSION_VAR = 'passthrough_auth_data_' + settings.SECRET_KEY |
24
|
|
|
|
25
|
|
|
|
26
|
|
|
class PassThroughAuth(BaseAuth): |
27
|
|
|
name = 'passthrough' |
28
|
|
|
|
29
|
|
|
def auth_url(self): |
30
|
|
|
"""Must return redirect URL to auth provider.""" |
31
|
|
|
return '/complete/%s/' % self.name |
32
|
|
|
|
33
|
|
|
def auth_complete(self, *args, **kwargs): |
34
|
|
|
"""Completes loging process, must return user instance""" |
35
|
|
|
if SESSION_VAR not in self.strategy.request.session: |
36
|
|
|
# This is the only protection layer when people |
37
|
|
|
# go directly to the passthrough login view. |
38
|
|
|
raise PermissionDenied |
39
|
|
|
auth_data = self.strategy.request.session[SESSION_VAR] |
40
|
|
|
kwargs.update({'response': auth_data, 'backend': self}) |
41
|
|
|
return self.strategy.authenticate(*args, **kwargs) |
42
|
|
|
|
43
|
|
|
def get_user_details(self, response): |
44
|
|
|
""" Complete with additional information from session, as available. """ |
45
|
|
|
result = { |
46
|
|
|
'id': response['id'], |
47
|
|
|
'username': response.get('username', None), |
48
|
|
|
'email': response.get('email', None), |
49
|
|
|
'first_name': response.get('first_name', None), |
50
|
|
|
'last_name': response.get('last_name', None) |
51
|
|
|
} |
52
|
|
|
if result['first_name'] and result['last_name']: |
53
|
|
|
result['fullname'] = result['first_name'] + \ |
54
|
|
|
' ' + result['last_name'] |
55
|
|
|
return result |
56
|
|
|
|
57
|
|
|
def get_user_id(self, details, response): |
58
|
|
|
"""Return a unique ID for the current user, by default from server response.""" |
59
|
|
|
return response['id'] |
60
|
|
|
|