feat: improved user attribute handling and username uniqueness in SpidCieOidcRpCallbackView

This commit is contained in:
gabdevele
2026-06-18 01:19:57 +02:00 Unverified
parent a69051ed56
commit 4bce9004bf
@@ -65,6 +65,25 @@ class SpidCieOidcRpCallbackView(View, SpidCieOidcRp, OidcUserInfo, OAuth2Authori
def user_reunification(self, user_attrs: dict): def user_reunification(self, user_attrs: dict):
user_model = get_user_model() user_model = get_user_model()
desired_username = user_attrs.get("username", user_attrs["sub"])
def update_user(user):
user.first_name = user_attrs.get("given_name", user.first_name)
user.last_name = user_attrs.get("family_name", user.last_name)
user.email = user_attrs.get("email", user.email)
merged_attrs = dict(user.attributes or {})
merged_attrs.update(user_attrs)
user.attributes = merged_attrs
user.save()
return user
def unique_username(base_username):
username = base_username
index = 1
while user_model.objects.filter(username=username).exists():
username = f"{base_username}__{index}"
index += 1
return username
if user_attrs.get(RP_USER_LOOKUP_FIELD, None): if user_attrs.get(RP_USER_LOOKUP_FIELD, None):
lookup = { lookup = {
@@ -77,13 +96,34 @@ class SpidCieOidcRpCallbackView(View, SpidCieOidcRp, OidcUserInfo, OAuth2Authori
} }
user = user_model.objects.filter(**lookup).first() user = user_model.objects.filter(**lookup).first()
if user: if user:
user.attributes.update(user_attrs) user = update_user(user)
user.save()
logger.info(f"{RP_USER_LOOKUP_FIELD} matched on user {user}") logger.info(f"{RP_USER_LOOKUP_FIELD} matched on user {user}")
return user return user
elif RP_USER_CREATE: elif RP_USER_CREATE:
existing_username_user = user_model.objects.filter(
username=desired_username
).first()
if existing_username_user:
existing_lookup_value = (existing_username_user.attributes or {}).get(
RP_USER_LOOKUP_FIELD
)
requested_lookup_value = user_attrs.get(RP_USER_LOOKUP_FIELD)
if (
not requested_lookup_value
or not existing_lookup_value
or existing_lookup_value == requested_lookup_value
):
user = update_user(existing_username_user)
logger.info(f"Username matched on existing user {user}")
return user
logger.warning(
"Username collision for %s with different %s values, generating a unique username",
desired_username,
RP_USER_LOOKUP_FIELD,
)
user = user_model.objects.create( user = user_model.objects.create(
username=user_attrs.get("username", user_attrs["sub"]), username=unique_username(desired_username),
first_name=user_attrs.get("given_name", user_attrs["sub"]), first_name=user_attrs.get("given_name", user_attrs["sub"]),
last_name=user_attrs.get("family_name", user_attrs["sub"]), last_name=user_attrs.get("family_name", user_attrs["sub"]),
email=user_attrs.get("email", ""), email=user_attrs.get("email", ""),