Adds permissions checking for admin models

This commit is contained in:
Mouse Reeve 2022-09-19 09:51:41 -07:00
parent e51980bc12
commit 330be16516
5 changed files with 35 additions and 8 deletions

View file

@ -2,13 +2,14 @@
import datetime
from django import forms
from django.core.exceptions import PermissionDenied
from django.forms import widgets
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from django_celery_beat.models import IntervalSchedule
from bookwyrm import models
from .custom_form import CustomForm
from .custom_form import CustomForm, StyledForm
# pylint: disable=missing-class-docstring
@ -130,7 +131,7 @@ class AutoModRuleForm(CustomForm):
fields = ["string_match", "flag_users", "flag_statuses", "created_by"]
class IntervalScheduleForm(CustomForm):
class IntervalScheduleForm(StyledForm):
class Meta:
model = IntervalSchedule
fields = ["every", "period"]
@ -139,3 +140,9 @@ class IntervalScheduleForm(CustomForm):
"every": forms.NumberInput(attrs={"aria-describedby": "desc_every"}),
"period": forms.Select(attrs={"aria-describedby": "desc_period"}),
}
def save(self, request, *args, **kwargs):
"""This is an outside model so the perms check works differently"""
if not request.user.has_perm("bookwyrm.moderate_user"):
raise PermissionDenied()
return super().save(*args, **kwargs)

View file

@ -4,7 +4,7 @@ from django.forms import ModelForm
from django.forms.widgets import Textarea
class CustomForm(ModelForm):
class StyledForm(ModelForm):
"""add css classes to the forms"""
def __init__(self, *args, **kwargs):
@ -16,7 +16,7 @@ class CustomForm(ModelForm):
css_classes["checkbox"] = "checkbox"
css_classes["textarea"] = "textarea"
# pylint: disable=super-with-arguments
super(CustomForm, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
for visible in self.visible_fields():
if hasattr(visible.field.widget, "input_type"):
input_type = visible.field.widget.input_type
@ -25,6 +25,10 @@ class CustomForm(ModelForm):
visible.field.widget.attrs["rows"] = 5
visible.field.widget.attrs["class"] = css_classes[input_type]
class CustomForm(StyledForm):
"""Check permissions on save"""
def save(self, request, *args, **kwargs):
"""Save and check perms"""
self.instance.raise_not_editable(request.user)

View file

@ -3,6 +3,7 @@ from functools import reduce
import operator
from django.apps import apps
from django.core.exceptions import PermissionDenied
from django.db import models, transaction
from django.db.models import Q
from django.utils.translation import gettext_lazy as _
@ -12,7 +13,21 @@ from .base_model import BookWyrmModel
from .user import User
class EmailBlocklist(BookWyrmModel):
class AdminModel(BookWyrmModel):
"""Overrides the permissions methods"""
class Meta:
"""this is just here to provide default fields for other models"""
abstract = True
def raise_not_editable(self, viewer):
if viewer.has_perm("bookwyrm.moderate_user"):
return
raise PermissionDenied()
class EmailBlocklist(AdminModel):
"""blocked email addresses"""
domain = models.CharField(max_length=255, unique=True)
@ -29,7 +44,7 @@ class EmailBlocklist(BookWyrmModel):
return User.objects.filter(email__endswith=f"@{self.domain}")
class IPBlocklist(BookWyrmModel):
class IPBlocklist(AdminModel):
"""blocked ip addresses"""
address = models.CharField(max_length=255, unique=True)
@ -41,7 +56,7 @@ class IPBlocklist(BookWyrmModel):
ordering = ("-created_date",)
class AutoMod(BookWyrmModel):
class AutoMod(AdminModel):
"""rules to automatically flag suspicious activity"""
string_match = models.CharField(max_length=200, unique=True)

View file

@ -25,7 +25,7 @@ class Report(BookWyrmModel):
def raise_not_editable(self, viewer):
"""instead of user being the owner field, it's reporter"""
if self.reporter == viewer:
if self.reporter == viewer or viewer.has_perm("bookwyrm.moderate_user"):
return
raise PermissionDenied()

View file

@ -15,6 +15,7 @@ from bookwyrm.tests.validate_html import validate_html
class AutomodViews(TestCase):
"""every response to a get request, html or json"""
# pylint: disable=invalid-name
def setUp(self):
"""we need basic test data and mocks"""
self.factory = RequestFactory()