0001-manager-always-check-role-s-name-uniqueness-33944.patch
src/authentic2/a2_rbac/models.py | ||
---|---|---|
27 | 27 |
CHANGE_OP, Operation) |
28 | 28 |
from django_rbac import utils as rbac_utils |
29 | 29 | |
30 |
from authentic2.decorators import errorcollector |
|
31 | ||
30 | 32 |
try: |
31 | 33 |
from django.contrib.contenttypes.fields import GenericForeignKey, \ |
32 | 34 |
GenericRelation |
... | ... | |
213 | 215 |
self_administered=True) |
214 | 216 |
return admin_role |
215 | 217 | |
216 |
def clean(self): |
|
217 |
super(Role, self).clean() |
|
218 |
if not self.service and not self.admin_scope_ct_id: |
|
219 |
if not self.id and self.__class__.objects.filter( |
|
220 |
name=self.name, ou=self.ou): |
|
221 |
raise ValidationError( |
|
222 |
{'name': _('This name is not unique over this ' |
|
223 |
'organizational unit.')}) |
|
218 |
def validate_unique(self, exclude=None): |
|
219 |
errors = {} |
|
220 | ||
221 |
with errorcollector(errors): |
|
222 |
super(Role, self).validate_unique(exclude=exclude) |
|
223 | ||
224 |
exclude = exclude or [] |
|
225 | ||
226 |
if 'name' not in exclude: |
|
227 |
qs = self.__class__.objects.filter(name=self.name, ou=self.ou) |
|
228 |
if self.pk: |
|
229 |
qs = qs.exclude(pk=self.pk) |
|
230 |
if qs.exists(): |
|
231 |
errors.setdefault('name', []).append(_('Name already used')) |
|
232 | ||
233 |
if errors: |
|
234 |
raise ValidationError(errors) |
|
224 | 235 | |
225 | 236 |
def save(self, *args, **kwargs): |
226 | 237 |
# Service roles can only be part of the same ou as the service |
src/authentic2/manager/forms.py | ||
---|---|---|
241 | 241 |
raise forms.ValidationError({ |
242 | 242 |
'email': _('Email already used.') |
243 | 243 |
}) |
244 |
return super(UserEditForm, self).clean() |
|
244 | 245 | |
245 | 246 |
class Meta: |
246 | 247 |
model = User |
... | ... | |
437 | 438 |
if utils.get_ou_count() < 2: |
438 | 439 |
del self.fields['ou'] |
439 | 440 | |
440 |
def save(self, *args, **kwargs):
|
|
441 |
def clean(self):
|
|
441 | 442 |
if 'ou' not in self.fields: |
442 | 443 |
self.instance.ou = get_default_ou() |
443 |
return super(HideOUFieldMixin, self).save(*args, **kwargs)
|
|
444 |
return super(HideOUFieldMixin, self).clean()
|
|
444 | 445 | |
445 | 446 | |
446 | 447 |
class OUSearchForm(FormWithRequest): |
... | ... | |
650 | 651 |
ou = forms.ModelChoiceField(queryset=get_ou_model().objects, |
651 | 652 |
required=True, label=_('Organizational unit')) |
652 | 653 | |
653 |
def clean_name(self): |
|
654 |
qs = get_role_model().objects.all() |
|
655 |
if self.instance and self.instance.pk: |
|
656 |
qs = qs.exclude(pk=self.instance.pk) |
|
657 |
ou = self.cleaned_data.get('ou') |
|
658 |
# Test unicity of name for an OU and globally if no OU is present |
|
659 |
name = self.cleaned_data.get('name') |
|
660 |
if name and ou: |
|
661 |
query = Q(name=name) & (Q(ou__isnull=True) | Q(ou=ou)) |
|
662 |
if qs.filter(query).exists(): |
|
663 |
raise ValidationError( |
|
664 |
{'name': _('This name is not unique over this organizational unit.')}) |
|
665 |
return name |
|
666 | ||
667 | 654 |
class Meta: |
668 | 655 |
model = get_role_model() |
669 | 656 |
fields = ('name', 'ou', 'description') |
tests/test_role_manager.py | ||
---|---|---|
35 | 35 |
assert export.keys() == ['roles'] |
36 | 36 |
assert len(export['roles']) == 1 |
37 | 37 |
assert export['roles'][0]['slug'] == 'role_ou1' |
38 | ||
39 | ||
40 |
def test_manager_role_name_uniqueness_single_ou(app, admin): |
|
41 |
response = login(app, admin, 'a2-manager-roles') |
|
42 | ||
43 |
response = response.click('Add') |
|
44 |
response.form.set('name', 'Role1') |
|
45 |
response = response.form.submit('Save').follow() |
|
46 |
response = response.click('Roles') |
|
47 |
assert response.pyquery('td.name').text() == 'Role1' |
|
48 | ||
49 |
response = response.click('Add') |
|
50 |
response.form.set('name', 'Role1') |
|
51 |
response = response.form.submit('Save') |
|
52 |
assert response.pyquery('.errorlist').eq(1).text() == 'Name already used' |
|
53 | ||
54 | ||
55 |
def test_manager_role_name_uniqueness_multiple_ou(app, admin, ou1): |
|
56 |
response = login(app, admin, 'a2-manager-roles') |
|
57 | ||
58 |
response = response.click('Add') |
|
59 |
response.form.set('ou', str(ou1.id)) |
|
60 |
response.form.set('name', 'Role1') |
|
61 |
response = response.form.submit('Save').follow() |
|
62 |
response = response.click('Roles') |
|
63 |
assert response.pyquery('td.name').text() == 'Role1' |
|
64 | ||
65 |
response = response.click('Add') |
|
66 |
response.form.set('ou', str(ou1.id)) |
|
67 |
response.form.set('name', 'Role1') |
|
68 |
response = response.form.submit('Save') |
|
69 |
assert response.pyquery('.errorlist').eq(1).text() == 'Name already used' |
|
38 |
- |