idp_oidc: enforce name uniqueness on claims in UI (#74920)
gitea/authentic/pipeline/head This commit looks good
Details
gitea/authentic/pipeline/head This commit looks good
Details
This commit is contained in:
parent
e59226cb5b
commit
324c368a20
|
@ -16,11 +16,13 @@
|
|||
|
||||
from django import forms
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from authentic2.attributes_ng.engine import get_service_attributes
|
||||
from authentic2.forms.mixins import SlugMixin
|
||||
from authentic2.forms.widgets import DatalistTextInput
|
||||
from authentic2.middleware import StoreRequestMiddleware
|
||||
from authentic2_idp_oidc.models import OIDCClaim, OIDCClient
|
||||
|
||||
|
||||
|
@ -86,9 +88,27 @@ class OIDCClaimForm(forms.ModelForm):
|
|||
'value': DatalistTextInput,
|
||||
}
|
||||
|
||||
def clean_name(self):
|
||||
name = self.cleaned_data['name'] # name is now a mandatory field
|
||||
request = StoreRequestMiddleware.get_request()
|
||||
client = OIDCClient.objects.get(pk=request.resolver_match.kwargs['service_pk'])
|
||||
errmsg = _('This claim name is already defined for this client. Pick another claim name')
|
||||
try:
|
||||
claim = OIDCClaim.objects.get(client=client, name=name)
|
||||
except OIDCClaim.DoesNotExist:
|
||||
pass
|
||||
except OIDCClaim.MultipleObjectsReturned:
|
||||
raise ValidationError(errmsg)
|
||||
else:
|
||||
if self.instance != claim:
|
||||
raise ValidationError(errmsg)
|
||||
return name
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
data = dict(get_service_attributes(getattr(self.instance, 'client', None))).keys()
|
||||
for field in ('name', 'value', 'scopes'):
|
||||
self.fields[field].required = True
|
||||
widget = self.fields['value'].widget
|
||||
widget.data = data
|
||||
widget.name = 'list__oidcclaim-inline'
|
||||
|
|
|
@ -126,6 +126,60 @@ class TestEdit:
|
|||
client=oidc_client, name='claim', value='value', scopes='profile'
|
||||
).exists()
|
||||
|
||||
def test_add_claim_mandatory_field_name(self, app, oidc_client):
|
||||
resp = app.get(f'/manage/services/{oidc_client.pk}/settings/')
|
||||
resp = resp.click('Add claim')
|
||||
form = resp.form
|
||||
form['value'] = 'value'
|
||||
form['scopes'] = 'profile'
|
||||
resp = form.submit()
|
||||
assert len(resp.pyquery('.error')) == 1
|
||||
assert 'This field is required.' in resp.pyquery('.error')[0].text
|
||||
assert not OIDCClaim.objects.filter(client=oidc_client, name='claim', value='value', scopes='profile')
|
||||
|
||||
def test_add_claim_mandatory_field_value(self, app, oidc_client):
|
||||
resp = app.get(f'/manage/services/{oidc_client.pk}/settings/')
|
||||
resp = resp.click('Add claim')
|
||||
form = resp.form
|
||||
form['name'] = 'claim'
|
||||
form['scopes'] = 'profile'
|
||||
resp = form.submit()
|
||||
assert len(resp.pyquery('.error')) == 1
|
||||
assert 'This field is required.' in resp.pyquery('.error')[0].text
|
||||
assert not OIDCClaim.objects.filter(client=oidc_client, name='claim', value='value', scopes='profile')
|
||||
|
||||
def test_add_claim_mandatory_field_scope(self, app, oidc_client):
|
||||
resp = app.get(f'/manage/services/{oidc_client.pk}/settings/')
|
||||
resp = resp.click('Add claim')
|
||||
form = resp.form
|
||||
form['name'] = 'claim'
|
||||
form['value'] = 'value'
|
||||
resp = form.submit()
|
||||
assert len(resp.pyquery('.error')) == 1
|
||||
assert 'This field is required.' in resp.pyquery('.error')[0].text
|
||||
assert not OIDCClaim.objects.filter(client=oidc_client, name='claim', value='value', scopes='profile')
|
||||
|
||||
def test_add_claim_redundancy_error(self, app, oidc_client):
|
||||
resp = app.get(f'/manage/services/{oidc_client.pk}/settings/')
|
||||
OIDCClaim.objects.create(
|
||||
client=oidc_client, name='yet_another_claim', value='value', scopes='profile'
|
||||
)
|
||||
|
||||
resp = resp.click('Add claim')
|
||||
form = resp.form
|
||||
form['name'] = 'yet_another_claim'
|
||||
form['value'] = 'value'
|
||||
form['scopes'] = 'profile'
|
||||
resp = form.submit()
|
||||
assert len(resp.pyquery('.error')) == 1
|
||||
assert 'claim name is already defined for this client' in resp.pyquery('.error')[0].text
|
||||
assert (
|
||||
OIDCClaim.objects.filter(
|
||||
client=oidc_client, name='yet_another_claim', value='value', scopes='profile'
|
||||
).count()
|
||||
== 1
|
||||
)
|
||||
|
||||
class TestEditClaim:
|
||||
@pytest.fixture(autouse=True)
|
||||
def claim(self, oidc_client):
|
||||
|
|
Loading…
Reference in New Issue