auth_oidc: add STRATEGY_FIND_USERNAME to match sub with username (#53445)
This commit is contained in:
parent
c7418ad4eb
commit
8915d6fc96
|
@ -143,7 +143,13 @@ class OIDCBackend(ModelBackend):
|
|||
pass
|
||||
else:
|
||||
logger.info('auth_oidc: found user using UUID (=sub) "%s": %s', id_token.sub, user)
|
||||
|
||||
elif provider.strategy == models.OIDCProvider.STRATEGY_FIND_USERNAME:
|
||||
users = User.objects.filter(username=id_token.sub, is_active=True).order_by('pk')
|
||||
if not users:
|
||||
logger.warning('auth_oidc: user with username (=sub) "%s" not found', id_token.sub)
|
||||
else:
|
||||
user = users[0]
|
||||
logger.info('auth_oidc: found user using username (=sub) "%s": %s', id_token.sub, user)
|
||||
else:
|
||||
try:
|
||||
user = User.objects.get(
|
||||
|
|
|
@ -20,6 +20,7 @@ class Migration(migrations.Migration):
|
|||
choices=[
|
||||
('create', 'create'),
|
||||
('find-uuid', 'use sub to find existing user through UUID'),
|
||||
('find-username', 'use sub to find existing user through username'),
|
||||
('none', 'none'),
|
||||
],
|
||||
),
|
||||
|
|
|
@ -40,11 +40,13 @@ def validate_jwkset(data):
|
|||
class OIDCProvider(models.Model):
|
||||
STRATEGY_CREATE = 'create'
|
||||
STRATEGY_FIND_UUID = 'find-uuid'
|
||||
STRATEGY_FIND_USERNAME = 'find-username'
|
||||
STRATEGY_NONE = 'none'
|
||||
|
||||
STRATEGIES = [
|
||||
(STRATEGY_CREATE, _('create')),
|
||||
(STRATEGY_FIND_UUID, _('use sub to find existing user through UUID')),
|
||||
(STRATEGY_FIND_USERNAME, _('use sub to find existing user through username')),
|
||||
(STRATEGY_NONE, _('none')),
|
||||
]
|
||||
ALGO_NONE = 0
|
||||
|
|
|
@ -912,3 +912,38 @@ def test_manager_user_sidebar(app, superuser, simple_user, oidc_provider):
|
|||
assert 'OIDC' in response
|
||||
assert 'Server' in response
|
||||
assert '1234' in response
|
||||
|
||||
|
||||
def test_strategy_find_username(app, caplog, code, oidc_provider, oidc_provider_jwkset, simple_user):
|
||||
# no mapping please
|
||||
OIDCClaimMapping.objects.all().delete()
|
||||
oidc_provider.strategy = oidc_provider.STRATEGY_FIND_USERNAME
|
||||
oidc_provider.save()
|
||||
|
||||
assert User.objects.count() == 1
|
||||
|
||||
response = app.get('/').maybe_follow()
|
||||
assert oidc_provider.name in response.text
|
||||
response = response.click(oidc_provider.name)
|
||||
location = urllib.parse.urlparse(response.location)
|
||||
query = QueryDict(location.query)
|
||||
state = query['state']
|
||||
nonce = query['nonce']
|
||||
|
||||
# sub=simple_user.uuid MUST not work
|
||||
with utils.check_log(caplog, 'cannot create user'):
|
||||
with oidc_provider_mock(oidc_provider, oidc_provider_jwkset, code, sub=simple_user.uuid, nonce=nonce):
|
||||
response = app.get(login_callback_url(oidc_provider), params={'code': code, 'state': state})
|
||||
|
||||
# sub=john.doe, MUST not work
|
||||
with utils.check_log(caplog, 'cannot create user'):
|
||||
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})
|
||||
|
||||
simple_user.username = 'john.doe'
|
||||
simple_user.save()
|
||||
|
||||
# sub=john.doe, MUST work
|
||||
with utils.check_log(caplog, 'found user using username'):
|
||||
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})
|
||||
|
|
Loading…
Reference in New Issue