Files
web2.0-backend/webapp/views.py
T
2020-06-15 20:25:24 +03:00

190 lines
6.8 KiB
Python

"""Webapp views."""
import jwt
import json
from django.utils import timezone
from dealer.git import git
from django.conf import settings
from django.contrib.auth import authenticate
from django.http import HttpResponseBadRequest, HttpResponse
from django.shortcuts import redirect, render
from django.views.decorators.http import require_http_methods
from django_filters import rest_framework as filters
from rest_framework import permissions, routers, viewsets
from rest_framework.filters import OrderingFilter, SearchFilter
from rest_framework.permissions import IsAuthenticatedOrReadOnly, AllowAny
from rest_framework.response import Response
from rest_framework.reverse import reverse
from jsonschema import validate
import logging
from webapp.models import Event, SignupForm, Signup, TemplateQuestion, Feed, Committee, Occupation, Tag
from webapp.serializers import (EventSerializer, SignupFormSerializer, SignupSerializer,
SavedQuestionsSerializer, FeedSerializer, CommitteeSerializer,
OccupationSerializer, TagSerializer)
class IsPostOrIsAuthenticated(permissions.BasePermission):
def has_permission(self, request, view):
if request.method == 'POST':
return True
return request.user and request.user.is_authenticated
# -- REST API -- #
class RootView(routers.APIRootView):
permission_classes = [IsAuthenticatedOrReadOnly]
class EventViewSet(viewsets.ModelViewSet):
queryset = Event.objects.all()
ordering = ["start_time"]
serializer_class = EventSerializer
permission_classes = [IsAuthenticatedOrReadOnly]
filter_backends = (filters.DjangoFilterBackend, SearchFilter, OrderingFilter)
filter_fields = '__all__'
search_fields = '__all__'
def get_queryset(self):
if self.request.user.is_authenticated:
return Event.objects.all()
since = self.request.query_params.get('since', None)
if since:
return Event.objects.filter(visible=True, end_time__gt=since).order_by('start_time')
return Event.objects.filter(visible=True, end_time__gt=timezone.now()).order_by('start_time')
class SignupFormViewSet(viewsets.ModelViewSet):
queryset = SignupForm.objects.all()
serializer_class = SignupFormSerializer
permission_classes = [IsAuthenticatedOrReadOnly]
# Throws errors with JSONFIeld. Modify __all__ to not use JSONField if filters are enadbled
# filter_backends = (filters.DjangoFilterBackend, SearchFilter, OrderingFilter)
# filter_fields = '__all__'
# search_fields = '__all__'
def get_queryset(self):
if self.request.user.is_authenticated:
return SignupForm.objects.all().order_by('start_time')
return SignupForm.objects.filter(visible=True, end_time__gt=timezone.now()).order_by('start_time')
class SignupViewSet(viewsets.ModelViewSet):
queryset = Signup.objects.all()
serializer_class = SignupSerializer
permission_classes = [AllowAny]
# permission_classes = [IsPostOrIsAuthenticated]
# filter_backends = (filters.DjangoFilterBackend, SearchFilter, OrderingFilter)
# filter_fields = '__all__'
# search_fields = '__all__'
def create(self, request, *args, **kwargs):
try:
form = SignupForm.objects.get(id=request.data["signupForm_id"])
if (form.visible):
signup = json.loads(request.data["answer"])
# Throws error if not valid
validate(instance=signup, schema=form.schema)
return super().create(request, *args, **kwargs)
except Exception as inst:
return HttpResponseBadRequest()
else:
return HttpResponseBadRequest()
def update(self, request, *args, **kwargs):
return super().update(request, *args, **kwargs)
class SavedQuestionsViewSet(viewsets.ModelViewSet):
queryset = TemplateQuestion.objects.all()
serializer_class = SavedQuestionsSerializer
permission_classes = [IsAuthenticatedOrReadOnly]
class FeedViewSet(viewsets.ModelViewSet):
queryset = Feed.objects.all()
serializer_class = FeedSerializer
permission_classes = [IsAuthenticatedOrReadOnly]
filter_backends = (filters.DjangoFilterBackend, SearchFilter, OrderingFilter)
filter_fields = '__all__'
search_fields = '__all__'
def get_queryset(self):
if self.request.user.is_authenticated:
return Feed.objects.all().order_by('publish_time')
else:
objs = Feed.objects.filter(visible=True).order_by('publish_time')
result_ids = []
for obj in objs:
if obj.autohide_enabled:
if obj.autohide > timezone.now():
result_ids.append(obj.id)
else:
result_ids.append(obj.id)
return Feed.objects.filter(id__in=result_ids)
class ContactsViewSet(viewsets.ReadOnlyModelViewSet):
queryset = Occupation.objects.all()
serializer_class = OccupationSerializer
permission_classes = [IsAuthenticatedOrReadOnly]
def get_queryset(self):
year = self.request.query_params.get('year')
if not year:
return Occupation.by_year(timezone.now().year)
return Occupation.by_year(int(year))
class CommitteeViewSet(viewsets.ReadOnlyModelViewSet):
queryset = Committee.objects.all()
serializer_class = CommitteeSerializer
permission_classes = [IsAuthenticatedOrReadOnly]
class TagsViewSet(viewsets.ReadOnlyModelViewSet):
queryset = Tag.objects.all()
serializer_class = TagSerializer
permission_classes = [IsAuthenticatedOrReadOnly]
@require_http_methods(["GET"])
def about_view(request, *args, **kwargs):
"""Render about page."""
latest_commit = "Not found"
latest_date = "Not found"
latest_tag = "Not found"
try:
repo = git.init_repo()
latest_commit = repo.git("rev-parse HEAD").decode('utf-8')
latest_date = repo.git("show -s --format=%ci " + latest_commit).decode('utf-8')
latest_tag = repo.git("describe --tags " + repo.git("rev-list --tags --max-count=1").decode('utf-8')).decode('utf-8')
except Exception as e:
print(f"Git failed:\n{e}")
context = {
'commit': latest_commit,
'date': latest_date,
'tag': latest_tag
}
return render(request, "about.html", context)
@require_http_methods(["GET"])
def nginx_jwt_resp(request, *args, **kwargs):
cookie = request.COOKIES.get("jwt", None)
if not cookie:
return HttpResponse("", status=401)
try:
token = jwt.decode(cookie, settings.SECRET_KEY)
except jwt.exceptions.InvalidSignatureError:
return HttpResponse("", status=403)
user = 'admin' if token.get('username', '') == 'admin' else 'moderator'
resp = HttpResponse("", status=200)
resp['X-FBrowser-User'] = user
return resp