Add permissions via plan.group

This commit is contained in:
Stefan Wehrmeyer 2022-02-16 14:30:47 +01:00
parent 19170142c3
commit df92fa5c27
2 changed files with 101 additions and 20 deletions

View file

@ -1,5 +1,5 @@
from django import forms from django import forms
from django.contrib import admin from django.contrib import admin, auth
from django.urls import reverse_lazy from django.urls import reverse_lazy
from tinymce.widgets import TinyMCE from tinymce.widgets import TinyMCE
@ -8,6 +8,8 @@ from froide.helper.widgets import TagAutocompleteWidget
from .models import Government, GovernmentPlan, GovernmentPlanUpdate from .models import Government, GovernmentPlan, GovernmentPlanUpdate
User = auth.get_user_model()
class GovernmentPlanAdminForm(forms.ModelForm): class GovernmentPlanAdminForm(forms.ModelForm):
class Meta: class Meta:
@ -24,9 +26,7 @@ class GovernmentPlanUpdateAdminForm(forms.ModelForm):
class Meta: class Meta:
model = GovernmentPlanUpdate model = GovernmentPlanUpdate
fields = "__all__" fields = "__all__"
widgets = { widgets = {"content": TinyMCE(attrs={"cols": 80, "rows": 30})}
"content": TinyMCE(attrs={'cols': 80, 'rows': 30})
}
class GovernmentAdmin(admin.ModelAdmin): class GovernmentAdmin(admin.ModelAdmin):
@ -54,9 +54,10 @@ class GovernmentPlanUpdateAdmin(admin.ModelAdmin):
form = GovernmentPlanUpdateAdminForm form = GovernmentPlanUpdateAdminForm
raw_id_fields = ("user", "foirequest") raw_id_fields = ("user", "foirequest")
list_display = ( list_display = (
"title",
"timestamp",
"plan", "plan",
"user", "user",
"timestamp",
"status", "status",
"rating", "rating",
"public", "public",
@ -65,7 +66,10 @@ class GovernmentPlanUpdateAdmin(admin.ModelAdmin):
"status", "status",
"public", "public",
) )
search_fields = ("title", "plan__title",) search_fields = (
"title",
"plan__title",
)
date_hierarchy = "timestamp" date_hierarchy = "timestamp"
def get_queryset(self, request): def get_queryset(self, request):
@ -74,8 +78,75 @@ class GovernmentPlanUpdateAdmin(admin.ModelAdmin):
"plan", "plan",
"user", "user",
) )
if self.has_limited_access(request.user):
qs = qs.filter(plan__in=self.get_allowed_plans(request))
return qs return qs
def save_model(self, request, obj, form, change):
limited = self.has_limited_access(request.user)
if not change and limited:
# When added by a limited user,
# autofill user and organization
obj.user = request.user
if obj.plan.organization:
user_has_org = request.user.organization_set.all().filter(pk=1).exists()
if user_has_org:
obj.organization = obj.plan.organization
res = super().save_model(request, obj, form, change)
obj.plan.update_from_updates()
return res
def has_limited_access(self, user):
return not user.has_perm("froide_gov.change_governmentplanupdate")
def get_allowed_plans(self, request):
if not self.has_limited_access(request.user):
return GovernmentPlan.objects.all()
groups = request.user.groups.all()
return GovernmentPlan.objects.filter(group__in=groups).distinct()
def get_fields(self, request, obj=None):
if self.has_limited_access(request.user):
return (
"plan",
"title",
"timestamp",
"content",
"url",
"status",
"rating",
"public",
)
return super().get_fields(request, obj=obj)
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == "plan":
if self.has_limited_access(request.user):
kwargs["queryset"] = self.get_allowed_plans(request)
return super().formfield_for_foreignkey(db_field, request, **kwargs)
def user_in_obj_group(self, request, obj):
if not obj.plan.group_id:
return False
user = request.user
return User.objects.filter(pk=user.pk, groups=obj.plan.group_id).exists()
def has_view_permission(self, request, obj=None):
if obj and self.user_in_obj_group(request, obj):
return True
return super().has_view_permission(request, obj=obj)
def has_add_permission(self, request):
return super().has_add_permission(request)
def has_change_permission(self, request, obj=None):
if obj and self.user_in_obj_group(request, obj):
return True
return super().has_change_permission(request, obj=obj)
admin.site.register(Government, GovernmentAdmin) admin.site.register(Government, GovernmentAdmin)
admin.site.register(GovernmentPlan, GovernmentPlanAdmin) admin.site.register(GovernmentPlan, GovernmentPlanAdmin)

View file

@ -109,13 +109,12 @@ class GovernmentPlan(models.Model):
verbose_name_plural = _("Government plans") verbose_name_plural = _("Government plans")
def __str__(self): def __str__(self):
return 'GovernmentPlan "%s" (#%s)' % (self.title, self.pk) return self.title
def get_absolute_url(self): def get_absolute_url(self):
return reverse("govplan:plan", kwargs={ return reverse(
"gov": self.government.slug, "govplan:plan", kwargs={"gov": self.government.slug, "plan": self.slug}
"plan": self.slug )
})
def get_absolute_domain_url(self): def get_absolute_domain_url(self):
return settings.SITE_URL + self.get_absolute_url() return settings.SITE_URL + self.get_absolute_url()
@ -123,10 +122,21 @@ class GovernmentPlan(models.Model):
def get_reference_link(self): def get_reference_link(self):
if self.reference.startswith("https://"): if self.reference.startswith("https://"):
return self.reference return self.reference
return "{}#{}".format( return "{}#{}".format(self.government.planning_document, self.reference)
self.government.planning_document,
self.reference def update_from_updates(self):
last_status_update = (
self.updates.all().filter(public=True).exclude(status="").first()
) )
if last_status_update:
self.status = last_status_update.status
last_rating_update = (
self.updates.all().filter(public=True).exclude(rating=None).first()
)
if last_rating_update:
self.rating = last_rating_update.rating
if last_status_update or last_rating_update:
self.save()
class GovernmentPlanUpdate(models.Model): class GovernmentPlanUpdate(models.Model):
@ -161,7 +171,7 @@ class GovernmentPlanUpdate(models.Model):
verbose_name_plural = _("Plan updates") verbose_name_plural = _("Plan updates")
def __str__(self): def __str__(self):
return "Plan Update (%s)" % (self.pk,) return "{} - {} ({})".format(self.title, self.timestamp, self.plan)
if CMSPlugin: if CMSPlugin:
@ -175,7 +185,9 @@ if CMSPlugin:
CMS Plugin for displaying latest articles CMS Plugin for displaying latest articles
""" """
government = models.ForeignKey(Government, null=True, blank=True, on_delete=models.SET_NULL) government = models.ForeignKey(
Government, null=True, blank=True, on_delete=models.SET_NULL
)
categories = models.ManyToManyField( categories = models.ManyToManyField(
Category, verbose_name=_("categories"), blank=True Category, verbose_name=_("categories"), blank=True
) )
@ -235,9 +247,7 @@ if CMSPlugin:
filters["categories__in"] = cat_list filters["categories__in"] = cat_list
plans = plans.filter(**filters).distinct() plans = plans.filter(**filters).distinct()
plans = plans.prefetch_related( plans = plans.prefetch_related("categories", "government", "organization")
"categories", "government", "organization"
)
if self.count == 0: if self.count == 0:
return plans[self.offset :] return plans[self.offset :]
return plans[self.offset : self.offset + self.count] return plans[self.offset : self.offset + self.count]