From 1644e61d98329ea69ca9407e83e087366bbfa3e5 Mon Sep 17 00:00:00 2001 From: Francis Date: Wed, 22 Jul 2020 21:19:31 +0200 Subject: [PATCH 1/2] reformat oauth code --- oauth/views.py | 72 ++++++++++++++++++++++++++++---------------------- 1 file changed, 41 insertions(+), 31 deletions(-) diff --git a/oauth/views.py b/oauth/views.py index 5027976..50afd74 100644 --- a/oauth/views.py +++ b/oauth/views.py @@ -25,36 +25,25 @@ 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: + return login_fail('') + 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(str(e)) + +def login_fail(error: str): + # TODO: create login failed page return redirect('/') @@ -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() From 6de3f2ab40d13090f34dd239627a1ec3f9a15bb9 Mon Sep 17 00:00:00 2001 From: Francis Date: Wed, 22 Jul 2020 21:34:19 +0200 Subject: [PATCH 2/2] add failed page --- oauth/templates/oauth/failed.html | 11 +++++++++++ oauth/views.py | 12 ++++++------ 2 files changed, 17 insertions(+), 6 deletions(-) create mode 100644 oauth/templates/oauth/failed.html diff --git a/oauth/templates/oauth/failed.html b/oauth/templates/oauth/failed.html new file mode 100644 index 0000000..aee4cd6 --- /dev/null +++ b/oauth/templates/oauth/failed.html @@ -0,0 +1,11 @@ +{% extends "base.html" %} + +{% block title %}Login Failed{% endblock %} + +{% block content %} +

Login Failed

+ + {% if error %} +

{{ error }}

+ {% endif %} +{% endblock %} diff --git a/oauth/views.py b/oauth/views.py index 50afd74..37c8643 100644 --- a/oauth/views.py +++ b/oauth/views.py @@ -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 @@ -26,7 +26,8 @@ def register(_): def register_callback(req: HttpRequest): if 'code' not in req.GET or 'error' in req.GET: - return login_fail('') + error = req.GET['error'] if 'error' in req.GET else None + return login_fail(req, error) try: access_token = get_access_token(req.GET['code']) @@ -39,12 +40,11 @@ def register_callback(req: HttpRequest): return redirect('/') except OAuthException as e: logger.error(e) - return login_fail(str(e)) + return login_fail(req, str(e)) -def login_fail(error: str): - # TODO: create login failed page - return redirect('/') +def login_fail(request, error: str = None): + return render(request, "oauth/failed.html", {'error': error}) def validate_user(zeus_id, username) -> CustomUser: