OpenSlides/openslides/participant/forms.py
Norman Jäckel aa0728ff60 User lockout protection, fixed #666
Protection of updating and deleting users and groups if this caused a lockout of the requesting user.
2013-06-11 11:02:40 +02:00

157 lines
6.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
openslides.participant.forms
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Forms for the participant app.
:copyright: 20112013 by OpenSlides team, see AUTHORS.
:license: GNU GPL, see LICENSE for more details.
"""
from django import forms
from django.contrib import messages
from django.contrib.auth.models import Permission
from django.utils.translation import ugettext as _, ugettext_lazy
from django.conf import settings
from openslides.utils.forms import CssClassMixin, LocalizedModelMultipleChoiceField
from openslides.participant.models import User, Group, get_protected_perm
from openslides.participant.api import get_registered_group
class UserCreateForm(CssClassMixin, forms.ModelForm):
groups = LocalizedModelMultipleChoiceField(
# Hide the built-in groups 'Anonymous' (pk=1) and 'Registered' (pk=2)
queryset=Group.objects.exclude(pk=1).exclude(pk=2),
label=ugettext_lazy('Groups'), required=False,
help_text=ugettext_lazy('Hold down "Control", or "Command" on a Mac, to select more than one.'))
class Meta:
model = User
fields = ('title', 'first_name', 'last_name', 'gender', 'email',
'groups', 'structure_level', 'committee', 'about_me', 'comment',
'is_active', 'default_password')
def clean(self, *args, **kwargs):
"""
Ensures that a user has either a first name or a last name.
"""
cleaned_data = super(UserCreateForm, self).clean(*args, **kwargs)
if not cleaned_data['first_name'] and not cleaned_data['last_name']:
error_msg = _('First name and last name can not both be empty.')
raise forms.ValidationError(error_msg)
return cleaned_data
class UserUpdateForm(UserCreateForm):
"""
Form to update an user. It raises a validation error, if a non-superuser
user edits himself and removes the last group containing the permission
to manage participants.
"""
class Meta:
model = User
fields = ('username', 'title', 'first_name', 'last_name', 'gender', 'email',
'groups', 'structure_level', 'committee', 'about_me', 'comment',
'is_active', 'default_password')
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request')
return super(UserUpdateForm, self).__init__(*args, **kwargs)
def clean(self, *args, **kwargs):
"""
Raises a validation error if a non-superuser user edits himself
and removes the last group containing the permission to manage participants.
"""
# TODO: Check this in clean_groups
if (self.request.user == self.instance and
not self.instance.is_superuser and
not self.cleaned_data['groups'].filter(permissions__in=[get_protected_perm()]).exists()):
error_msg = _('You can not remove the last group containing the permission to manage participants.')
raise forms.ValidationError(error_msg)
return super(UserUpdateForm, self).clean(*args, **kwargs)
class GroupForm(forms.ModelForm, CssClassMixin):
permissions = LocalizedModelMultipleChoiceField(
queryset=Permission.objects.all(), label=ugettext_lazy('Permissions'),
required=False)
users = forms.ModelMultipleChoiceField(
queryset=User.objects.all(), label=ugettext_lazy('Participants'), required=False)
class Meta:
model = Group
def __init__(self, *args, **kwargs):
# Take request argument
self.request = kwargs.pop('request', None)
# Initial users
if kwargs.get('instance', None) is not None:
initial = kwargs.setdefault('initial', {})
initial['users'] = [django_user.user.pk for django_user in kwargs['instance'].user_set.all()]
super(GroupForm, self).__init__(*args, **kwargs)
def save(self, commit=True):
instance = forms.ModelForm.save(self, False)
old_save_m2m = self.save_m2m
def save_m2m():
old_save_m2m()
instance.user_set.clear()
for user in self.cleaned_data['users']:
instance.user_set.add(user)
self.save_m2m = save_m2m
if commit:
instance.save()
self.save_m2m()
return instance
def clean(self, *args, **kwargs):
"""
Raises a validation error if a non-superuser user removes himself
from the last group containing the permission to manage participants.
Raises also a validation error if a non-superuser removes his last
permission to manage participants from the (last) group.
"""
# TODO: Check this in clean_users or clean_permissions
if (self.request and
not self.request.user.is_superuser and
not self.request.user in self.cleaned_data['users'] and
not Group.objects.exclude(pk=self.instance.pk).filter(
permissions__in=[get_protected_perm()],
user__pk=self.request.user.pk).exists()):
error_msg = _('You can not remove yourself from the last group containing the permission to manage participants.')
raise forms.ValidationError(error_msg)
if (self.request and
not self.request.user.is_superuser and
not get_protected_perm() in self.cleaned_data['permissions'] and
not Group.objects.exclude(pk=self.instance.pk).filter(
permissions__in=[get_protected_perm()],
user__pk=self.request.user.pk).exists()):
error_msg = _('You can not remove the permission to manage participants from the last group your are in.')
raise forms.ValidationError(error_msg)
return super(GroupForm, self).clean(*args, **kwargs)
class UsersettingsForm(forms.ModelForm, CssClassMixin):
language = forms.ChoiceField(choices=settings.LANGUAGES)
class Meta:
model = User
fields = ('username', 'title', 'first_name', 'last_name', 'gender', 'email',
'committee', 'about_me')
class UserImportForm(forms.Form, CssClassMixin):
csvfile = forms.FileField(widget=forms.FileInput(attrs={'size': '50'}),
label=ugettext_lazy('CSV File'))