From d728e02beeb166d22cdf75a7bc2515bd7d44fec2 Mon Sep 17 00:00:00 2001 From: Andrea Lepori Date: Tue, 4 Jan 2022 12:31:37 +0100 Subject: autoupdate oauth token when expired --- accounts/views.py | 66 ++++++++++++-------------- client/migrations/0011_usercode_midata_code.py | 18 +++++++ client/models.py | 1 + version.txt | 2 +- 4 files changed, 51 insertions(+), 36 deletions(-) create mode 100644 client/migrations/0011_usercode_midata_code.py diff --git a/accounts/views.py b/accounts/views.py index abfd184..d8de4fe 100644 --- a/accounts/views.py +++ b/accounts/views.py @@ -4,7 +4,7 @@ from django.shortcuts import redirect from django.conf import settings from django.contrib.auth.forms import UserCreationForm from django.contrib.auth.models import User -from django.contrib.auth import login, authenticate +from django.contrib.auth import login, authenticate, logout from django.http import FileResponse from django.contrib.auth.decorators import login_required from django.views.decorators.debug import sensitive_variables @@ -26,21 +26,7 @@ from pdf2image.exceptions import ( PDFSyntaxError ) -def update_token(name, token, refresh_token=None, access_token=None): - if refresh_token: - item = OAuth2Token.find(name=name, refresh_token=refresh_token) - elif access_token: - item = OAuth2Token.find(name=name, access_token=access_token) - else: - return - - # update old token - item.access_token = token['access_token'] - item.refresh_token = token.get('refresh_token') - item.expires_at = token['expires_at'] - item.save() - -oauth = OAuth(update_token=update_token) +oauth = OAuth() hitobito = oauth.register(name="hitobito") api_url = settings.AUTHLIB_OAUTH_CLIENTS["hitobito"]["api_url"] @@ -52,6 +38,15 @@ class RegisterForm(UserCreationForm): for fieldname in ['username', 'password1', 'password2']: self.fields[fieldname].help_text = None +def get_oauth_data(token): + # request data from user account + headers = { + "Authorization" : "Bearer " + token, + "X-Scope": "with_roles", + } + + return requests.get(api_url, headers=headers) + # send to hitobito request to get token def oauth_login(request): redirect_uri = request.build_absolute_uri(reverse('auth')) @@ -59,15 +54,11 @@ def oauth_login(request): # callback after acquiring token def auth(request): + code = request.GET["code"] token = hitobito.authorize_access_token(request) # request data from user account - headers = { - "Authorization" : "Bearer " + token["access_token"], - "X-Scope": "with_roles", - } - resp = requests.get(api_url, headers=headers) - resp_data = resp.json() + resp_data = get_oauth_data(token["access_token"]).json() # find user with that id usercode = UserCode.objects.filter(midata_id=resp_data["id"]) @@ -85,6 +76,8 @@ def auth(request): usercode[0].cap = resp_data["zip_code"] usercode[0].country = resp_data["town"] usercode[0].born_date = dateparser.parse(resp_data["birthday"]) + usercode[0].midata_token = token["access_token"] + usercode[0].midata_code = code usercode[0].save() return HttpResponseRedirect('/') @@ -99,7 +92,7 @@ def auth(request): medic = MedicalData() medic.save() - userCode = UserCode(user=user, code=code, medic=medic, midata_id=resp_data["id"], midata_token=token["access_token"]) + userCode = UserCode(user=user, code=code, medic=medic, midata_id=resp_data["id"], midata_token=token["access_token"], midata_code=code) user.first_name = resp_data["first_name"] user.last_name = resp_data["last_name"] user.email = resp_data["email"] @@ -126,6 +119,7 @@ def oauth_disconnect(request): usercode = UserCode.objects.filter(user=request.user)[0] usercode.midata_id = 0 usercode.midata_token = "" + usercode.midata_code = "" usercode.save() return HttpResponseRedirect(reverse("personal") + "#settings") @@ -136,12 +130,7 @@ def auth_connect(request): token = hitobito.authorize_access_token(request) # request data from user account - headers = { - "Authorization" : "Bearer " + token["access_token"], - "X-Scope": "with_roles", - } - resp = requests.get(api_url, headers=headers) - resp_data = resp.json() + resp_data = get_oauth_data(token["access_token"]).json() # check that account is not linked to another existing_codes = UserCode.objects.filter(midata_id=resp_data["id"]) @@ -152,6 +141,7 @@ def auth_connect(request): usercode = UserCode.objects.filter(user=request.user)[0] usercode.midata_id = resp_data["id"] usercode.midata_token = token["access_token"] + usercode.midata_code = request.GET["code"] usercode.save() return HttpResponseRedirect(reverse("personal") + "#settings") @@ -483,13 +473,19 @@ def personal_wrapper(request, error, error_text): midata_disable = "" if midata_user: - # request data from user account - headers = { - "Authorization" : "Bearer " + usercode.midata_token, - "X-Scope": "with_roles", - } + resp = get_oauth_data(usercode.midata_token) + + if resp.status_code != 200: + request.GET["code"] = usercode.midata_code + token = hitobito.authorize_access_token(request) + usercode.midata_token = token["access_token"] + usercode.save() + resp = get_oauth_data(usercode.midata_token) + + if resp.status_code != 200: + logout(request) + return HttpResponseRedirect("/") - resp = requests.get(api_url, headers=headers) resp_data = resp.json() midata_disable = " disabled" diff --git a/client/migrations/0011_usercode_midata_code.py b/client/migrations/0011_usercode_midata_code.py new file mode 100644 index 0000000..a5f3601 --- /dev/null +++ b/client/migrations/0011_usercode_midata_code.py @@ -0,0 +1,18 @@ +# Generated by Django 3.1.4 on 2022-01-04 11:10 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('client', '0010_auto_20220102_1933'), + ] + + operations = [ + migrations.AddField( + model_name='usercode', + name='midata_code', + field=models.CharField(default='', max_length=1024), + ), + ] diff --git a/client/models.py b/client/models.py index b94806b..5f0da0d 100644 --- a/client/models.py +++ b/client/models.py @@ -115,6 +115,7 @@ class UserCode(models.Model): avs_number = models.CharField(default="", max_length=250) midata_id = models.IntegerField(default=0) midata_token = models.CharField(default="", max_length=1024) + midata_code = models.CharField(default="", max_length=1024) class GroupSettings(models.Model): group = models.ForeignKey(Group, default=None, on_delete=models.CASCADE) diff --git a/version.txt b/version.txt index 6fcdb3a..b74496b 100644 --- a/version.txt +++ b/version.txt @@ -1,2 +1,2 @@ version=0.4 -rev=11 +rev=12 -- cgit v1.2.1