From 69d26deef92b7f353794b37fcf90a2894a98c7cf Mon Sep 17 00:00:00 2001 From: Jan Tuomi Date: Thu, 28 Sep 2017 19:57:50 +0300 Subject: [PATCH] Rework infoscreen permissions --- infoscreen/views/__init__.py | 2 + infoscreen/{views.py => views/admin_views.py} | 118 +++--------------- infoscreen/views/public_views.py | 101 +++++++++++++++ 3 files changed, 122 insertions(+), 99 deletions(-) create mode 100644 infoscreen/views/__init__.py rename infoscreen/{views.py => views/admin_views.py} (63%) create mode 100644 infoscreen/views/public_views.py diff --git a/infoscreen/views/__init__.py b/infoscreen/views/__init__.py new file mode 100644 index 0000000..941a415 --- /dev/null +++ b/infoscreen/views/__init__.py @@ -0,0 +1,2 @@ +from infoscreen.views.admin_views import * +from infoscreen.views.public_views import * diff --git a/infoscreen/views.py b/infoscreen/views/admin_views.py similarity index 63% rename from infoscreen/views.py rename to infoscreen/views/admin_views.py index 0636f3d..152859a 100644 --- a/infoscreen/views.py +++ b/infoscreen/views/admin_views.py @@ -5,7 +5,7 @@ from django.http import HttpResponse, HttpResponseBadRequest from django.views.decorators.csrf import ensure_csrf_cookie from django.views.decorators.http import require_http_methods from django.contrib.contenttypes.models import ContentType -from django.contrib.auth.decorators import permission_required +from django.contrib.auth.decorators import permission_required, login_required from infoscreen.models import UploadFileForm import sikweb.settings as settings @@ -23,53 +23,22 @@ from infoscreen.models import ImageUploadForm from infoscreen.models import HSLDataModel from infoscreen.models import ApyInfoItem from infoscreen.models import VideoInfoItem -from infoscreen.hsl_fetcher import HSLFetcher -def index(request, idx, *args, **kwargs): - """Render infoscreen index page.""" - return render(request, 'infoscreen_index.html', {'rotation': idx}) - - -@permission_required('infoscreen.change_infoinstance', login_url='/login') +@login_required(login_url='/login') +@permission_required('infoscreen.change_infoinstance', raise_exception=True) def admin(request, *args, **kwargs): """Render infoscreen admin page.""" return render(request, 'infoscreen_admin.html', {}) -def default(request, *args, **kwargs): - """Try getting first rotation item.""" - try: - first = Rotation.objects.all()[0].id - except: - first = 0 - return index(request, first, *args, **kwargs) - - -def get_apy_json(request): - """Render APY diilikone page.""" - return HttpResponse( - requests.get("https://api-diilikone.apy.fi/deals/top-groups").text) - - -@require_http_methods(["GET"]) -def rotation(request, idx, *args, **kwargs): - """Get rotation.""" - try: - rotation = Rotation.objects.get(pk=idx) - except Rotation.DoesNotExist: - resp = HttpResponse('{"error": "Rotation not found"}') - resp.status_code = 404 - return resp - - return HttpResponse(json.dumps(rotation.get_dict())) - - def create_item_generator(model): """Create Infoscreen item generator.""" + @ensure_csrf_cookie @require_http_methods(["POST"]) - @permission_required('infoscreen.change_infoinstance', login_url='/login') + @login_required(login_url='/login') + @permission_required('infoscreen.add_infoinstance', raise_exception=True) def create_item(request, *args, **kwargs): try: data = json.loads(request.body.decode("utf-8")) @@ -87,9 +56,11 @@ def create_item_generator(model): def delete_item_generator(model): """Delete Infoscreen item generator.""" + @ensure_csrf_cookie @require_http_methods(["DELETE"]) - @permission_required('infoscreen.change_infoinstance', login_url='/login') + @login_required(login_url='/login') + @permission_required('infoscreen.delete_infoinstance', raise_exception=True) def delete_item(request, *args, **kwargs): idx = kwargs.pop("idx", 0) try: @@ -110,7 +81,8 @@ def delete_item_generator(model): # due to model structure this is little complicated @ensure_csrf_cookie -@permission_required('infoscreen.change_infoinstance', login_url='/login') +@login_required(login_url='/login') +@permission_required('infoscreen.delete_infoinstance', raise_exception=True) @require_http_methods(["DELETE"]) def delete_info_item(request, *args, **kwargs): """Delete info item.""" @@ -132,39 +104,10 @@ def delete_info_item(request, *args, **kwargs): return resp -@require_http_methods(["GET"]) -def rotations(request, *args, **kwargs): - """Return rotation lists.""" - rotations = list(map(lambda r: r.get_list(), Rotation.objects.all())) - return HttpResponse(json.dumps(rotations)) - - -@require_http_methods(["GET"]) -def info_types(request, *args, **kwargs): - """Return info item types.""" - types = [] - classes = InfoItem.get_subclasses() - for c in classes: - types.append({ - "name": c.display_name, - "create_template_url": c.get_create_template_url(), - }) - return HttpResponse(json.dumps(types)) - - -def info_items(request, *args, **kwargs): - """Return Infoscreen items.""" - items = [] - classes = InfoItem.get_subclasses() - for c in classes: - for i in c.objects.all(): - items.append(i.get_dict()) - return HttpResponse(json.dumps(items)) - - @require_http_methods(["POST"]) @ensure_csrf_cookie -@permission_required('infoscreen.change_infoinstance', login_url='/login') +@login_required(login_url='/login') +@permission_required('infoscreen.add_infoinstance', raise_exception=True) def create_image_item(request, *args, **kwargs): """Create image Infoscreen item.""" form = ImageUploadForm(request.POST, request.FILES) @@ -180,7 +123,8 @@ def create_image_item(request, *args, **kwargs): @require_http_methods(["POST"]) @ensure_csrf_cookie -@permission_required('infoscreen.change_infoinstance', login_url='/login') +@login_required(login_url='/login') +@permission_required('infoscreen.add_infoinstance', raise_exception=True) def create_video_item(request, *args, **kwargs): """Create video Infoscreen item.""" form = UploadFileForm(request.POST, request.FILES) @@ -196,7 +140,8 @@ def create_video_item(request, *args, **kwargs): @require_http_methods(["POST"]) @ensure_csrf_cookie -@permission_required('infoscreen.add_rotation', login_url='/login') +@login_required(login_url='/login') +@permission_required('infoscreen.add_rotation', raise_exception=True) def create_rotation(request, *args, **kwargs): """Create rotation.""" try: @@ -217,7 +162,8 @@ def create_rotation(request, *args, **kwargs): @require_http_methods(["DELETE"]) @ensure_csrf_cookie -@permission_required('infoscreen.delete_rotation', login_url='/login') +@login_required(login_url='/login') +@permission_required('infoscreen.delete_rotation', raise_exception=True) def delete_rotation(request, *args, **kwargs): """Delete rotation.""" id = kwargs.pop("id", 0) @@ -233,32 +179,6 @@ def delete_rotation(request, *args, **kwargs): return resp -@require_http_methods(["GET"]) -def hsl_timetable_settings(request, *args, **kwargs): - """Set HSL timetable settings.""" - d = {"departure_threshold": settings.HSL_DEPARTURE_THRESHOLD, - "hurry_threshold": settings.HSL_HURRY_THRESHOLD} - resp = json.dumps(d) - return HttpResponse(resp, status=200) - - -@require_http_methods(["GET"]) -def CurrentHSLView(request, *args, **kwargs): - """Get HSL data and return it.""" - fetcher = HSLFetcher() - fetcherThread = threading.Thread(target=fetcher.fetch_if_needed, args=[]) - fetcherThread.setDaemon(False) - fetcherThread.start() - - data = HSLDataModel.objects.all() - if len(data) < 1: - return HttpResponse( - '{"error" : "Could not find timetables from database."}', - status=500) - - return HttpResponse(data[len(data) - 1].data, status=200) - - createInstance = create_item_generator(InfoInstance) deleteInstance = delete_item_generator(InfoInstance) createABBItem = create_item_generator(ABBInfoItem) diff --git a/infoscreen/views/public_views.py b/infoscreen/views/public_views.py new file mode 100644 index 0000000..d0c264b --- /dev/null +++ b/infoscreen/views/public_views.py @@ -0,0 +1,101 @@ +from django.shortcuts import render +from django.http import HttpResponse, HttpResponseBadRequest +from django.views.decorators.http import require_http_methods + +from infoscreen.models import Rotation, InfoItem, InfoInstance +from infoscreen.hsl_fetcher import HSLFetcher + +import json + + +@require_http_methods(["GET"]) +def index(request, idx, *args, **kwargs): + """Render infoscreen index page.""" + return render(request, 'infoscreen_index.html', {'rotation': idx}) + + +@require_http_methods(["GET"]) +def default(request, *args, **kwargs): + """Try getting first rotation item.""" + try: + first = Rotation.objects.all()[0].id + except: + first = 0 + return index(request, first, *args, **kwargs) + + +@require_http_methods(["GET"]) +def get_apy_json(request): + """Render APY diilikone page.""" + return HttpResponse( + requests.get("https://api-diilikone.apy.fi/deals/top-groups").text) + + +@require_http_methods(["GET"]) +def rotation(request, idx, *args, **kwargs): + """Get rotation.""" + try: + rotation = Rotation.objects.get(pk=idx) + except Rotation.DoesNotExist: + resp = HttpResponse('{"error": "Rotation not found"}') + resp.status_code = 404 + return resp + + return HttpResponse(json.dumps(rotation.get_dict())) + + +@require_http_methods(["GET"]) +def rotations(request, *args, **kwargs): + """Return rotation lists.""" + rotations = list(map(lambda r: r.get_list(), Rotation.objects.all())) + return HttpResponse(json.dumps(rotations)) + + +@require_http_methods(["GET"]) +def info_types(request, *args, **kwargs): + """Return info item types.""" + types = [] + classes = InfoItem.get_subclasses() + for c in classes: + types.append({ + "name": c.display_name, + "create_template_url": c.get_create_template_url(), + }) + return HttpResponse(json.dumps(types)) + + +@require_http_methods(["GET"]) +def info_items(request, *args, **kwargs): + """Return Infoscreen items.""" + items = [] + classes = InfoItem.get_subclasses() + for c in classes: + for i in c.objects.all(): + items.append(i.get_dict()) + return HttpResponse(json.dumps(items)) + + +@require_http_methods(["GET"]) +def hsl_timetable_settings(request, *args, **kwargs): + """Set HSL timetable settings.""" + d = {"departure_threshold": settings.HSL_DEPARTURE_THRESHOLD, + "hurry_threshold": settings.HSL_HURRY_THRESHOLD} + resp = json.dumps(d) + return HttpResponse(resp, status=200) + + +@require_http_methods(["GET"]) +def CurrentHSLView(request, *args, **kwargs): + """Get HSL data and return it.""" + fetcher = HSLFetcher() + fetcherThread = threading.Thread(target=fetcher.fetch_if_needed, args=[]) + fetcherThread.setDaemon(False) + fetcherThread.start() + + data = HSLDataModel.objects.all() + if len(data) < 1: + return HttpResponse( + '{"error" : "Could not find timetables from database."}', + status=500) + + return HttpResponse(data[len(data) - 1].data, status=200)