digitaleagenturnc/users/middleware/oauth.py

117 lines
4.4 KiB
Python

import re
from requests.api import request
from authlib.integrations.base_client import OAuthError
from authlib.integrations.django_client import OAuth
from authlib.oauth2.rfc6749 import OAuth2Token
from django.shortcuts import redirect
from django.utils.deprecation import MiddlewareMixin
from users.models import Agency, Profile
from django.contrib.auth.models import User
from django.contrib.auth import login, logout
from digitaleagentur import settings
import requests, json
class OAuthMiddleware(MiddlewareMixin):
def __init__(self, get_response=None):
super().__init__(get_response)
self.oauth = OAuth()
def process_request(self, request):
if settings.OAUTH_URL_WHITELISTS is not None:
for w in settings.OAUTH_URL_WHITELISTS:
if request.path.startswith(w):
return self.get_response(request)
def update_token(token, refresh_token, access_token):
request.session['token'] = token
return None
# Check, if logged user is in Database - if not, create and save by SUB
def checkUserInDatabase(userdata):
# Get sub of current user
sub = userdata
activeuser = None
# Check in Database, if user exist - if not, create new user
if not User.objects.filter(username = sub).exists():
pr = Profile(user=None, agency=Agency.objects.get(pk=1))
pr.save()
activeuser = User.objects.create(username=sub, profile=pr)
pr.user = activeuser
pr.save()
else:
activeuser = User.objects.get(username=sub)
if activeuser is not None:
headers = {
'Authorization': 'Bearer ' + request.session.get('token').get('access_token'),
'Content-Type': 'application/json',
'Accept': 'application/json',
}
data = {}
#response = requests.get("http://localhost:8080/apps/agency/getcurrentuser", data=data, headers=headers)
#print(response.text)
login(request, activeuser)
sso_client = self.oauth.register(
settings.OAUTH_CLIENT_NAME, overwrite=True, **settings.OAUTH_CLIENT, update_token=update_token
)
if request.path.startswith('/oauth/callback'):
self.clear_session(request)
request.session['token'] = sso_client.authorize_access_token(request)
if self.get_current_user(sso_client, request) is not None:
redirect_uri = request.session.pop('redirect_uri', None)
if redirect_uri is not None:
return redirect(redirect_uri)
return redirect('users-dashboard')
if request.session.get('token', None) is not None:
#current_user = self.get_current_user(sso_client, request)
current_user = request.session.get('token').get('user_id')
if current_user is not None:
checkUserInDatabase(current_user)
return self.get_response(request)
# remember redirect URI for redirecting to the original URL.
request.session['redirect_uri'] = request.path
return sso_client.authorize_redirect(request, settings.OAUTH_CLIENT['redirect_uri'])
# fetch current login user info
# 1. check if it's in cache
# 2. fetch from remote API when it's not in cache
@staticmethod
def get_current_user(sso_client, request):
token = request.session.get('token', None)
if token is None or 'access_token' not in token:
return None
if not OAuth2Token.from_dict(token).is_expired() and 'user' in request.session:
return request.session['user']
try:
res = sso_client.get(settings.OAUTH_CLIENT['userinfo_endpoint'], token=OAuth2Token(token))
if res.ok:
#request.session['user'] = res.json()
#request.session['user'] = res
return True
#return res.json()
else:
print(res)
except OAuthError as e:
print(e)
return None
@staticmethod
def clear_session(request):
try:
del request.session['user']
del request.session['token']
except KeyError:
pass
def __del__(self):
print('destroyed')