Tweak how managers work

Anyone can add to any group, and can edit their own items. Managers of a group can edit any items in that group.
This commit is contained in:
Yingtong Li 2019-01-25 10:30:55 +11:00
parent 0941726c05
commit 4638a71cfb
Signed by: RunasSudo
GPG Key ID: 7234E476BF21C61A
4 changed files with 25 additions and 17 deletions

View File

@ -28,8 +28,6 @@ ALLOWED_HOSTS = []
PROMO_LOGO_URL = 'https://placehold.it/2000x500' PROMO_LOGO_URL = 'https://placehold.it/2000x500'
PROMO_LOGO_LINK = 'https://example.com' PROMO_LOGO_LINK = 'https://example.com'
ENFORCE_GROUP_MANAGERS = True
# Application definition # Application definition

View File

@ -2,7 +2,7 @@
{# {#
Society Self-Service Society Self-Service
Copyright © 2018 Yingtong Li (RunasSudo) Copyright © 2018-2019 Yingtong Li (RunasSudo)
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by it under the terms of the GNU Affero General Public License as published by
@ -28,6 +28,10 @@
<label class="three wide column">ID</label> <label class="three wide column">ID</label>
<input class="eleven wide column" type="text" name="id" value="{{ item.id if item.id != None else '' }}"> <input class="eleven wide column" type="text" name="id" value="{{ item.id if item.id != None else '' }}">
</div> </div>
<div class="ui disabled inline grid field">
<label class="three wide column">Author</label>
<input class="eleven wide column" type="text" name="author" value="{{ item.author.email }}">
</div>
<div class="ui required inline grid field"> <div class="ui required inline grid field">
<label class="three wide column">Title</label> <label class="three wide column">Title</label>
<input class="eleven wide column" type="text" name="title" value="{{ item.title }}"> <input class="eleven wide column" type="text" name="title" value="{{ item.title }}">
@ -70,7 +74,7 @@
<div class="ui inline grid field"> <div class="ui inline grid field">
<label class="three wide column">Also limit to</label> <label class="three wide column">Also limit to</label>
<div class="eleven wide column"> <div class="eleven wide column">
{% for group in all_groups %} {% for group in groups %}
<div class="field" style="display: inline; margin-right: 1em;"> <div class="field" style="display: inline; margin-right: 1em;">
<div class="ui checkbox"> <div class="ui checkbox">
<input type="checkbox" name="also_limit_{{ group.id }}"{% if group.id in item.also_limit %} checked{% endif %}> <input type="checkbox" name="also_limit_{{ group.id }}"{% if group.id in item.also_limit %} checked{% endif %}>

View File

@ -25,14 +25,12 @@ class Group(models.Model):
subscribable = models.BooleanField() subscribable = models.BooleanField()
order = models.IntegerField(null=True, blank=True) order = models.IntegerField(null=True, blank=True)
managers = JSONField(default=[]) managers = JSONField(default=[], blank=True)
def __str__(self): def __str__(self):
return self.name return self.name
def can_user_access(self, user): def can_user_access(self, user):
if not settings.ENFORCE_GROUP_MANAGERS:
return True
if user.is_superuser: if user.is_superuser:
return True return True
if user.email in self.managers: if user.email in self.managers:
@ -47,6 +45,7 @@ class Group(models.Model):
ordering = ['order', 'id'] ordering = ['order', 'id']
class BulletinItem(models.Model): class BulletinItem(models.Model):
author = models.ForeignKey(User, on_delete=models.CASCADE)
group = models.ForeignKey(Group, on_delete=models.CASCADE) group = models.ForeignKey(Group, on_delete=models.CASCADE)
also_limit = JSONField(default=[]) also_limit = JSONField(default=[])
title = models.CharField(max_length=100) title = models.CharField(max_length=100)
@ -54,6 +53,15 @@ class BulletinItem(models.Model):
image = models.ImageField(upload_to='promo_uploads/%Y/%m/%d/', null=True) image = models.ImageField(upload_to='promo_uploads/%Y/%m/%d/', null=True)
content = models.TextField() content = models.TextField()
date = models.DateField() date = models.DateField()
def can_user_access(self, user):
if self.group.can_user_access(user):
return True
if user == self.author:
return True
if user.email in self.author.delegates:
return True
return False
class CalendarItem(models.Model): class CalendarItem(models.Model):
group = models.ForeignKey(Group, on_delete=models.CASCADE) group = models.ForeignKey(Group, on_delete=models.CASCADE)

View File

@ -39,7 +39,7 @@ def bulletin_list(request):
dtend = dtbegin + datetime.timedelta(days=7) dtend = dtbegin + datetime.timedelta(days=7)
for item in models.BulletinItem.objects.all(): for item in models.BulletinItem.objects.all():
if not item.group.can_user_access(request.user): if not item.can_user_access(request.user):
continue continue
if item.date >= dtbegin and item.date < dtend: if item.date >= dtbegin and item.date < dtend:
@ -75,9 +75,8 @@ def bulletin_preview(request):
def bulletin_new(request): def bulletin_new(request):
if request.method == 'POST': if request.method == 'POST':
item = models.BulletinItem() item = models.BulletinItem()
item.author = request.user
item.group = models.Group.objects.get(id=int(request.POST['group'])) item.group = models.Group.objects.get(id=int(request.POST['group']))
if not item.group.can_user_access(request.user):
return HttpResponse('Unauthorized', status=401)
item.title = request.POST['title'] item.title = request.POST['title']
item.date = request.POST['date'] item.date = request.POST['date']
item.content = request.POST['content'] item.content = request.POST['content']
@ -93,12 +92,12 @@ def bulletin_new(request):
return redirect(reverse('bulletin_edit', kwargs={'id': item.id})) return redirect(reverse('bulletin_edit', kwargs={'id': item.id}))
else: else:
item = models.BulletinItem() item = models.BulletinItem()
item.author = request.user
item.date = timezone.now().date() item.date = timezone.now().date()
item.date += datetime.timedelta(days=(6 - item.date.weekday() + 7) % 7) # Next Sunday (6 = Sunday) item.date += datetime.timedelta(days=(6 - item.date.weekday() + 7) % 7) # Next Sunday (6 = Sunday)
return render(request, 'sspromotions/bulletin_edit.html', { return render(request, 'sspromotions/bulletin_edit.html', {
'item': item, 'item': item,
'groups': [group for group in models.Group.objects.all() if group.can_user_access(request.user)], 'groups': models.Group.objects.all()
'all_groups': models.Group.objects.all()
}) })
@login_required @login_required
@ -106,7 +105,7 @@ def bulletin_edit(request, id):
if request.method == 'POST': if request.method == 'POST':
item = models.BulletinItem.objects.get(id=id) item = models.BulletinItem.objects.get(id=id)
item.group = models.Group.objects.get(id=int(request.POST['group'])) item.group = models.Group.objects.get(id=int(request.POST['group']))
if not item.group.can_user_access(request.user): if not item.can_user_access(request.user):
return HttpResponse('Unauthorized', status=401) return HttpResponse('Unauthorized', status=401)
item.title = request.POST['title'] item.title = request.POST['title']
item.date = request.POST['date'] item.date = request.POST['date']
@ -123,18 +122,17 @@ def bulletin_edit(request, id):
return redirect(reverse('bulletin_edit', kwargs={'id': item.id})) return redirect(reverse('bulletin_edit', kwargs={'id': item.id}))
else: else:
item = models.BulletinItem.objects.get(id=id) item = models.BulletinItem.objects.get(id=id)
if not item.group.can_user_access(request.user): if not item.can_user_access(request.user):
return HttpResponse('Unauthorized', status=401) return HttpResponse('Unauthorized', status=401)
return render(request, 'sspromotions/bulletin_edit.html', { return render(request, 'sspromotions/bulletin_edit.html', {
'item': item, 'item': item,
'groups': [group for group in models.Group.objects.all() if group.can_user_access(request.user)], 'groups': models.Group.objects.all()
'all_groups': models.Group.objects.all()
}) })
@login_required @login_required
def bulletin_delete(request, id): def bulletin_delete(request, id):
item = models.BulletinItem.objects.get(id=id) item = models.BulletinItem.objects.get(id=id)
if not item.group.can_user_access(request.user): if not item.can_user_access(request.user):
return HttpResponse('Unauthorized', status=401) return HttpResponse('Unauthorized', status=401)
item.delete() item.delete()