0003-auth_saml-genericize-related-object-code-53442.patch
src/authentic2/apps/authenticators/models.py | ||
---|---|---|
74 | 74 |
authenticators = AuthenticatorManager() |
75 | 75 | |
76 | 76 |
type = '' |
77 |
related_models = [] |
|
78 |
related_object_form_class = None |
|
77 | 79 |
manager_view_template_name = 'authentic2/authenticators/authenticator_detail.html' |
78 | 80 |
unique = False |
79 | 81 |
protected = False |
src/authentic2_auth_saml/journal_event_types.py | ||
---|---|---|
16 | 16 | |
17 | 17 |
from django.utils.translation import gettext_lazy as _ |
18 | 18 | |
19 |
from authentic2.apps.journal.models import EventTypeDefinition |
|
19 |
from authentic2.apps.authenticators.journal_event_types import AuthenticatorEvents |
|
20 |
from authentic2.apps.authenticators.models import BaseAuthenticator |
|
20 | 21 |
from authentic2.apps.journal.utils import form_to_old_new |
21 | 22 | |
22 |
from .models import SAMLAuthenticator |
|
23 | 23 | |
24 | ||
25 |
class SAMLAuthenticatorEvents(EventTypeDefinition): |
|
24 |
class AuthenticatorRelatedObjectEvents(AuthenticatorEvents): |
|
26 | 25 |
@classmethod |
27 | 26 |
def record(cls, *, user, session, related_object, data=None): |
28 | 27 |
data = data or {} |
29 | 28 |
data.update({'related_object': related_object.get_journal_text()}) |
30 |
super().record(user=user, session=session, references=[related_object.authenticator], data=data)
|
|
29 |
super().record(user=user, session=session, authenticator=related_object.authenticator, data=data)
|
|
31 | 30 | |
32 | 31 | |
33 |
class SAMLAuthenticatorRelatedObjectCreation(SAMLAuthenticatorEvents):
|
|
34 |
name = 'authenticator.saml.related_object.creation'
|
|
35 |
label = _('SAML authenticator related object creation')
|
|
32 |
class AuthenticatorRelatedObjectCreation(AuthenticatorRelatedObjectEvents):
|
|
33 |
name = 'authenticator.related_object.creation' |
|
34 |
label = _('Authenticator related object creation')
|
|
36 | 35 | |
37 | 36 |
@classmethod |
38 | 37 |
def get_message(cls, event, context): |
39 |
(authenticator,) = event.get_typed_references(SAMLAuthenticator) |
|
38 |
(authenticator,) = event.get_typed_references(BaseAuthenticator) |
|
39 |
authenticator = authenticator or event.get_data('authenticator_name') |
|
40 | 40 |
related_object = event.get_data('related_object') |
41 | 41 |
if context != authenticator: |
42 | 42 |
return _('creation of object "{related_object}" in authenticator "{authenticator}"').format( |
... | ... | |
46 | 46 |
return _('creation of object "%s"') % related_object |
47 | 47 | |
48 | 48 | |
49 |
class SAMLAuthenticatorRelatedObjectEdit(SAMLAuthenticatorEvents):
|
|
50 |
name = 'authenticator.saml.related_object.edit'
|
|
51 |
label = _('SAML authenticator related object edit')
|
|
49 |
class AuthenticatorRelatedObjectEdit(AuthenticatorRelatedObjectEvents):
|
|
50 |
name = 'authenticator.related_object.edit' |
|
51 |
label = _('Authenticator related object edit')
|
|
52 | 52 | |
53 | 53 |
@classmethod |
54 | 54 |
def record(cls, *, user, session, form): |
... | ... | |
61 | 61 | |
62 | 62 |
@classmethod |
63 | 63 |
def get_message(cls, event, context): |
64 |
(authenticator,) = event.get_typed_references(SAMLAuthenticator) |
|
64 |
(authenticator,) = event.get_typed_references(BaseAuthenticator) |
|
65 |
authenticator = authenticator or event.get_data('authenticator_name') |
|
65 | 66 |
related_object = event.get_data('related_object') |
66 | 67 |
new = event.get_data('new') or {} |
67 | 68 |
edited_attributes = ', '.join(new) or '' |
... | ... | |
79 | 80 |
) |
80 | 81 | |
81 | 82 | |
82 |
class SAMLAuthenticatorRelatedObjectDeletion(SAMLAuthenticatorEvents):
|
|
83 |
name = 'authenticator.saml.related_object.deletion'
|
|
84 |
label = _('SAML authenticator related object deletion')
|
|
83 |
class AuthenticatorRelatedObjectDeletion(AuthenticatorRelatedObjectEvents):
|
|
84 |
name = 'authenticator.related_object.deletion' |
|
85 |
label = _('Authenticator related object deletion')
|
|
85 | 86 | |
86 | 87 |
@classmethod |
87 | 88 |
def get_message(cls, event, context): |
88 |
(authenticator,) = event.get_typed_references(SAMLAuthenticator) |
|
89 |
(authenticator,) = event.get_typed_references(BaseAuthenticator) |
|
90 |
authenticator = authenticator or event.get_data('authenticator_name') |
|
89 | 91 |
related_object = event.get_data('related_object') |
90 | 92 |
if context != authenticator: |
91 | 93 |
return _('deletion of object "{related_object}" in authenticator "{authenticator}"').format( |
src/authentic2_auth_saml/migrations/0005_addroleaction_renameattributeaction_samlattributelookup_setattributeaction.py | ||
---|---|---|
39 | 39 |
], |
40 | 40 |
options={ |
41 | 41 |
'verbose_name': 'Set an attribute', |
42 |
'verbose_name_plural': 'Set attributes', |
|
42 | 43 |
'default_related_name': 'set_attribute_actions', |
43 | 44 |
}, |
44 | 45 |
), |
... | ... | |
63 | 64 |
], |
64 | 65 |
options={ |
65 | 66 |
'verbose_name': 'Attribute lookup', |
67 |
'verbose_name_plural': 'Lookup by attributes', |
|
66 | 68 |
'default_related_name': 'attribute_lookups', |
67 | 69 |
}, |
68 | 70 |
), |
... | ... | |
86 | 88 |
], |
87 | 89 |
options={ |
88 | 90 |
'verbose_name': 'Rename an attribute', |
91 |
'verbose_name_plural': 'Rename attributes', |
|
89 | 92 |
'default_related_name': 'rename_attribute_actions', |
90 | 93 |
}, |
91 | 94 |
), |
... | ... | |
126 | 129 |
], |
127 | 130 |
options={ |
128 | 131 |
'verbose_name': 'Add a role', |
132 |
'verbose_name_plural': 'Add roles', |
|
129 | 133 |
'default_related_name': 'add_role_actions', |
130 | 134 |
}, |
131 | 135 |
), |
src/authentic2_auth_saml/models.py | ||
---|---|---|
170 | 170 |
(_('Advanced'), SAMLAuthenticatorAdvancedForm), |
171 | 171 |
] |
172 | 172 | |
173 |
@property |
|
174 |
def related_object_form_class(self): |
|
175 |
from .forms import SAMLRelatedObjectForm |
|
176 | ||
177 |
return SAMLRelatedObjectForm |
|
178 | ||
179 |
@property |
|
180 |
def related_models(self): |
|
181 |
return { |
|
182 |
SAMLAttributeLookup: self.attribute_lookups.all(), |
|
183 |
SetAttributeAction: self.set_attribute_actions.all(), |
|
184 |
AddRoleAction: self.add_role_actions.all(), |
|
185 |
} |
|
186 | ||
173 | 187 |
def clean(self): |
174 | 188 |
if not (self.metadata or self.metadata_path or self.metadata_url): |
175 | 189 |
raise ValidationError(_('One of the metadata fields must be filled.')) |
... | ... | |
199 | 213 |
return views.profile(request, *args, **kwargs) |
200 | 214 | |
201 | 215 | |
202 |
class SAMLRelatedObjectBase(models.Model):
|
|
216 |
class AuthenticatorRelatedObjectBase(models.Model):
|
|
203 | 217 |
authenticator = models.ForeignKey(SAMLAuthenticator, on_delete=models.CASCADE) |
204 | 218 | |
205 | 219 |
class Meta: |
... | ... | |
208 | 222 |
def get_journal_text(self): |
209 | 223 |
return '%s (%s)' % (self._meta.verbose_name, self.pk) |
210 | 224 | |
211 |
def get_user_field_display(self): |
|
212 |
from authentic2.forms.widgets import SelectAttributeWidget |
|
225 |
@property |
|
226 |
def model_name(self): |
|
227 |
return self._meta.model_name |
|
213 | 228 | |
214 |
return SelectAttributeWidget.get_options().get(self.user_field, self.user_field) |
|
229 |
@property |
|
230 |
def verbose_name_plural(self): |
|
231 |
return self._meta.verbose_name_plural |
|
215 | 232 | |
216 | 233 | |
217 |
class SAMLAttributeLookup(SAMLRelatedObjectBase):
|
|
234 |
class SAMLAttributeLookup(AuthenticatorRelatedObjectBase):
|
|
218 | 235 |
user_field = models.CharField(_('User field'), max_length=256) |
219 | 236 |
saml_attribute = models.CharField(_('SAML attribute'), max_length=1024) |
220 | 237 |
ignore_case = models.BooleanField(_('Ignore case'), default=False) |
... | ... | |
222 | 239 |
class Meta: |
223 | 240 |
default_related_name = 'attribute_lookups' |
224 | 241 |
verbose_name = _('Attribute lookup') |
242 |
verbose_name_plural = _('Lookup by attributes') |
|
225 | 243 | |
226 | 244 |
def __str__(self): |
227 | 245 |
label = _('"%(saml_attribute)s" (from "%(user_field)s")') % { |
... | ... | |
239 | 257 |
'ignore-case': self.ignore_case, |
240 | 258 |
} |
241 | 259 | |
260 |
def get_user_field_display(self): |
|
261 |
from authentic2.forms.widgets import SelectAttributeWidget |
|
262 | ||
263 |
return SelectAttributeWidget.get_options().get(self.user_field, self.user_field) |
|
264 | ||
242 | 265 | |
243 |
class SetAttributeAction(SAMLRelatedObjectBase):
|
|
266 |
class SetAttributeAction(AuthenticatorRelatedObjectBase):
|
|
244 | 267 |
user_field = models.CharField(_('User field'), max_length=256) |
245 | 268 |
saml_attribute = models.CharField(_('SAML attribute name'), max_length=1024) |
246 | 269 |
mandatory = models.BooleanField(_('Mandatory'), default=False, help_text=_('Deny login if action fails.')) |
... | ... | |
248 | 271 |
class Meta: |
249 | 272 |
default_related_name = 'set_attribute_actions' |
250 | 273 |
verbose_name = _('Set an attribute') |
274 |
verbose_name_plural = _('Set attributes') |
|
251 | 275 | |
252 | 276 |
def __str__(self): |
253 | 277 |
label = _('"%(attribute)s" from "%(saml_attribute)s"') % { |
... | ... | |
258 | 282 |
label = '%s (%s)' % (label, _('mandatory')) |
259 | 283 |
return label |
260 | 284 | |
285 |
def get_user_field_display(self): |
|
286 |
from authentic2.forms.widgets import SelectAttributeWidget |
|
287 | ||
288 |
return SelectAttributeWidget.get_options().get(self.user_field, self.user_field) |
|
289 | ||
261 | 290 | |
262 |
class AddRoleAction(SAMLRelatedObjectBase):
|
|
291 |
class AddRoleAction(AuthenticatorRelatedObjectBase):
|
|
263 | 292 |
role = models.ForeignKey(Role, verbose_name=_('Role'), on_delete=models.CASCADE) |
264 | 293 |
condition = models.CharField(_('Condition (unused)'), editable=False, max_length=256, blank=True) |
265 | 294 |
mandatory = models.BooleanField(_('Mandatory (unused)'), editable=False, default=False) |
... | ... | |
267 | 296 |
class Meta: |
268 | 297 |
default_related_name = 'add_role_actions' |
269 | 298 |
verbose_name = _('Add a role') |
299 |
verbose_name_plural = _('Add roles') |
|
270 | 300 | |
271 | 301 |
def __str__(self): |
272 | 302 |
return label_from_role(self.role) |
src/authentic2_auth_saml/templates/authentic2_auth_saml/authenticator_detail.html | ||
---|---|---|
12 | 12 |
{% endblock %} |
13 | 13 | |
14 | 14 |
{% block extra-tab-buttons %} |
15 |
<button aria-controls="panel-samlattributelookup" aria-selected="false" id="tab-samlattributelookup" role="tab" tabindex="-1">{% trans "Lookup by attributes" %}</button>
|
|
16 |
<button aria-controls="panel-setattributeaction" aria-selected="false" id="tab-setattributeaction" role="tab" tabindex="-1">{% trans "Set attributes" %}</button>
|
|
17 |
<button aria-controls="panel-addroleaction" aria-selected="false" id="tab-addroleaction" role="tab" tabindex="-1">{% trans "Add roles" %}</button>
|
|
15 |
{% for model in object.related_models %}
|
|
16 |
<button aria-controls="panel-{{ model.model_name }}" aria-selected="false" id="tab-{{ model.model_name }}" role="tab" tabindex="-1">{{ model.verbose_name_plural }}</button>
|
|
17 |
{% endfor %}
|
|
18 | 18 |
{% endblock %} |
19 | 19 | |
20 | 20 |
{% block extra-tab-list %} |
21 |
<div aria-labelledby="tab-samlattributelookup" hidden="" id="panel-samlattributelookup" role="tabpanel" tabindex="0"> |
|
22 |
{% include 'authentic2_auth_saml/related_object_list.html' with object_list=object.attribute_lookups.all model_name='samlattributelookup' %} |
|
23 |
</div> |
|
24 | ||
25 |
<div aria-labelledby="tab-setattributeaction" hidden="" id="panel-setattributeaction" role="tabpanel" tabindex="0"> |
|
26 |
{% include 'authentic2_auth_saml/related_object_list.html' with object_list=object.set_attribute_actions.all model_name='setattributeaction' %} |
|
27 |
</div> |
|
28 | ||
29 |
<div aria-labelledby="tab-addroleaction" hidden="" id="panel-addroleaction" role="tabpanel" tabindex="0"> |
|
30 |
{% include 'authentic2_auth_saml/related_object_list.html' with object_list=object.add_role_actions.all model_name='addroleaction' %} |
|
31 |
</div> |
|
21 |
{% for model, objects in object.related_models.items %} |
|
22 |
<div aria-labelledby="tab-{{ model.model_name }}" hidden="" id="panel-{{ model.model_name }}" role="tabpanel" tabindex="0"> |
|
23 |
{% include 'authentic2_auth_saml/related_object_list.html' with object_list=objects model_name=model.model_name %} |
|
24 |
</div> |
|
25 |
{% endfor %} |
|
32 | 26 |
{% endblock %} |
src/authentic2_auth_saml/templates/authentic2_auth_saml/related_object_list.html | ||
---|---|---|
3 | 3 |
<ul class="objects-list single-links"> |
4 | 4 |
{% for related_object in object_list %} |
5 | 5 |
<li> |
6 |
<a rel="popup" href="{% url 'a2-manager-saml-edit-related-object' authenticator_pk=object.pk model_name=model_name pk=related_object.pk %}">{{ related_object }}</a>
|
|
7 |
<a rel="popup" class="delete" href="{% url 'a2-manager-saml-delete-related-object' authenticator_pk=object.pk model_name=model_name pk=related_object.pk %}">{% trans "Remove" %}</a>
|
|
6 |
<a rel="popup" href="{% url 'a2-manager-authenticators-edit-related-object' authenticator_pk=object.pk model_name=model_name pk=related_object.pk %}">{{ related_object }}</a>
|
|
7 |
<a rel="popup" class="delete" href="{% url 'a2-manager-authenticators-delete-related-object' authenticator_pk=object.pk model_name=model_name pk=related_object.pk %}">{% trans "Remove" %}</a>
|
|
8 | 8 |
</li> |
9 | 9 |
{% endfor %} |
10 |
<li><a class="add" rel="popup" href="{% url 'a2-manager-saml-add-related-object' authenticator_pk=object.pk model_name=model_name %}">{% trans 'Add' %}</a></li>
|
|
10 |
<li><a class="add" rel="popup" href="{% url 'a2-manager-authenticators-add-related-object' authenticator_pk=object.pk model_name=model_name %}">{% trans 'Add' %}</a></li>
|
|
11 | 11 |
</ul> |
src/authentic2_auth_saml/urls.py | ||
---|---|---|
32 | 32 |
path( |
33 | 33 |
'authenticators/<int:authenticator_pk>/<slug:model_name>/add/', |
34 | 34 |
views.add_related_object, |
35 |
name='a2-manager-saml-add-related-object',
|
|
35 |
name='a2-manager-authenticators-add-related-object',
|
|
36 | 36 |
), |
37 | 37 |
path( |
38 | 38 |
'authenticators/<int:authenticator_pk>/<slug:model_name>/<int:pk>/edit/', |
39 | 39 |
views.edit_related_object, |
40 |
name='a2-manager-saml-edit-related-object',
|
|
40 |
name='a2-manager-authenticators-edit-related-object',
|
|
41 | 41 |
), |
42 | 42 |
path( |
43 | 43 |
'authenticators/<int:authenticator_pk>/<slug:model_name>/<int:pk>/delete/', |
44 | 44 |
views.delete_related_object, |
45 |
name='a2-manager-saml-delete-related-object',
|
|
45 |
name='a2-manager-authenticators-delete-related-object',
|
|
46 | 46 |
), |
47 | 47 |
], |
48 | 48 |
) |
src/authentic2_auth_saml/views.py | ||
---|---|---|
7 | 7 |
from django.views.generic import CreateView, DeleteView, UpdateView |
8 | 8 |
from mellon.utils import get_idp |
9 | 9 | |
10 |
from authentic2.apps.authenticators.models import BaseAuthenticator |
|
10 | 11 |
from authentic2.manager.views import MediaMixin, TitleMixin |
11 | 12 |
from authentic2.utils.misc import redirect_to_login |
12 | 13 | |
13 |
from .forms import SAMLRelatedObjectForm |
|
14 |
from .models import AddRoleAction, SAMLAttributeLookup, SAMLAuthenticator, SetAttributeAction |
|
15 | ||
16 | 14 | |
17 | 15 |
def login(request, authenticator, *args, **kwargs): |
18 | 16 |
context = kwargs.pop('context', {}).copy() |
... | ... | |
45 | 43 |
return render_to_string('authentic2_auth_saml/profile.html', context, request=request) |
46 | 44 | |
47 | 45 | |
48 |
class SAMLAuthenticatorMixin(MediaMixin, TitleMixin): |
|
49 |
allowed_models = (SAMLAttributeLookup, SetAttributeAction, AddRoleAction) |
|
50 | ||
46 |
class AuthenticatorRelatedObjectMixin(MediaMixin, TitleMixin): |
|
51 | 47 |
def dispatch(self, request, *args, **kwargs): |
52 |
self.authenticator = get_object_or_404(SAMLAuthenticator, pk=kwargs.get('authenticator_pk')) |
|
48 |
self.authenticator = get_object_or_404( |
|
49 |
BaseAuthenticator.authenticators.all(), pk=kwargs.get('authenticator_pk') |
|
50 |
) |
|
53 | 51 | |
54 | 52 |
model_name = kwargs.get('model_name') |
55 |
if model_name not in (x._meta.model_name for x in self.allowed_models):
|
|
53 |
if model_name not in (x._meta.model_name for x in self.authenticator.related_models):
|
|
56 | 54 |
raise Http404() |
57 |
self.model = apps.get_model('authentic2_auth_saml', model_name)
|
|
55 |
self.model = apps.get_model(self.authenticator._meta.app_label, model_name)
|
|
58 | 56 | |
59 | 57 |
return super().dispatch(request, *args, **kwargs) |
60 | 58 | |
61 | 59 |
def get_form_class(self): |
62 |
return modelform_factory(self.model, SAMLRelatedObjectForm)
|
|
60 |
return modelform_factory(self.model, self.authenticator.related_object_form_class)
|
|
63 | 61 | |
64 | 62 |
def get_form_kwargs(self): |
65 | 63 |
kwargs = super().get_form_kwargs() |
... | ... | |
79 | 77 |
return self.model._meta.verbose_name |
80 | 78 | |
81 | 79 | |
82 |
class RelatedObjectAddView(SAMLAuthenticatorMixin, CreateView):
|
|
80 |
class RelatedObjectAddView(AuthenticatorRelatedObjectMixin, CreateView):
|
|
83 | 81 |
template_name = 'authentic2/manager/form.html' |
84 | 82 | |
85 | 83 |
def form_valid(self, form): |
86 | 84 |
resp = super().form_valid(form) |
87 |
self.request.journal.record( |
|
88 |
'authenticator.saml.related_object.creation', related_object=form.instance |
|
89 |
) |
|
85 |
self.request.journal.record('authenticator.related_object.creation', related_object=form.instance) |
|
90 | 86 |
return resp |
91 | 87 | |
92 | 88 | |
93 | 89 |
add_related_object = RelatedObjectAddView.as_view() |
94 | 90 | |
95 | 91 | |
96 |
class RelatedObjectEditView(SAMLAuthenticatorMixin, UpdateView):
|
|
92 |
class RelatedObjectEditView(AuthenticatorRelatedObjectMixin, UpdateView):
|
|
97 | 93 |
template_name = 'authentic2/manager/form.html' |
98 | 94 | |
99 | 95 |
def form_valid(self, form): |
100 | 96 |
resp = super().form_valid(form) |
101 |
self.request.journal.record('authenticator.saml.related_object.edit', form=form)
|
|
97 |
self.request.journal.record('authenticator.related_object.edit', form=form) |
|
102 | 98 |
return resp |
103 | 99 | |
104 | 100 | |
105 | 101 |
edit_related_object = RelatedObjectEditView.as_view() |
106 | 102 | |
107 | 103 | |
108 |
class RelatedObjectDeleteView(SAMLAuthenticatorMixin, DeleteView):
|
|
104 |
class RelatedObjectDeleteView(AuthenticatorRelatedObjectMixin, DeleteView):
|
|
109 | 105 |
template_name = 'authentic2/authenticators/authenticator_delete_form.html' |
110 | 106 |
title = '' |
111 | 107 | |
112 | 108 |
def delete(self, *args, **kwargs): |
113 |
self.request.journal.record( |
|
114 |
'authenticator.saml.related_object.deletion', related_object=self.get_object() |
|
115 |
) |
|
109 |
self.request.journal.record('authenticator.related_object.deletion', related_object=self.get_object()) |
|
116 | 110 |
return super().delete(*args, **kwargs) |
117 | 111 | |
118 | 112 |
tests/test_manager_authenticators.py | ||
---|---|---|
355 | 355 |
resp.form['user_field'].select(text='Email address (email)') |
356 | 356 |
resp.form['saml_attribute'] = 'mail' |
357 | 357 |
resp = resp.form.submit() |
358 |
assert_event('authenticator.saml.related_object.creation', user=superuser, session=app.session)
|
|
358 |
assert_event('authenticator.related_object.creation', user=superuser, session=app.session) |
|
359 | 359 |
assert '#open:samlattributelookup' in resp.location |
360 | 360 | |
361 | 361 |
resp = resp.follow() |
... | ... | |
365 | 365 |
resp.form['ignore_case'] = True |
366 | 366 |
resp = resp.form.submit().follow() |
367 | 367 |
assert escape('"mail" (from "Email address (email)"), case insensitive') in resp.text |
368 |
assert_event('authenticator.saml.related_object.edit', user=superuser, session=app.session)
|
|
368 |
assert_event('authenticator.related_object.edit', user=superuser, session=app.session) |
|
369 | 369 | |
370 | 370 |
Attribute.objects.create(kind='string', name='test', label='Test') |
371 | 371 |
resp = resp.click('mail') |
... | ... | |
376 | 376 |
resp = resp.click('Remove', href='samlattributelookup') |
377 | 377 |
resp = resp.form.submit().follow() |
378 | 378 |
assert 'mail' not in resp.text |
379 |
assert_event('authenticator.saml.related_object.deletion', user=superuser, session=app.session)
|
|
379 |
assert_event('authenticator.related_object.deletion', user=superuser, session=app.session) |
|
380 | 380 | |
381 | 381 | |
382 | 382 |
def test_authenticators_saml_set_attribute(app, superuser): |
tests/test_manager_journal.py | ||
---|---|---|
308 | 308 |
make('authenticator.disable', user=agent, session=session2, authenticator=authenticator) |
309 | 309 |
make('authenticator.deletion', user=agent, session=session2, authenticator=authenticator) |
310 | 310 |
make( |
311 |
'authenticator.saml.related_object.creation',
|
|
311 |
'authenticator.related_object.creation', |
|
312 | 312 |
user=agent, |
313 | 313 |
session=session2, |
314 | 314 |
related_object=set_attribute_action, |
... | ... | |
318 | 318 |
action_edit_form.initial = {'from_name': 'old'} |
319 | 319 |
action_edit_form.changed_data = ['from_name'] |
320 | 320 |
action_edit_form.cleaned_data = {'from_name': 'new'} |
321 |
make('authenticator.saml.related_object.edit', user=agent, session=session2, form=action_edit_form)
|
|
321 |
make('authenticator.related_object.edit', user=agent, session=session2, form=action_edit_form) |
|
322 | 322 |
make( |
323 |
'authenticator.saml.related_object.deletion',
|
|
323 |
'authenticator.related_object.deletion', |
|
324 | 324 |
user=agent, |
325 | 325 |
session=session2, |
326 | 326 |
related_object=set_attribute_action, |
... | ... | |
730 | 730 |
'message': 'creation of object "Set an attribute (%s)" in authenticator "SAML"' |
731 | 731 |
% set_attribute_action.pk, |
732 | 732 |
'timestamp': 'Jan. 3, 2020, 8 a.m.', |
733 |
'type': 'authenticator.saml.related_object.creation',
|
|
733 |
'type': 'authenticator.related_object.creation', |
|
734 | 734 |
'user': 'agent', |
735 | 735 |
}, |
736 | 736 |
{ |
737 | 737 |
'message': 'edit of object "Set an attribute (%s)" in authenticator "SAML" (from_name)' |
738 | 738 |
% set_attribute_action.pk, |
739 | 739 |
'timestamp': 'Jan. 3, 2020, 9 a.m.', |
740 |
'type': 'authenticator.saml.related_object.edit',
|
|
740 |
'type': 'authenticator.related_object.edit', |
|
741 | 741 |
'user': 'agent', |
742 | 742 |
}, |
743 | 743 |
{ |
744 | 744 |
'message': 'deletion of object "Set an attribute (%s)" in authenticator "SAML"' |
745 | 745 |
% set_attribute_action.pk, |
746 | 746 |
'timestamp': 'Jan. 3, 2020, 10 a.m.', |
747 |
'type': 'authenticator.saml.related_object.deletion',
|
|
747 |
'type': 'authenticator.related_object.deletion', |
|
748 | 748 |
'user': 'agent', |
749 | 749 |
}, |
750 | 750 |
{ |
751 |
- |