auth_oidc: only update user's fields if they changed (fixes #21560)

This commit is contained in:
Benjamin Dauvergne 2018-03-09 22:35:15 +01:00
parent 067e51da7f
commit 1aa16b62e0
2 changed files with 32 additions and 10 deletions

View File

@ -218,12 +218,27 @@ class OIDCBackend(ModelBackend):
u' allow it', id_token.sub, id_token.iss)
return None
if created:
logger.info(u'auth_oidc: created user %s for sub %s and issuer %s',
user, id_token.sub, id_token.iss)
if linked:
logger.info(u'auth_oidc: linked user %s to sub %s and issuer %s',
user, id_token.sub, id_token.iss)
# legacy attributes
for attribute, value, verified in mappings:
if attribute in ('username', 'first_name', 'last_name', 'email'):
if attribute not in ('username', 'first_name', 'last_name', 'email'):
continue
if getattr(user, attribute) != value:
logger.info(u'auth_oidc: set user %s attribute %s to value %s',
user, attribute, value)
setattr(user, attribute, value)
save_user = True
if user.ou != user_ou:
logger.info(u'auth_oidc: set user %s ou to %s',
user, user_ou)
user.ou = user_ou
save_user = True
@ -237,17 +252,13 @@ class OIDCBackend(ModelBackend):
# new style attributes
for attribute, value, verified in mappings:
if attribute in attributes_map:
if attribute not in attributes_map:
continue
if attributes_map[attribute].get_value(user, verified=verified) != value:
logger.info(u'auth_oidc: set user %s attribute %s to %s',
user, attribute, value)
attributes_map[attribute].set_value(user, value, verified=verified)
if created:
logger.info(u'auth_oidc: created user %s for sub %s and issuer %s',
user, id_token.sub, id_token.iss)
if linked:
logger.info(u'auth_oidc: linked user %s to sub %s and issuer %s',
user, id_token.sub, id_token.iss)
return user
def get_saml2_authn_context(self):

View File

@ -3,6 +3,7 @@ import datetime
import pytest
import urlparse
import json
import time
from jwcrypto.jwk import JWKSet, JWK
from jwcrypto.jwt import JWT
@ -328,6 +329,16 @@ def test_sso(app, caplog, code, oidc_provider, oidc_provider_jwkset, login_url,
assert User.objects.count() == 1
user = User.objects.get()
assert user.ou == get_default_ou()
last_modified = user.modified
time.sleep(0.1)
with oidc_provider_mock(oidc_provider, oidc_provider_jwkset, code):
response = app.get(login_callback_url, params={'code': code, 'state': query['state']})
assert User.objects.count() == 1
user = User.objects.get()
assert user.ou == get_default_ou()
assert user.modified == last_modified
response = app.get(reverse('account_management'))
with utils.check_log(caplog, 'revoked token from OIDC'):