gault-millau/apps/utils/views.py
2019-11-21 18:12:52 +03:00

159 lines
6.5 KiB
Python

from collections import namedtuple
from django.conf import settings
from django.db.transaction import on_commit
from django.shortcuts import get_object_or_404
from rest_framework import generics, status
from rest_framework.response import Response
from gallery.tasks import delete_image
from search_indexes.documents import es_update
# JWT
# Login base view mixins
class JWTGenericViewMixin(generics.GenericAPIView):
"""JWT view mixin"""
ACCESS_TOKEN_HTTP_ONLY = False
ACCESS_TOKEN_SECURE = False
REFRESH_TOKEN_HTTP_ONLY = False
REFRESH_TOKEN_SECURE = False
LOCALE_HTTP_ONLY = False
LOCALE_SECURE = False
COUNTRY_CODE_HTTP_ONLY = False
COUNTRY_CODE_SECURE = False
COOKIE = namedtuple('COOKIE', ['key', 'value', 'http_only', 'secure', 'max_age'])
def _put_data_in_cookies(self,
access_token: str = None,
refresh_token: str = None,
permanent: bool = None):
"""
cookies it is list that contain namedtuples
cookies would contain key, value and secure parameters.
"""
COOKIES = []
if hasattr(self.request, 'locale'):
COOKIES.append(self.COOKIE(key='locale',
value=self.request.locale,
http_only=self.ACCESS_TOKEN_HTTP_ONLY,
secure=self.LOCALE_SECURE,
max_age=settings.COOKIES_MAX_AGE if permanent else None))
if hasattr(self.request, 'country_code'):
COOKIES.append(self.COOKIE(key='country_code',
value=self.request.country_code,
http_only=self.COUNTRY_CODE_HTTP_ONLY,
secure=self.COUNTRY_CODE_SECURE,
max_age=settings.COOKIES_MAX_AGE if permanent else None))
if access_token:
COOKIES.append(self.COOKIE(key='access_token',
value=access_token,
http_only=self.ACCESS_TOKEN_HTTP_ONLY,
secure=self.ACCESS_TOKEN_SECURE,
max_age=settings.COOKIES_MAX_AGE if permanent else None))
if refresh_token:
COOKIES.append(self.COOKIE(key='refresh_token',
value=refresh_token,
http_only=self.REFRESH_TOKEN_HTTP_ONLY,
secure=self.REFRESH_TOKEN_SECURE,
max_age=settings.COOKIES_MAX_AGE if permanent else None))
return COOKIES
def _put_cookies_in_response(self, cookies: list, response: Response):
"""Update COOKIES in response from namedtuple"""
for cookie in cookies:
# todo: remove config for develop
from os import environ
configuration = environ.get('SETTINGS_CONFIGURATION', None)
if configuration == 'development' or configuration == 'stage':
response.set_cookie(key=cookie.key,
value=cookie.value,
secure=cookie.secure,
httponly=cookie.http_only,
max_age=cookie.max_age,
domain='.id-east.ru')
else:
response.set_cookie(key=cookie.key,
value=cookie.value,
secure=cookie.secure,
httponly=cookie.http_only,
max_age=cookie.max_age,)
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_only=self.ACCESS_TOKEN_HTTP_ONLY,
secure=self.ACCESS_TOKEN_SECURE,
max_age=_cookies.get('max_age')),
self.COOKIE(key='refresh_token',
value=_cookies.get('refresh_token'),
http_only=self.REFRESH_TOKEN_HTTP_ONLY,
secure=self.REFRESH_TOKEN_SECURE,
max_age=_cookies.get('max_age'))]
class CreateDestroyGalleryViewMixin(generics.CreateAPIView,
generics.DestroyAPIView):
"""Mixin for creating and destroying entity linked with gallery."""
def create(self, request, *args, **kwargs):
"""Overridden create method"""
super().create(request, *args, **kwargs)
return Response(status=status.HTTP_201_CREATED)
def destroy(self, request, *args, **kwargs):
"""Override destroy method."""
gallery_obj = self.get_object()
if settings.USE_CELERY:
on_commit(lambda: delete_image.delay(image_id=gallery_obj.image.id,
completely=False))
else:
on_commit(lambda: delete_image(image_id=gallery_obj.image.id,
completely=False))
# Delete an instances of Gallery model
gallery_obj.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
class FavoritesCreateDestroyMixinView(generics.CreateAPIView,
generics.DestroyAPIView):
"""Favorites Create Destroy mixin."""
_model = None
serializer_class = None
lookup_field = 'slug'
def get_base_object(self):
return get_object_or_404(self._model, slug=self.kwargs['slug'])
def get_object(self):
"""
Returns the object the view is displaying.
"""
obj = self.get_base_object()
favorites = get_object_or_404(obj.favorites.filter(user=self.request.user))
# May raise a permission denied
self.check_object_permissions(self.request, favorites)
return favorites
def es_update_base_object(self):
es_update(self.get_base_object())
def perform_create(self, serializer):
serializer.save()
self.es_update_base_object()
def perform_destroy(self, instance):
instance.delete()
self.es_update_base_object()