From 30212ec3827ff39af8876335731cd3164cacf721 Mon Sep 17 00:00:00 2001 From: Stark Date: Wed, 17 Mar 2021 20:31:40 +0530 Subject: [PATCH 01/13] project dropdown and pagination on logs page --- .gitignore | 2 + src/log/templates/log/list_view.html | 26 ++- src/log/urls.py | 2 +- src/log/views.py | 237 +++++++++++++++------------ src/project/views.py | 2 +- src/templates/common/base.html | 7 +- src/templates/common/pagination.html | 29 ++++ 7 files changed, 193 insertions(+), 112 deletions(-) create mode 100644 src/templates/common/pagination.html diff --git a/.gitignore b/.gitignore index 62dd050..80f300b 100644 --- a/.gitignore +++ b/.gitignore @@ -158,3 +158,5 @@ docs/public/ backup/rclone.* webserver/certs/* !webserver/certs/.gitkeep + +psql12.dump.sql diff --git a/src/log/templates/log/list_view.html b/src/log/templates/log/list_view.html index 5d13ab2..e4e5196 100644 --- a/src/log/templates/log/list_view.html +++ b/src/log/templates/log/list_view.html @@ -102,7 +102,17 @@

{{ page_title }}

- + {% if not personal %} + + {% endif %} {% if userpage %}
@@ -156,12 +166,26 @@

{{ log.title }}

{% endfor %} + {% if not personal %} +


+ {% include 'common/pagination.html' with page=logs %} + {% endif %} +
{% endblock content %} {% block scripts %} +{% if not personal %} + +{% endif %} + {% endblock scripts %} \ No newline at end of file diff --git a/src/log/urls.py b/src/log/urls.py index a42f4d3..6af5570 100644 --- a/src/log/urls.py +++ b/src/log/urls.py @@ -8,7 +8,7 @@ path('log//edit', views.logEditView, name='log-edit'), path('log/', views.logListView, name='log-list'), - path('logs/all', views.allLogsView, name='logs-all'), + path('logs/', views.allLogsView, name='logs-all'), path('log/uploadfile', views.fileUploadHandler, name='file-upload'), path('log/delete', views.logDeleteView, name='log-delete'), path('log/bin', views.recBinView, name='log-bin'), diff --git a/src/log/views.py b/src/log/views.py index 844c576..b48af61 100644 --- a/src/log/views.py +++ b/src/log/views.py @@ -12,7 +12,9 @@ from django.db.models import Q from Crypto.Cipher import AES from Crypto.Util.Padding import pad -import re, os +import json +import re +import os from django.views.generic import ( View, ListView, @@ -22,6 +24,7 @@ DeleteView, TemplateView ) +from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger from django.shortcuts import redirect from django.urls import reverse, reverse_lazy from django.contrib.auth.models import User @@ -90,22 +93,21 @@ class LoggerUnPublish(LoginRequiredMixin, UserPassesTestMixin, TemplateView): model = Logger template_name = 'log/logger_unpublish.html' + @login_required def logCreateView(request): - user_teams = request.user.team_set.all() project_list = [] for team in user_teams: project_list.append(team.project) - # pass in this list context = { - "projects":project_list, - "files":LogFile.objects.filter(user=request.user), - + "projects": project_list, + "files": LogFile.objects.filter(user=request.user), + } if request.method == "POST": log_title = request.POST.get('log-title', "") @@ -113,20 +115,21 @@ def logCreateView(request): log_content = request.POST.get('log-content', "") log_project = request.POST.get('selection', "") custom_password_true = request.POST.get('custom-password-check', "") - + if custom_password_true == "on": password = request.POST.get("custom-password", "") else: password = request.user.password.split('$')[-1] - password=generatePassword(password) + password = generatePassword(password) BLOCK_SIZE = 32 - encryption_suite = AES.new(generatePassword(password).encode(), AES.MODE_ECB) + encryption_suite = AES.new( + generatePassword(password).encode(), AES.MODE_ECB) - cipher_text = encryption_suite.encrypt(pad(log_content.encode(), BLOCK_SIZE)).hex() + cipher_text = encryption_suite.encrypt( + pad(log_content.encode(), BLOCK_SIZE)).hex() - if log_project == "Personal Log": newlog = Logger.objects.create( title=log_title, @@ -134,8 +137,8 @@ def logCreateView(request): note=cipher_text, user=request.user, password=password, - - ) + + ) else: project = Project.objects.get(id=log_project) newlog = Logger.objects.create( @@ -145,13 +148,16 @@ def logCreateView(request): user=request.user, project=project, password=password, - + ) - messages.add_message(request, messages.SUCCESS, "Log Successfully created.") + messages.add_message(request, messages.SUCCESS, + "Log Successfully created.") return redirect('log-list') - + return render(request, 'log/create_log.html', context=context) + + @login_required def logDetailView(request, *args, **kwargs): @@ -161,35 +167,27 @@ def logDetailView(request, *args, **kwargs): logtoview = UUID(str(logtoview)) except ValueError: return HttpResponse("Error: Invalid log ID", status=400) - try: thelog = Logger.objects.get(id=logtoview) - allowedusers = [] allowedusers.append(thelog.user) for users in thelog.access.all(): allowedusers.append(users) - + if thelog.project: if (request.user.team_set.all() & thelog.project.team_set.all()).exists(): allowedusers.append(request.user) pass - if request.user not in allowedusers: return render(request, 'common/404.html', {}) - - - - password = thelog.password - BLOCK_SIZE = 32 encryption_suite = AES.new(password.encode(), AES.MODE_ECB) @@ -197,17 +195,14 @@ def logDetailView(request, *args, **kwargs): padding = deciphered_text[-1] deciphered_text = deciphered_text[:-padding].decode() - thelog.note = deciphered_text - - userlist = thelog.access.all() context = { - "log":thelog, - "userlist":userlist, - "files":LogFile.objects.filter(user=request.user), + "log": thelog, + "userlist": userlist, + "files": LogFile.objects.filter(user=request.user), } return render(request, 'log/view_log.html', context) @@ -216,7 +211,8 @@ def logDetailView(request, *args, **kwargs): return HttpResponse("Error: Invalid log ID", status=400) except Exception as ಠ_ಠ: print(ಠ_ಠ) - messages.add_message(request, messages.ERROR, "Log data is corrupt. Decryption failed.") + messages.add_message(request, messages.ERROR, + "Log data is corrupt. Decryption failed.") return redirect('log-list') @@ -233,25 +229,27 @@ def fileUploadHandler(request): # except Exception as e: # print(e) # return JsonResponse({"message":"Bad Request"}, status=400) - + file_extension = pathlib.Path(filetoupload.name).suffix file_name = filetoupload.name filetoupload.name = secrets.token_hex(10) + file_extension - savedfile = LogFile.objects.create(file=filetoupload, title=file_name, user=request.user) + savedfile = LogFile.objects.create( + file=filetoupload, title=file_name, user=request.user) SITE_PROTOCOL = 'http://' if request.is_secure(): SITE_PROTOCOL = 'https://' - - return JsonResponse({"message": "File uploaded.", "link":SITE_PROTOCOL + request.META['HTTP_HOST'] + savedfile.file.url}) + + return JsonResponse({"message": "File uploaded.", "link": SITE_PROTOCOL + request.META['HTTP_HOST'] + savedfile.file.url}) if request.method == "GET": - return JsonResponse({"message":"Get method not allowed"}) + return JsonResponse({"message": "Get method not allowed"}) + @login_required def logDeleteView(request): if request.method != "GET": return HttpResponse("Error: Invalid request", status=400) - + else: logtodelete = request.GET.get('id', "") @@ -259,13 +257,13 @@ def logDeleteView(request): logtodelete = UUID(logtodelete) except ValueError: return HttpResponse("Error: Invalid log ID", status=400) - try: log = Logger.objects.get(id=logtodelete) log.published = False log.save() - messages.add_message(request, messages.SUCCESS, "Log was successfully deleted.") + messages.add_message(request, messages.SUCCESS, + "Log was successfully deleted.") return redirect("log-list") return HttpResponse(log) @@ -276,27 +274,58 @@ def logDeleteView(request): @login_required def logListView(request): context = { - "logs":Logger.objects.filter(user=request.user, project=None).filter(published=True).order_by('-date_created'), - "page_title":"Personal logs:", - "userpage":True, - "welcomemessage":'Create your first log by clicking on the "New Log" Button !', + "logs": Logger.objects.filter(user=request.user, project=None).filter(published=True).order_by('-date_created'), + "page_title": "Personal logs:", + "userpage": True, + "personal": True, + "welcomemessage": 'Create your first log by clicking on the "New Log" Button !', } return render(request, 'log/list_view.html', context) - + + @login_required -def allLogsView(request): +def allLogsView(request, slug): teams = request.user.team_set.all() projects = Project.objects.filter(team__in=teams) - logs = Logger.objects.filter(project__in=projects).filter(published=True) - context = { - "logs":logs.order_by('-date_created'), - "page_title":"Project logs:", - "userpage":True, - "welcomemessage":'Create your first log by clicking on the "New Log" Button !', - } + if slug == 'all': + logs_list = Logger.objects.filter( + project__in=projects).filter(published=True).order_by('-date_created') + context = { + "projects": projects.order_by('title'), + "page_title": "Project logs:", + "userpage": True, + "personal": False, + "selected": 'all', + "welcomemessage": 'Create your first log by clicking on the "New Log" Button !', + } + else: + project = projects.filter(id=slug) + logs_list = Logger.objects.filter( + project__in=project).filter(published=True).order_by('-date_created') + context = { + "projects": projects.order_by('title'), + "page_title": "Project logs:", + "userpage": True, + "personal": False, + "selected": project[0].id, + "welcomemessage": 'Create your first log by clicking on the "New Log" Button !', + } + + paginator = Paginator(logs_list, 10) + page = request.GET.get('page') + try: + logs = paginator.page(page) + except PageNotAnInteger: + logs = paginator.page(1) + except EmptyPage: + logs = paginator.page(paginator.num_pages) + + context["logs"] = logs + context["page"] = page + return render(request, 'log/list_view.html', context) - + @login_required def logEditView(request, *args, **kwargs): @@ -307,13 +336,11 @@ def logEditView(request, *args, **kwargs): logtoview = UUID(str(logtoview)) except ValueError: return HttpResponse("Error: Invalid log ID", status=400) - try: thelog = Logger.objects.get(id=logtoview) password = thelog.password - BLOCK_SIZE = 32 encryption_suite = AES.new(password.encode(), AES.MODE_ECB) @@ -325,7 +352,8 @@ def logEditView(request, *args, **kwargs): except ObjectDoesNotExist: return HttpResponse("Error: Invalid log ID", status=400) except: - messages.add_message(request, messages.ERROR, "An Unknown error occurred.") + messages.add_message(request, messages.ERROR, + "An Unknown error occurred.") return redirect('landing-page') if request.method == "POST": @@ -337,46 +365,47 @@ def logEditView(request, *args, **kwargs): BLOCK_SIZE = 32 encryption_suite = AES.new(thelog.password.encode(), AES.MODE_ECB) - cipher_text = encryption_suite.encrypt(pad(log_content.encode(), BLOCK_SIZE)).hex() + cipher_text = encryption_suite.encrypt( + pad(log_content.encode(), BLOCK_SIZE)).hex() thelog.title = log_title - thelog.short_description=log_description + thelog.short_description = log_description thelog.note = cipher_text thelog.save() - messages.add_message(request, messages.SUCCESS, "Log saved successfully.") + messages.add_message(request, messages.SUCCESS, + "Log saved successfully.") return redirect('log-list') - - - context = { - "log":thelog, - "files":LogFile.objects.filter(user=request.user), + "log": thelog, + "files": LogFile.objects.filter(user=request.user), } - - return render(request, 'log/log_edit_view.html', context) + @login_required def recBinView(request): if request.method != "GET": - logs_to_delete = Logger.objects.filter(user=request.user).filter(published=False) + logs_to_delete = Logger.objects.filter( + user=request.user).filter(published=False) try: logs_to_delete.delete() except Exception as e: - messages.add_message(request, messages.ERROR, f"Could not empty recycle bin. Error: {e}") - messages.add_message(request, messages.SUCCESS, f"Recycle bin was cleared successfully.") + messages.add_message(request, messages.ERROR, + f"Could not empty recycle bin. Error: {e}") + messages.add_message(request, messages.SUCCESS, + f"Recycle bin was cleared successfully.") return redirect('log-bin') - + else: logtodelete = request.GET.get('id', "") if logtodelete == "": context = { - "logs":Logger.objects.filter(user=request.user).filter(published=False).order_by('-date_created') + "logs": Logger.objects.filter(user=request.user).filter(published=False).order_by('-date_created') } return render(request, 'log/bin_view.html', context) else: @@ -384,31 +413,33 @@ def recBinView(request): logtodelete = UUID(logtodelete) except ValueError: return HttpResponse("Error: Invalid log ID", status=400) - try: log = Logger.objects.get(id=logtodelete) log.published = True log.save() - messages.add_message(request, messages.SUCCESS, "Log was successfully recovered.") + messages.add_message( + request, messages.SUCCESS, "Log was successfully recovered.") return redirect("log-list") return HttpResponse(log) except ObjectDoesNotExist: return HttpResponse("Error: Invalid log ID", status=400) + def generatePassword(unpaddedPassword): if len(unpaddedPassword) < 32: generated_padding = (32-len(unpaddedPassword))*"#" return unpaddedPassword + generated_padding - + elif len(unpaddedPassword) > 32: return unpaddedPassword[:32] - + else: return unpaddedPassword + @login_required def shareController(request): if request.method == "GET": @@ -417,76 +448,69 @@ def shareController(request): print(request.POST.dict()) usernames = request.POST.get('usernames', '') logid = request.POST.get('loguuid', '') - + try: logtoview = UUID(str(logid)) - + except ValueError: - return JsonResponse({"message":"Log ID Invalid. Please contact Administrator."}, status=400) - + return JsonResponse({"message": "Log ID Invalid. Please contact Administrator."}, status=400) + try: thelog = Logger.objects.get(id=logtoview) usernames = usernames.split(',') - except ObjectDoesNotExist: - return JsonResponse({"message":"Log ID Invalid. Please contact Administrator."}, status=400) + return JsonResponse({"message": "Log ID Invalid. Please contact Administrator."}, status=400) except Exception as ಠ_ಠ: print(ಠ_ಠ) - return JsonResponse({"message":"An unknown error occurred."}, status=400) + return JsonResponse({"message": "An unknown error occurred."}, status=400) print(usernames) if usernames == [""]: thelog.access.set([]) - return JsonResponse({"message":"Shared users cleared successfully."}) - + return JsonResponse({"message": "Shared users cleared successfully."}) - doesnotexistlist = [] existslist = [] - + # Remove the @ sign. usernames = [x[1:] for x in usernames] for users in usernames: - try: existslist.append(User.objects.get(username=users)) except ObjectDoesNotExist as ಠ_ಠ: doesnotexistlist.append(users) - + except Exception as ಠ_ಠ: - return JsonResponse({"message":"An unknown error occurred."}, status=400) - - + return JsonResponse({"message": "An unknown error occurred."}, status=400) + if doesnotexistlist != []: doesnotexistlist = ["@" + x for x in doesnotexistlist] if len(doesnotexistlist) == 1: - return JsonResponse({"message":f"{doesnotexistlist[0]} does not exist."}, status=400) + return JsonResponse({"message": f"{doesnotexistlist[0]} does not exist."}, status=400) else: - return JsonResponse({"message":'Usernames "' + ', '.join(doesnotexistlist) + '" do not exist.'}, status=400) + return JsonResponse({"message": 'Usernames "' + ', '.join(doesnotexistlist) + '" do not exist.'}, status=400) - thelog.access.set(existslist) if request.method == "GET": pass shareurl = reverse('log-detail', args=[logid]) - return JsonResponse({"message":f'Log shared Successfully
Link : {shareurl}'}, status=200) + return JsonResponse({"message": f'Log shared Successfully
Link : {shareurl}'}, status=200) @login_required def mySharesView(request): context = { - "logs":request.user.user_access.all().filter(published=True).order_by('-date_created'), - "page_title":"Shared with me:", - "userpage":False, + "logs": request.user.user_access.all().filter(published=True).order_by('-date_created'), + "page_title": "Shared with me:", + "userpage": False, } return render(request, 'log/list_view.html', context) - def searchResults(request): @@ -495,16 +519,17 @@ def searchResults(request): teams = request.user.team_set.all() projects = Project.objects.filter(team__in=teams) - logs = Logger.objects.filter(project__in=projects).filter(Q(title__icontains=query) | Q(short_description__icontains=query)) | (Logger.objects.filter(user=request.user)).filter(Q(title__icontains=query) | Q(short_description__icontains=query)) + logs = Logger.objects.filter(project__in=projects).filter(Q(title__icontains=query) | Q(short_description__icontains=query)) | ( + Logger.objects.filter(user=request.user)).filter(Q(title__icontains=query) | Q(short_description__icontains=query)) - context = { - "logs":logs, - "page_title":"Search results:", - "userpage":False, + "logs": logs, + "page_title": "Search results:", + "userpage": False, } return render(request, 'log/list_view.html', context) - + + @login_required def deleteAllLogs(request): user = request.user diff --git a/src/project/views.py b/src/project/views.py index 74fefda..648c889 100644 --- a/src/project/views.py +++ b/src/project/views.py @@ -172,7 +172,7 @@ def projectListView(request): # add member and log count project.nooflogs = Logger.objects.filter(project=project).count() project.noofteams = project.team_set.all().count() - print(project.noofteams, project.nooflogs) + # print(project.noofteams, project.nooflogs) # Limit description length if len(project.description) > 130: diff --git a/src/templates/common/base.html b/src/templates/common/base.html index bea0735..e89a40c 100644 --- a/src/templates/common/base.html +++ b/src/templates/common/base.html @@ -152,7 +152,7 @@ Personal Logs - + Project Logs @@ -529,7 +529,8 @@

Please switch to a pc, or maximize the window.

{% endcomment %} {% block scripts %} {% endblock scripts %} - + + - + \ No newline at end of file diff --git a/src/templates/common/pagination.html b/src/templates/common/pagination.html new file mode 100644 index 0000000..3a7e268 --- /dev/null +++ b/src/templates/common/pagination.html @@ -0,0 +1,29 @@ + + + \ No newline at end of file From 87da094c6e2cfef94066f4bb73bd2bc915fcfd1f Mon Sep 17 00:00:00 2001 From: Stark Date: Thu, 18 Mar 2021 17:13:33 +0530 Subject: [PATCH 02/13] testing for search and pagination - debugging --- src/log/templates/log/list_view.html | 4 ++-- src/log/views.py | 10 +++++++--- src/project/views.py | 1 - src/templates/common/pagination.html | 14 -------------- 4 files changed, 9 insertions(+), 20 deletions(-) diff --git a/src/log/templates/log/list_view.html b/src/log/templates/log/list_view.html index e4e5196..8ff3a98 100644 --- a/src/log/templates/log/list_view.html +++ b/src/log/templates/log/list_view.html @@ -102,7 +102,7 @@

{{ page_title }}

- {% if not personal %} + {% if loglistpage %} + + + {% endif %} {% if userpage %} - New Log + New Log {% endif %} @@ -55,13 +75,30 @@

{% endfor %} + {% if loglistpage %} +
+

+ {% include 'common/pagination.html' with page=logs %} + {% endif %} + + - +{% endif %} {% endblock content %} {% block scripts %} - +{% if not error %} + {% if not personal %} + + {% endif %} + +{% endif %} {% endblock scripts %} \ No newline at end of file diff --git a/src/templates/log/view_log.html b/src/templates/log/view_log.html index 8706bb8..f857438 100644 --- a/src/templates/log/view_log.html +++ b/src/templates/log/view_log.html @@ -65,8 +65,8 @@

{{ log.date_modified }}
-

- {{log.note}} +

+ {{log.note}}

@@ -181,12 +181,15 @@ {% endblock content %} {% block scripts %} - - + + - {% endblock scripts %} \ No newline at end of file + {% endblock scripts %}