diff --git a/README.md b/README.md index a30699a..07e1764 100644 --- a/README.md +++ b/README.md @@ -108,3 +108,6 @@ Useful commands: need to be frequent, but otherwise, the database is going to bloat eventually) - ``reencrypt_fields``: Run after you changed your ``SERVALA_SECRET_KEY`` or ``SERVALA_SALT_KEY`` in order to use the new keys, and be able to retire the previous ones. +- ``make_staff_user``: Mark one or multiple users as staff users. Use ``--substring`` flag to e.g. match + entire email domains. +- ``make_superuser``: Mark one given user (by email address) as superuser. diff --git a/src/servala/core/management/commands/make_staff_user.py b/src/servala/core/management/commands/make_staff_user.py new file mode 100644 index 0000000..a8b76a2 --- /dev/null +++ b/src/servala/core/management/commands/make_staff_user.py @@ -0,0 +1,58 @@ +from django.core.management.base import BaseCommand +from django.db.models import Q + +from servala.core.models import User + + +class Command(BaseCommand): + help = "Make user(s) into staff users" + + def add_arguments(self, parser): + parser.add_argument( + "emails", + nargs="*", + type=str, + help="Email addresses of users to make staff", + ) + parser.add_argument( + "--substring", + action="store_true", + help="Match emails by substring instead of exact match, allowing you to e.g. make all users on your home domain staff users.", + ) + + def handle(self, *args, **options): + emails = options["emails"] + substring_match = options["substring"] + + if not emails: + self.stdout.write(self.style.ERROR("No email addresses provided")) + return + + query = None + if substring_match: + for email in emails: + if query is None: + query = Q(email__icontains=email) + else: + query |= Q(email__icontains=email) + else: + query = Q(email__in=emails) + + users = User.objects.filter(query) + already_staff = users.filter(is_staff=True).count() + + if already_staff: + self.stdout.write( + self.style.WARNING( + f"{already_staff} matching users were already staff users." + ) + ) + + users = users.filter(is_staff=False) + if not users.exists(): + self.stdout.write(self.style.ERROR("No matching non-staff users found.")) + return + + count = users.count() + users.update(is_staff=True) + self.stdout.write(self.style.SUCCESS(f"Made {count} user(s) into staff users")) diff --git a/src/servala/core/management/commands/make_superuser.py b/src/servala/core/management/commands/make_superuser.py new file mode 100644 index 0000000..fe43ec8 --- /dev/null +++ b/src/servala/core/management/commands/make_superuser.py @@ -0,0 +1,26 @@ +from django.core.management.base import BaseCommand + +from servala.core.models import User + + +class Command(BaseCommand): + help = "Turn a user into a superuser. Use with caution." + + def add_arguments(self, parser): + parser.add_argument( + "email", + type=str, + help="Email address of user to grant superuser permissions", + ) + + def handle(self, *args, **options): + email = options["email"] + + user = User.objects.filter(email__iexact=email).first() + if not user: + self.stdout.write(self.style.ERROR("No matching user found.")) + return + + user.is_superuser = True + user.save() + self.stdout.write(self.style.SUCCESS(f"{user} is now a superuser."))