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.models import JSONField
from vbv_lernwelt.core.managers import UserManager
class User(AbstractUser):
"""
Default custom user model for VBV Lernwelt.
If adding fields that need to be filled at user signup,
"""
objects = UserManager()
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.shortcuts import redirect
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.jwt import decode_jwt
logger = logging.getLogger(__name__)
@ -22,12 +23,24 @@ def authorize(request):
try:
logger.debug(request)
token = oauth.lernetz.authorize_access_token(request)
print(token)
deocded_token = decode_jwt(token["access_token"])
except OAuthError as e:
logger.warning(f'OAuth error: {e}')
if not settings.DEBUG:
capture_exception(e)
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')
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", ""),
}