From 7926fee19b2241e2f3facef8b6eb8789f5d97d49 Mon Sep 17 00:00:00 2001 From: Andrea Lepori Date: Wed, 23 Mar 2022 19:10:35 +0100 Subject: initial support of user switcher --- accounts/urls.py | 1 + accounts/views.py | 75 +++++++++++++++++++++++++++++++++ client/templatetags/app_filter.py | 11 ++++- client/views.py | 2 +- templates/registration/base_client.html | 34 +++++++++++++-- version.txt | 2 +- 6 files changed, 118 insertions(+), 7 deletions(-) diff --git a/accounts/urls.py b/accounts/urls.py index 46cb438..b35796b 100644 --- a/accounts/urls.py +++ b/accounts/urls.py @@ -12,4 +12,5 @@ urlpatterns = [ path('oauth_connect/', views.oauth_connect, name='oauth_connect'), path('oauth_disconnect/', views.oauth_disconnect, name='oauth_disconnect'), path('auth_connect/', views.auth_connect, name='auth_connect'), + path('user_switcher/', views.user_switcher, name='user_switcher'), ] diff --git a/accounts/views.py b/accounts/views.py index cd17552..e9d2bfe 100644 --- a/accounts/views.py +++ b/accounts/views.py @@ -1,3 +1,4 @@ +import datetime from django.shortcuts import render from django.urls import reverse from django.conf import settings @@ -15,6 +16,7 @@ from client.models import UserCode, MedicalData from authlib.integrations.django_client import OAuth +import json import dateparser import os import requests @@ -203,6 +205,79 @@ def auth_connect(request): return HttpResponseRedirect(reverse("personal") + "#settings") +@sensitive_variables("sessionid") +def set_session_cookie(response, sessionid, expires): + expires_date = datetime.datetime.fromtimestamp(int(expires)) + max_age = (expires_date - datetime.datetime.utcnow()).total_seconds() + response.set_cookie( + "sessionid", + sessionid, + max_age=max_age, + expires=expires, + domain=settings.SESSION_COOKIE_DOMAIN, + secure=settings.SESSION_COOKIE_SECURE, + httponly=settings.SESSION_COOKIE_HTTPONLY, + samesite=settings.SESSION_COOKIE_SAMESITE, + ) + +@sensitive_variables("data") +def set_switch_cookie(response, data): + + max_age = 30 * 60 * 60 * 24 + expires = datetime.datetime.strftime( + datetime.datetime.utcnow() + datetime.timedelta(seconds=max_age), + "%a, %d-%b-%Y %H:%M:%S GMT", + ) + response.set_cookie( + "user_switcher", + json.dumps(data), + max_age=max_age, + expires=expires, + domain=settings.SESSION_COOKIE_DOMAIN, + secure=settings.SESSION_COOKIE_SECURE, + httponly=settings.SESSION_COOKIE_HTTPONLY, + samesite=settings.SESSION_COOKIE_SAMESITE, + ) + +@sensitive_variables("sessions") +def user_switcher(request): + if request.method == 'POST': + if request.POST["metadata"] == 'new': + response = HttpResponseRedirect('/accounts/login') + + sessions = dict() + if "user_switcher" in request.COOKIES: + sessions = json.loads(request.COOKIES.get("user_switcher")) + + sessions[request.user.username] = (request.session.session_key, request.session.get_expiry_date().timestamp()) + set_switch_cookie(response, sessions) + + response.set_cookie("sessionid", "") + + return response + + if request.POST["metadata"][0] == 's': + response = HttpResponseRedirect("/") + username = request.POST["metadata"][1:] + + sessions = dict() + if "user_switcher" in request.COOKIES: + sessions = json.loads(request.COOKIES.get("user_switcher")) + + sessions[request.user.username] = (request.session.session_key, request.session.get_expiry_date().timestamp()) + set_switch_cookie(response, sessions) + + if username in sessions: + set_session_cookie(response, sessions[username][0], sessions[username][1]) + else: + set_session_cookie(response, "", 0) + + print("done") + return response + + + return HttpResponseRedirect("/") + @sensitive_variables("raw_passsword") def signup(request): out_errors = [] diff --git a/client/templatetags/app_filter.py b/client/templatetags/app_filter.py index df92775..c447d35 100644 --- a/client/templatetags/app_filter.py +++ b/client/templatetags/app_filter.py @@ -2,6 +2,8 @@ from django import template from django.db.models.query_utils import Q from client.models import Document, KeyVal, Keys +import json + register = template.Library() @register.filter(name="doc_key") def doc_key(doc): @@ -46,4 +48,11 @@ def parse_multiple_choice(str): if len(arr) < 2: return [arr[0], []] - return [arr[0], arr[1:]] \ No newline at end of file + return [arr[0], arr[1:]] + +@register.filter(name="parse_userswitcher") +def parse_userswitcher(str): + if not str: + return [] + + return json.loads(str).keys() \ No newline at end of file diff --git a/client/views.py b/client/views.py index 0f1bfaa..04ebaf9 100644 --- a/client/views.py +++ b/client/views.py @@ -2,7 +2,7 @@ from django.db.models.expressions import OuterRef, Subquery from django.template.loader import get_template from client.models import GroupSettings, UserCode, Keys, DocumentType, Document, PersonalData, KeyVal, MedicalData from django.db.models import Q -from django.http import HttpResponseRedirect, FileResponse +from django.http import HttpResponse, HttpResponseRedirect, FileResponse from django.contrib.auth.decorators import login_required from django.shortcuts import render from accounts.views import copy_from_midata diff --git a/templates/registration/base_client.html b/templates/registration/base_client.html index 362238c..8543852 100644 --- a/templates/registration/base_client.html +++ b/templates/registration/base_client.html @@ -5,6 +5,7 @@ {% load static %} + {% load app_filter %}