User admin and LD schema fixes

pull/184/head
Andrew Godwin 2022-12-16 16:38:52 -07:00
rodzic 1bcdff79e7
commit 45c6978bc3
13 zmienionych plików z 189 dodań i 23 usunięć

Wyświetl plik

@ -659,7 +659,7 @@ class Post(StatorModel):
if update or created:
post.content = data["content"]
post.summary = data.get("summary")
post.sensitive = data.get("as:sensitive", False)
post.sensitive = data.get("sensitive", False)
post.url = data.get("url")
post.published = parse_ld_date(data.get("published"))
post.edited = parse_ld_date(data.get("updated"))
@ -670,7 +670,7 @@ class Post(StatorModel):
if tag["type"].lower() == "mention":
mention_identity = Identity.by_actor_uri(tag["href"], create=True)
post.mentions.add(mention_identity)
elif tag["type"].lower() == "as:hashtag":
elif tag["type"].lower() == "hashtag":
post.hashtags.append(tag["name"].lower().lstrip("#"))
elif tag["type"].lower() == "http://joinmastodon.org/ns#emoji":
emoji = Emoji.by_ap_tag(post.author.domain, tag, create=True)

Wyświetl plik

@ -415,6 +415,7 @@ def canonicalise(json_data: dict, include_security: bool = False) -> dict:
"votersCount": "toot:votersCount",
"Hashtag": "as:Hashtag",
"Public": "as:Public",
"manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
},
]
if include_security:

Wyświetl plik

@ -96,9 +96,14 @@ urlpatterns = [
),
path(
"admin/users/",
admin.Users.as_view(),
admin.UsersRoot.as_view(),
name="admin_users",
),
path(
"admin/users/<id>/",
admin.UserEdit.as_view(),
name="admin_user_edit",
),
path(
"admin/identities/",
admin.Identities.as_view(),

Wyświetl plik

@ -0,0 +1,36 @@
{% extends "settings/base.html" %}
{% block subtitle %}{{ user.email }}{% endblock %}
{% block content %}
<h1>{{ editing_user.email }}</h1>
<form action="." method="POST">
{% csrf_token %}
<fieldset>
<legend>Permissions</legend>
{% include "forms/_field.html" with field=form.status %}
{% if same_user %}
<ul class="errorlist">
<li>You cannot edit your own permission status!</li>
</ul>
{% endif %}
</fieldset>
<fieldset>
<legend>Identities</legend>
{% for identity in editing_user.identities.all %}
{% include "activities/_identity.html" %}
{% empty %}
<p>This user has no identities yet.</p>
{% endfor %}
</fieldset>
<fieldset>
<legend>Dates</legend>
<p>Last seen: <time title="{{ editing_user.last_seen }} UTC">{{ editing_user.last_seen | timesince }} ago</time></p>
<p>Created: <time title="{{ editing_user.created }} UTC">{{ editing_user.created | timesince }} ago</time></p>
</fieldset>
<div class="buttons">
<a href="{{ editing_user.urls.admin }}" class="button secondary left">Back</a>
<button>Save</button>
</div>
</form>
{% endblock %}

Wyświetl plik

@ -3,7 +3,40 @@
{% block subtitle %}Users{% endblock %}
{% block content %}
<p>
Please use the <a href="/djadmin/users/user/">Django Admin</a> for now.
</p>
<form action="." class="search">
<input type="search" name="query" value="{{ query }}" placeholder="Search by email">
<button><i class="fa-solid fa-search"></i></button>
</form>
<section class="icon-menu">
{% for user in page_obj %}
<a class="option" href="{{ user.urls.admin_edit }}">
<i class="fa-solid fa-user"></i>
<span class="handle">
{{ user.email }}
<small>
{{ user.num_identities }} identit{{ user.num_identities|pluralize:"y,ies" }}
</small>
</span>
{% if user.banned %}
<span class="pill bad">Banned</span>
{% endif %}
</a>
{% empty %}
<p class="option empty">
{% if query %}
No users match your query.
{% else %}
There are no users yet.
{% endif %}
</p>
{% endfor %}
<div class="load-more">
{% if page_obj.has_previous %}
<a class="button" href=".?page={{ page_obj.previous_page_number }}">Previous Page</a>
{% endif %}
{% if page_obj.has_next %}
<a class="button" href=".?page={{ page_obj.next_page_number }}">Next Page</a>
{% endif %}
</div>
</section>
{% endblock %}

Wyświetl plik

@ -155,7 +155,7 @@ def test_fetch_actor(httpx_mock, config_system):
"mediaType": "image/jpeg",
"url": "https://example.com/image.jpg",
},
"as:manuallyApprovesFollowers": False,
"manuallyApprovesFollowers": False,
"name": "Test User",
"preferredUsername": "test",
"published": "2022-11-02T00:00:00Z",

Wyświetl plik

@ -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"]

Wyświetl plik

@ -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")

Wyświetl plik

@ -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")

Wyświetl plik

@ -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,

Wyświetl plik

@ -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)

Wyświetl plik

@ -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):

Wyświetl plik

@ -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