So I am seeing something similar in our setup. If a federated user gets created by logging in via the OpenStack web interface (via OIDC), the user does NOT have a local_user entry created. Such a user will NOT show a duplicate user warning.
However, if I create a user with federated identity data such a user will get entries in both the local_user database table, and in the federated_users database table.
A simple fix for this would be to add `del user['name']` right after `del user['federated']`. This will result in the same behavior for federated user creation via the Keystone API (POST /v3/users). The reason, this works is that in the SQL backend, the "create_user" interface will automatically create a local_user entry when setting the 'name' attribute IF there is no federated data. Since the federated data does not get added until after the user is created, there is a chicken and egg scenario.
However, your question makes me wonder if creating of a local_user entry is correct, but the the "GET /v3/users" behavior is wrong, and it shouldn't report the presense of both the local_user and federated_user as a duplicate. In this case, I would also ask the question of whether a user that gets added as a result of authenticationg via the OIDC, etc. should end up with the same database entries as a user that is added via the Keystone API with federated info.
```
def _create_user_with_federated_objects(self, user, driver):
# If the user did not pass a federated object along inside the user
# object then we simply create the user as normal.
if not user.get('federated'):
if 'federated' in user:
del user['federated']
user = driver.create_user(user['id'], user)
return user
# Otherwise, validate the federated object and create the user.
else: user_ref = user.copy()
del user['federated'] self._validate_federated_objects(user_ref['federated'])
user = driver.create_user(user['id'], user) self._create_federated_objects(user_ref, user_ref['federated']) user['federated'] = user_ref['federated']
return user
```
So I am seeing something similar in our setup. If a federated user gets created by logging in via the OpenStack web interface (via OIDC), the user does NOT have a local_user entry created. Such a user will NOT show a duplicate user warning.
However, if I create a user with federated identity data such a user will get entries in both the local_user database table, and in the federated_users database table.
My original thinking was that in the keystone/ identity/ core.py (https:/ /github. com/openstack/ keystone/ blob/master/ keystone/ identity/ core.py# L960C1- L976C24), there is a bug because this creation code will create both of these entries (see code snippet below)
A simple fix for this would be to add `del user['name']` right after `del user['federated']`. This will result in the same behavior for federated user creation via the Keystone API (POST /v3/users). The reason, this works is that in the SQL backend, the "create_user" interface will automatically create a local_user entry when setting the 'name' attribute IF there is no federated data. Since the federated data does not get added until after the user is created, there is a chicken and egg scenario.
However, your question makes me wonder if creating of a local_user entry is correct, but the the "GET /v3/users" behavior is wrong, and it shouldn't report the presense of both the local_user and federated_user as a duplicate. In this case, I would also ask the question of whether a user that gets added as a result of authenticationg via the OIDC, etc. should end up with the same database entries as a user that is added via the Keystone API with federated info.
``` user_with_ federated_ objects( self, user, driver): 'federated' ): create_ user(user[ 'id'], user)
user_ ref = user.copy()
self. _validate_ federated_ objects( user_ref[ 'federated' ]) create_ user(user[ 'id'], user)
self. _create_ federated_ objects( user_ref, user_ref[ 'federated' ])
user[ 'federated' ] = user_ref[ 'federated' ]
def _create_
# If the user did not pass a federated object along inside the user
# object then we simply create the user as normal.
if not user.get(
if 'federated' in user:
del user['federated']
user = driver.
return user
# Otherwise, validate the federated object and create the user.
else:
del user['federated']
user = driver.
return user
```