From 0d9a51ea7719afe95c754cbf4efba4621e6a58e6 Mon Sep 17 00:00:00 2001 From: Lance Bragstad Date: Thu, 8 Dec 2016 15:53:51 +0000 Subject: [PATCH] Expose idempotency issue with bootstrap During some upgrade testing I was doing locally, I noticed an issue where `keystone-manage bootstrap` isn't completely idempotent. This is because `bootstrap` has the ability to recover lost admin accounts by reseting the admin user's enabled status and updating their password, regardless of it being different. This creates a revocation event and causes admin tokens to be invalid after bootstrap is run for a second time, making it not as idempotent as we'd like. This commit introduces a test that exposes this behavior. Change-Id: I627255b2b5d6ec401af2c07c4018930fea206e4a Partial-Bug: 1647800 (cherry picked from commit 2dae412940105c64c4ea1ed77e6a45793faa0efa) --- keystone/tests/unit/test_cli.py | 42 +++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/keystone/tests/unit/test_cli.py b/keystone/tests/unit/test_cli.py index 5f51f90e27..591de62705 100644 --- a/keystone/tests/unit/test_cli.py +++ b/keystone/tests/unit/test_cli.py @@ -23,6 +23,7 @@ from oslotest import mockpatch from six.moves import range from testtools import matchers +from keystone.auth import controllers from keystone.cmd import cli from keystone.common import dependency from keystone.common.sql import migration_helpers @@ -160,7 +161,48 @@ class CliBootStrapTestCase(unit.SQLDriverOverrides, unit.TestCase): # without erroring. bootstrap = cli.BootStrap() self._do_test_bootstrap(bootstrap) + v3_token_controller = controllers.Auth() + v3_password_data = { + 'identity': { + "methods": ["password"], + "password": { + "user": { + "name": bootstrap.username, + "password": bootstrap.password, + "domain": { + "id": CONF.identity.default_domain_id + } + } + } + } + } + auth_response = v3_token_controller.authenticate_for_token( + self.make_request(), v3_password_data) + token = auth_response.headers['X-Subject-Token'] self._do_test_bootstrap(bootstrap) + # build validation request + request = self.make_request( + is_admin=True, + headers={ + 'X-Subject-Token': token, + 'X-Auth-Token': token + } + ) + request.context_dict['subject_token_id'] = token + # NOTE(lbragstad): This is currently broken because the bootstrap + # operation will automatically reset a user's password even if it is + # the same as it was before. Bootstrap has this behavior so it's + # possible to recover admin accounts, which was one of our main + # usecases for introducing the bootstrap functionality. The side-effect + # is that changing the password will create a revocation event. So if a + # token is obtained in-between two bootstrap calls, the token will no + # longer be valid after the second bootstrap operation completes, even + # if the password is the same. + self.assertRaises( + exception.TokenNotFound, + v3_token_controller.validate_token, + request + ) def test_bootstrap_recovers_user(self): bootstrap = cli.BootStrap()