From 971ba5fa4522349d8c24a318fd6f0701ff0668f4 Mon Sep 17 00:00:00 2001 From: Lance Bragstad Date: Mon, 2 May 2016 18:57:05 +0000 Subject: [PATCH] Make keystone exit when fernet keys don't exist An outcome of some of the token discussions in Austin was that when Fernet is the configured token provider, Keystone should fail on start up if there are no keys in the key repository or if the repository doesn't exist. Closes-Bug: 1576315 Change-Id: I0351dddc49da5908f46e09e22467f6fb112593dd --- keystone/tests/unit/test_token_provider.py | 2 ++ keystone/tests/unit/test_v2.py | 3 +-- keystone/tests/unit/test_v3_auth.py | 2 +- keystone/token/providers/fernet/core.py | 17 +++++++++++++++++ 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/keystone/tests/unit/test_token_provider.py b/keystone/tests/unit/test_token_provider.py index 3042299530..6f8fe33989 100644 --- a/keystone/tests/unit/test_token_provider.py +++ b/keystone/tests/unit/test_token_provider.py @@ -22,6 +22,7 @@ from keystone.common import dependency from keystone.common import utils from keystone import exception from keystone.tests import unit +from keystone.tests.unit import ksfixtures from keystone.tests.unit.ksfixtures import database from keystone import token from keystone.token.providers import fernet @@ -717,6 +718,7 @@ class TestTokenProvider(unit.TestCase): def setUp(self): super(TestTokenProvider, self).setUp() self.useFixture(database.Database()) + self.useFixture(ksfixtures.KeyRepository(self.config_fixture)) self.load_backends() def test_get_token_version(self): diff --git a/keystone/tests/unit/test_v2.py b/keystone/tests/unit/test_v2.py index d938a72a1b..56711c7263 100644 --- a/keystone/tests/unit/test_v2.py +++ b/keystone/tests/unit/test_v2.py @@ -1421,8 +1421,6 @@ class TestFernetTokenProviderV2(RestfulTestCase): def setUp(self): super(TestFernetTokenProviderV2, self).setUp() - self.useFixture(ksfixtures.KeyRepository(self.config_fixture)) - # Add catalog data self.region = unit.new_region_ref() self.region_id = self.region['id'] @@ -1458,6 +1456,7 @@ class TestFernetTokenProviderV2(RestfulTestCase): def config_overrides(self): super(TestFernetTokenProviderV2, self).config_overrides() self.config_fixture.config(group='token', provider='fernet') + self.useFixture(ksfixtures.KeyRepository(self.config_fixture)) def test_authenticate_unscoped_token(self): unscoped_token = self.get_unscoped_token() diff --git a/keystone/tests/unit/test_v3_auth.py b/keystone/tests/unit/test_v3_auth.py index e2915e5976..70ddb765c6 100644 --- a/keystone/tests/unit/test_v3_auth.py +++ b/keystone/tests/unit/test_v3_auth.py @@ -4718,10 +4718,10 @@ class TestTrustAuthFernetTokenProvider(TrustAPIBehavior, TestTrustChain): class TestAuthFernetTokenProvider(TestAuth): def setUp(self): super(TestAuthFernetTokenProvider, self).setUp() - self.useFixture(ksfixtures.KeyRepository(self.config_fixture)) def config_overrides(self): super(TestAuthFernetTokenProvider, self).config_overrides() + self.useFixture(ksfixtures.KeyRepository(self.config_fixture)) self.config_fixture.config(group='token', provider='fernet') def test_verify_with_bound_token(self): diff --git a/keystone/token/providers/fernet/core.py b/keystone/token/providers/fernet/core.py index ff6fe9cc78..52fa80c806 100644 --- a/keystone/token/providers/fernet/core.py +++ b/keystone/token/providers/fernet/core.py @@ -10,11 +10,14 @@ # License for the specific language governing permissions and limitations # under the License. +import os + from oslo_config import cfg from keystone.common import dependency from keystone.common import utils as ks_utils from keystone.federation import constants as federation_constants +from keystone.i18n import _ from keystone.token.providers import common from keystone.token.providers.fernet import token_formatters as tf @@ -27,6 +30,20 @@ class Provider(common.BaseProvider): def __init__(self, *args, **kwargs): super(Provider, self).__init__(*args, **kwargs) + # NOTE(lbragstad): We add these checks here because if the fernet + # provider is going to be used and either the `key_repository` is empty + # or doesn't exist we should fail, hard. It doesn't make sense to start + # keystone and just 500 because we can't do anything with an empty or + # non-existant key repository. + if not os.path.exists(CONF.fernet_tokens.key_repository): + subs = {'key_repo': CONF.fernet_tokens.key_repository} + raise SystemExit(_('%(key_repo)s does not exist') % subs) + if not os.listdir(CONF.fernet_tokens.key_repository): + subs = {'key_repo': CONF.fernet_tokens.key_repository} + raise SystemExit(_('%(key_repo)s does not contain keys, use ' + 'keystone-manage fernet_setup to create ' + 'Fernet keys.') % subs) + self.token_formatter = tf.TokenFormatter() def needs_persistence(self):