from rest_framework import generics from collections import namedtuple from translation import models as translation_models from utils import exceptions from rest_framework.response import Response # JWT # Login base view mixin class JWTViewMixin(generics.GenericAPIView): """JWT view mixin""" ACCESS_TOKEN_HTTP = True ACCESS_TOKEN_SECURE = False REFRESH_TOKEN_HTTP = True REFRESH_TOKEN_SECURE = False COOKIE = namedtuple('COOKIE', ['key', 'value', 'http', 'secure']) def _check_locale(self, locale: str): locale_qs = translation_models.Language.objects.by_locale(locale=locale) if not locale_qs.exists(): raise exceptions.LocaleNotExisted() return locale def _put_data_in_cookies(self, locale: str, access_token: str, refresh_token: str): """ CHECK locale in cookies and PUT access and refresh tokens there. cookies it is list that contain namedtuples cookies would contain key, value and secure parameters. """ COOKIES = list() # Create locale namedtuple locale = self.COOKIE(key='locale', value=locale, http=True, secure=False) COOKIES.append(locale) # Write to cookie access and refresh token with secure flag _access_token = self.COOKIE(key='access_token', value=access_token, http=self.ACCESS_TOKEN_HTTP, secure=self.ACCESS_TOKEN_SECURE) _refresh_token = self.COOKIE(key='refresh_token', value=refresh_token, http=self.REFRESH_TOKEN_HTTP, secure=self.REFRESH_TOKEN_SECURE) COOKIES.extend((_access_token, _refresh_token)) return COOKIES def _put_cookies_in_response(self, cookies: list, response: Response): """Update COOKIES in response from namedtuple""" for cookie in cookies: response.set_cookie(key=cookie.key, value=cookie.value, secure=cookie.secure) return response def _get_tokens_from_cookies(self, request, cookies: dict = None): """Get user tokens from cookies and put in namedtuple""" _cookies = request.COOKIES or cookies return [self.COOKIE(key='access_token', value=_cookies.get('access_token'), http=self.ACCESS_TOKEN_HTTP, secure=self.ACCESS_TOKEN_SECURE), self.COOKIE(key='refresh_token', value=_cookies.get('refresh_token'), http=self.REFRESH_TOKEN_HTTP, secure=self.REFRESH_TOKEN_SECURE)] def get(self, request, *args, **kwargs): """Implement GET method""" _locale = request.COOKIES.get('locale') try: locale = self._check_locale(locale=_locale) queryset = self.filter_queryset(self.get_queryset()) page = self.paginate_queryset(queryset) if page is not None: serializer = self.get_serializer(page, many=True) response = self.get_paginated_response(serializer.data) else: serializer = self.get_serializer(queryset, many=True) response = Response(serializer.data) access_token, refresh_token = self._get_tokens_from_cookies(request) except exceptions.LocaleNotExisted: raise exceptions.LocaleNotExisted(locale=_locale) else: return self._put_cookies_in_response( cookies=self._put_data_in_cookies(locale=locale, access_token=access_token, refresh_token=refresh_token), response=response)