GET /v3/users?name=NAME returns duplicate
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
OpenStack Identity (keystone) |
New
|
Undecided
|
Unassigned |
Bug Description
GET /v3/users?
I have a federated local user in the default domain:
REQ: GET https:/
RESP: 200: OK
{
"user": {
"description": "Local federated user",
"email": "<email address hidden>",
"id": "91665ebad88b49
"name": "federated-user",
"domain_id": "default",
"enabled": true,
"password_
"options": {},
"federated": [
{
"idp_id": "eduid",
{
}
]
}
],
"links": {
"self": "https:/
}
}
}
But when I try to get the user by name, it is returned twice:
REQ: GET https:/
RESP: 200: OK
{
"users": [
{
"
"email": "<email address hidden>",
"id": "91665ebad88b49
"name": "federated-user",
"domain_id": "default",
"enabled": true,
"
"options": {},
"links": {
"self": "https:/
}
},
{
"
"email": "<email address hidden>",
"id": "91665ebad88b49
"name": "federated-user",
"domain_id": "default",
"enabled": true,
"
"options": {},
"links": {
"self": "https:/
}
}
],
"links": {
"next": null,
"self": "https:/
"previous": null
}
}
The same problem with the openstack CLI:
$ openstack user show federated-user
More than one user exists with the name 'federated-user'.
Why does this append?
Why is the user by name returned twice?
This is breaking a lot of python code, based on OpenstackSDK, typically the code:
api = openstack.connect()
user = api.identity.
will throw an exception!
description: | updated |
description: | updated |
description: | updated |
description: | updated |
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
```