Refs #39 -- Add permission editor for organizers

This commit is contained in:
Raphael Michel
2017-01-07 14:10:31 +01:00
parent e53562dda2
commit c7676cd17a
11 changed files with 407 additions and 29 deletions

View File

@@ -1,12 +1,20 @@
from django import forms
from django.contrib import messages
from django.core.exceptions import PermissionDenied
from django.core.urlresolvers import reverse
from django.db import transaction
from django.forms import modelformset_factory
from django.shortcuts import redirect
from django.utils.functional import cached_property
from django.utils.translation import ugettext_lazy as _
from django.views.generic import CreateView, ListView, UpdateView
from django.views.generic import CreateView, DetailView, ListView, UpdateView
from pretix.base.models import Organizer, OrganizerPermission
from pretix.base.forms import I18nModelForm
from pretix.base.models import Organizer, OrganizerPermission, User
from pretix.base.services.mail import SendMailException, mail
from pretix.control.forms.organizer import OrganizerForm, OrganizerUpdateForm
from pretix.control.permissions import OrganizerPermissionRequiredMixin
from pretix.helpers.urls import build_absolute_uri
class OrganizerList(ListView):
@@ -24,10 +32,147 @@ class OrganizerList(ListView):
)
class OrganizerPermissionForm(I18nModelForm):
class Meta:
model = OrganizerPermission
fields = (
'can_create_events', 'can_change_permissions'
)
class OrganizerPermissionCreateForm(OrganizerPermissionForm):
user = forms.EmailField(required=False, label=_('User'))
class OrganizerDetail(OrganizerPermissionRequiredMixin, DetailView):
model = Organizer
template_name = 'pretixcontrol/organizers/detail.html'
permission = None
context_object_name = 'organizer'
def get_object(self, queryset=None) -> Organizer:
return self.request.organizer
@cached_property
def formset(self):
fs = modelformset_factory(
OrganizerPermission,
form=OrganizerPermissionForm,
can_delete=True, can_order=False, extra=0
)
return fs(data=self.request.POST if self.request.method == "POST" else None,
prefix="formset",
queryset=OrganizerPermission.objects.filter(organizer=self.request.organizer))
@cached_property
def add_form(self):
return OrganizerPermissionCreateForm(data=self.request.POST if self.request.method == "POST" else None,
prefix="add")
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)
ctx['formset'] = self.formset
ctx['add_form'] = self.add_form
ctx['events'] = self.request.organizer.events.all()
return ctx
def _send_invite(self, instance):
try:
mail(
instance.invite_email,
_('Account information changed'),
'pretixcontrol/email/invitation_organizer.txt',
{
'user': self,
'organizer': self.request.organizer.name,
'url': build_absolute_uri('control:auth.invite', kwargs={
'token': instance.invite_token
})
},
event=None,
locale=self.request.LANGUAGE_CODE
)
except SendMailException:
pass # Already logged
@transaction.atomic
def post(self, *args, **kwargs):
if not self.request.orgaperm.can_change_permissions:
raise PermissionDenied(_("You have no permission to do this."))
if self.formset.is_valid() and self.add_form.is_valid():
if self.add_form.has_changed():
logdata = {
k: v for k, v in self.add_form.cleaned_data.items()
}
try:
self.add_form.instance.organizer = self.request.organizer
self.add_form.instance.organizer_id = self.request.organizer.id
self.add_form.instance.user = User.objects.get(email=self.add_form.cleaned_data['user'])
self.add_form.instance.user_id = self.add_form.instance.user.id
except User.DoesNotExist:
self.add_form.instance.invite_email = self.add_form.cleaned_data['user']
if OrganizerPermission.objects.filter(invite_email=self.add_form.instance.invite_email,
organizer=self.request.organizer).exists():
messages.error(self.request, _('This user already has been invited for this team.'))
return self.get(*args, **kwargs)
self.add_form.save()
self._send_invite(self.add_form.instance)
self.request.organizer.log_action(
'pretix.organizer.permissions.invited', user=self.request.user, data=logdata
)
else:
if OrganizerPermission.objects.filter(user=self.add_form.instance.user,
organizer=self.request.organizer).exists():
messages.error(self.request, _('This user already has permissions for this team.'))
return self.get(*args, **kwargs)
self.add_form.save()
logdata['user'] = self.add_form.instance.user_id
self.request.organizer.log_action(
'pretix.organizer.permissions.added', user=self.request.user, data=logdata
)
for form in self.formset.forms:
if form.has_changed():
changedata = {
k: form.cleaned_data.get(k) for k in form.changed_data
}
changedata['user'] = form.instance.user_id
self.request.organizer.log_action(
'pretix.organizer.permissions.changed', user=self.request.user, data=changedata
)
if form.instance.user_id == self.request.user.pk:
if not form.cleaned_data['can_change_permissions'] or form in self.formset.deleted_forms:
messages.error(self.request, _('You cannot remove your own permission to view this page.'))
return self.get(*args, **kwargs)
for form in self.formset.deleted_forms:
logdata = {
k: v for k, v in form.cleaned_data.items()
}
self.request.organizer.log_action(
'pretix.organizer.permissions.deleted', user=self.request.user, data=logdata
)
self.formset.save()
messages.success(self.request, _('Your changes have been saved.'))
return redirect(self.get_success_url())
else:
messages.error(self.request, _('Your changes could not be saved.'))
return self.get(*args, **kwargs)
def get_success_url(self) -> str:
return reverse('control:organizer', kwargs={
'organizer': self.request.organizer.slug,
})
class OrganizerUpdate(OrganizerPermissionRequiredMixin, UpdateView):
model = Organizer
form_class = OrganizerUpdateForm
template_name = 'pretixcontrol/organizers/detail.html'
template_name = 'pretixcontrol/organizers/edit.html'
permission = None
context_object_name = 'organizer'