From 45c6978bc397691b22db0360b16b19979eac7dce Mon Sep 17 00:00:00 2001 From: Andrew Godwin Date: Fri, 16 Dec 2022 16:38:52 -0700 Subject: User admin and LD schema fixes --- users/admin.py | 8 ++++- users/models/identity.py | 2 +- users/models/inbox_message.py | 7 ++++ users/models/system_actor.py | 2 +- users/models/user.py | 5 +++ users/views/admin/__init__.py | 15 ++------ users/views/admin/users.py | 84 +++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 107 insertions(+), 16 deletions(-) create mode 100644 users/views/admin/users.py (limited to 'users') diff --git a/users/admin.py b/users/admin.py index 0b502d5..6c89881 100644 --- a/users/admin.py +++ b/users/admin.py @@ -89,7 +89,13 @@ class PasswordResetAdmin(admin.ModelAdmin): @admin.register(InboxMessage) class InboxMessageAdmin(admin.ModelAdmin): - list_display = ["id", "state", "state_changed", "message_type", "message_actor"] + list_display = [ + "id", + "state", + "state_changed", + "message_type_full", + "message_actor", + ] list_filter = ("state",) search_fields = ["message"] actions = ["reset_state"] diff --git a/users/models/identity.py b/users/models/identity.py index 2e13de1..574e54e 100644 --- a/users/models/identity.py +++ b/users/models/identity.py @@ -438,7 +438,7 @@ class Identity(StatorModel): self.username = self.username["@value"] if self.username: self.username = self.username.lower() - self.manually_approves_followers = document.get("as:manuallyApprovesFollowers") + self.manually_approves_followers = document.get("manuallyApprovesFollowers") self.public_key = document.get("publicKey", {}).get("publicKeyPem") self.public_key_id = document.get("publicKey", {}).get("id") self.icon_uri = document.get("icon", {}).get("url") diff --git a/users/models/inbox_message.py b/users/models/inbox_message.py index 0bf6851..526311d 100644 --- a/users/models/inbox_message.py +++ b/users/models/inbox_message.py @@ -115,6 +115,13 @@ class InboxMessage(StatorModel): def message_object_type(self): return self.message["object"]["type"].lower() + @property + def message_type_full(self): + if isinstance(self.message.get("object"), dict): + return f"{self.message_type}.{self.message_object_type}" + else: + return f"{self.message_type}" + @property def message_actor(self): return self.message.get("actor") diff --git a/users/models/system_actor.py b/users/models/system_actor.py index fb5a9e1..46a0007 100644 --- a/users/models/system_actor.py +++ b/users/models/system_actor.py @@ -48,7 +48,7 @@ class SystemActor: }, "preferredUsername": self.username, "url": self.profile_uri, - "as:manuallyApprovesFollowers": True, + "manuallyApprovesFollowers": True, "publicKey": { "id": self.public_key_id, "owner": self.actor_uri, diff --git a/users/models/user.py b/users/models/user.py index e0cac9d..8e3dc59 100644 --- a/users/models/user.py +++ b/users/models/user.py @@ -1,3 +1,4 @@ +import urlman from django.contrib.auth.models import AbstractBaseUser, BaseUserManager from django.db import models @@ -44,6 +45,10 @@ class User(AbstractBaseUser): objects = UserManager() + class urls(urlman.Urls): + admin = "/admin/users/" + admin_edit = "{admin}{self.pk}/" + @property def is_active(self): return not (self.deleted or self.banned) diff --git a/users/views/admin/__init__.py b/users/views/admin/__init__.py index bb70ff7..5ace04d 100644 --- a/users/views/admin/__init__.py +++ b/users/views/admin/__init__.py @@ -3,7 +3,7 @@ from django.utils.decorators import method_decorator from django.views.generic import FormView, RedirectView, TemplateView from users.decorators import admin_required -from users.models import Identity, User +from users.models import Identity from users.views.admin.domains import ( # noqa DomainCreate, DomainDelete, @@ -23,6 +23,7 @@ from users.views.admin.settings import ( # noqa TuningSettings, ) from users.views.admin.stator import Stator # noqa +from users.views.admin.users import UserEdit, UsersRoot # noqa @method_decorator(admin_required, name="dispatch") @@ -30,18 +31,6 @@ class AdminRoot(RedirectView): pattern_name = "admin_basic" -@method_decorator(admin_required, name="dispatch") -class Users(TemplateView): - - template_name = "admin/users.html" - - def get_context_data(self): - return { - "users": User.objects.order_by("email"), - "section": "users", - } - - @method_decorator(admin_required, name="dispatch") class Identities(TemplateView): diff --git a/users/views/admin/users.py b/users/views/admin/users.py new file mode 100644 index 0000000..fab4616 --- /dev/null +++ b/users/views/admin/users.py @@ -0,0 +1,84 @@ +from django import forms +from django.db import models +from django.shortcuts import get_object_or_404, redirect +from django.utils.decorators import method_decorator +from django.views.generic import FormView, ListView + +from users.decorators import admin_required +from users.models import User + + +@method_decorator(admin_required, name="dispatch") +class UsersRoot(ListView): + + template_name = "admin/users.html" + paginate_by = 50 + + def get(self, request, *args, **kwargs): + self.query = request.GET.get("query") + self.extra_context = { + "section": "users", + "query": self.query or "", + } + return super().get(request, *args, **kwargs) + + def get_queryset(self): + users = User.objects.annotate( + num_identities=models.Count("identities") + ).order_by("created") + if self.query: + users = users.filter(email__icontains=self.query) + return users + + +@method_decorator(admin_required, name="dispatch") +class UserEdit(FormView): + + template_name = "admin/user_edit.html" + extra_context = { + "section": "users", + } + + class form_class(forms.Form): + status = forms.ChoiceField( + choices=[ + ("normal", "Normal User"), + ("moderator", "Moderator"), + ("admin", "Admin"), + ("banned", "Banned"), + ] + ) + + def dispatch(self, request, id, *args, **kwargs): + self.user = get_object_or_404(User, id=id) + return super().dispatch(request, *args, **kwargs) + + def get_initial(self): + status = "normal" + if self.user.moderator: + status = "moderator" + if self.user.admin: + status = "admin" + if self.user.banned: + status = "banned" + return { + "email": self.user.email, + "status": status, + } + + def form_valid(self, form): + # Don't let them change themselves + if self.user == self.request.user: + return redirect(".") + status = form.cleaned_data["status"] + self.user.banned = status == "banned" + self.user.moderator = status == "moderator" + self.user.admin = status == "admin" + self.user.save() + return redirect(self.user.urls.admin) + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context["editing_user"] = self.user + context["same_user"] = self.user == self.request.user + return context -- cgit v1.2.3