From 455fa1fb79ee25f4d5a77fd7c5ab362cbc1d942b Mon Sep 17 00:00:00 2001 From: Scott Hussey Date: Thu, 2 Nov 2017 12:55:41 -0500 Subject: [PATCH] NoAuth filter for PasteDeploy Implement a filter usable by PasteDeploy to forge the headers normally used by keystonemiddleware to signal a properly authenitcated request. The filter needs to be added to the pipeline in paste.ini if noauth support is needed for testing. - Add PasteDeploy config to disable keystone config loading Change-Id: Ie33ee86f1ca8209a6d96cf34c41acd7dca848d58 --- drydock_provisioner/drydock.py | 15 +++--- drydock_provisioner/util.py | 47 +++++++++++++++++++ .../{api-paste.ini => ks-api-paste.ini} | 0 etc/drydock/noauth-api-paste.ini | 10 ++++ tests/start_postgres.sh | 10 ++++ 5 files changed, 76 insertions(+), 6 deletions(-) rename etc/drydock/{api-paste.ini => ks-api-paste.ini} (100%) create mode 100644 etc/drydock/noauth-api-paste.ini create mode 100755 tests/start_postgres.sh diff --git a/drydock_provisioner/drydock.py b/drydock_provisioner/drydock.py index a05117ea..6f30b1cd 100644 --- a/drydock_provisioner/drydock.py +++ b/drydock_provisioner/drydock.py @@ -28,7 +28,7 @@ import drydock_provisioner.objects as objects import drydock_provisioner.control.api as api -def start_drydock(): +def start_drydock(enable_keystone=True): objects.register_all() # Setup configuration parsing @@ -38,7 +38,7 @@ def start_drydock(): ] config.config_mgr.conf.register_cli_opts(cli_options) - config.config_mgr.register_options() + config.config_mgr.register_options(enable_keystone=enable_keystone) config.config_mgr.conf(sys.argv[1:]) if config.config_mgr.conf.debug: @@ -110,9 +110,12 @@ def start_drydock(): # Initialization compatible with PasteDeploy -def paste_start_drydock(global_conf, **kwargs): - # At this time just ignore everything in the paste configuration and rely on oslo_config - return drydock +def paste_start_drydock(global_conf, disable=None): + enable_keystone = True + if disable is not None: + for d in disable.split(): + if d == 'keystone': + enable_keystone = False -drydock = start_drydock() + return start_drydock(enable_keystone=enable_keystone) diff --git a/drydock_provisioner/util.py b/drydock_provisioner/util.py index 101d9ddb..ad99036d 100644 --- a/drydock_provisioner/util.py +++ b/drydock_provisioner/util.py @@ -38,3 +38,50 @@ class KeystoneUtils(object): auth = v3.Password(**auth_info) return session.Session(auth=auth) + +class NoAuthFilter(object): + """PasteDeploy filter for NoAuth to be used in testing.""" + + def __init__(self, app, forged_roles): + self.app = app + self.forged_roles = forged_roles + + def __call__(self, environ, start_response): + """Forge headers to make unauthenticated requests look authenticated. + + If the request has a X-AUTH-TOKEN header, assume it is a valid request and + noop. Otherwise forge Keystone middleware headers so the request looks valid + with the configured forged roles. + """ + if 'HTTP_X_AUTH_TOKEN' in environ: + return self.app(environ, start_response) + + environ['HTTP_X_IDENTITY_STATUS'] = 'Confirmed' + + for envvar in ['USER_NAME', 'USER_ID', 'USER_DOMAIN_ID', 'PROJECT_ID', + 'PROJECT_DOMAIN_NAME']: + varname = "HTTP_X_%s" % envvar + environ[varname] = 'noauth' + + if self.forged_roles: + if 'admin' in self.forged_roles: + environ['HTTP_X_IS_ADMIN_PROJECT'] = 'True' + else: + environ['HTTP_X_IS_ADMIN_PROJECT'] = 'False' + environ['HTTP_X_ROLES'] = ','.join(self.forged_roles) + else: + environ['HTTP_X_IS_ADMIN_PROJECT'] = 'True' + environ['HTTP_X_ROLES'] = 'admin' + + return self.app(environ, start_response) + +def noauth_filter_factory(global_conf, forged_roles): + """Create a NoAuth paste deploy filter + + :param forged_roles: A space seperated list for roles to forge on requests + """ + forged_roles = forged_roles.split() + + def filter(app): + return NoAuthFilter(app, forged_roles) + return filter diff --git a/etc/drydock/api-paste.ini b/etc/drydock/ks-api-paste.ini similarity index 100% rename from etc/drydock/api-paste.ini rename to etc/drydock/ks-api-paste.ini diff --git a/etc/drydock/noauth-api-paste.ini b/etc/drydock/noauth-api-paste.ini new file mode 100644 index 00000000..521fed00 --- /dev/null +++ b/etc/drydock/noauth-api-paste.ini @@ -0,0 +1,10 @@ +[app:drydock-api] +disable = keystone +paste.app_factory = drydock_provisioner.drydock:paste_start_drydock + +[filter:noauth] +forged_roles = admin +paste.filter_factory = drydock_provisioner.util:noauth_filter_factory + +[pipeline:main] +pipeline = noauth drydock-api diff --git a/tests/start_postgres.sh b/tests/start_postgres.sh new file mode 100755 index 00000000..80eaaf8e --- /dev/null +++ b/tests/start_postgres.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +sudo docker run --rm -dp 5432:5432 --name 'psql_integration' postgres:9.5 +sleep 15 + +psql -h localhost -c "create user drydock with password 'drydock';" postgres postgres +psql -h localhost -c "create database drydock;" postgres postgres + +sudo docker run --rm -t --net=host -e DRYDOCK_DB_URL="postgresql+psycopg2://drydock:drydock@localhost:5432/drydock" --entrypoint /usr/local/bin/alembic drydock:latest upgrade head +export DRYDOCK_DB_URL="postgresql+psycopg2://drydock:drydock@localhost:5432/drydock"