-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathbackend.py
More file actions
106 lines (90 loc) · 3.58 KB
/
backend.py
File metadata and controls
106 lines (90 loc) · 3.58 KB
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import logging
from django.conf import settings
from django.core.cache import cache
from django.contrib.auth import get_user_model
from django.utils.translation import gettext_lazy
from social_core.utils import cache as social_cache
from social_core.backends.open_id_connect import OpenIdConnectAuth
from rest_framework import exceptions
logger = logging.getLogger(__name__)
User = get_user_model()
class DryccOIDC(OpenIdConnectAuth):
"""Drycc Openid Connect authentication backend"""
name = 'drycc'
AUTHORIZATION_URL = settings.SOCIAL_AUTH_DRYCC_AUTHORIZATION_URL
ACCESS_TOKEN_URL = settings.SOCIAL_AUTH_DRYCC_ACCESS_TOKEN_URL
USERINFO_URL = settings.SOCIAL_AUTH_DRYCC_USERINFO_URL
JWKS_URI = settings.SOCIAL_AUTH_DRYCC_JWKS_URI
OIDC_ENDPOINT = settings.SOCIAL_AUTH_DRYCC_OIDC_ENDPOINT
DEFAULT_SCOPE = ['openid']
EXTRA_DATA = [
('id', 'id'),
('access_token', 'access_token'),
('refresh_token', 'refresh_token'),
('expires_in', 'expires_in'),
('token_type', 'token_type'),
('id_token', 'id_token'),
('scope', 'scope'),
]
def __init__(self, *args, **kwargs):
self.timeout = 3 # request timeout
super().__init__(*args, **kwargs)
@social_cache(ttl=86400)
def oidc_config(self):
return self.get_json(
self.OIDC_ENDPOINT + '/.well-known/openid-configuration/',
timeout=self.timeout
)
def get_user_data(self, access_token):
"""Loads user data from service"""
url = settings.SOCIAL_AUTH_DRYCC_USERINFO_URL
response = self.get_json(
url,
headers={
'authorization': 'Bearer ' + access_token
},
timeout=self.timeout,
)
return {
'id': response.get('id'),
'username': response.get('username'),
'email': response.get('email') or '',
'first_name': response.get('first_name'),
'last_name': response.get('last_name'),
'is_superuser': response.get('is_superuser'),
'is_staff': response.get('is_staff'),
'is_active': response.get('is_active'),
}
def refresh_token(self, refresh_token):
return self.get_json(
settings.SOCIAL_AUTH_DRYCC_ACCESS_TOKEN_URL,
method='POST',
data={
'grant_type': 'refresh_token',
'client_id': settings.SOCIAL_AUTH_DRYCC_KEY,
'refresh_token': refresh_token,
},
timeout=self.timeout,
)
class OauthCacheManager(object):
def __init__(self):
self.drycc_oauth = DryccOIDC()
def get_user(self, access_token):
def _get_user(access_token):
from api import serializers
try:
user_info = self.drycc_oauth.get_user_data(access_token)
user, _ = serializers.UserSerializer.update_or_create(user_info)
return user
except Exception as e:
logger.info(e)
raise exceptions.AuthenticationFailed(gettext_lazy('Verify token fail.'))
return cache.get_or_set(
access_token, lambda: _get_user(access_token), settings.DRYCC_CACHE_USER_TIME)
def set_state(self, key, state):
cache.set("oidc_key_" + key, state, settings.DRYCC_CACHE_USER_TIME)
def set_token(self, state, data):
cache.set("oidc_state_" + state, data, settings.DRYCC_CACHE_USER_TIME)
def get_token(self, key):
state = cache.get("oidc_key_" + key, "")
return cache.get("oidc_state_" + state, {})