From 80035a17f637c0823a478f7022a09711d0c0b775 Mon Sep 17 00:00:00 2001 From: Francesco Filicetti Date: Fri, 3 Feb 2023 10:31:25 +0100 Subject: [PATCH] feat: short URL for pre-compiled tickets --- .../migrations/0005_compiledticket.py | 22 +++++++++++++++++ .../0006_alter_compiledticket_url_path.py | 19 +++++++++++++++ .../0007_compiledticket_one_time.py | 18 ++++++++++++++ uniticket/uni_ticket/models.py | 24 +++++++++++++++++++ uniticket/uni_ticket/settings.py | 2 ++ uniticket/uni_ticket/views/user.py | 18 +++++++++++--- 6 files changed, 100 insertions(+), 3 deletions(-) create mode 100644 uniticket/uni_ticket/migrations/0005_compiledticket.py create mode 100644 uniticket/uni_ticket/migrations/0006_alter_compiledticket_url_path.py create mode 100644 uniticket/uni_ticket/migrations/0007_compiledticket_one_time.py diff --git a/uniticket/uni_ticket/migrations/0005_compiledticket.py b/uniticket/uni_ticket/migrations/0005_compiledticket.py new file mode 100644 index 00000000..c7c444d9 --- /dev/null +++ b/uniticket/uni_ticket/migrations/0005_compiledticket.py @@ -0,0 +1,22 @@ +# Generated by Django 3.2.15 on 2023-02-03 07:48 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('uni_ticket', '0004_alter_ticketcategorywsprotocollo_protocollo_uo'), + ] + + operations = [ + migrations.CreateModel( + name='CompiledTicket', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('url_path', models.CharField(max_length=255)), + ('content', models.TextField()), + ('created', models.DateTimeField(auto_now_add=True)), + ], + ), + ] diff --git a/uniticket/uni_ticket/migrations/0006_alter_compiledticket_url_path.py b/uniticket/uni_ticket/migrations/0006_alter_compiledticket_url_path.py new file mode 100644 index 00000000..04ec51ef --- /dev/null +++ b/uniticket/uni_ticket/migrations/0006_alter_compiledticket_url_path.py @@ -0,0 +1,19 @@ +# Generated by Django 3.2.15 on 2023-02-03 07:51 + +from django.db import migrations, models +import uuid + + +class Migration(migrations.Migration): + + dependencies = [ + ('uni_ticket', '0005_compiledticket'), + ] + + operations = [ + migrations.AlterField( + model_name='compiledticket', + name='url_path', + field=models.CharField(default=uuid.uuid4, max_length=255, unique=True), + ), + ] diff --git a/uniticket/uni_ticket/migrations/0007_compiledticket_one_time.py b/uniticket/uni_ticket/migrations/0007_compiledticket_one_time.py new file mode 100644 index 00000000..6a77c77e --- /dev/null +++ b/uniticket/uni_ticket/migrations/0007_compiledticket_one_time.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.15 on 2023-02-03 09:08 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('uni_ticket', '0006_alter_compiledticket_url_path'), + ] + + operations = [ + migrations.AddField( + model_name='compiledticket', + name='one_time', + field=models.BooleanField(default=False), + ), + ] diff --git a/uniticket/uni_ticket/models.py b/uniticket/uni_ticket/models.py index 0566e0d9..b979b598 100644 --- a/uniticket/uni_ticket/models.py +++ b/uniticket/uni_ticket/models.py @@ -33,6 +33,7 @@ NEW_TICKET_CREATED_ALERT, ORGANIZATION_EMPLOYEE_LABEL, ORGANIZATION_USER_LABEL, + PRECOMPILED_TICKET_EXPIRE_DAYS, PRIORITY_LEVELS, SHOW_HEADING_TEXT, TICKET_ATTACHMENT_FOLDER, @@ -48,6 +49,10 @@ from .validators import * +PRECOMPILED_TICKET_EXPIRE_DAYS = getattr(settings, + 'PRECOMPILED_TICKET_EXPIRE_DAYS', + PRECOMPILED_TICKET_EXPIRE_DAYS) + logger = logging.getLogger("__name__") @@ -1608,3 +1613,22 @@ class Meta: def __str__(self): return "{} - {}".format(self.name, self.organizational_structure) + + +class CompiledTicket(models.Model): + url_path = models.CharField(max_length=255, unique=True, default=uuid.uuid4) + content = models.TextField() + one_time = models.BooleanField(default=False) + created = models.DateTimeField(auto_now_add=True) + + @staticmethod + def clear(): + """ """ + if PRECOMPILED_TICKET_EXPIRE_DAYS: + to_clear = [] + precompiled_tickets = CompiledTicket.objects.all() + for precompiled in precompiled_tickets: + if (timezone.now() - precompiled.created).days >= PRECOMPILED_TICKET_EXPIRE_DAYS: + to_clear.append(precompiled.pk) + entries_to_clean = CompiledTicket.objects.filter(pk__in=to_clear) + entries_to_clean.delete() diff --git a/uniticket/uni_ticket/settings.py b/uniticket/uni_ticket/settings.py index 24735c40..1aba1398 100644 --- a/uniticket/uni_ticket/settings.py +++ b/uniticket/uni_ticket/settings.py @@ -507,3 +507,5 @@ ) STATS_SHOW_TICKETS_BY_USER = True + +PRECOMPILED_TICKET_EXPIRE_DAYS = 7 diff --git a/uniticket/uni_ticket/views/user.py b/uniticket/uni_ticket/views/user.py index b2f7b080..01537c25 100644 --- a/uniticket/uni_ticket/views/user.py +++ b/uniticket/uni_ticket/views/user.py @@ -329,10 +329,18 @@ def get_assets(self, structure_slug, category_slug) -> None: def get_modulo_and_form(self) -> None: # if there is an encrypted token with ticket params in URL if self.request.GET.get("import"): + CompiledTicket.clear() encoded_data = self.request.GET["import"] + try: + compiled_ticket = get_object_or_404(CompiledTicket, url_path=encoded_data) + except Exception: + return custom_message(self.request, _("Il ticket precompilato รจ scaduto")) try: # decrypt and get imported form content - imported_data = json.loads(decrypt_from_jwe(encoded_data)) + imported_data = json.loads(decrypt_from_jwe(compiled_ticket.content)) + # one time + if compiled_ticket.one_time: + compiled_ticket.delete() except Exception: return custom_message(self.request, _("Dati da importare non consistenti.")) # get input_module id from imported data @@ -613,7 +621,9 @@ def post(self, request, structure_slug, category_slug, api=False): ) ) # build url to display in message - url = base_url + "?import=" + encrypted_data + compiled_ticket = CompiledTicket.objects.create(content=encrypted_data) + # url = base_url + "?import=" + encrypted_data + url = f"{base_url}?import={compiled_ticket.url_path}" messages.add_message( request, messages.SUCCESS, @@ -1623,6 +1633,8 @@ def ticket_clone(request, ticket_id): # build encrypted url param with form data encrypted_data = encrypt_to_jwe(json.dumps(form_data).encode()) + compiled_ticket = CompiledTicket.objects.create(content=encrypted_data, + one_time=True) base_url = reverse( "uni_ticket:add_new_ticket", kwargs={ @@ -1630,7 +1642,7 @@ def ticket_clone(request, ticket_id): "category_slug": category.slug, }, ) - return HttpResponseRedirect(base_url + "?import={}".format(encrypted_data)) + return HttpResponseRedirect(f"{base_url}?import={compiled_ticket.url_path}") @login_required