Merge branch 'improve-oauth' into 'master'
Improve oauth See merge request bestuur/kers!1
This commit is contained in:
commit
01db89727e
2 changed files with 54 additions and 33 deletions
11
oauth/templates/oauth/failed.html
Normal file
11
oauth/templates/oauth/failed.html
Normal file
|
@ -0,0 +1,11 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Login Failed{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h2>Login Failed</h2>
|
||||
|
||||
{% if error %}
|
||||
<h3>{{ error }}</h3>
|
||||
{% endif %}
|
||||
{% endblock %}
|
|
@ -4,7 +4,7 @@ import requests
|
|||
from django.conf import settings
|
||||
from django.contrib.auth import login
|
||||
from django.http.request import HttpRequest
|
||||
from django.shortcuts import redirect
|
||||
from django.shortcuts import redirect, render
|
||||
|
||||
import users
|
||||
from users.models import CustomUser
|
||||
|
@ -25,37 +25,26 @@ def register(_):
|
|||
|
||||
|
||||
def register_callback(req: HttpRequest):
|
||||
code = req.GET['code']
|
||||
csrftoken = req.COOKIES.get('csrftoken')
|
||||
print(csrftoken)
|
||||
response = requests.post(settings.OAUTH["ACCESS_TOKEN_URI"],
|
||||
data={'code': code,
|
||||
'grant_type': 'authorization_code',
|
||||
'client_id': settings.OAUTH["CLIENT_ID"],
|
||||
'client_secret': settings.OAUTH["CLIENT_SECRET"],
|
||||
'redirect_uri': settings.OAUTH["REDIRECT_URI"]},
|
||||
cookies=None,
|
||||
headers={'Referer': f'{settings.SERVER_URL}/login/zeus/register'})
|
||||
if 'code' not in req.GET or 'error' in req.GET:
|
||||
error = req.GET['error'] if 'error' in req.GET else None
|
||||
return login_fail(req, error)
|
||||
|
||||
try:
|
||||
if response.status_code == 200:
|
||||
json: dict = response.json()
|
||||
print(response.cookies)
|
||||
# TODO: maybe later do something with the refresh token.
|
||||
user: dict = user_info(json['access_token'], csrftoken)
|
||||
if 'username' not in user.keys() or 'id' not in user.keys():
|
||||
raise OAuthException(f'username and id are expected values: {user}')
|
||||
else:
|
||||
logger.debug(f'Succesfully authenticated user: {user["username"]} with id: {user["id"]}')
|
||||
validated_user = validate_user(user['id'], user['username'])
|
||||
login(req, validated_user)
|
||||
redirect('/')
|
||||
else:
|
||||
print(response.request)
|
||||
raise OAuthException(f'Status code not 200, response: {response}: {response.text}')
|
||||
access_token = get_access_token(req.GET['code'])
|
||||
user_info = get_user_info(access_token)
|
||||
|
||||
logger.debug(f'Succesfully authenticated user: {user_info["username"]} with id: {user_info["id"]}')
|
||||
|
||||
validated_user = validate_user(user_info['id'], user_info['username'])
|
||||
login(req, validated_user)
|
||||
return redirect('/')
|
||||
except OAuthException as e:
|
||||
logger.error(e)
|
||||
return login_fail(req, str(e))
|
||||
|
||||
return redirect('/')
|
||||
|
||||
def login_fail(request, error: str = None):
|
||||
return render(request, "oauth/failed.html", {'error': error})
|
||||
|
||||
|
||||
def validate_user(zeus_id, username) -> CustomUser:
|
||||
|
@ -64,14 +53,35 @@ def validate_user(zeus_id, username) -> CustomUser:
|
|||
user.username = username
|
||||
user.save()
|
||||
return user
|
||||
except users.models.CustomUser.DoesNotExist as e:
|
||||
except users.models.CustomUser.DoesNotExist:
|
||||
return CustomUser.objects.create_user(zeus_id, username)
|
||||
|
||||
|
||||
def user_info(access_token, csrftoken):
|
||||
r = requests.get(
|
||||
def get_access_token(code):
|
||||
response = requests.post(
|
||||
settings.OAUTH["ACCESS_TOKEN_URI"],
|
||||
data={'code': code,
|
||||
'grant_type': 'authorization_code',
|
||||
'client_id': settings.OAUTH["CLIENT_ID"],
|
||||
'client_secret': settings.OAUTH["CLIENT_SECRET"],
|
||||
'redirect_uri': settings.OAUTH["REDIRECT_URI"]},
|
||||
headers={'Referer': f'{settings.SERVER_URL}/login/zeus/register'})
|
||||
if response.status_code is not 200:
|
||||
raise OAuthException(
|
||||
f'Status code {response.status_code} when requesting access token.\nresponse: {response.text}')
|
||||
if 'access_token' not in response.json():
|
||||
raise OAuthException('Got status code 200 but no access_token')
|
||||
return response.json()['access_token']
|
||||
|
||||
|
||||
def get_user_info(access_token):
|
||||
response = requests.get(
|
||||
settings.OAUTH["USER_API_URI"],
|
||||
headers={'Authorization': f'Bearer {access_token}'},
|
||||
cookies={'csrftoken': csrftoken}
|
||||
)
|
||||
return r.json()
|
||||
if response.status_code is not 200:
|
||||
raise OAuthException(
|
||||
f'Status code {response.status_code} when requesting user info.\nresponse: {response.text}')
|
||||
if 'username' not in response.json() or 'id' not in response.json():
|
||||
raise OAuthException(f'username and id are expected values: {response.json()}')
|
||||
return response.json()
|
||||
|
|
Loading…
Reference in a new issue