From 8411d51eb7816bc726492679743a072af9e765dc Mon Sep 17 00:00:00 2001 From: Nikita Manovich Date: Thu, 5 Dec 2019 13:29:21 +0300 Subject: [PATCH 1/3] Restore session id if we try to login using TokenAuth. --- cvat/apps/authentication/decorators.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cvat/apps/authentication/decorators.py b/cvat/apps/authentication/decorators.py index 047883596457..ca80da3ba3bc 100644 --- a/cvat/apps/authentication/decorators.py +++ b/cvat/apps/authentication/decorators.py @@ -9,6 +9,7 @@ from django.http import JsonResponse from django.conf import settings from rest_framework.authentication import TokenAuthentication +from django.contrib.auth import login def login_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME, login_url=None, redirect_methods=['GET']): @@ -21,7 +22,8 @@ def _wrapped_view(request, *args, **kwargs): tokenAuth = TokenAuthentication() auth = tokenAuth.authenticate(request) if auth is not None: - request.user = auth[0] + # If only token is available let's restore session id. + login(request, auth[0], 'django.contrib.auth.backends.ModelBackend') return view_func(request, *args, **kwargs) login_url = '{}/login'.format(settings.UI_URL) From e46561e94ba60aaf5096e5d4852cd1934c85ce86 Mon Sep 17 00:00:00 2001 From: Nikita Manovich Date: Thu, 5 Dec 2019 15:22:39 +0300 Subject: [PATCH 2/3] Restore session id when we use token authorization. --- cvat/apps/authentication/auth.py | 14 ++++++++++++++ cvat/apps/authentication/decorators.py | 4 +--- cvat/settings/base.py | 2 +- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/cvat/apps/authentication/auth.py b/cvat/apps/authentication/auth.py index 2f54558c62af..2951df7e76df 100644 --- a/cvat/apps/authentication/auth.py +++ b/cvat/apps/authentication/auth.py @@ -11,6 +11,20 @@ from rest_framework.permissions import BasePermission from django.core import signing from rest_framework import authentication, exceptions +from rest_framework.authentication import TokenAuthentication as _TokenAuthentication +from django.contrib.auth import login + +# Even with token authorization it is very important to have a valid session id +# in cookies because in some cases we cannot use token authorization (e.g. when +# we redirect to the server in UI using just URL). To overkill that we override +# the class to call `login` method which restores the session id in cookies. +class TokenAuthentication(_TokenAuthentication): + def authenticate(self, request): + auth = super().authenticate(request) + session = getattr(request, 'session') + if auth is not None and session.session_key is None: + login(request, auth[0], 'django.contrib.auth.backends.ModelBackend') + return auth def register_signals(): from django.db.models.signals import post_migrate, post_save diff --git a/cvat/apps/authentication/decorators.py b/cvat/apps/authentication/decorators.py index ca80da3ba3bc..1e014b305e5e 100644 --- a/cvat/apps/authentication/decorators.py +++ b/cvat/apps/authentication/decorators.py @@ -8,7 +8,7 @@ from django.contrib.auth import REDIRECT_FIELD_NAME from django.http import JsonResponse from django.conf import settings -from rest_framework.authentication import TokenAuthentication +from cvat.apps.authentication.auth import TokenAuthentication from django.contrib.auth import login def login_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME, @@ -22,8 +22,6 @@ def _wrapped_view(request, *args, **kwargs): tokenAuth = TokenAuthentication() auth = tokenAuth.authenticate(request) if auth is not None: - # If only token is available let's restore session id. - login(request, auth[0], 'django.contrib.auth.backends.ModelBackend') return view_func(request, *args, **kwargs) login_url = '{}/login'.format(settings.UI_URL) diff --git a/cvat/settings/base.py b/cvat/settings/base.py index 579cf8992254..b91af63fe96d 100644 --- a/cvat/settings/base.py +++ b/cvat/settings/base.py @@ -124,7 +124,7 @@ def generate_ssh_keys(): 'rest_framework.permissions.IsAuthenticated', ], 'DEFAULT_AUTHENTICATION_CLASSES': [ - 'rest_framework.authentication.TokenAuthentication', + 'cvat.apps.authentication.auth.TokenAuthentication', 'cvat.apps.authentication.auth.SignatureAuthentication', 'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.BasicAuthentication' From 55c0f46ea88b144a6f77d9c8aa426e80c4e88e8c Mon Sep 17 00:00:00 2001 From: Nikita Manovich Date: Thu, 5 Dec 2019 15:25:28 +0300 Subject: [PATCH 3/3] Removed unused imports --- cvat/apps/authentication/auth.py | 1 - cvat/apps/authentication/decorators.py | 1 - 2 files changed, 2 deletions(-) diff --git a/cvat/apps/authentication/auth.py b/cvat/apps/authentication/auth.py index 2951df7e76df..539707bbeca9 100644 --- a/cvat/apps/authentication/auth.py +++ b/cvat/apps/authentication/auth.py @@ -2,7 +2,6 @@ # # SPDX-License-Identifier: MIT -import os from django.conf import settings from django.db.models import Q import rules diff --git a/cvat/apps/authentication/decorators.py b/cvat/apps/authentication/decorators.py index 1e014b305e5e..569b13520fef 100644 --- a/cvat/apps/authentication/decorators.py +++ b/cvat/apps/authentication/decorators.py @@ -9,7 +9,6 @@ from django.http import JsonResponse from django.conf import settings from cvat.apps.authentication.auth import TokenAuthentication -from django.contrib.auth import login def login_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME, login_url=None, redirect_methods=['GET']):