← Back to team overview

yahoo-eng-team team mailing list archive

[Bug 1848342] Re: Duplicated entries in users API

 

Reviewed:  https://review.opendev.org/687990
Committed: https://git.openstack.org/cgit/openstack/keystone/commit/?id=7597ecc1350eb6918c09585e4116911102acb54a
Submitter: Zuul
Branch:    master

commit 7597ecc1350eb6918c09585e4116911102acb54a
Author: Pedro Martins <phpm13@xxxxxxxxx>
Date:   Thu Oct 10 08:51:32 2019 -0300

    Stop adding entry in local_user while updating ephemerals
    
    Problem description
    ===================
    Today we have a consistency problem when updating federated
    users via OpenStack. When I update a ephemeral user via OpenStack,
    a registry in the local_user table is created, making this user
    having entries in user, local_user and federated_user tables in
    the database.
    
    Furthermore, if I try to do some operations using this user
    (that has entries in all three tables), I get a "More than one
    user exists with the name ..." error from the OpenStack
    Keystone API. It happens because the user has an entry in both
    local_user and federated_user tables.
    
    I fix the persistence in the local_user table for ephemeral
    users when doing updates.
    
    Proposal
    ========
    I fix the problem with creating an entry in the
    local_user table while updating an ephemeral user
    
    Closes-Bug: #1848342
    
    Change-Id: I2ac6e90f24b94dc5c0d9c0758f008a388597036c


** Changed in: keystone
       Status: In Progress => Fix Released

-- 
You received this bug notification because you are a member of Yahoo!
Engineering Team, which is subscribed to OpenStack Identity (keystone).
https://bugs.launchpad.net/bugs/1848342

Title:
  Duplicated entries in users API

Status in OpenStack Identity (keystone):
  Fix Released

Bug description:
  System version
  ==============
  Keystone: 14.0.1 (Rocky)

  
  The error happens when I try to show a federated user via the user name as the key instead of using the ID

  Reproducing the error:

  ======================

  First of all, I created a user in my Identity Provider (Idp) that is
  configured my KeyStone instance.

  We use OpenID Connect protocol to create the federated environment. In
  this test, the user created is

   named as 'use_case'. At this moment, the user is not in the OpenStack
  database, just in the Idp

   (ephemeral user type).

  Authenticating with the ephemeral federated user:

      Let's see the database tables before the login process.

      Users already created in the Idp (before the login):

          select * from user;

  +----------------------------------+-------+---------+--------------------+---------------------+----------------+-----------+

          | id                               | extra | enabled |
  default_project_id | created_at          | last_active_at | domain_id
  |

  +----------------------------------+-------+---------+--------------------+---------------------+----------------+-----------+

          | 1b0ed400ec974420a3574a8788acc795 | {}    |       1 | NULL
  | 2019-09-16 20:06:39 | NULL           | default   |

  +----------------------------------+-------+---------+--------------------+---------------------+----------------+-----------+

          select * from local_user;

  +-----+----------------------------------+-----------+-------+-------------------+----------------+

          | id  | user_id                          | domain_id | name  |
  failed_auth_count | failed_auth_at |

  +-----+----------------------------------+-----------+-------+-------------------+----------------+

          |   1 | 1b0ed400ec974420a3574a8788acc795 | default   | admin |
  0 | NULL           |

  +-----+----------------------------------+-----------+-------+-------------------+----------------+

          select * from federated_user;

          Empty set (0.00 sec)

      So far, we have only the local user admin

  Then, we execute the login using the ephemeral user that we created in
  the IdP.

      Let's the database state after the first login:

          select * from user;

  +----------------------------------+---------------------------------+---------+--------------------+---------------------+----------------+----------------------------------+

          | id                               | extra
  | enabled | default_project_id | created_at          | last_active_at
  | domain_id                        |

  +----------------------------------+---------------------------------+---------+--------------------+---------------------+----------------+----------------------------------+

          | 1b0ed400ec974420a3574a8788acc795 | {}
  |       1 | NULL               | 2019-09-16 20:06:39 | NULL
  | default                          |

          | f0327d98278f4b1881aec9c051b027d3 | {"email":
  "use_case@xxxxxxxxx"} |       1 | NULL               | 2019-10-15
  18:08:17 | NULL           | d28c2423e9b546deb37a034bb2134f4d |

  +----------------------------------+---------------------------------+---------+--------------------+---------------------+----------------+----------------------------------+

          select * from local_user;

  +----+----------------------------------+-----------+-------+-------------------+----------------+

          | id | user_id                          | domain_id | name  |
  failed_auth_count | failed_auth_at |

  +----+----------------------------------+-----------+-------+-------------------+----------------+

          |  1 | 1b0ed400ec974420a3574a8788acc795 | default   | admin |
  0 | NULL           |

  +----+----------------------------------+-----------+-------+-------------------+----------------+

          select * from federated_user;

  +----+----------------------------------+--------+-------------+-----------+--------------+

          | id | user_id                          | idp_id | protocol_id
  | unique_id | display_name |

  +----+----------------------------------+--------+-------------+-----------+--------------+

          |  1 | f0327d98278f4b1881aec9c051b027d3 | my_idp | openid
  | use_case  | use_case     |

  +----+----------------------------------+--------+-------------+-----------+--------------+

          Here we can see that the user did not exist in OpenStack
  database before the first login; then, KeyStone receives the user
  attributes (during the authentication process) from the Idp and
  register the user in the OpenStack database as a federated user.

          (user and federated_user tables).

          Here is the OpenStack client output (when executing the show
  command after the first login):

          openstack user show use_case

          +---------------------+----------------------------------+

          | Field               | Value                            |

          +---------------------+----------------------------------+

          | domain_id           | d28c2423e9b546deb37a034bb2134f4d |

          | email               | use_case@xxxxxxxxx               |

          | enabled             | True                             |

          | id                  | f0327d98278f4b1881aec9c051b027d3 |

          | name                | use_case                         |

          | options             | {}                               |

          | password_expires_at | None                             |

          +---------------------+----------------------------------+

      Afterwards, we logout and then we login again in Horizon via the
  IdP. Please invalidate your session, OpenStack has a bug, and it is
  not invalidating IdP sessions when the logout is called in Horizon):

          select * from user;

  +----------------------------------+---------------------------------+---------+--------------------+---------------------+----------------+----------------------------------+

          | id                               | extra
  | enabled | default_project_id | created_at          | last_active_at
  | domain_id                        |

  +----------------------------------+---------------------------------+---------+--------------------+---------------------+----------------+----------------------------------+

          | 1b0ed400ec974420a3574a8788acc795 | {}
  |       1 | NULL               | 2019-09-16 20:06:39 | NULL
  | default                          |

          | f0327d98278f4b1881aec9c051b027d3 | {"email":
  "use_case@xxxxxxxxx"} |       1 | NULL               | 2019-10-15
  18:08:17 | NULL           | d28c2423e9b546deb37a034bb2134f4d |

  +----------------------------------+---------------------------------+---------+--------------------+---------------------+----------------+----------------------------------+

          select * from local_user;

  +----+----------------------------------+----------------------------------+----------+-------------------+----------------+

          | id | user_id                          | domain_id
  | name     | failed_auth_count | failed_auth_at |

  +----+----------------------------------+----------------------------------+----------+-------------------+----------------+

          |  1 | 1b0ed400ec974420a3574a8788acc795 | default
  | admin    |                 0 | NULL           |

          |  4 | f0327d98278f4b1881aec9c051b027d3 |
  d28c2423e9b546deb37a034bb2134f4d | use_case |                 0 | NULL
  |

  +----+----------------------------------+----------------------------------+----------+-------------------+----------------+

          select * from federated_user;

  +----+----------------------------------+--------+-------------+-----------+--------------+

          | id | user_id                          | idp_id | protocol_id
  | unique_id | display_name |

  +----+----------------------------------+--------+-------------+-----------+--------------+

          |  1 | f0327d98278f4b1881aec9c051b027d3 | my_idp | openid
  | use_case  | use_case     |

  +----+----------------------------------+--------+-------------+-----------+--------------+

          Here is the bug, the user already existed in the OpenStack
  database, and during the second login, Keystone tried to update data
  with the attributes that come from the IdP. During the update process,
  Keystone will create an entry in the local_user table.

          The code that is generating this behavior can be found in
  https://github.com/openstack/keystone/blob/master/keystone/identity/core.py#L1421

          After that, if I try to show the user via OpenStack client, I
  receive the following error

          openstack user show use_case

          More than one user exists with the name 'use_case'.

  Here is an excerpt of our Attribute Mapping JSON:

      [

      {

          "local": [

          {

              "user": {

              "name": "{0}",

              "email": "{1}",

              "domain": {

                  "name": "{2}"

              }

              },

              "domain": {

              "name": "{2}"

              },

              "projects": [

              {

                  "name": "{3}",

                  "roles": [

                  {

                      "name": "member"

                  },

                  {

                      "name": "domadmin"

                  },

                  {

                      "name": "heat_stack_owner"

                  },

                  {

                      "name": "load-balancer_member"

                  }

                  ]

              }

              ]

          }

          ],

          "remote": [

          {

              "type": "OIDC-preferred_username"

          },

          {

              "type": "OIDC-email"

          },

          {

              "type": "OIDC-openstack-user-domain"

          },

          {

              "type": "OIDC-openstack-default-project"

          },

          {

              "type": "OIDC-openstack-user-role",

              "any_one_of": [

              "domain-admin"

              ]

          }

          ]

      },

      {

          "local": [

          {

              "user": {

              "name": "{0}",

              "email": "{1}",

              "type": "local",

              "domain": {

                  "name": "{2}"

              }

              },

              "domain": {

              "name": "{2}"

              },

              "projects": [

              {

                  "name": "{3}",

                  "roles": [

                  {

                      "name": "member"

                  },

                  {

                      "name": "heat_stack_owner"

                  },

                  {

                      "name": "load-balancer_member"

                  }

                  ]

              }

              ]

          }

          ],

          "remote": [

          {

              "type": "OIDC-preferred_username"

          },

          {

              "type": "OIDC-email"

          },

          {

              "type": "OIDC-openstack-user-domain"

          },

          {

              "type": "OIDC-openstack-default-project"

          },

          {

              "type": "OIDC-openstack-user-status",

              "any_one_of": [

              "local"

              ]

          },

          {

              "type": "OIDC-openstack-user-role",

              "any_one_of": [

              "member"

              ]

          }

          ]

      }

      ]

  
  Here is a link to the PR that propose to fix that issue:

  https://review.opendev.org/#/c/687990

To manage notifications about this bug go to:
https://bugs.launchpad.net/keystone/+bug/1848342/+subscriptions


References