Fix OpenId login

This commit is contained in:
Christian Cueni 2022-04-06 19:58:53 +02:00
parent c6adf1ca41
commit 29258c4348
4 changed files with 53 additions and 2 deletions

View File

@ -0,0 +1,14 @@
from django.db import models
class UserManager(models.Manager):
def create_or_update_by_email(self, email: str, first_name: str, last_name: str, username: str) -> bool:
# create or sync user with OpenID Data
_user, created = self.model.objects.get_or_create(email=email, defaults={
"first_name": first_name,
"last_name": last_name,
"username": username
})
return created

View File

@ -2,12 +2,15 @@ from django.contrib.auth.models import AbstractUser
from django.db import models from django.db import models
from django.db.models import JSONField from django.db.models import JSONField
from vbv_lernwelt.core.managers import UserManager
class User(AbstractUser): class User(AbstractUser):
""" """
Default custom user model for VBV Lernwelt. Default custom user model for VBV Lernwelt.
If adding fields that need to be filled at user signup, If adding fields that need to be filled at user signup,
""" """
objects = UserManager()
class SecurityRequestResponseLog(models.Model): class SecurityRequestResponseLog(models.Model):

View File

@ -0,0 +1,21 @@
import logging
import base64
import json
logger = logging.getLogger(__name__)
def decode_jwt(jwt: str):
jwt_parts = jwt.split('.')
try:
payload_bytes = base64.urlsafe_b64decode(_correct_padding(jwt_parts[1]))
payload = json.loads(payload_bytes.decode("UTF-8"))
except Exception as e:
logger.warning(f'OAuthToken error: Could not decode jwt: {e}')
return None
return payload
# https://stackoverflow.com/questions/2941995/python-ignore-incorrect-padding-error-when-base64-decoding
def _correct_padding(data: str) -> str:
return f"{data}{'=' * (4 - len(data) % 4)}"

View File

@ -3,9 +3,10 @@ from authlib.integrations.base_client import OAuthError
from django.conf import settings from django.conf import settings
from django.shortcuts import redirect from django.shortcuts import redirect
from sentry_sdk import capture_exception from sentry_sdk import capture_exception
from django.contrib.auth import login as dj_login from django.contrib.auth import login as dj_login, get_user_model
from vbv_lernwelt.sso.client import oauth from vbv_lernwelt.sso.client import oauth
from vbv_lernwelt.sso.jwt import decode_jwt
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -22,12 +23,24 @@ def authorize(request):
try: try:
logger.debug(request) logger.debug(request)
token = oauth.lernetz.authorize_access_token(request) token = oauth.lernetz.authorize_access_token(request)
print(token) deocded_token = decode_jwt(token["access_token"])
except OAuthError as e: except OAuthError as e:
logger.warning(f'OAuth error: {e}') logger.warning(f'OAuth error: {e}')
if not settings.DEBUG: if not settings.DEBUG:
capture_exception(e) capture_exception(e)
return redirect(f'/{OAUTH_REDIRECT}?state=someerror') return redirect(f'/{OAUTH_REDIRECT}?state=someerror')
user_data = _user_data_from_token_data(deocded_token)
created = get_user_model().objects.create_or_update_by_email(user_data["email"], user_data["first_name"],
user_data["last_name"], user_data["username"])
return redirect(f'/{OAUTH_REDIRECT}?state=success') return redirect(f'/{OAUTH_REDIRECT}?state=success')
def _user_data_from_token_data(token: dict) -> dict:
return {
"first_name": token.get("given_name", ""),
"last_name": token.get("family_name", ""),
"username": token.get("preferred_username", ""),
"email": token.get("email", ""),
}