From 8f18267d3af18568606626c50fc4a96f8f49ebec Mon Sep 17 00:00:00 2001 From: Mstiekema Date: Tue, 12 Dec 2023 15:39:31 +0100 Subject: [PATCH 1/5] Changed auth check to decorator --- admin_board_view/middleware.py | 30 ++++++++++++++++++++ admin_board_view/templates/base.html | 26 +++-------------- admin_board_view/templates/login.html | 11 ++++++++ admin_board_view/templates/user_home.html | 14 ++++++++++ admin_board_view/urls.py | 2 ++ admin_board_view/views.py | 34 +++++++++++++++++------ 6 files changed, 87 insertions(+), 30 deletions(-) create mode 100644 admin_board_view/middleware.py create mode 100644 admin_board_view/templates/login.html create mode 100644 admin_board_view/templates/user_home.html diff --git a/admin_board_view/middleware.py b/admin_board_view/middleware.py new file mode 100644 index 0000000..5d75afb --- /dev/null +++ b/admin_board_view/middleware.py @@ -0,0 +1,30 @@ +from functools import wraps +from django.http.response import HttpResponseRedirect + +# Decorator to check if a user is authenticated +def dashboard_authenticated(f): + """ + Check if the user is logged in, if not redirect to login page + """ + @wraps(f) + def decorator(*args, **kwargs): + request = args[0] + if not request.user.is_authenticated: + return HttpResponseRedirect("/login") + + return f(*args, **kwargs) + return decorator + + +def dashboard_admin(f): + """ + Check if the user is logged in and is an admin, if not redirect to login page + """ + @wraps(f) + def decorator(*args, **kwargs): + request = args[0] + if not request.user.is_superuser: + return HttpResponseRedirect("/login") + + return f(*args, **kwargs) + return decorator diff --git a/admin_board_view/templates/base.html b/admin_board_view/templates/base.html index 7265ef1..7ccb3be 100644 --- a/admin_board_view/templates/base.html +++ b/admin_board_view/templates/base.html @@ -36,12 +36,12 @@
- {% if user.is_superuser %}

+ {% if user.is_authenticated %}
-
- {% endif %} diff --git a/admin_board_view/templates/login.html b/admin_board_view/templates/login.html new file mode 100644 index 0000000..ca991dd --- /dev/null +++ b/admin_board_view/templates/login.html @@ -0,0 +1,11 @@ +{% extends "base.html" %} +{% load static %} +{% block body %} +
+

Unauthenticated

+

+ You are currently not logged in. Please log in using a koala account: +

+ +
+{% endblock %} diff --git a/admin_board_view/templates/user_home.html b/admin_board_view/templates/user_home.html new file mode 100644 index 0000000..99fb349 --- /dev/null +++ b/admin_board_view/templates/user_home.html @@ -0,0 +1,14 @@ +{% extends "base.html" %} +{% load static %} +{% block body %} +
+

Welcome {{ user }}

+

+ You are not allowed to view this page as a non admin. Please logout and try again: +

+
+ {% csrf_token %} + +
+
+{% endblock %} diff --git a/admin_board_view/urls.py b/admin_board_view/urls.py index 55a6317..199464a 100644 --- a/admin_board_view/urls.py +++ b/admin_board_view/urls.py @@ -4,6 +4,8 @@ urlpatterns = [ path('', views.index, name='index'), + path('login', views.login, name='login'), + path('products', views.products, name='products'), path('users', views.users, name='users'), path('users/', views.users, name='user'), diff --git a/admin_board_view/views.py b/admin_board_view/views.py index c329e96..409133b 100644 --- a/admin_board_view/views.py +++ b/admin_board_view/views.py @@ -1,3 +1,5 @@ +import json + from django.db.models import Sum from django.core.paginator import Paginator from django.http.response import JsonResponse @@ -5,16 +7,26 @@ from django.http import HttpResponse from django.utils import timezone from itertools import groupby + +from admin_board_view.middleware import dashboard_authenticated, dashboard_admin from .models import * -import json +@dashboard_authenticated def index(request): - product_amount = Product.objects.count() - total_balance = sum(user.balance for user in User.objects.all()) - return render(request, "home.html", {"users": User.objects.all(), "product_amount": product_amount, "total_balance": total_balance, "top_types": top_up_types }) + if request.user.is_superuser: + product_amount = Product.objects.count() + total_balance = sum(user.balance for user in User.objects.all()) + return render(request, "home.html", {"users": User.objects.all(), "product_amount": product_amount, "total_balance": total_balance, "top_types": top_up_types }) + else: + return render(request, "user_home.html") + +def login(request): + return render(request, "login.html") + +@dashboard_admin def products(request): if request.POST: product = ProductForm(request.POST, request.FILES) @@ -47,12 +59,14 @@ def products(request): return render(request, "products.html", { "products": products, "categories": categories, "product_form": pf, "current_product": product, "product_sales": product_sales }) +@dashboard_admin def delete(request): id = request.POST.dict()['id'] Product.objects.get(id=id).delete() return JsonResponse({ "msg": f"Deleted product with {id}" }) +@dashboard_admin def toggle(request): id = request.POST.dict()['id'] product = Product.objects.get(id=id) @@ -61,8 +75,10 @@ def toggle(request): return JsonResponse({ "msg": f"Set the state of product {id} to enabled={product.enabled}" }) +@dashboard_admin def users(request, user_id=None): user, cards = None, None + print(user_id) if user_id: user = User.objects.get(id=user_id) top_ups = TopUpTransaction.objects.all().filter(user_id=user) @@ -97,6 +113,7 @@ def users(request, user_id=None): return render(request, "user.html", { "users": users }) +@dashboard_admin def settings_page(request): vat = VAT.objects.all() categories = Category.objects.all() @@ -104,6 +121,7 @@ def settings_page(request): return render(request, "settings.html", { "vat": vat, "categories": categories, "configuration": configuration }) +@dashboard_admin def category(request): try: categories = json.loads(request.POST.dict()['categories']) @@ -126,6 +144,7 @@ def category(request): return JsonResponse({ "msg": "Something went wrong whilst trying to save the categories" }, status=400) +@dashboard_admin def vat(request): try: vatBody = json.loads(request.POST.dict()['vat']) @@ -147,6 +166,7 @@ def vat(request): return JsonResponse({ "msg": "Something went wrong whilst trying to save the VAT percentages" }, status=400) +@dashboard_admin def settings_update(request): """ Updates the configuration settings for the undead-mongoose application. @@ -168,6 +188,7 @@ def settings_update(request): return JsonResponse({ "msg": "Something went wrong whilst trying to save the configuration" }, status=400) +@dashboard_admin def transactions(request): # Top up paginator top_ups = TopUpTransaction.objects.all() @@ -193,6 +214,7 @@ def transactions(request): return render(request, "transactions.html", { "top_ups": top_up_page, "sales": sales_page }) +@dashboard_admin def export_sale_transactions(request): """ Exports the sale transactions in the given date range to a csv file. @@ -203,10 +225,6 @@ def export_sale_transactions(request): Returns: HttpResponse: The csv file containing the sale transactions in the given date range. """ - # Only allow export for authanticated users - if not request.user.is_superuser: - return HttpResponse("You are not authenticated.", status=401) - try: req_get = request.GET export_type = req_get.get('type') From 55e462e7374fb6e88dc1164e9ca5b781e214f0c6 Mon Sep 17 00:00:00 2001 From: Mstiekema Date: Tue, 12 Dec 2023 16:16:55 +0100 Subject: [PATCH 2/5] Setting the koala id to the oidc user id --- undead_mongoose/oidc.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/undead_mongoose/oidc.py b/undead_mongoose/oidc.py index 7f205f8..e3e1aba 100644 --- a/undead_mongoose/oidc.py +++ b/undead_mongoose/oidc.py @@ -3,11 +3,13 @@ class UndeadMongooseOIDC(OIDCAuthenticationBackend): def create_user(self, claims): + print(claims) user = super(UndeadMongooseOIDC, self).create_user(claims) if claims['is_admin']: user.is_superuser = True user.is_staff = True user.username = claims['email'] + user.id = claims['sub'] user.save() return user @@ -17,6 +19,7 @@ def update_user(self, user, claims): user.is_superuser = True user.is_staff = True user.username = claims['email'] + user.id = claims['sub'] user.save() - return user \ No newline at end of file + return user From 63ae47b7b761ee189a26cc1dab3a083da4feb58a Mon Sep 17 00:00:00 2001 From: Mstiekema Date: Tue, 12 Dec 2023 16:17:32 +0100 Subject: [PATCH 3/5] Generalized paginator creator, added userinfo to user home --- admin_board_view/utils.py | 19 ++++++++++++++ admin_board_view/views.py | 52 ++++++++++++++++----------------------- 2 files changed, 40 insertions(+), 31 deletions(-) create mode 100644 admin_board_view/utils.py diff --git a/admin_board_view/utils.py b/admin_board_view/utils.py new file mode 100644 index 0000000..6386374 --- /dev/null +++ b/admin_board_view/utils.py @@ -0,0 +1,19 @@ +from django.core.paginator import Paginator + +def create_paginator(data, page, p_len=5): + """ + Create paginator for data. + + Args: + data: Data to paginate + page: Page number + p_len: Length of the page, defaults to 5 + """ + page = None + paginator = Paginator(data, p_len) + try: + page = paginator.get_page(page) + except Exception: + page = paginator.page(1) + + return page diff --git a/admin_board_view/views.py b/admin_board_view/views.py index 409133b..912ba82 100644 --- a/admin_board_view/views.py +++ b/admin_board_view/views.py @@ -1,7 +1,6 @@ import json from django.db.models import Sum -from django.core.paginator import Paginator from django.http.response import JsonResponse from django.shortcuts import render, HttpResponseRedirect from django.http import HttpResponse @@ -9,6 +8,7 @@ from itertools import groupby from admin_board_view.middleware import dashboard_authenticated, dashboard_admin +from admin_board_view.utils import create_paginator from .models import * @@ -19,7 +19,19 @@ def index(request): total_balance = sum(user.balance for user in User.objects.all()) return render(request, "home.html", {"users": User.objects.all(), "product_amount": product_amount, "total_balance": total_balance, "top_types": top_up_types }) else: - return render(request, "user_home.html") + user = User.objects.get(user_id=request.user.id) + + # Get product sales + product_sales = list(ProductTransactions.objects.all().filter(transaction_id__user_id=user)) + product_sale_groups = [] + for designation, member_group in groupby(product_sales, lambda sale: sale.transaction_id): + product_sale_groups.append({ "key": designation, "values": list(member_group) }) + sales_page = create_paginator(product_sale_groups, request.GET.get('sales')) + + # Get topup page + top_ups = TopUpTransaction.objects.all().filter(user_id=user) + top_up_page = create_paginator(top_ups, request.GET.get('top_ups')) + return render(request, "user_home.html", {"user_info": user, "top_ups": top_up_page, "sales": sales_page }) def login(request): @@ -78,7 +90,6 @@ def toggle(request): @dashboard_admin def users(request, user_id=None): user, cards = None, None - print(user_id) if user_id: user = User.objects.get(id=user_id) top_ups = TopUpTransaction.objects.all().filter(user_id=user) @@ -93,19 +104,8 @@ def users(request, user_id=None): if card.active is False: cards[i]["token"] = CardConfirmation.objects.get(card=card).token - top_up_page = None - top_ups_paginator = Paginator(top_ups, 5) - try: - top_up_page = top_ups_paginator.get_page(request.GET.get('top_ups')) - except Exception: - top_up_page = top_ups_paginator.page(1) - - sales_page = None - sales_paginator = Paginator(product_sale_groups, 5) - try: - sales_page = sales_paginator.get_page(request.GET.get('sales')) - except Exception: - sales_page = sales_paginator.page(1) + top_up_page = create_paginator(top_ups, request.GET.get('top_ups')) + sales_page = create_paginator(product_sale_groups, request.GET.get('sales')) return render(request, "user.html", { "user_info": user, "cards": cards, "top_ups": top_up_page, "sales": sales_page, "top_types": top_up_types }) else: @@ -190,26 +190,16 @@ def settings_update(request): @dashboard_admin def transactions(request): - # Top up paginator - top_ups = TopUpTransaction.objects.all() - top_ups_paginator = Paginator(top_ups, 5) - try: - top_up_page = top_ups_paginator.get_page(request.GET.get('top_ups')) - except Exception: - top_up_page = top_ups_paginator.page(1) - - # Product sale paginator + # Get product sale groups product_sales = ProductTransactions.objects.all() product_sales_sorted = sorted(product_sales, key=lambda sale: sale.transaction_id.date, reverse=True) product_sale_groups = [] for designation, member_group in groupby(product_sales_sorted, lambda sale: sale.transaction_id): product_sale_groups.append({ "key": designation, "values": list(member_group) }) - - sales_paginator = Paginator(product_sale_groups, 10) - try: - sales_page = sales_paginator.get_page(request.GET.get('sales')) - except Exception: - sales_page = sales_paginator.page(1) + + # Get paginators + top_up_page = create_paginator(TopUpTransaction.objects.all(), request.GET.get('top_ups')) + sales_paginator = create_paginator(product_sale_groups, request.GET.get('sales'), p_len=10) return render(request, "transactions.html", { "top_ups": top_up_page, "sales": sales_page }) From cb1acb93244188ce45037fdf2b0fb338a032d4d2 Mon Sep 17 00:00:00 2001 From: Mstiekema Date: Tue, 12 Dec 2023 16:20:01 +0100 Subject: [PATCH 4/5] Displaying information on user page --- admin_board_view/templates/user_home.html | 71 ++++++++++++++++++++--- 1 file changed, 63 insertions(+), 8 deletions(-) diff --git a/admin_board_view/templates/user_home.html b/admin_board_view/templates/user_home.html index 99fb349..db70e3e 100644 --- a/admin_board_view/templates/user_home.html +++ b/admin_board_view/templates/user_home.html @@ -2,13 +2,68 @@ {% load static %} {% block body %}
-

Welcome {{ user }}

-

- You are not allowed to view this page as a non admin. Please logout and try again: -

-
- {% csrf_token %} - -
+

Welcome {{ user_info.name }}

+
+ Current balance: {{ user_info.euro_balance }} +
+
+
+
+
+
Product sales
+
+ + + + + + + + + + {% for transaction in sales %} + + + + + + {% endfor %} + +
DateSumProducts
{{ transaction.key.date }}€{{ transaction.key.transaction_sum }} + {% for product in transaction.values %} + {{ product.amount }}x {{ product.product_id.name }}
+ {% endfor %} +
+ {% include "pagination_footer.html" with page=sales page_name='sales' %} +
+
+
+
+
+
Top ups
+
+ + + + + + + + + + {% for top_up in top_ups.object_list %} + + + + + + {% endfor %} + +
DateSumType
{{ top_up.date }}€{{ top_up.transaction_sum }}{% if top_up.type == 1 %}Pin{% elif top_up.type == 3 %}Mollie{% endif %}
+ {% include "pagination_footer.html" with page=top_ups page_name='top_ups' %} +
+
+
+
{% endblock %} From b0388f74c2fae39788d4d464d8dd3beac3ccde07 Mon Sep 17 00:00:00 2001 From: Mstiekema Date: Tue, 12 Dec 2023 16:21:18 +0100 Subject: [PATCH 5/5] Fixed logout button --- admin_board_view/templates/base.html | 1 + undead_mongoose/oidc.py | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/admin_board_view/templates/base.html b/admin_board_view/templates/base.html index 7ccb3be..d0f8073 100644 --- a/admin_board_view/templates/base.html +++ b/admin_board_view/templates/base.html @@ -64,6 +64,7 @@ diff --git a/undead_mongoose/oidc.py b/undead_mongoose/oidc.py index e3e1aba..5d2827c 100644 --- a/undead_mongoose/oidc.py +++ b/undead_mongoose/oidc.py @@ -3,7 +3,6 @@ class UndeadMongooseOIDC(OIDCAuthenticationBackend): def create_user(self, claims): - print(claims) user = super(UndeadMongooseOIDC, self).create_user(claims) if claims['is_admin']: user.is_superuser = True