import logging import os from django.contrib.auth import login, views as auth_views from django.contrib.auth.decorators import login_required from django.core.exceptions import PermissionDenied, SuspiciousOperation from django.db.models import Q from django.http import HttpResponseRedirect from django.urls import reverse, reverse_lazy from django.utils.decorators import method_decorator from django.views import generic from . import config from . import forms from . import models logger = logging.getLogger(__name__) class HomeView(generic.TemplateView): template_name = 'dav_events/home.html' class ImprintView(generic.TemplateView): template_name = 'dav_events/imprint.html' class LoginView(auth_views.LoginView): form_class = forms.auth.LoginForm next_page = reverse_lazy('dav_events:event_list') template_name = 'dav_events/auth/login_form.html' def get_success_url(self): url = self.get_redirect_url() return url or self.next_page class LogoutView(auth_views.LogoutView): next_page = reverse_lazy('dav_events:home') class SetPasswordView(auth_views.PasswordChangeView): form_class = forms.auth.SetPasswordForm template_name = 'dav_events/auth/set_password_form.html' success_url = reverse_lazy('dav_events:event_list') class EventListView(generic.ListView): model = models.Event def get_queryset(self): user = self.request.user if user.is_superuser: qs = self.model.objects.all() elif user.groups.filter(name=config.MANAGE_ALL_GROUP).count(): qs = self.model.objects.all() else: user_sports_list = list() for k in ['W', 'S', 'M', 'K', 'B']: group_name_var = 'MANAGE_{}_GROUP'.format(k) group_name = getattr(config, group_name_var, None) if group_name and user.groups.filter(name=group_name).count(): user_sports_list.append(k) qs = self.model.objects.filter(Q(owner=user) | Q(sport__in=user_sports_list)) return qs @method_decorator(login_required) def dispatch(self, request, *args, **kwargs): return super(EventListView, self).dispatch(request, *args, **kwargs) class EventPermissionMixin(object): permission = 'view' def has_permission(self, permission, obj): user = self.request.user if user.is_superuser: return True if permission == 'view': if obj.owner == user: return True if user.groups.filter(name=config.MANAGE_ALL_GROUP).count(): return True group_name_var = 'MANAGE_{}_GROUP'.format(obj.sport) group_name = getattr(config, group_name_var, None) if group_name and user.groups.filter(name=group_name).count(): return True elif permission in ('edit', 'accept'): if user.groups.filter(name=config.MANAGE_ALL_GROUP).count(): return True group_name_var = 'MANAGE_{}_GROUP'.format(obj.sport) group_name = getattr(config, group_name_var, None) if group_name and user.groups.filter(name=group_name).count(): return True return False def enforce_permission(self, obj): permission = self.permission if not self.has_permission(permission, obj): raise PermissionDenied() class EventDetailView(EventPermissionMixin, generic.DetailView): model = models.Event def get_object(self, queryset=None): obj = super(EventDetailView, self).get_object(queryset=queryset) self.enforce_permission(obj) return obj def get_context_data(self, **kwargs): context = super(EventDetailView, self).get_context_data(**kwargs) obj = context.get('event') context['has_permission_accept'] = self.has_permission('accept', obj) context['has_permission_edit'] = self.has_permission('edit', obj) return context @method_decorator(login_required) def dispatch(self, request, *args, **kwargs): return super(EventDetailView, self).dispatch(request, *args, **kwargs) class EventAcceptView(EventDetailView): permission = 'accept' def accept(self): event = self.get_object() event.accept() def get(self, request, *args, **kwargs): self.accept() return super(EventAcceptView, self).get(request, *args, **kwargs) class EventCreateView(generic.FormView): form_class = forms.events.EventCreateForm template_dir = os.path.join('dav_events', 'event_create') default_template_name = 'default.html' abort_url = reverse_lazy('dav_events:home') def get_template_names(self): form = self.get_form() form_name = form.form_name template = os.path.join(self.template_dir, '{}.html'.format(form_name)) default_template = os.path.join(self.template_dir, self.default_template_name) return [ template, default_template ] def get_form_class(self, form_name=None): if form_name is not None: form_class = getattr(forms.events, form_name) elif 'dav_events_event_create_next_form_name' in self.request.session: form_name = self.request.session['dav_events_event_create_next_form_name'] form_class = getattr(forms.events, form_name) if not issubclass(form_class, self.form_class): raise SuspiciousOperation('Invalid next form: {}'.format(form_name)) else: base_form_class = self.form_class initial_form_name = base_form_class.get_initial_form_name() form_class = getattr(forms.events, initial_form_name) return form_class def get_form_kwargs(self): kwargs = super(EventCreateView, self).get_form_kwargs() if 'request' not in kwargs: kwargs['request'] = self.request return kwargs def get_context_data(self, **kwargs): context = super(EventCreateView, self).get_context_data(**kwargs) context['abort_url'] = self.abort_url return context def form_valid(self, form): event = form.save() next_form_name = form.next_form_name if next_form_name: self.request.session['dav_events_event_create_next_form_name'] = next_form_name next_form_class = self.get_form_class(next_form_name) next_form = next_form_class(request=self.request) return self.render_to_response(self.get_context_data(form=next_form, event=event)) else: event.save() owner = event.owner self.clean_session_data() if self.request.user.is_authenticated: next_url = reverse('dav_events:event_list') elif owner.has_usable_password(): next_url = reverse('dav_events:event_list') else: login(self.request, owner) next_url = reverse('dav_events:set_password') return HttpResponseRedirect(next_url) def clean_session_data(self, session=None): if session is None: session = self.request.session if 'dav_events_event_create_next_form_name' in session: del session['dav_events_event_create_next_form_name'] def get(self, request, *args, **kwargs): self.clean_session_data(request.session) return super(EventCreateView, self).get(request, *args, **kwargs)