hobo/hobo/agent/authentic2/role_forms.py

119 lines
4.2 KiB
Python

# hobo - portal to configure and deploy applications
# Copyright (C) 2015 Entr'ouvert
#
# 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 the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import json
from authentic2.a2_rbac.models import Role, RoleAttribute
from authentic2.manager.forms import RoleEditForm
from authentic2.validators import EmailValidator
from django import forms
from django.core import validators
from django.core.exceptions import ValidationError
from django.utils import six
from django.utils.translation import ugettext_lazy as _
class ListValidator(object):
def __init__(self, item_validator):
self.item_validator = item_validator
def __call__(self, value):
for i, item in enumerate(value):
try:
self.item_validator(item)
except ValidationError as e:
raise ValidationError(_('Item {0} is invalid: {1}').format(i, e.args[0]))
class CommaSeparatedInput(forms.TextInput):
def format_value(self, value):
if not value:
return ''
if not isinstance(value, six.string_types):
return u', '.join(value)
return value
class CommaSeparatedCharField(forms.Field):
widget = CommaSeparatedInput
def __init__(self, dedup=True, max_length=None, min_length=None, *args, **kwargs):
self.dedup = dedup
self.max_length = max_length
self.min_length = min_length
item_validators = kwargs.pop('item_validators', [])
super(CommaSeparatedCharField, self).__init__(*args, **kwargs)
for item_validator in item_validators:
self.validators.append(ListValidator(item_validator))
def to_python(self, value):
if value in validators.EMPTY_VALUES:
return []
value = [item.strip() for item in value.split(',') if item.strip()]
if self.dedup:
value = list(set(value))
return value
def clean(self, value):
value = self.to_python(value)
self.validate(value)
self.run_validators(value)
return value
class RoleForm(RoleEditForm):
details = forms.CharField(
label=_('Role details (frontoffice)'), widget=forms.Textarea, initial='', required=False
)
emails = CommaSeparatedCharField(
label=_('Emails'),
item_validators=[EmailValidator()],
required=False,
help_text=_('Emails must be separated by commas.'),
)
emails_to_members = forms.BooleanField(required=False, initial=True, label=_('Emails to members'))
def __init__(self, *args, **kwargs):
instance = kwargs.get('instance')
if instance:
fields = [x.name for x in Role._meta.get_fields()]
initial = kwargs.setdefault('initial', {})
role_attributes = RoleAttribute.objects.filter(role=instance, kind='json')
for role_attribute in role_attributes:
if role_attribute.name in fields:
continue
initial[role_attribute.name] = json.loads(role_attribute.value)
super(RoleForm, self).__init__(*args, **kwargs)
def save(self, commit=True):
fields = [x.name for x in Role._meta.get_fields()]
assert commit
instance = super(RoleForm, self).save(commit=commit)
for field in self.cleaned_data:
if field in fields:
continue
value = json.dumps(self.cleaned_data[field])
ra, created = RoleAttribute.objects.get_or_create(
role=instance, name=field, kind='json', defaults={'value': value}
)
if not created and ra.value != value:
ra.value = value
ra.save()
instance.save()
return instance