diff --git a/app.py b/app.py index 5dd11062f..88272056d 100644 --- a/app.py +++ b/app.py @@ -177,7 +177,7 @@ build_logs = BuildLogs(app) authentication = UserAuthentication(app, config_provider, OVERRIDE_CONFIG_DIRECTORY) userevents = UserEventsBuilderModule(app) superusers = SuperUserManager(app) -signer = Signer(app, OVERRIDE_CONFIG_DIRECTORY) +signer = Signer(app, config_provider) start_cloudwatch_sender(metric_queue, app) tf = app.config['DB_TRANSACTION_FACTORY'] diff --git a/endpoints/web.py b/endpoints/web.py index 668221a51..aa8bee810 100644 --- a/endpoints/web.py +++ b/endpoints/web.py @@ -105,7 +105,7 @@ def aci_signing_key(): if not signer.name: abort(404) - return send_file(signer.public_key_path) + return send_file(signer.open_public_key_file()) @web.route('/plans/') @no_cache diff --git a/test/testconfig.py b/test/testconfig.py index 9d64cbe7d..aa8b8e549 100644 --- a/test/testconfig.py +++ b/test/testconfig.py @@ -70,8 +70,8 @@ class TestConfig(DefaultConfig): SIGNING_ENGINE = 'gpg2' GPG2_PRIVATE_KEY_NAME = 'EEB32221' - GPG2_PRIVATE_KEY_FILENAME = '/test/data/signing-private.gpg' - GPG2_PUBLIC_KEY_FILENAME = '/test/data/signing-public.gpg' + GPG2_PRIVATE_KEY_FILENAME = 'test/data/signing-private.gpg' + GPG2_PUBLIC_KEY_FILENAME = 'test/data/signing-public.gpg' JWT_AUTH_CERTIFICATE_PATH = 'test/data/registry_v2_auth.crt' JWT_AUTH_PRIVATE_KEY_PATH = 'test/data/registry_v2_auth_private.key' diff --git a/util/config/provider/testprovider.py b/util/config/provider/testprovider.py index 7c8e1054f..d607e2ff5 100644 --- a/util/config/provider/testprovider.py +++ b/util/config/provider/testprovider.py @@ -3,6 +3,8 @@ from StringIO import StringIO from util.config.provider.baseprovider import BaseProvider +REAL_FILES = ['test/data/signing-private.gpg', 'test/data/signing-public.gpg'] + class TestConfigProvider(BaseProvider): """ Implementation of the config provider for testing. Everything is kept in-memory instead on the real file system. """ @@ -36,12 +38,18 @@ class TestConfigProvider(BaseProvider): return True def volume_file_exists(self, filename): + if filename in REAL_FILES: + return True + return filename in self.files def save_volume_file(self, filename, flask_file): self.files[filename] = '' def get_volume_file(self, filename, mode='r'): + if filename in REAL_FILES: + return open(filename, mode=mode) + return StringIO(self.files[filename]) def requires_restart(self, app_config): diff --git a/util/security/signing.py b/util/security/signing.py index ccff00019..4e649e344 100644 --- a/util/security/signing.py +++ b/util/security/signing.py @@ -9,7 +9,7 @@ from StringIO import StringIO class GPG2Signer(object): """ Helper class for signing data using GPG2. """ - def __init__(self, config, key_directory): + def __init__(self, config, config_provider): if not config.get('GPG2_PRIVATE_KEY_NAME'): raise Exception('Missing configuration key GPG2_PRIVATE_KEY_NAME') @@ -22,22 +22,21 @@ class GPG2Signer(object): self._ctx = gpgme.Context() self._ctx.armor = True self._private_key_name = config['GPG2_PRIVATE_KEY_NAME'] - self._public_key_path = os.path.join(key_directory, config['GPG2_PUBLIC_KEY_FILENAME']) + self._public_key_filename = config['GPG2_PUBLIC_KEY_FILENAME'] + self._config_provider = config_provider - key_file = os.path.join(key_directory, config['GPG2_PRIVATE_KEY_FILENAME']) - if not os.path.exists(key_file): - raise Exception('Missing key file %s' % key_file) + if not config_provider.volume_file_exists(config['GPG2_PRIVATE_KEY_FILENAME']): + raise Exception('Missing key file %s' % config['GPG2_PRIVATE_KEY_FILENAME']) - with open(key_file, 'rb') as fp: + with config_provider.get_volume_file(config['GPG2_PRIVATE_KEY_FILENAME'], mode='rb') as fp: self._ctx.import_(fp) @property def name(self): return 'gpg2' - @property - def public_key_path(self): - return self._public_key_path + def open_public_key_file(self): + return self._config_provider.get_volume_file(self._public_key_filename, mode='rb') def detached_sign(self, stream): """ Signs the given stream, returning the signature. """ @@ -54,14 +53,14 @@ class GPG2Signer(object): class Signer(object): - def __init__(self, app=None, key_directory=None): + def __init__(self, app=None, config_provider=None): self.app = app if app is not None: - self.state = self.init_app(app, key_directory) + self.state = self.init_app(app, config_provider) else: self.state = None - def init_app(self, app, key_directory): + def init_app(self, app, config_provider): preference = app.config.get('SIGNING_ENGINE', None) if preference is None: return None