1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-11-09 19:56:48 +00:00

fix(admin): the Users pages keep an administrator in and say what their fields mean

- An administrator could block, delete or demote (unset Active or
  Superuser on) their own account, and with it the last one, leaving the
  panel without anyone to undo it. These are now refused.
- The user form showed "No password set." for users who have one: its
  password field never read the user's password. Its "Set password"
  link went to ../password/, a page this panel does not have. The form
  now says whether a password is set and links the page that sets it.
- "Staff status" said "can log into this admin site"; here it lets a
  user change and delete the template VMs given to them, and is now
  called Template editor.
- A quota of 0 counted as no limit, like -1, so a user's quota could not
  be taken away. Now -1 has no limit and 0 allows none; the help says
  so, and the labels give the units: memory in MiB, disk in GiB.
- A user's page for a user that does not exist answered with a server
  error instead of not found.
- The user list said "None" for a user who never logged in; it says
  "never", and dates fit their column.
- The password form's labels no longer break mid-word.
This commit is contained in:
catborise 2026-10-25 22:26:23 +03:00
parent 07a2e09c2f
commit 0e8130f1b0
11 changed files with 161 additions and 43 deletions

View file

@ -96,6 +96,11 @@ def group_delete(request, pk):
)
# an administrator who blocks, deletes or demotes their own account is out of
# these pages at once, and may have been the last one
OWN_ACCOUNT = _("You cannot block, delete or demote your own account")
@superuser_only
def user_list(request):
# API tokens that still work: an expired one is deleted only at the user's next create
@ -145,7 +150,11 @@ def user_update(request, pk):
attributes_form = forms.UserAttributesForm(
request.POST or None, instance=attributes
)
if user_form.is_valid() and attributes_form.is_valid():
valid = user_form.is_valid() and attributes_form.is_valid()
if valid and user == request.user and not (user_form.cleaned_data["is_active"] and user_form.cleaned_data["is_superuser"]):
user_form.add_error(None, OWN_ACCOUNT)
valid = False
if valid:
with audit(request, None, subject, "change") as entry:
user_form.save()
attributes_form.save()
@ -166,6 +175,7 @@ def user_update(request, pk):
{
"user_form": user_form,
"attributes_form": attributes_form,
"edited_user": user,
"title": _("Update User"),
},
)
@ -202,6 +212,9 @@ def user_update_password(request, pk):
@superuser_only
def user_delete(request, pk):
user = get_object_or_404(User, pk=pk)
if user == request.user:
messages.error(request, OWN_ACCOUNT)
return redirect("admin:user_list")
if request.method == "POST":
with audit(request, None, f"User {user.username}", "delete"):
user.delete()
@ -219,6 +232,9 @@ def user_delete(request, pk):
@superuser_only
def user_block(request, pk):
user: User = get_object_or_404(User, pk=pk)
if user == request.user:
messages.error(request, OWN_ACCOUNT)
return redirect("admin:user_list")
with audit(request, None, f"User {user.username}", "block") as entry:
entry.skip = not user.is_active # already blocked
user.is_active = False