Skip to content

Commit

Permalink
Merge pull request #125 from fsinfuhh/gprot_hash_blocking
Browse files Browse the repository at this point in the history
Add functionality to block gprots based on their hash
  • Loading branch information
timonegk authored Jul 31, 2023
2 parents 0570460 + 7279b41 commit 39de4ef
Show file tree
Hide file tree
Showing 8 changed files with 204 additions and 14 deletions.
29 changes: 25 additions & 4 deletions locale/de_DE/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ msgstr ""
"Project-Id-Version: Mafiasi\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-01-18 14:54+0100\n"
"PO-Revision-Date: 2023-01-18 14:58+0100\n"
"Last-Translator: Markus Neblung <markus.neblung@uni-hamburg.de>\n"
"PO-Revision-Date: 2023-07-27 20:41+0200\n"
"Last-Translator: Timon Engelke <timon.engelke@uni-hamburg.de>\n"
"Language-Team: \n"
"Language: de_DE\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 3.2.2\n"
"X-Generator: Poedit 3.0.1\n"

#: mafiasi/base/middleware.py:15
msgid ""
Expand Down Expand Up @@ -376,6 +376,18 @@ msgstr "PDF hochladen"
msgid "Reminder: Memory minutes for \"%(coursename)s\""
msgstr "Erinnerung: Gedächtnisprotokoll für \"%(coursename)s\""

#: mafiasi/gprot/templates/admin/gprot/gprot/change_form.html:33
msgid "Block this Gprot"
msgstr "Dieses GProt blockieren"

#: mafiasi/gprot/templates/admin/gprot/gprot/change_form.html:34
msgid ""
"When a Gprot is blocked, a hash is saved that ensures that the same file "
"cannot be uploaded again."
msgstr ""
"Wenn das GProt blockiert ist, dann wird ein Hash gespeichert, der "
"verhindert, dass die gleiche Datei erneut hochgeladen wird."

#: mafiasi/gprot/templates/gprot/_action_list.html:6
msgid "View"
msgstr "Anzeigen"
Expand Down Expand Up @@ -987,7 +999,16 @@ msgstr "Es sind nur PDF-Dateien erlaubt."
msgid "Please select a file to upload."
msgstr "Bitte wähle eine Datei zum Hochladen aus."

#: mafiasi/gprot/views.py:285
#: mafiasi/gprot/views.py:217
msgid ""
"This file was blocked because it is an original exam. Please do not try to "
"upload it again because we will get problems with the university."
msgstr ""
"Der Upload wurde blockiert, weil es sich um eine Originalklausur handelt. "
"Bitte versuche nicht, sie nochmal hochzuladen, damit wir keine Probleme mit "
"der Universität bekommen."

#: mafiasi/gprot/views.py:307
msgid "Only PNG, JPEG and GIF files are allowed."
msgstr "Es sind nur Bilder im PNG-, JPEG- oder GIF-Format erlaubt."

Expand Down
28 changes: 24 additions & 4 deletions locale/en_US/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ msgstr ""
"Project-Id-Version: Mafiasi\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-01-18 14:47+0100\n"
"PO-Revision-Date: 2022-03-07 16:02+0100\n"
"Last-Translator: Markus Neblung <9neblung@informatik.uni-hamburg.de>\n"
"PO-Revision-Date: 2023-07-27 20:41+0200\n"
"Last-Translator: Timon Engelke <timon.engelke@uni-hamburg.de>\n"
"Language-Team: \n"
"Language: en\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 2.4.2\n"
"X-Generator: Poedit 3.0.1\n"

#: mafiasi/base/middleware.py:15
msgid ""
Expand Down Expand Up @@ -371,6 +371,18 @@ msgstr "Upload PDF"
msgid "Reminder: Memory minutes for \"%(coursename)s\""
msgstr "Reminder: Memory minutes for \"%(coursename)s\""

#: mafiasi/gprot/templates/admin/gprot/gprot/change_form.html:33
msgid "Block this Gprot"
msgstr "Block this Gprot"

#: mafiasi/gprot/templates/admin/gprot/gprot/change_form.html:34
msgid ""
"When a Gprot is blocked, a hash is saved that ensures that the same file "
"cannot be uploaded again."
msgstr ""
"When a Gprot is blocked, a hash is saved that ensures that the same file "
"cannot be uploaded again."

#: mafiasi/gprot/templates/gprot/_action_list.html:6
msgid "View"
msgstr "View"
Expand Down Expand Up @@ -987,7 +999,15 @@ msgstr "Only PDF files are allowed."
msgid "Please select a file to upload."
msgstr "Please select a file to upload."

#: mafiasi/gprot/views.py:285
#: mafiasi/gprot/views.py:217
msgid ""
"This file was blocked because it is an original exam. Please do not try to "
"upload it again because we will get problems with the university."
msgstr ""
"This file was blocked because it is an original exam. Please do not try to "
"upload it again because we will get problems with the university."

#: mafiasi/gprot/views.py:307
msgid "Only PNG, JPEG and GIF files are allowed."
msgstr "Only PNG, JPEG and GIF files are allowed."

Expand Down
29 changes: 25 additions & 4 deletions locale/fr_FR/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ msgstr ""
"Project-Id-Version: Mafiasi\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-01-18 14:47+0100\n"
"PO-Revision-Date: 2022-03-07 16:02+0100\n"
"Last-Translator: Markus Neblung <9neblung@informatik.uni-hamburg.de>\n"
"PO-Revision-Date: 2023-07-27 20:48+0200\n"
"Last-Translator: Timon Engelke <timon.engelke@uni-hamburg.de>\n"
"Language-Team: \n"
"Language: fr_FR\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 2.4.2\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
"X-Generator: Poedit 3.0.1\n"

#: mafiasi/base/middleware.py:15
msgid ""
Expand Down Expand Up @@ -380,6 +380,18 @@ msgstr "Télécharger le PDF"
msgid "Reminder: Memory minutes for \"%(coursename)s\""
msgstr "Rappel: Mémoire minutes pour \"%(coursename)s\""

#: mafiasi/gprot/templates/admin/gprot/gprot/change_form.html:33
msgid "Block this Gprot"
msgstr "Bloquer cette mémoire"

#: mafiasi/gprot/templates/admin/gprot/gprot/change_form.html:34
msgid ""
"When a Gprot is blocked, a hash is saved that ensures that the same file "
"cannot be uploaded again."
msgstr ""
"Quand une mémoire est bloquée, un hachage est enregistré pour assurer que le "
"même fichier ne peut plus être téléversé."

#: mafiasi/gprot/templates/gprot/_action_list.html:6
msgid "View"
msgstr "Vue"
Expand Down Expand Up @@ -1006,7 +1018,16 @@ msgstr "Seuls les fichiers PDF sont autorisés."
msgid "Please select a file to upload."
msgstr "S'il vous plaît sélectionner un fichier à télécharger."

#: mafiasi/gprot/views.py:285
#: mafiasi/gprot/views.py:217
msgid ""
"This file was blocked because it is an original exam. Please do not try to "
"upload it again because we will get problems with the university."
msgstr ""
"Le fichier a été bloqué parce qu'il s'agit d'un examen original. Merce de ne "
"pas essayer pas de le téléverser à nouveau afin d'éviter des problèmes avec "
"l'université."

#: mafiasi/gprot/views.py:307
msgid "Only PNG, JPEG and GIF files are allowed."
msgstr "Seuls les fichiers PNG, JPEG et GIF sont autorisés."

Expand Down
38 changes: 37 additions & 1 deletion mafiasi/gprot/admin.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
from django.contrib import admin
import hashlib

from django.contrib import admin, messages
from django.shortcuts import get_object_or_404, redirect
from django.urls import path, reverse

from mafiasi.gprot.models import (
Attachment,
BlockedGprots,
Favorite,
GProt,
Label,
Expand All @@ -18,10 +23,41 @@ class GProtAdmin(admin.ModelAdmin):
list_filter = ("published", "is_pdf")
search_fields = ("course__name",)

def get_urls(self):
urls = super().get_urls()
custom_urls = [
path("<path:object_id>/block/", self.admin_site.admin_view(self.block_view), name="gprot_block"),
]

return custom_urls + urls

def block_view(self, request, object_id):
to_block = get_object_or_404(GProt, pk=object_id)
if not to_block.is_pdf:
messages.error(request, "Cannot block, not a PDF")
else:
to_block.published = False
to_block.owner = None
to_block.save()
pdf_filefield = to_block.content_pdf
if not pdf_filefield:
messages.error(request, "Cannot block, no file")
else:
pdf_filefield.file.open()
contents = pdf_filefield.file.read()
pdf_filefield.file.close()
pdf_filefield.delete()
hash = hashlib.sha256(contents).hexdigest()
BlockedGprots.objects.create(pdf_hash=hash, gprot_title=str(to_block), blocked_by=request.user)
messages.success(request, "Successfully blocked")

return redirect(reverse("admin:gprot_gprot_change", args=(object_id,)))


admin.site.register(GProt, GProtAdmin)

admin.site.register(Notification)
admin.site.register(Reminder)
admin.site.register(Label)
admin.site.register(Favorite)
admin.site.register(BlockedGprots)
27 changes: 27 additions & 0 deletions mafiasi/gprot/migrations/0006_blockedgprots.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Generated by Django 4.1 on 2023-07-27 17:43

import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
("gprot", "0005_alter_favorite_url"),
]

operations = [
migrations.CreateModel(
name="BlockedGprots",
fields=[
("id", models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
("pdf_hash", models.CharField(max_length=64)),
("gprot_title", models.CharField(max_length=100)),
(
"blocked_by",
models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
),
],
),
]
9 changes: 9 additions & 0 deletions mafiasi/gprot/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,15 @@ def __str__(self):
return "[{0}] {1}: {2}{3}".format(self.pk, self.exam_date, self.course, append)


class BlockedGprots(models.Model):
pdf_hash = models.CharField(max_length=64)
gprot_title = models.CharField(max_length=100)
blocked_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)

def __str__(self):
return "BlockedGprot: {0}".format(self.gprot_title)


class Attachment(models.Model):
gprot = models.ForeignKey(GProt, on_delete=models.CASCADE)
file = models.FileField(upload_to=make_attachment_filename)
Expand Down
37 changes: 37 additions & 0 deletions mafiasi/gprot/templates/admin/gprot/gprot/change_form.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{% extends "admin/change_form.html" %}
{% load i18n %}
{% block extrastyle %}{{ block.super }}
<style>
.block {
padding: 12px 14px 7px;
margin: 0 0 20px;
background: var(--darkened-bg);
border: 1px solid var(--hairline-color);
border-radius: 4px;
text-align: right;
overflow: hidden;
}

.block > p {
margin: 10px 7px;
}
.block > a {
float: left;
background: var(--delete-button-bg);
border-radius: 4px;
height: 15px;
line-height: 15px;
margin-bottom: 5px;
color: var(--button-fg);
padding: 10px 7px;
display: block;
}
</style>
{% endblock %}
{% block after_related_objects %}
<div class="block">
<a href="{% url 'admin:gprot_block' object_id %}">{% translate 'Block this Gprot' %}</a>
<p>{% blocktranslate %}When a Gprot is blocked, a hash is saved that ensures that the same file cannot be uploaded again.{% endblocktranslate %}</p>
</div>
<div style="clear: left;"></div>
{% endblock %}
21 changes: 20 additions & 1 deletion mafiasi/gprot/views.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
import hashlib
import json
import time
from datetime import date
Expand All @@ -24,7 +25,14 @@
from raven.contrib.django.raven_compat.models import client

from mafiasi.gprot.forms import GProtBasicForm, GProtCreateForm, GProtSearchForm
from mafiasi.gprot.models import Attachment, Favorite, GProt, Notification, Reminder
from mafiasi.gprot.models import (
Attachment,
BlockedGprots,
Favorite,
GProt,
Notification,
Reminder,
)
from mafiasi.gprot.sanitize import clean_html
from mafiasi.teaching.forms import CourseForm, TeacherForm
from mafiasi.teaching.models import Course, Teacher, insert_autocomplete_courses
Expand Down Expand Up @@ -195,6 +203,7 @@ def edit_gprot(request, gprot_pk):
error = _("Only files up to {0} MB are allowed.").format(settings.GPROT_PDF_MAX_SIZE)
if magic.from_buffer(upload.read(1024), mime=True) != "application/pdf":
error = _("Only PDF files are allowed.")

else:
error = _("Please select a file to upload.")

Expand All @@ -204,6 +213,16 @@ def edit_gprot(request, gprot_pk):
gprot.content_pdf = upload
gprot.save()
_clean_pdf_metadata(gprot)
# we have to calculate the hash after cleaning the file
gprot.content_pdf.file.open()
pdf_content = gprot.content_pdf.file.read()
gprot.content_pdf.file.close()
hash = hashlib.sha256(pdf_content).hexdigest()
if BlockedGprots.objects.filter(pdf_hash=hash).exists():
error = _(
"This file was blocked because it is an original exam. Please do not try to upload it again because we will get problems with the university."
)
gprot.content_pdf.delete()

else:
content = request.POST.get("content", "")
Expand Down

0 comments on commit 39de4ef

Please sign in to comment.