-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathviews.py
83 lines (70 loc) · 2.85 KB
/
views.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
from django.conf import settings
from django.contrib import auth, messages
from django.utils.http import is_safe_url
from django.views.generic.base import RedirectView
from oauth2client import client
from .utils import do_with_retry
def _get_flow(request):
"""
Get the oauth flow to use for the given request.The flow can be specified
in the query string for step 1, and is then stored in the session for
retrival on step 2.
"""
flow_name = request.GET.get('flow') or request.session.get(
settings.GOOGLE_OAUTH2_FLOW_SESSION_KEY, 'default')
request.session[settings.GOOGLE_OAUTH2_FLOW_SESSION_KEY] = flow_name
flow_kwargs = settings.GOOGLE_OAUTH2_FLOWS.get(
flow_name) or settings.GOOGLE_OAUTH2_FLOWS['default']
flow_kwargs['redirect_uri'] = '{}://{}{}'.format(
request.scheme,
request.get_host(),
str(settings.GOOGLE_OAUTH2_REDIRECT_URI))
return do_with_retry(
client.OAuth2WebServerFlow,
_attempts=5,
_catch=client.FlowExchangeError,
**flow_kwargs
)
def _get_authorize_url(request, state):
flow = _get_flow(request)
authorize_url = flow.step1_get_authorize_url(state=state)
return authorize_url
class OauthStepOne(RedirectView):
"""
Handle the first step of oauth flow
"""
permanent = False
def get_redirect_url(self, *args, **kwargs):
continue_url = self.request.GET.get(auth.REDIRECT_FIELD_NAME)
state = self.request.GET.get('state')
if continue_url:
self.request.session[
settings.LOGIN_REDIRECT_SESSION_KEY] = continue_url
authorize_url = _get_authorize_url(self.request, state)
return authorize_url
class OauthStepTwo(RedirectView):
"""
Handle second and final step of oauth flow
"""
def get_redirect_url(self, *args, **kwargs):
code = self.request.GET.get('code', '')
flow = _get_flow(self.request)
try:
credentials = flow.step2_exchange(code=code)
except client.FlowExchangeError:
messages.error(self.request, 'Try connecting your account again.')
return settings.LOGIN_URL
# This will use our custom backend to get user info from Google and
# get or create the User object
user = auth.authenticate(oauth_credentials=credentials)
if not user:
messages.error(self.request, 'Try connecting your account again.')
return settings.LOGIN_URL
# associate that user with the current browser session
auth.login(self.request, user)
continue_url = self.request.session.pop(
settings.LOGIN_REDIRECT_SESSION_KEY, None)
if not continue_url or not is_safe_url(
url=continue_url, host=self.request.get_host()):
continue_url = settings.LOGIN_REDIRECT_URL
return continue_url