auth_oidc: allow adding roles on login (#53442)

This commit is contained in:
Valentin Deniaud 2022-09-20 15:38:41 +02:00
parent 5e156b6168
commit d7212589c2
4 changed files with 44 additions and 1 deletions

View File

@ -382,6 +382,12 @@ class OIDCBackend(ModelBackend):
setattr(user.verified_attributes, attribute, value)
else:
setattr(user.attributes, attribute, value)
for action in provider.add_role_actions.all():
if action.role not in user.roles.all():
logger.info('auth_oidc: adding role "%s" to user %s', action.role, user)
user.roles.add(action.role)
return user
def get_saml2_authn_context(self):

View File

@ -26,7 +26,11 @@ from django.utils.translation import gettext_lazy as _
from jwcrypto.jwk import InvalidJWKValue, JWKSet
from authentic2.a2_rbac.utils import get_default_ou
from authentic2.apps.authenticators.models import AuthenticatorRelatedObjectBase, BaseAuthenticator
from authentic2.apps.authenticators.models import (
AddRoleAction,
AuthenticatorRelatedObjectBase,
BaseAuthenticator,
)
from authentic2.utils.misc import make_url, redirect_to_login
from authentic2.utils.template import validate_template
@ -136,6 +140,7 @@ class OIDCProvider(BaseAuthenticator):
def related_models(self):
return {
OIDCClaimMapping: self.claim_mappings.all(),
AddRoleAction: self.add_role_actions.all(),
}
@property

View File

@ -1315,3 +1315,25 @@ def test_only_idtoken_claims(app, caplog, code, oidc_provider, oidc_provider_jwk
):
response = app.get(login_callback_url(oidc_provider), params={'code': code, 'state': state})
assert User.objects.count() == 1
def test_oidc_add_role(app, code, oidc_provider, oidc_provider_jwkset, simple_role):
oidc_provider.add_role_actions.create(role=simple_role)
response = app.get('/').maybe_follow()
response = response.click(oidc_provider.name)
location = urllib.parse.urlparse(response.location)
query = QueryDict(location.query)
state = query['state']
nonce = query['nonce']
with oidc_provider_mock(
oidc_provider,
oidc_provider_jwkset,
code,
nonce=nonce,
):
response = app.get(login_callback_url(oidc_provider), params={'code': code, 'state': state})
user = User.objects.get()
assert simple_role in user.roles.all()

View File

@ -223,6 +223,16 @@ def test_authenticators_oidc_claims(app, superuser):
assert_event('authenticator.related_object.deletion', user=superuser, session=app.session)
def test_authenticators_oidc_add_role(app, superuser, role_ou1):
authenticator = OIDCProvider.objects.create(slug='idp1')
resp = login(app, superuser, path=authenticator.get_absolute_url())
resp = resp.click('Add', href='role')
resp.form['role'] = role_ou1.pk
resp = resp.form.submit().follow()
assert 'role_ou1' in resp.text
def test_authenticators_fc(app, superuser):
resp = login(app, superuser, path='/manage/authenticators/')