feat: improved user attribute handling and username uniqueness in SpidCieOidcRpCallbackView
This commit is contained in:
+43
-3
@@ -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", ""),
|
||||||
|
|||||||
Reference in New Issue
Block a user