diff --git a/docs/changelog.rst b/docs/changelog.rst index 7e6be33..4aeb686 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -1,6 +1,8 @@ Changelog ========= +* :feature:`-` add support model for offline account reset codes in new help + app * :support:`-` remove unused PowerDNS support tables from domains app * :feature:`-` add impersonation support for superusers * :support:`-` remove django-braces dependency diff --git a/gnuviechadmin/gnuviechadmin/settings.py b/gnuviechadmin/gnuviechadmin/settings.py index 243b6e8..089e171 100644 --- a/gnuviechadmin/gnuviechadmin/settings.py +++ b/gnuviechadmin/gnuviechadmin/settings.py @@ -232,6 +232,7 @@ LOCAL_APPS = ( "userdbs", "hostingpackages", "websites", + "help", "contact_form", ) @@ -276,7 +277,7 @@ LOGGING = { "formatters": { "verbose": { "format": "%(levelname)s %(asctime)s %(name)s " - "%(module)s:%(lineno)d %(process)d %(thread)d %(message)s" + "%(module)s:%(lineno)d %(process)d %(thread)d %(message)s" }, "simple": {"format": "%(levelname)s %(name)s:%(lineno)d %(message)s"}, }, @@ -404,23 +405,8 @@ if GVA_ENVIRONMENT == "local": dict( [ (key, {"handlers": ["console"], "level": "DEBUG", "propagate": True}) - for key in [ - "dashboard", - "domains", - "fileservertasks", - "gvacommon", - "gvawebcore", - "hostingpackages", - "ldaptasks", - "managemails", - "mysqltasks", - "osusers", - "pgsqltasks", - "taskresults", - "userdbs", - "websites", - ] - ] + for key in LOCAL_APPS + ], ) ) elif GVA_ENVIRONMENT == "test": @@ -439,22 +425,7 @@ elif GVA_ENVIRONMENT == "test": dict( [ (key, {"handlers": ["console"], "level": "ERROR", "propagate": True}) - for key in [ - "dashboard", - "domains", - "fileservertasks", - "gvacommon", - "gvawebcore", - "hostingpackages", - "ldaptasks", - "managemails", - "mysqltasks", - "osusers", - "pgsqltasks", - "taskresults", - "userdbs", - "websites", - ] + for key in LOCAL_APPS ] ) ) diff --git a/gnuviechadmin/help/__init__.py b/gnuviechadmin/help/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/gnuviechadmin/help/admin.py b/gnuviechadmin/help/admin.py new file mode 100644 index 0000000..b143c6c --- /dev/null +++ b/gnuviechadmin/help/admin.py @@ -0,0 +1,22 @@ +from django.contrib import admin +from django.contrib.auth import get_user_model +from django.contrib.auth.admin import UserAdmin as BaseUserAdmin +from django.utils.translation import ugettext_lazy as _ + +from help.models import HelpUser + +User = get_user_model() + + +class HelpUserInline(admin.StackedInline): + model = HelpUser + can_delete = False + readonly_fields = ("offline_account_code",) + + +class UserAdmin(BaseUserAdmin): + inlines = (HelpUserInline,) + + +admin.site.unregister(User) +admin.site.register(User, UserAdmin) diff --git a/gnuviechadmin/help/apps.py b/gnuviechadmin/help/apps.py new file mode 100644 index 0000000..870ccf9 --- /dev/null +++ b/gnuviechadmin/help/apps.py @@ -0,0 +1,8 @@ +from django.apps import AppConfig +from django.utils.translation import gettext_lazy as _ + + +class HelpConfig(AppConfig): + default_auto_field = "django.db.models.BigAutoField" + name = "help" + verbose_name = _("User self help") diff --git a/gnuviechadmin/help/management/__init__.py b/gnuviechadmin/help/management/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/gnuviechadmin/help/management/commands/__init__.py b/gnuviechadmin/help/management/commands/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/gnuviechadmin/help/management/commands/populate.py b/gnuviechadmin/help/management/commands/populate.py new file mode 100644 index 0000000..77ee7c3 --- /dev/null +++ b/gnuviechadmin/help/management/commands/populate.py @@ -0,0 +1,17 @@ +from django.contrib.auth import get_user_model +from django.core.management import BaseCommand + +from help.models import HelpUser + +User = get_user_model() + + +class Command(BaseCommand): + help = "Populate help user information for existing users" + + def handle(self, *args, **options): + for user in User.objects.filter(helpuser=None): + help_user = HelpUser.objects.create(user_id=user.id, email_address=user.email) + help_user.generate_offline_account_code() + help_user.save() + self.stdout.write(f"created offline account code {help_user.offline_account_code} for {user}.") diff --git a/gnuviechadmin/help/management/commands/reset_offline_code.py b/gnuviechadmin/help/management/commands/reset_offline_code.py new file mode 100644 index 0000000..a93579d --- /dev/null +++ b/gnuviechadmin/help/management/commands/reset_offline_code.py @@ -0,0 +1,29 @@ +from django.contrib.auth import get_user_model +from django.core.management import BaseCommand, CommandError + +from help.models import HelpUser + +User = get_user_model() + + +class Command(BaseCommand): + help = "Reset offline account reset code for existing users" + + def add_arguments(self, parser): + parser.add_argument("users", nargs='+', type=str) + + def handle(self, *args, **options): + for name in options["users"]: + try: + user = User.objects.get(username=name) + except User.DoesNotExist: + raise CommandError(f'User {name} does not exist') + + help_user = user.helpuser + if help_user is None: + help_user = HelpUser.objects.create(email_address=user.email) + + help_user.generate_offline_account_code() + help_user.save() + + self.stdout.write(f"generated new offline account reset code {help_user.offline_account_code} for {name}") diff --git a/gnuviechadmin/help/migrations/0001_add_help_user_model_extension.py b/gnuviechadmin/help/migrations/0001_add_help_user_model_extension.py new file mode 100644 index 0000000..fb20210 --- /dev/null +++ b/gnuviechadmin/help/migrations/0001_add_help_user_model_extension.py @@ -0,0 +1,55 @@ +# Generated by Django 3.2.18 on 2023-04-16 09:32 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name="HelpUser", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "email_address", + models.EmailField( + help_text="Contact email address", max_length=254 + ), + ), + ( + "postal_address", + models.TextField(blank=True, help_text="Contact postal address"), + ), + ( + "offline_account_code", + models.CharField( + default="", + help_text="Offline account reset code", + max_length=36, + ), + ), + ( + "user", + models.OneToOneField( + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, + ), + ), + ], + ), + ] diff --git a/gnuviechadmin/help/migrations/__init__.py b/gnuviechadmin/help/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/gnuviechadmin/help/models.py b/gnuviechadmin/help/models.py new file mode 100644 index 0000000..5debb7e --- /dev/null +++ b/gnuviechadmin/help/models.py @@ -0,0 +1,17 @@ +import uuid + +from django.conf import settings +from django.db import models +from django.utils.translation import ugettext_lazy as _ + + +class HelpUser(models.Model): + user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) + email_address = models.EmailField(help_text=_("Contact email address")) + postal_address = models.TextField(help_text=_("Contact postal address"), blank=True) + offline_account_code = models.CharField( + help_text=_("Offline account reset code"), max_length=36, default="" + ) + + def generate_offline_account_code(self): + self.offline_account_code = str(uuid.uuid4()) diff --git a/gnuviechadmin/help/tests.py b/gnuviechadmin/help/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/gnuviechadmin/help/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/gnuviechadmin/help/views.py b/gnuviechadmin/help/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/gnuviechadmin/help/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here.