From ef65869c7c8b951419c2b8e6d4c559dd0be14eb9 Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Wed, 12 Jan 2022 12:56:22 +0100 Subject: [PATCH] # 63 Refactoring * refactors django User model to custom User model to provide further attributes and methods directly on the user model --- compensation/forms/forms.py | 2 +- compensation/models/compensation.py | 2 +- compensation/models/eco_account.py | 2 +- compensation/tables.py | 2 +- compensation/utils/quality.py | 12 -- ema/forms.py | 2 +- intervention/forms/forms.py | 2 +- intervention/forms/modalForms.py | 2 +- intervention/models/intervention.py | 2 +- konova/autocompletes.py | 2 +- konova/forms.py | 2 +- konova/management/commands/setup.py | 3 +- konova/management/commands/setup_data.py | 3 +- konova/models/object.py | 7 +- konova/sso/sso.py | 3 +- konova/sub_settings/django_settings.py | 2 +- konova/tasks.py | 9 +- konova/tests/test_views.py | 3 +- konova/utils/mailer.py | 37 ++++-- konova/utils/messenger.py | 2 +- konova/utils/user_checks.py | 2 +- locale/de/LC_MESSAGES/django.mo | Bin 29827 -> 29910 bytes locale/de/LC_MESSAGES/django.po | 105 ++++++++++-------- .../email/sharing/shared_access_removed.html | 0 user/admin.py | 14 ++- user/enums.py | 5 +- user/forms.py | 12 +- user/models/__init__.py | 2 +- user/models/konova_user.py | 19 ---- user/models/user.py | 28 +++++ user/models/user_action.py | 15 ++- user/views.py | 7 +- 32 files changed, 174 insertions(+), 136 deletions(-) create mode 100644 templates/email/sharing/shared_access_removed.html delete mode 100644 user/models/konova_user.py create mode 100644 user/models/user.py diff --git a/compensation/forms/forms.py b/compensation/forms/forms.py index dbd3c6c8..0970daad 100644 --- a/compensation/forms/forms.py +++ b/compensation/forms/forms.py @@ -6,7 +6,7 @@ Created on: 04.12.20 """ from dal import autocomplete -from django.contrib.auth.models import User +from user.models import User from django.db import transaction from django.urls import reverse_lazy, reverse from django.utils.translation import gettext_lazy as _ diff --git a/compensation/models/compensation.py b/compensation/models/compensation.py index 65a62b6e..b68ad105 100644 --- a/compensation/models/compensation.py +++ b/compensation/models/compensation.py @@ -8,7 +8,7 @@ Created on: 16.11.21 import shutil from django.contrib import messages -from django.contrib.auth.models import User +from user.models import User from django.db import models, transaction from django.db.models import QuerySet, Sum from django.http import HttpRequest diff --git a/compensation/models/eco_account.py b/compensation/models/eco_account.py index dad7bfff..7d339b4d 100644 --- a/compensation/models/eco_account.py +++ b/compensation/models/eco_account.py @@ -7,7 +7,7 @@ Created on: 16.11.21 """ import shutil -from django.contrib.auth.models import User +from user.models import User from django.core.exceptions import ValidationError from django.core.validators import MinValueValidator from django.db import models, transaction diff --git a/compensation/tables.py b/compensation/tables.py index 6e6a190b..9daf2b23 100644 --- a/compensation/tables.py +++ b/compensation/tables.py @@ -5,7 +5,7 @@ Contact: michel.peltriaux@sgdnord.rlp.de Created on: 01.12.20 """ -from django.contrib.auth.models import User +from user.models import User from django.http import HttpRequest from django.template.loader import render_to_string from django.urls import reverse diff --git a/compensation/utils/quality.py b/compensation/utils/quality.py index b7f8daa7..b622fcdd 100644 --- a/compensation/utils/quality.py +++ b/compensation/utils/quality.py @@ -58,20 +58,8 @@ class EcoAccountQualityChecker(CompensationQualityChecker): self._check_deductable_surface() self._check_responsible_data() self._check_legal_data() - self._check_record_state() super().run_check() - def _check_record_state(self): - """ Checks the data quality for recorded state - - Returns: - - """ - if self.obj.recorded is None: - self.messages.append( - _("Not recorded") - ) - def _check_legal_data(self): """ Checks the data quality for Legal diff --git a/ema/forms.py b/ema/forms.py index cb7f0cc8..5dc3bcfb 100644 --- a/ema/forms.py +++ b/ema/forms.py @@ -7,7 +7,7 @@ Created on: 06.10.21 """ from dal import autocomplete from django import forms -from django.contrib.auth.models import User +from user.models import User from django.db import transaction from django.urls import reverse, reverse_lazy from django.utils.translation import gettext_lazy as _ diff --git a/intervention/forms/forms.py b/intervention/forms/forms.py index 5340dd6e..6f098151 100644 --- a/intervention/forms/forms.py +++ b/intervention/forms/forms.py @@ -7,7 +7,7 @@ Created on: 02.12.20 """ from dal import autocomplete from django import forms -from django.contrib.auth.models import User +from user.models import User from django.db import transaction from django.urls import reverse, reverse_lazy from django.utils.translation import gettext_lazy as _ diff --git a/intervention/forms/modalForms.py b/intervention/forms/modalForms.py index aea9f2ce..063a912a 100644 --- a/intervention/forms/modalForms.py +++ b/intervention/forms/modalForms.py @@ -6,7 +6,7 @@ Created on: 27.09.21 """ from dal import autocomplete -from django.contrib.auth.models import User +from user.models import User from django.db import transaction from django import forms from django.urls import reverse diff --git a/intervention/models/intervention.py b/intervention/models/intervention.py index 737dd407..6f721237 100644 --- a/intervention/models/intervention.py +++ b/intervention/models/intervention.py @@ -8,7 +8,7 @@ Created on: 15.11.21 import shutil from django.contrib import messages -from django.contrib.auth.models import User +from user.models import User from django.db import models, transaction from django.db.models import QuerySet from django.http import HttpRequest diff --git a/konova/autocompletes.py b/konova/autocompletes.py index f47117cc..bee8dad8 100644 --- a/konova/autocompletes.py +++ b/konova/autocompletes.py @@ -6,7 +6,7 @@ Created on: 07.12.20 """ from dal_select2.views import Select2QuerySetView, Select2GroupQuerySetView -from django.contrib.auth.models import User +from user.models import User from django.db.models import Q from codelist.models import KonovaCode diff --git a/konova/forms.py b/konova/forms.py index 4ad309ed..aae83e6a 100644 --- a/konova/forms.py +++ b/konova/forms.py @@ -12,7 +12,7 @@ from bootstrap_modal_forms.forms import BSModalForm from bootstrap_modal_forms.utils import is_ajax from django import forms from django.contrib import messages -from django.contrib.auth.models import User +from user.models import User from django.contrib.gis.forms import OSMWidget, MultiPolygonField from django.contrib.gis.geos import MultiPolygon from django.db import transaction diff --git a/konova/management/commands/setup.py b/konova/management/commands/setup.py index f02a8e36..6c52ba9e 100644 --- a/konova/management/commands/setup.py +++ b/konova/management/commands/setup.py @@ -7,7 +7,8 @@ Created on: 15.12.20 """ from getpass import getpass -from django.contrib.auth.models import User, Group +from user.models import User +from django.contrib.auth.models import Group from django.core.management import BaseCommand, call_command from django.db import transaction diff --git a/konova/management/commands/setup_data.py b/konova/management/commands/setup_data.py index 85e64907..159dd3ec 100644 --- a/konova/management/commands/setup_data.py +++ b/konova/management/commands/setup_data.py @@ -23,8 +23,7 @@ GROUPS_DATA = [ # Must match with UserNotificationEnum USER_NOTIFICATIONS_NAMES = { - "NOTIFY_ON_NEW_RELATED_DATA": _("On new related data"), - "NOTIFY_ON_SHARE_LINK_DISABLED": _("On disabled share link"), + "NOTIFY_ON_SHARED_ACCESS_GAINED": _("On shared access gained"), "NOTIFY_ON_SHARED_ACCESS_REMOVED": _("On shared access removed"), "NOTIFY_ON_SHARED_DATA_RECORDED": _("On shared data recorded"), "NOTIFY_ON_SHARED_DATA_DELETED": _("On shared data deleted"), diff --git a/konova/models/object.py b/konova/models/object.py index 49c1f4e0..23a21651 100644 --- a/konova/models/object.py +++ b/konova/models/object.py @@ -10,7 +10,7 @@ import uuid from abc import abstractmethod from django.contrib import messages -from django.contrib.auth.models import User +from user.models import User from django.core.exceptions import ObjectDoesNotExist from django.http import HttpRequest from django.utils.timezone import now @@ -411,6 +411,11 @@ class ShareableObjectMixin(models.Model): users = User.objects.filter( id__in=accessing_users ) + removed_users = self.users.all().exclude( + id__in=accessing_users + ) + for user in removed_users: + user.send_mail_shared_access_removed(self) self.share_with_list(users) diff --git a/konova/sso/sso.py b/konova/sso/sso.py index 69cd2b36..f33376fc 100644 --- a/konova/sso/sso.py +++ b/konova/sso/sso.py @@ -5,9 +5,10 @@ Contact: michel.peltriaux@sgdnord.rlp.de Created on: 17.08.21 """ -from django.contrib.auth.models import User from simple_sso.sso_client.client import Client +from user.models import User + class KonovaSSOClient(Client): """ Konova specialized derivate of general sso.Client. diff --git a/konova/sub_settings/django_settings.py b/konova/sub_settings/django_settings.py index df875a81..199ab17a 100644 --- a/konova/sub_settings/django_settings.py +++ b/konova/sub_settings/django_settings.py @@ -129,7 +129,7 @@ DATABASES = { # Password validation # https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators - +AUTH_USER_MODEL = "user.User" AUTH_PASSWORD_VALIDATORS = [ { 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', diff --git a/konova/tasks.py b/konova/tasks.py index b0108a4b..2db4b19f 100644 --- a/konova/tasks.py +++ b/konova/tasks.py @@ -1,3 +1,5 @@ +from time import sleep + from celery import shared_task from django.core.exceptions import ObjectDoesNotExist @@ -5,10 +7,13 @@ from konova.models import Geometry @shared_task -def celery_update_parcels(geometry_id: str): +def celery_update_parcels(geometry_id: str, recheck: bool = True): try: geom = Geometry.objects.get(id=geometry_id) geom.parcels.clear() geom.update_parcels() except ObjectDoesNotExist: - return + if recheck: + sleep(5) + celery_update_parcels(geometry_id, False) + diff --git a/konova/tests/test_views.py b/konova/tests/test_views.py index dad44297..1e0ae7f8 100644 --- a/konova/tests/test_views.py +++ b/konova/tests/test_views.py @@ -7,7 +7,8 @@ Created on: 26.10.21 """ import datetime -from django.contrib.auth.models import User, Group +from user.models import User +from django.contrib.auth.models import Group from django.contrib.gis.geos import MultiPolygon, Polygon from django.core.exceptions import ObjectDoesNotExist from django.test import TestCase, Client diff --git a/konova/utils/mailer.py b/konova/utils/mailer.py index 0dc32c66..cc25f660 100644 --- a/konova/utils/mailer.py +++ b/konova/utils/mailer.py @@ -8,6 +8,8 @@ Created on: 09.11.20 import logging from django.core.mail import send_mail +from django.template.loader import render_to_string +from django.utils.translation import gettext_lazy as _ from konova.sub_settings.django_settings import DEFAULT_FROM_EMAIL @@ -26,18 +28,13 @@ class Mailer: auth_user = None auth_password = None - def __init__(self, to_mail: list, from_mail: str = DEFAULT_FROM_EMAIL, auth_user: str = None, auth_password: str = None, fail_silently: bool = False): - # Make sure given to_mail parameter is a list - if isinstance(to_mail, str): - to_mail = [to_mail] - + def __init__(self, from_mail: str = DEFAULT_FROM_EMAIL, auth_user: str = None, auth_password: str = None, fail_silently: bool = False): self.from_mail = from_mail - self.to_mail = to_mail self.fail_silently = fail_silently self.auth_user = auth_user self.auth_password = auth_password - def send(self, subject: str, msg: str): + def send(self, recipient_list: list, subject: str, msg: str): """ Sends a mail with subject and message """ @@ -45,8 +42,30 @@ class Mailer: subject=subject, message=msg, from_email=self.from_mail, - recipient_list=self.to_mail, + recipient_list=recipient_list, fail_silently=self.fail_silently, auth_user=self.auth_user, auth_password=self.auth_password - ) \ No newline at end of file + ) + + def send_mail_shared_access_removed(self, obj, user): + """ Send a mail if user has no access to the object anymore + + Args: + obj (): + + Returns: + + """ + context = { + "user": user, + "obj": obj, + } + msg = render_to_string("email/sharing/shared_access_removed.html", context) + user_mail_address = [user.email] + self.send( + user_mail_address, + _("{} - Shared access removed").format(obj.identifier), + msg + ) + diff --git a/konova/utils/messenger.py b/konova/utils/messenger.py index 8169d5e6..5be4dc1e 100644 --- a/konova/utils/messenger.py +++ b/konova/utils/messenger.py @@ -8,7 +8,7 @@ Created on: 17.08.21 from collections import Iterable import requests -from django.contrib.auth.models import User +from user.models import User from django.utils.translation import gettext_lazy as _ from konova.settings import SSO_SERVER_BASE, SSO_PUBLIC_KEY, PROXIES diff --git a/konova/utils/user_checks.py b/konova/utils/user_checks.py index a01dadbe..b4f65271 100644 --- a/konova/utils/user_checks.py +++ b/konova/utils/user_checks.py @@ -5,7 +5,7 @@ Contact: michel.peltriaux@sgdnord.rlp.de Created on: 02.07.21 """ -from django.contrib.auth.models import User +from user.models import User from konova.settings import ETS_GROUP, ZB_GROUP diff --git a/locale/de/LC_MESSAGES/django.mo b/locale/de/LC_MESSAGES/django.mo index 1246234f1e0debae2285b00e000c54893295026c..37299851a48bd993a37c2dea089bb4b52d56c980 100644 GIT binary patch delta 8620 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 diff --git a/locale/de/LC_MESSAGES/django.po b/locale/de/LC_MESSAGES/django.po index cb6b2a81..ba3953af 100644 --- a/locale/de/LC_MESSAGES/django.po +++ b/locale/de/LC_MESSAGES/django.po @@ -3,26 +3,30 @@ # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # -#: compensation/filters.py:91 compensation/forms/modalForms.py:34 +#: compensation/filters.py:122 compensation/forms/modalForms.py:34 #: compensation/forms/modalForms.py:45 compensation/forms/modalForms.py:61 #: compensation/forms/modalForms.py:238 compensation/forms/modalForms.py:316 #: intervention/forms/forms.py:52 intervention/forms/forms.py:154 #: intervention/forms/forms.py:166 intervention/forms/modalForms.py:125 #: intervention/forms/modalForms.py:138 intervention/forms/modalForms.py:151 -#: konova/filters.py:63 konova/filters.py:64 konova/filters.py:91 -#: konova/filters.py:92 konova/filters.py:104 konova/filters.py:105 -#: konova/filters.py:117 konova/filters.py:118 konova/filters.py:130 -#: konova/filters.py:131 konova/filters.py:144 konova/filters.py:145 -#: konova/filters.py:280 konova/filters.py:324 konova/forms.py:140 -#: konova/forms.py:241 konova/forms.py:312 konova/forms.py:339 -#: konova/forms.py:349 konova/forms.py:362 konova/forms.py:374 -#: konova/forms.py:392 user/forms.py:38 +#: konova/filters/mixins.py:53 konova/filters/mixins.py:54 +#: konova/filters/mixins.py:81 konova/filters/mixins.py:82 +#: konova/filters/mixins.py:94 konova/filters/mixins.py:95 +#: konova/filters/mixins.py:107 konova/filters/mixins.py:108 +#: konova/filters/mixins.py:120 konova/filters/mixins.py:121 +#: konova/filters/mixins.py:134 konova/filters/mixins.py:135 +#: konova/filters/mixins.py:270 konova/filters/mixins.py:315 +#: konova/filters/mixins.py:353 konova/filters/mixins.py:354 +#: konova/filters/mixins.py:385 konova/filters/mixins.py:386 +#: konova/forms.py:140 konova/forms.py:241 konova/forms.py:312 +#: konova/forms.py:339 konova/forms.py:349 konova/forms.py:362 +#: konova/forms.py:374 konova/forms.py:392 user/forms.py:38 #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-01-11 17:07+0100\n" +"POT-Creation-Date: 2022-01-12 11:33+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -48,7 +52,7 @@ msgstr "Bis" #: intervention/forms/forms.py:100 #: intervention/templates/intervention/detail/view.html:56 #: intervention/templates/intervention/report/report.html:37 -#: intervention/utils/quality.py:49 +#: intervention/utils/quality.py:49 konova/filters/mixins.py:395 msgid "Conservation office" msgstr "Eintragungsstelle" @@ -301,7 +305,7 @@ msgstr "Altfälle" msgid "Before" msgstr "Vor" -#: compensation/filters.py:90 +#: compensation/filters.py:121 msgid "Show only unrecorded" msgstr "Nur unverzeichnete anzeigen" @@ -1218,7 +1222,7 @@ msgstr "Mehrfachauswahl möglich" #: intervention/forms/forms.py:84 #: intervention/templates/intervention/detail/view.html:48 #: intervention/templates/intervention/report/report.html:29 -#: intervention/utils/quality.py:46 +#: intervention/utils/quality.py:46 konova/filters/mixins.py:363 msgid "Registration office" msgstr "Zulassungsbehörde" @@ -1508,62 +1512,73 @@ msgstr "" "somit nichts eingeben, bearbeiten oder sonstige Aktionen ausführen. " "Kontaktieren Sie bitte einen Administrator. +++" -#: konova/filters.py:67 +#: konova/filters/mixins.py:57 msgid "File number" msgstr "Aktenzeichen" -#: konova/filters.py:68 +#: konova/filters/mixins.py:58 msgid "Search for file number" msgstr "Nach Aktenzeichen suchen" -#: konova/filters.py:95 +#: konova/filters/mixins.py:85 msgid "District" msgstr "Kreis" -#: konova/filters.py:96 +#: konova/filters/mixins.py:86 msgid "Search for district" msgstr "Nach Kreis suchen" -#: konova/filters.py:108 +#: konova/filters/mixins.py:98 msgid "Parcel gmrkng" msgstr "Gemarkung" -#: konova/filters.py:109 +#: konova/filters/mixins.py:99 msgid "Search for parcel gmrkng" msgstr "Nach Gemarkung suchen" -#: konova/filters.py:121 konova/templates/konova/includes/parcels.html:18 +#: konova/filters/mixins.py:111 +#: konova/templates/konova/includes/parcels.html:18 msgid "Parcel" msgstr "Flur" -#: konova/filters.py:122 +#: konova/filters/mixins.py:112 msgid "Search for parcel" msgstr "Nach Flur suchen" -#: konova/filters.py:134 konova/templates/konova/includes/parcels.html:19 +#: konova/filters/mixins.py:124 +#: konova/templates/konova/includes/parcels.html:19 msgid "Parcel counter" msgstr "Flurstückzähler" -#: konova/filters.py:135 +#: konova/filters/mixins.py:125 msgid "Search for parcel counter" msgstr "Nach Flurstückzähler suchen" -#: konova/filters.py:148 konova/templates/konova/includes/parcels.html:20 +#: konova/filters/mixins.py:138 +#: konova/templates/konova/includes/parcels.html:20 msgid "Parcel number" msgstr "Flurstücknenner" -#: konova/filters.py:149 +#: konova/filters/mixins.py:139 msgid "Search for parcel number" msgstr "Nach Flurstücknenner suchen" -#: konova/filters.py:279 +#: konova/filters/mixins.py:269 msgid "Show unshared" msgstr "Nicht freigegebene anzeigen" -#: konova/filters.py:323 +#: konova/filters/mixins.py:314 msgid "Show recorded" msgstr "Verzeichnete anzeigen" +#: konova/filters/mixins.py:364 +msgid "Search for registration office" +msgstr "Nach Zulassungsbehörde suchen" + +#: konova/filters/mixins.py:396 +msgid "Search for conservation office" +msgstr "Nch Eintragungsstelle suchen" + #: konova/forms.py:37 templates/form/collapsable/form.html:62 msgid "Save" msgstr "Speichern" @@ -1644,26 +1659,22 @@ msgstr "" "Ich, {} {}, bestätige, dass diese Daten wieder entzeichnet werden müssen." #: konova/management/commands/setup_data.py:26 -msgid "On new related data" -msgstr "Wenn neue Daten für mich angelegt werden" +msgid "On shared access gained" +msgstr "Wenn mir eine Freigabe zu Daten erteilt wird" #: konova/management/commands/setup_data.py:27 -msgid "On disabled share link" -msgstr "Wenn ein Freigabelink deaktiviert wird" - -#: konova/management/commands/setup_data.py:28 msgid "On shared access removed" msgstr "Wenn mir eine Freigabe zu Daten entzogen wird" -#: konova/management/commands/setup_data.py:29 +#: konova/management/commands/setup_data.py:28 msgid "On shared data recorded" msgstr "Wenn meine freigegebenen Daten verzeichnet wurden" -#: konova/management/commands/setup_data.py:30 +#: konova/management/commands/setup_data.py:29 msgid "On shared data deleted" msgstr "Wenn meine freigegebenen Daten gelöscht wurden" -#: konova/management/commands/setup_data.py:31 +#: konova/management/commands/setup_data.py:30 msgid "On registered data edited" msgstr "Wenn meine freigegebenen Daten bearbeitet wurden" @@ -1906,35 +1917,35 @@ msgstr "Abbrechen" msgid "Fields with * are required." msgstr "* sind Pflichtfelder." -#: templates/generic_index.html:28 +#: templates/generic_index.html:39 msgid "New entry" msgstr "Neuer Eintrag" -#: templates/generic_index.html:30 +#: templates/generic_index.html:41 msgid "New" msgstr "Neu" -#: templates/generic_index.html:45 +#: templates/generic_index.html:56 msgid "Search for keywords" msgstr "Nach Schlagwörtern suchen" -#: templates/generic_index.html:45 +#: templates/generic_index.html:56 msgid "Search" msgstr "Suchen" -#: templates/generic_index.html:46 +#: templates/generic_index.html:57 msgid "Start search" msgstr "Starte Suche" -#: templates/generic_index.html:58 +#: templates/generic_index.html:69 msgid "Results per page" msgstr "Treffer pro Seite" -#: templates/generic_index.html:82 templates/generic_index.html:99 +#: templates/generic_index.html:93 templates/generic_index.html:118 msgid "Filter" msgstr "" -#: templates/generic_index.html:101 +#: templates/generic_index.html:120 msgid "Apply filter" msgstr "Filter anwenden" @@ -3591,6 +3602,12 @@ msgstr "" msgid "Unable to connect to qpid with SASL mechanism %s" msgstr "" +#~ msgid "On new related data" +#~ msgstr "Wenn neue Daten für mich angelegt werden" + +#~ msgid "On disabled share link" +#~ msgstr "Wenn ein Freigabelink deaktiviert wird" + #~ msgid "Deduct" #~ msgstr "Abbuchen" diff --git a/templates/email/sharing/shared_access_removed.html b/templates/email/sharing/shared_access_removed.html new file mode 100644 index 00000000..e69de29b diff --git a/user/admin.py b/user/admin.py index 9a633e77..92266b92 100644 --- a/user/admin.py +++ b/user/admin.py @@ -1,6 +1,6 @@ from django.contrib import admin -from user.models import UserNotification, KonovaUserExtension, UserActionLogEntry +from user.models import UserNotification, UserActionLogEntry, User class UserNotificationAdmin(admin.ModelAdmin): @@ -11,9 +11,13 @@ class UserNotificationAdmin(admin.ModelAdmin): ] -class KonovaUserExtensionAdmin(admin.ModelAdmin): +class UserAdmin(admin.ModelAdmin): list_display = [ - "user", + "id", + "username", + "first_name", + "last_name", + "email", ] @@ -27,5 +31,5 @@ class UserActionLogEntryAdmin(admin.ModelAdmin): admin.site.register(UserNotification, UserNotificationAdmin) -admin.site.register(KonovaUserExtension, KonovaUserExtensionAdmin) -admin.site.register(UserActionLogEntry, UserActionLogEntryAdmin) \ No newline at end of file +admin.site.register(UserActionLogEntry, UserActionLogEntryAdmin) +admin.site.register(User, UserAdmin) \ No newline at end of file diff --git a/user/enums.py b/user/enums.py index 1575a778..9ba6cf95 100644 --- a/user/enums.py +++ b/user/enums.py @@ -9,9 +9,8 @@ from konova.enums import BaseEnum class UserNotificationEnum(BaseEnum): - NOTIFY_ON_NEW_RELATED_DATA = "NOTIFY_ON_NEW_RELATED_DATA" # notifies in case new data has been added which is related to the user's organisation - NOTIFY_ON_SHARE_LINK_DISABLED = "NOTIFY_ON_SHARE_LINK_DISABLED" # notifies in case share link for data has been disabled NOTIFY_ON_SHARED_ACCESS_REMOVED = "NOTIFY_ON_SHARED_ACCESS_REMOVED" # notifies in case shared access to data has been removed NOTIFY_ON_SHARED_DATA_RECORDED = "NOTIFY_ON_SHARED_DATA_RECORDED" # notifies in case data has been "verzeichnet" NOTIFY_ON_SHARED_DATA_DELETED = "NOTIFY_ON_SHARED_DATA_DELETED" # notifies in case data has been deleted - NOTIFY_ON_REGISTERED_DATA_EDITED = "NOTIFY_ON_REGISTERED_DATA_EDITED" # notifies in case registered ("verzeichnet") data has been edited \ No newline at end of file + NOTIFY_ON_REGISTERED_DATA_EDITED = "NOTIFY_ON_REGISTERED_DATA_EDITED" # notifies in case registered ("verzeichnet") data has been edited + NOTIFY_ON_SHARED_ACCESS_GAINED = "NOTIFY_ON_SHARED_ACCESS_GAINED" # notifies in case new access has been gained \ No newline at end of file diff --git a/user/forms.py b/user/forms.py index 6d6accbc..66f9fab7 100644 --- a/user/forms.py +++ b/user/forms.py @@ -8,10 +8,10 @@ Created on: 08.07.21 from django import forms from django.urls import reverse from django.utils.translation import gettext_lazy as _ -from django.contrib.auth.models import User +from user.models import User from konova.forms import BaseForm, BaseModalForm -from user.models import UserNotification, KonovaUserExtension +from user.models import UserNotification class UserNotificationForm(BaseForm): @@ -50,11 +50,7 @@ class UserNotificationForm(BaseForm): ) self.fields["notifications"].choices = choices - # Set currently selected notifications as initial - self.konova_extension = KonovaUserExtension.objects.get_or_create( - user=user - )[0] - users_current_notifications = self.konova_extension.notifications.all() + users_current_notifications = self.user.notifications.all() users_current_notifications = [str(n.id) for n in users_current_notifications] self.fields["notifications"].initial = users_current_notifications @@ -68,7 +64,7 @@ class UserNotificationForm(BaseForm): notifications = UserNotification.objects.filter( id__in=selected_notification_ids, ) - self.konova_extension.notifications.set(notifications) + self.user.notifications.set(notifications) class UserContactForm(BaseModalForm): diff --git a/user/models/__init__.py b/user/models/__init__.py index 85a98b67..7788d8e4 100644 --- a/user/models/__init__.py +++ b/user/models/__init__.py @@ -6,5 +6,5 @@ Created on: 15.11.21 """ from .user_action import * -from .konova_user import * +from .user import * from .notification import * diff --git a/user/models/konova_user.py b/user/models/konova_user.py deleted file mode 100644 index b100e02f..00000000 --- a/user/models/konova_user.py +++ /dev/null @@ -1,19 +0,0 @@ -""" -Author: Michel Peltriaux -Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany -Contact: michel.peltriaux@sgdnord.rlp.de -Created on: 15.11.21 - -""" -from django.contrib.auth.models import User -from django.db import models - - -class KonovaUserExtension(models.Model): - """ Extension model for additional ksp features - - Extends the default user model for some extras - - """ - user = models.OneToOneField(User, on_delete=models.CASCADE) - notifications = models.ManyToManyField("user.UserNotification", related_name="+") diff --git a/user/models/user.py b/user/models/user.py new file mode 100644 index 00000000..63f71e35 --- /dev/null +++ b/user/models/user.py @@ -0,0 +1,28 @@ +""" +Author: Michel Peltriaux +Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany +Contact: michel.peltriaux@sgdnord.rlp.de +Created on: 15.11.21 + +""" +from django.contrib.auth.models import AbstractUser + +from django.db import models + +from konova.utils.mailer import Mailer + + +class User(AbstractUser): + notifications = models.ManyToManyField("user.UserNotification", related_name="+", blank=True) + + def send_mail_shared_access_removed(self, obj): + """ Sends a mail to the user in case of removed shared access + + Args: + obj (): + + Returns: + + """ + mailer = Mailer() + mailer.send_mail_shared_access_removed(obj, self) diff --git a/user/models/user_action.py b/user/models/user_action.py index c1894f7d..72e86151 100644 --- a/user/models/user_action.py +++ b/user/models/user_action.py @@ -7,7 +7,6 @@ Created on: 15.11.21 """ import uuid -from django.contrib.auth.models import User from django.db import models from django.utils.translation import gettext_lazy as _ @@ -34,7 +33,7 @@ class UserActionLogEntry(models.Model): primary_key=True, default=uuid.uuid4, ) - user = models.ForeignKey(User, related_name='+', on_delete=models.CASCADE, help_text="Performing user") + user = models.ForeignKey("user.User", related_name='+', on_delete=models.CASCADE, help_text="Performing user") timestamp = models.DateTimeField(auto_now_add=True, help_text="Timestamp of performed action") action = models.CharField( max_length=255, @@ -69,7 +68,7 @@ class UserActionLogEntry(models.Model): return None @classmethod - def get_created_action(cls, user: User, comment: str = None): + def get_created_action(cls, user, comment: str = None): action = UserActionLogEntry.objects.create( user=user, action=UserAction.CREATED, @@ -78,7 +77,7 @@ class UserActionLogEntry(models.Model): return action @classmethod - def get_edited_action(cls, user: User, comment: str = None): + def get_edited_action(cls, user, comment: str = None): action = UserActionLogEntry.objects.create( user=user, action=UserAction.EDITED, @@ -87,7 +86,7 @@ class UserActionLogEntry(models.Model): return action @classmethod - def get_deleted_action(cls, user: User, comment: str = None): + def get_deleted_action(cls, user, comment: str = None): action = UserActionLogEntry.objects.create( user=user, action=UserAction.DELETED, @@ -96,7 +95,7 @@ class UserActionLogEntry(models.Model): return action @classmethod - def get_checked_action(cls, user: User, comment: str = None): + def get_checked_action(cls, user, comment: str = None): action = UserActionLogEntry.objects.create( user=user, action=UserAction.CHECKED, @@ -105,7 +104,7 @@ class UserActionLogEntry(models.Model): return action @classmethod - def get_recorded_action(cls, user: User, comment: str = None): + def get_recorded_action(cls, user, comment: str = None): action = UserActionLogEntry.objects.create( user=user, action=UserAction.RECORDED, @@ -114,7 +113,7 @@ class UserActionLogEntry(models.Model): return action @classmethod - def get_unrecorded_action(cls, user: User, comment: str = None): + def get_unrecorded_action(cls, user, comment: str = None): action = UserActionLogEntry.objects.create( user=user, action=UserAction.UNRECORDED, diff --git a/user/views.py b/user/views.py index f63b14bd..13fecf5c 100644 --- a/user/views.py +++ b/user/views.py @@ -1,6 +1,6 @@ from django.contrib import messages from django.contrib.auth.decorators import login_required -from django.contrib.auth.models import User +from user.models import User from django.http import HttpRequest from django.shortcuts import render, redirect, get_object_or_404 from django.utils.translation import gettext_lazy as _ @@ -8,7 +8,6 @@ from django.utils.translation import gettext_lazy as _ from konova.contexts import BaseContext from konova.decorators import any_group_check from user.forms import UserNotificationForm, UserContactForm -from user.models import KonovaUserExtension @login_required @@ -43,9 +42,6 @@ def notifications_view(request: HttpRequest): """ template = "user/notifications.html" user = request.user - konova_ext = KonovaUserExtension.objects.get_or_create( - user=user - )[0] form = UserNotificationForm(user=user, data=request.POST or None) if request.method == "POST": @@ -65,7 +61,6 @@ def notifications_view(request: HttpRequest): context = { "user": user, "form": form, - "konova_ext": konova_ext, } context = BaseContext(request, context).context return render(request, template, context)