From 2dae412940105c64c4ea1ed77e6a45793faa0efa 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 --- 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 09f355341d..e965383665 100644 --- a/keystone/tests/unit/test_cli.py +++ b/keystone/tests/unit/test_cli.py @@ -24,6 +24,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.cmd.doctor import caching from keystone.cmd.doctor import federation @@ -163,7 +164,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()