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')