0003-auth_oidc-improve-claims-string-representation-66419.patch
src/authentic2_auth_oidc/forms.py | ||
---|---|---|
14 | 14 |
# You should have received a copy of the GNU Affero General Public License |
15 | 15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | 16 | |
17 |
from collections import OrderedDict |
|
18 | ||
19 | 17 |
from django import forms |
18 |
from django.utils.text import capfirst |
|
20 | 19 |
from django.utils.translation import ugettext as _ |
21 | 20 | |
22 | 21 |
from authentic2.custom_user.models import User |
... | ... | |
37 | 36 |
self.fields['ou'].empty_label = None |
38 | 37 | |
39 | 38 | |
39 |
class SelectAttributeWidget(forms.Select): |
|
40 |
def __init__(self, *args, **kwargs): |
|
41 |
super().__init__(*args, **kwargs) |
|
42 |
self.choices = [('', '---------')] + list(self.get_options().items()) |
|
43 | ||
44 |
@staticmethod |
|
45 |
def get_options(): |
|
46 |
choices = {} |
|
47 |
for name in ('email', 'username', 'first_name', 'last_name'): |
|
48 |
field = User._meta.get_field(name) |
|
49 |
choices[name] = '%s (%s)' % (capfirst(field.verbose_name), name) |
|
50 |
for attribute in Attribute.objects.exclude(name__in=choices): |
|
51 |
choices[attribute.name] = '%s (%s)' % (attribute.label, attribute.name) |
|
52 |
choices['ou__slug'] = _('Organizational unit slug (ou__slug)') |
|
53 |
return choices |
|
54 | ||
55 | ||
40 | 56 |
class OIDCClaimMappingForm(forms.ModelForm): |
41 | 57 |
def __init__(self, *args, **kwargs): |
42 | 58 |
super().__init__(*args, **kwargs) |
... | ... | |
67 | 83 |
claim_widget.name = 'list__oidcclaim-mapping-inline' |
68 | 84 |
claim_widget.attrs.update({'list': 'list__oidcclaim-mapping-inline'}) |
69 | 85 | |
70 |
# Setup the attribute field |
|
71 |
choices = OrderedDict([('', '---------')]) |
|
72 |
for name in ('email', 'username', 'first_name', 'last_name'): |
|
73 |
field = User._meta.get_field(name) |
|
74 |
choices[name] = '%s (%s)' % (field.verbose_name.title(), name) |
|
75 |
for attribute in Attribute.objects.all(): |
|
76 |
if attribute.name in choices: |
|
77 |
continue |
|
78 |
choices[attribute.name] = '%s (%s)' % (attribute.label, attribute.name) |
|
79 |
choices['ou__slug'] = _('Organizational unit slug (ou__slug)') |
|
80 |
self.fields['attribute'] = forms.ChoiceField(choices=choices.items()) |
|
86 |
self.fields['attribute'].widget = SelectAttributeWidget() |
|
81 | 87 | |
82 | 88 |
class Meta: |
83 | 89 |
model = OIDCClaimMapping |
src/authentic2_auth_oidc/models.py | ||
---|---|---|
243 | 243 |
def natural_key(self): |
244 | 244 |
return (self.claim, self.attribute, self.verified, self.required) |
245 | 245 | |
246 |
def get_attribute_display(self): |
|
247 |
from .forms import SelectAttributeWidget |
|
248 | ||
249 |
return SelectAttributeWidget.get_options().get(self.attribute, self.attribute) |
|
250 | ||
246 | 251 |
def __str__(self): |
247 |
s = f'{self.claim} -> {self.attribute}'
|
|
252 |
s = '%s → %s' % (self.claim, self.get_attribute_display())
|
|
248 | 253 |
if self.verified: |
249 | 254 |
s += ', verified' |
250 | 255 |
if self.required: |
tests/test_manager_authenticators.py | ||
---|---|---|
199 | 199 | |
200 | 200 |
resp = resp.click('Add') |
201 | 201 |
resp.form['claim'] = 'email' |
202 |
resp.form['attribute'].select(text='Email Address (email)')
|
|
202 |
resp.form['attribute'].select(text='Email address (email)')
|
|
203 | 203 |
resp.form['verified'].select(text='verified claim') |
204 | 204 |
resp.form['required'] = True |
205 | 205 |
resp.form['idtoken_claim'] = True |
... | ... | |
208 | 208 |
assert '#open:claims' in resp.location |
209 | 209 | |
210 | 210 |
resp = resp.follow() |
211 |
assert escape('email -> email, verified, required, idtoken') in resp.text
|
|
211 |
assert 'email → Email address (email), verified, required, idtoken' in resp.text
|
|
212 | 212 | |
213 | 213 |
resp = resp.click('email') |
214 |
resp.form['attribute'].select(text='First Name (first_name)')
|
|
214 |
resp.form['attribute'].select(text='First name (first_name)')
|
|
215 | 215 |
resp = resp.form.submit().follow() |
216 |
assert escape('email -> first_name, verified, required, idtoken') in resp.text
|
|
216 |
assert 'email → First name (first_name), verified, required, idtoken' in resp.text
|
|
217 | 217 |
assert_event('authenticator.oidc.claim.edit', user=superuser, session=app.session) |
218 | 218 | |
219 | 219 |
resp = resp.click('Remove') |
220 |
- |