diff -Nru python-keystonemiddleware-5.3.0/AUTHORS python-keystonemiddleware-6.0.0/AUTHORS --- python-keystonemiddleware-5.3.0/AUTHORS 2018-10-24 17:26:17.000000000 +0000 +++ python-keystonemiddleware-6.0.0/AUTHORS 2019-02-28 18:03:58.000000000 +0000 @@ -1,3 +1,4 @@ +Abhishek Sharma Adam Young Alan Pevec Alexander Makarov @@ -11,6 +12,7 @@ Andrey Pavlov Anh Tran Anthony Young +Artem Vasilyev Arun Kant Boris Bobrov Boris Bobrov @@ -33,7 +35,9 @@ Clark Boylan Clint Byrum Colleen Murphy +Colleen Murphy Colleen Murphy +Corey Bryant Cyril Roelandt D G Lee Dan Prince @@ -42,6 +46,7 @@ Davanum Srinivas Dave Chen David Höppner <0xffea@gmail.com> +David Olorundare David Stanek Dazhao Dean Troyer @@ -62,6 +67,7 @@ Gordon Chung Guang Yee Guang Yee +Guang Yee Hangdong Zhang Harry Rybacki Henry Nash @@ -93,6 +99,7 @@ Lance Bragstad Lance Bragstad Lauren Taylor +Leehom Li (feli5) Lei Zhang Liem Nguyen Lin Hua Cheng @@ -108,6 +115,7 @@ Mehdi Abaakouk Mehdi Abaakouk Michael J Fork +Michael Johnson Mitsuhiro SHIGEMATSU Monty Taylor Morgan Fainberg @@ -127,6 +135,7 @@ Rodrigo Duarte Sousa Roman Bodnarchuk Roxana Gherle +Rui Yuan Dou Samuel de Medeiros Queiroz Sean Perry Sean Winn @@ -151,14 +160,17 @@ Tristan Cacqueray Van Hung Pham Victor Stinner +Vieri <15050873171@163.com> Vishvananda Ishaya Wu Wenxiang Yaguang Tang +Yang Youseok Yatin Kumbhare Zhenguo Niu Zhi Yan Liu ZhiQiang Fan ZhiQiang Fan +ZhongShengping Zhongyue Luo Zhongyue Luo ankita_wagh diff -Nru python-keystonemiddleware-5.3.0/ChangeLog python-keystonemiddleware-6.0.0/ChangeLog --- python-keystonemiddleware-5.3.0/ChangeLog 2018-10-24 17:26:17.000000000 +0000 +++ python-keystonemiddleware-6.0.0/ChangeLog 2019-02-28 18:03:58.000000000 +0000 @@ -1,6 +1,24 @@ CHANGES ======= +6.0.0 +----- + +* Fix service\_token\_role\_required option +* add python 3.7 unit test job +* trivial: fix convention in release note +* Add auth invalidation in auth\_token for identity endpoint update +* Remove testr.conf as it's been replaced by stestr +* Make sure audit middleware use own context +* Trivial: Update pypi url to new url +* Change openstack-dev to openstack-discuss +* Added request\_id and global\_request\_id to CADF notifications +* Add py36 tox environment +* Documentation Fix - auth\_url Port Number +* Stop supporting revocation list +* Fix audit target service selection +* Skip the services with no endpoints when parsing service catalog + 5.3.0 ----- @@ -74,6 +92,7 @@ * Log TokenNotFound at INFO level instead of WARNING * rel-note and doc for lazy loading of oslo\_cache * lazy loading of oslo\_cache +* Expect paste.deploy and gnocchi/panko options 4.19.0 ------ diff -Nru python-keystonemiddleware-5.3.0/debian/changelog python-keystonemiddleware-6.0.0/debian/changelog --- python-keystonemiddleware-5.3.0/debian/changelog 2018-11-20 10:43:56.000000000 +0000 +++ python-keystonemiddleware-6.0.0/debian/changelog 2019-03-11 19:03:54.000000000 +0000 @@ -1,3 +1,9 @@ +python-keystonemiddleware (6.0.0-0ubuntu1) disco; urgency=medium + + * New upstream release for OpenStack Stein. + + -- Corey Bryant Mon, 11 Mar 2019 15:03:54 -0400 + python-keystonemiddleware (5.3.0-0ubuntu1) disco; urgency=medium * New upstream release for OpenStack Stein. diff -Nru python-keystonemiddleware-5.3.0/doc/source/middlewarearchitecture.rst python-keystonemiddleware-6.0.0/doc/source/middlewarearchitecture.rst --- python-keystonemiddleware-5.3.0/doc/source/middlewarearchitecture.rst 2018-10-24 17:22:09.000000000 +0000 +++ python-keystonemiddleware-6.0.0/doc/source/middlewarearchitecture.rst 2019-02-28 18:01:33.000000000 +0000 @@ -230,8 +230,8 @@ the requirements.txt file. .. _`memcached`: http://memcached.org/ -.. _`python-memcached`: https://pypi.python.org/pypi/python-memcached -.. _`pycrypto`: https://pypi.python.org/pypi/pycrypto +.. _`python-memcached`: https://pypi.org/project/python-memcached +.. _`pycrypto`: https://pypi.org/project/pycrypto Memcache Protection =================== diff -Nru python-keystonemiddleware-5.3.0/examples/pki/gen_cmsz.py python-keystonemiddleware-6.0.0/examples/pki/gen_cmsz.py --- python-keystonemiddleware-5.3.0/examples/pki/gen_cmsz.py 2018-10-24 17:22:09.000000000 +0000 +++ python-keystonemiddleware-6.0.0/examples/pki/gen_cmsz.py 2019-02-28 18:01:33.000000000 +0000 @@ -16,7 +16,6 @@ import os from keystoneclient.common import cms -from keystoneclient import utils CURRENT_DIR = os.path.abspath(os.path.dirname(__file__)) @@ -25,41 +24,6 @@ return os.path.join(CURRENT_DIR, *args) -def generate_revocation_list(): - REVOKED_TOKENS = ['auth_token_revoked', 'auth_v3_token_revoked'] - revoked_list = [] - for token in REVOKED_TOKENS: - with open(make_filename('cms', '%s.pkiz' % name), 'r') as f: - token_data = f.read() - id = utils.hash_signed_token(token_data.encode('utf-8')) - revoked_list.append({ - 'id': id, - "expires": "2112-08-14T17:58:48Z" - }) - with open(make_filename('cms', '%s.pem' % name), 'r') as f: - pem_data = f.read() - token_data = cms.cms_to_token(pem_data).encode('utf-8') - id = utils.hash_signed_token(token_data) - revoked_list.append({ - 'id': id, - "expires": "2112-08-14T17:58:48Z" - }) - revoked_json = json.dumps({"revoked": revoked_list}) - with open(make_filename('cms', 'revocation_list.json'), 'w') as f: - f.write(revoked_json) - encoded = cms.pkiz_sign(revoked_json, - SIGNING_CERT_FILE_NAME, - SIGNING_KEY_FILE_NAME) - with open(make_filename('cms', 'revocation_list.pkiz'), 'w') as f: - f.write(encoded) - - encoded = cms.cms_sign_data(revoked_json, - SIGNING_CERT_FILE_NAME, - SIGNING_KEY_FILE_NAME) - with open(make_filename('cms', 'revocation_list.pem'), 'w') as f: - f.write(encoded) - - CA_CERT_FILE_NAME = make_filename('certs', 'cacert.pem') SIGNING_CERT_FILE_NAME = make_filename('certs', 'signing_cert.pem') SIGNING_KEY_FILE_NAME = make_filename('private', 'signing_key.pem') @@ -113,5 +77,3 @@ with open(pkiz_file, 'w') as f: f.write(encoded) - - generate_revocation_list() diff -Nru python-keystonemiddleware-5.3.0/keystonemiddleware/audit/_api.py python-keystonemiddleware-6.0.0/keystonemiddleware/audit/_api.py --- python-keystonemiddleware-5.3.0/keystonemiddleware/audit/_api.py 2018-10-24 17:22:09.000000000 +0000 +++ python-keystonemiddleware-6.0.0/keystonemiddleware/audit/_api.py 2019-02-28 18:01:33.000000000 +0000 @@ -57,10 +57,15 @@ class ClientResource(resource.Resource): - def __init__(self, project_id=None, **kwargs): + def __init__(self, project_id=None, request_id=None, + global_request_id=None, **kwargs): super(ClientResource, self).__init__(**kwargs) if project_id is not None: self.project_id = project_id + if request_id is not None: + self.request_id = request_id + if global_request_id is not None: + self.global_request_id = global_request_id class KeystoneCredential(credential.Credential): @@ -261,14 +266,19 @@ default_endpoint = None for endp in catalog: + if not endp['endpoints']: + self._log.warning( + 'Skipping service %s as it have no endpoints.', + endp['name']) + continue endpoint_urls = endp['endpoints'][0] admin_urlparse = urlparse.urlparse( endpoint_urls.get('adminURL', '')) public_urlparse = urlparse.urlparse( endpoint_urls.get('publicURL', '')) req_url = urlparse.urlparse(req.host_url) - if (req_url.netloc == admin_urlparse.netloc - or req_url.netloc == public_urlparse.netloc): + if req_url.port and (req_url.netloc == admin_urlparse.netloc + or req_url.netloc == public_urlparse.netloc): service_info = self._get_service_info(endp) break elif (self._MAP.default_target_endpoint_type and @@ -292,7 +302,10 @@ token=req.environ.get('HTTP_X_AUTH_TOKEN', ''), identity_status=req.environ.get('HTTP_X_IDENTITY_STATUS', taxonomy.UNKNOWN)), - project_id=req.environ.get('HTTP_X_PROJECT_ID', taxonomy.UNKNOWN)) + project_id=req.environ.get('HTTP_X_PROJECT_ID', taxonomy.UNKNOWN), + request_id=req.environ.get('openstack.request_id'), + global_request_id=req.environ.get('openstack.global_request_id')) + target = self.get_target_resource(req) event = factory.EventFactory().new_event( diff -Nru python-keystonemiddleware-5.3.0/keystonemiddleware/audit/__init__.py python-keystonemiddleware-6.0.0/keystonemiddleware/audit/__init__.py --- python-keystonemiddleware-5.3.0/keystonemiddleware/audit/__init__.py 2018-10-24 17:22:09.000000000 +0000 +++ python-keystonemiddleware-6.0.0/keystonemiddleware/audit/__init__.py 2019-02-28 18:01:33.000000000 +0000 @@ -111,7 +111,7 @@ @_log_and_ignore_error def _process_request(self, request): - self._notifier.notify(request.context, + self._notifier.notify(request.environ['audit.context'], 'audit.http.request', self._create_event(request).as_dict()) @@ -139,7 +139,7 @@ reporter=resource.Resource(id='target'), reporterTime=timestamp.get_utc_now())) - self._notifier.notify(request.context, + self._notifier.notify(request.environ['audit.context'], 'audit.http.response', event.as_dict()) @@ -151,7 +151,8 @@ # Cannot use a RequestClass on wsgify above because the `req` object is # a `WebOb.Request` when this method is called so the RequestClass is # ignored by the wsgify wrapper. - req.context = oslo_context.get_admin_context().to_dict() + req.environ['audit.context'] = \ + oslo_context.get_admin_context().to_dict() self._process_request(req) try: diff -Nru python-keystonemiddleware-5.3.0/keystonemiddleware/auth_token/_identity.py python-keystonemiddleware-6.0.0/keystonemiddleware/auth_token/_identity.py --- python-keystonemiddleware-5.3.0/keystonemiddleware/auth_token/_identity.py 2018-10-24 17:22:09.000000000 +0000 +++ python-keystonemiddleware-6.0.0/keystonemiddleware/auth_token/_identity.py 2019-02-28 18:01:33.000000000 +0000 @@ -61,9 +61,6 @@ def _fetch_ca_cert(self): pass - def fetch_revocation_list(self): - pass - class _V2RequestStrategy(_RequestStrategy): @@ -89,9 +86,6 @@ def _fetch_ca_cert(self): return self._client.certificates.get_ca_certificate() - def fetch_revocation_list(self): - return self._client.tokens.get_revoked() - class _V3RequestStrategy(_RequestStrategy): @@ -119,9 +113,6 @@ def _fetch_ca_cert(self): return self._client.simple_cert.get_ca_certificates() - def fetch_revocation_list(self): - return self._client.tokens.get_revoked() - _REQUEST_STRATEGIES = [_V3RequestStrategy, _V2RequestStrategy] @@ -130,7 +121,7 @@ """Base class for operations on the Identity API server. The auth_token middleware needs to communicate with the Identity API server - to validate UUID tokens, fetch the revocation list, signing certificates, + to validate UUID tokens, signing certificates, etc. This class encapsulates the data and methods to perform these operations. @@ -243,19 +234,11 @@ else: return auth_ref - def fetch_revocation_list(self): - try: - data = self._request_strategy.fetch_revocation_list() - except ksa_exceptions.HttpError as e: - msg = _('Failed to fetch token revocation list: %d') - raise ksm_exceptions.RevocationListError(msg % e.http_status) - if 'signed' not in data: - msg = _('Revocation list improperly formatted.') - raise ksm_exceptions.RevocationListError(msg) - return data['signed'] - def fetch_signing_cert(self): return self._request_strategy.fetch_signing_cert() def fetch_ca_cert(self): return self._request_strategy.fetch_ca_cert() + + def invalidate(self): + return self._adapter.invalidate() diff -Nru python-keystonemiddleware-5.3.0/keystonemiddleware/auth_token/__init__.py python-keystonemiddleware-6.0.0/keystonemiddleware/auth_token/__init__.py --- python-keystonemiddleware-5.3.0/keystonemiddleware/auth_token/__init__.py 2018-10-24 17:22:09.000000000 +0000 +++ python-keystonemiddleware-6.0.0/keystonemiddleware/auth_token/__init__.py 2019-02-28 18:01:33.000000000 +0000 @@ -195,7 +195,7 @@ [keystone_authtoken] auth_plugin = password - auth_url = http://keystone:35357/ + auth_url = http://keystone:5000/ username = nova user_domain_id = default password = whyarewestillusingpasswords @@ -219,7 +219,6 @@ import binascii import copy -import datetime from keystoneauth1 import access from keystoneauth1 import adapter @@ -243,7 +242,6 @@ from keystonemiddleware.auth_token import _identity from keystonemiddleware.auth_token import _opts from keystonemiddleware.auth_token import _request -from keystonemiddleware.auth_token import _revocations from keystonemiddleware.auth_token import _signing_dir from keystonemiddleware.auth_token import _user_plugin from keystonemiddleware.i18n import _ @@ -376,9 +374,9 @@ check = self._service_token_roles.intersection(role_names) role_check_passed = bool(check) - # if service_token_role_required then the service token is only - # valid if the roles check out. Otherwise at this point it is - # true because keystone has already validated it. + # if service_token_roles_required then the service token is + # only valid if the roles check out. Otherwise at this point it + # is true because keystone has already validated it. if self._service_token_roles_required: request.service_token_valid = role_check_passed else: @@ -597,17 +595,6 @@ self._token_cache = self._token_cache_factory() - revocation_cache_timeout = datetime.timedelta( - seconds=self._conf.get('revocation_cache_time')) - self._revocations = _revocations.Revocations(revocation_cache_timeout, - self._signing_directory, - self._identity_server, - self._cms_verify, - self.log) - - self._check_revocations_for_cached = self._conf.get( - 'check_revocations_for_cached') - def process_request(self, request): """Process request. @@ -690,9 +677,6 @@ def _token_hashes(self, token): """Generate a list of hashes that the current token may be cached as. - With PKI tokens we have multiple hashing algorithms that we test with - revocations. This generates that whole list. - The first element of this list is the preferred algorithm and is what new cache values should be saved as. @@ -740,11 +724,6 @@ self.log.debug('Cached token is marked unauthorized') raise ksm_exceptions.InvalidToken() - if self._check_revocations_for_cached: - # A token might have been revoked, regardless of initial - # mechanism used to validate it, and needs to be checked. - self._revocations.check(token_hashes) - # NOTE(jamielennox): Cached values used to be stored as a tuple # of data and expiry time. They no longer are but we have to # allow some time to transition the old format so if it's a @@ -765,7 +744,6 @@ except (ksa_exceptions.ConnectFailure, ksa_exceptions.DiscoveryFailure, ksa_exceptions.RequestTimeout, - ksm_exceptions.RevocationListError, ksm_exceptions.ServiceError) as e: self.log.critical('Unable to validate token: %s', e) if self._delay_auth_decision: @@ -782,6 +760,10 @@ _CACHE_INVALID_INDICATOR) self.log.warning('Authorization failed for token') raise + except ksa_exceptions.EndpointNotFound: + # Invalidate auth in adapter for identity endpoint update + self._identity_server.invalidate() + raise return data @@ -797,14 +779,10 @@ return try: - self._revocations.check(token_hashes) verified = self._cms_verify(token_data, inform) except ksc_exceptions.CertificateConfigError: self.log.warning('Fetch certificate config failed, ' 'fallback to online validation.') - except ksm_exceptions.RevocationListError: - self.log.warning('Fetch revocation list failed, ' - 'fallback to online validation.') else: self.log.warning('auth_token middleware received a PKI/Z token. ' 'This form of token is deprecated and has been ' @@ -815,17 +793,6 @@ data = jsonutils.loads(verified) - audit_ids = None - if 'access' in data: - # It's a v2 token. - audit_ids = data['access']['token'].get('audit_ids') - else: - # It's a v3 token - audit_ids = data['token'].get('audit_ids') - - if audit_ids: - self._revocations.check_by_audit_id(audit_ids) - return data def _validate_token(self, auth_ref, **kwargs): @@ -1005,4 +972,3 @@ InvalidToken = ksm_exceptions.InvalidToken ServiceError = ksm_exceptions.ServiceError ConfigurationError = ksm_exceptions.ConfigurationError -RevocationListError = ksm_exceptions.RevocationListError diff -Nru python-keystonemiddleware-5.3.0/keystonemiddleware/auth_token/_opts.py python-keystonemiddleware-6.0.0/keystonemiddleware/auth_token/_opts.py --- python-keystonemiddleware-5.3.0/keystonemiddleware/auth_token/_opts.py 2018-10-24 17:22:09.000000000 +0000 +++ python-keystonemiddleware-6.0.0/keystonemiddleware/auth_token/_opts.py 2019-02-28 18:01:33.000000000 +0000 @@ -113,17 +113,6 @@ ' tokens, the middleware caches previously-seen tokens for a' ' configurable duration (in seconds). Set to -1 to disable' ' caching completely.'), - cfg.IntOpt('revocation_cache_time', - default=10, - deprecated_for_removal=True, - deprecated_reason='PKI token format is no longer supported.', - deprecated_since='Ocata', - help='Determines the frequency at which the list of revoked' - ' tokens is retrieved from the Identity service (in seconds). A' - ' high number of revocation events combined with a low cache' - ' duration may significantly reduce performance. Only valid' - ' for PKI tokens. This option has been deprecated in the Ocata' - ' release and will be removed in the P release.'), cfg.StrOpt('memcache_security_strategy', default='None', choices=('None', 'MAC', 'ENCRYPT'), @@ -179,13 +168,6 @@ ' unknown the token will be rejected. "required" any form of' ' token binding is needed to be allowed. Finally the name of a' ' binding method that must be present in tokens.'), - cfg.BoolOpt('check_revocations_for_cached', default=False, - deprecated_for_removal=True, - deprecated_reason='PKI token format is no longer supported.', - deprecated_since='Ocata', - help='If true, the revocation list will be checked for cached' - ' tokens. This requires that PKI tokens are configured on the' - ' identity server.'), cfg.ListOpt('hash_algorithms', default=['md5'], deprecated_for_removal=True, deprecated_reason='PKI token format is no longer supported.', diff -Nru python-keystonemiddleware-5.3.0/keystonemiddleware/auth_token/_revocations.py python-keystonemiddleware-6.0.0/keystonemiddleware/auth_token/_revocations.py --- python-keystonemiddleware-5.3.0/keystonemiddleware/auth_token/_revocations.py 2018-10-24 17:22:09.000000000 +0000 +++ python-keystonemiddleware-6.0.0/keystonemiddleware/auth_token/_revocations.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,128 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import datetime -import os - -from oslo_log import log as logging -from oslo_serialization import jsonutils -from oslo_utils import timeutils - -from keystonemiddleware.auth_token import _exceptions as exc -from keystonemiddleware.i18n import _ - -_LOG = logging.getLogger(__name__) - - -class Revocations(object): - _FILE_NAME = 'revoked.pem' - - def __init__(self, timeout, signing_directory, identity_server, - cms_verify, log=_LOG): - self._cache_timeout = timeout - self._signing_directory = signing_directory - self._identity_server = identity_server - self._cms_verify = cms_verify - self._log = log - - self._fetched_time_prop = None - self._list_prop = None - - @property - def _fetched_time(self): - if not self._fetched_time_prop: - # If the fetched list has been written to disk, use its - # modification time. - file_path = self._signing_directory.calc_path(self._FILE_NAME) - if os.path.exists(file_path): - mtime = os.path.getmtime(file_path) - fetched_time = datetime.datetime.utcfromtimestamp(mtime) - # Otherwise the list will need to be fetched. - else: - fetched_time = datetime.datetime.min - self._fetched_time_prop = fetched_time - return self._fetched_time_prop - - @_fetched_time.setter - def _fetched_time(self, value): - self._fetched_time_prop = value - - def _fetch(self): - revocation_list_data = self._identity_server.fetch_revocation_list() - return self._cms_verify(revocation_list_data) - - @property - def _list(self): - timeout = self._fetched_time + self._cache_timeout - list_is_current = timeutils.utcnow() < timeout - - if list_is_current: - # Load the list from disk if required - if not self._list_prop: - self._list_prop = jsonutils.loads( - self._signing_directory.read_file(self._FILE_NAME)) - else: - self._list = self._fetch() - return self._list_prop - - @_list.setter - def _list(self, value): - """Save a revocation list to memory and to disk. - - :param value: A json-encoded revocation list - - """ - self._list_prop = jsonutils.loads(value) - self._fetched_time = timeutils.utcnow() - self._signing_directory.write_file(self._FILE_NAME, value) - - def _is_revoked(self, token_id): - """Indicate whether the token_id appears in the revocation list.""" - revoked_tokens = self._list.get('revoked', None) - if not revoked_tokens: - return False - - revoked_ids = (x['id'] for x in revoked_tokens) - return token_id in revoked_ids - - def _any_revoked(self, token_ids): - for token_id in token_ids: - if self._is_revoked(token_id): - return True - return False - - def check(self, token_ids): - if self._any_revoked(token_ids): - self._log.debug('Token is marked as having been revoked') - raise exc.InvalidToken(_('Token has been revoked')) - - def check_by_audit_id(self, audit_ids): - """Check whether the audit_id appears in the revocation list. - - :raises keystonemiddleware.auth_token._exceptions.InvalidToken: - if the audit ID(s) appear in the revocation list. - - """ - revoked_tokens = self._list.get('revoked', None) - if not revoked_tokens: - # There's no revoked tokens, so nothing to do. - return - - # The audit_id may not be present in the revocation events because - # earlier versions of the identity server didn't provide them. - revoked_ids = set( - x['audit_id'] for x in revoked_tokens if 'audit_id' in x) - for audit_id in audit_ids: - if audit_id in revoked_ids: - self._log.debug( - 'Token is marked as having been revoked by audit id') - raise exc.InvalidToken(_('Token has been revoked')) diff -Nru python-keystonemiddleware-5.3.0/keystonemiddleware/_common/config.py python-keystonemiddleware-6.0.0/keystonemiddleware/_common/config.py --- python-keystonemiddleware-5.3.0/keystonemiddleware/_common/config.py 2018-10-24 17:22:09.000000000 +0000 +++ python-keystonemiddleware-6.0.0/keystonemiddleware/_common/config.py 2019-02-28 18:01:33.000000000 +0000 @@ -49,17 +49,18 @@ for k, v in conf.items(): dest = k try: - if v is not None: + # 'here' and '__file__' come from paste.deploy + # 'configkey' is added by panko and gnocchi + if v is not None and k not in ['here', '__file__', 'configkey']: type_, dest = opt_types[k] v = type_(v) except KeyError: # nosec - # This option is not known to auth_token. v is not converted. _LOG.warning( - 'The option "%s" in conf is not known to auth_token', k) + 'The option "%s" is not known to keystonemiddleware', k) except ValueError as e: raise exceptions.ConfigurationError( - _('Unable to convert the value of %(key)s option into correct ' - 'type: %(ex)s') % {'key': k, 'ex': e}) + _('Unable to convert the value of option "%(key)s" into ' + 'correct type: %(ex)s') % {'key': k, 'ex': e}) opts[dest] = v return opts diff -Nru python-keystonemiddleware-5.3.0/keystonemiddleware/tests/unit/audit/test_audit_api.py python-keystonemiddleware-6.0.0/keystonemiddleware/tests/unit/audit/test_audit_api.py --- python-keystonemiddleware-5.3.0/keystonemiddleware/tests/unit/audit/test_audit_api.py 2018-10-24 17:22:09.000000000 +0000 +++ python-keystonemiddleware-6.0.0/keystonemiddleware/tests/unit/audit/test_audit_api.py 2019-02-28 18:01:33.000000000 +0000 @@ -201,7 +201,7 @@ req = webob.Request.blank(url, environ=self.get_environ_header('GET'), remote_addr='192.168.0.1') - req.context = {} + req.environ['audit.context'] = {} middleware = self.create_simple_middleware() middleware._process_request(req) payload = req.environ['cadf_event'].as_dict() @@ -303,6 +303,61 @@ payload = self.get_payload('GET', url, environ=env_headers) self.assertEqual((payload['target']['addresses'][0]['url']), "unknown") + def test_service_with_no_endpoints(self): + env_headers = {'HTTP_X_SERVICE_CATALOG': + '''[{"endpoints_links": [], + "endpoints": [], + "type": "foo", + "name": "bar"}]''', + 'HTTP_X_USER_ID': 'user_id', + 'HTTP_X_USER_NAME': 'user_name', + 'HTTP_X_AUTH_TOKEN': 'token', + 'HTTP_X_PROJECT_ID': 'tenant_id', + 'HTTP_X_IDENTITY_STATUS': 'Confirmed', + 'REQUEST_METHOD': 'GET'} + + url = 'http://public_host:8774/v2/' + str(uuid.uuid4()) + '/servers' + payload = self.get_payload('GET', url, environ=env_headers) + self.assertEqual(payload['target']['name'], "unknown") + + def test_endpoint_no_service_port(self): + with open(self.audit_map, "w") as f: + f.write("[DEFAULT]\n") + f.write("target_endpoint_type = load-balancer\n") + f.write("[path_keywords]\n") + f.write("loadbalancers = loadbalancer\n\n") + f.write("[service_endpoints]\n") + f.write("load-balancer = service/load-balancer") + + env_headers = {'HTTP_X_SERVICE_CATALOG': + '''[{"endpoints_links": [], + "endpoints": [{"adminURL": + "http://admin_host/compute", + "region": "RegionOne", + "publicURL": + "http://public_host/compute"}], + "type": "compute", + "name": "nova"}, + {"endpoints_links": [], + "endpoints": [{"adminURL": + "http://admin_host/load-balancer", + "region": "RegionOne", + "publicURL": + "http://public_host/load-balancer"}], + "type": "load-balancer", + "name": "octavia"}]''', + 'HTTP_X_USER_ID': 'user_id', + 'HTTP_X_USER_NAME': 'user_name', + 'HTTP_X_AUTH_TOKEN': 'token', + 'HTTP_X_PROJECT_ID': 'tenant_id', + 'HTTP_X_IDENTITY_STATUS': 'Confirmed', + 'REQUEST_METHOD': 'GET'} + + url = ('http://admin_host/load-balancer/v2/loadbalancers/' + + str(uuid.uuid4())) + payload = self.get_payload('GET', url, environ=env_headers) + self.assertEqual(payload['target']['id'], 'octavia') + def test_no_auth_token(self): # Test cases where API requests such as Swift list public containers # which does not require an auth token. In these cases, CADF event @@ -340,3 +395,25 @@ self.assertNotIn('reporterchain', payload) self.assertEqual(payload['observer']['id'], 'target') self.assertEqual(path, payload['requestPath']) + + def test_request_and_global_request_id(self): + path = '/v1/' + str(uuid.uuid4()) + url = 'https://23.253.72.207' + path + + request_id = 'req-%s' % uuid.uuid4() + global_request_id = 'req-%s' % uuid.uuid4() + + env_headers = self.get_environ_header('GET') + env_headers['openstack.request_id'] = request_id + env_headers['openstack.global_request_id'] = global_request_id + + payload = self.get_payload('GET', url, environ=env_headers) + + self.assertEqual(payload['initiator']['request_id'], request_id) + self.assertEqual(payload['initiator']['global_request_id'], + global_request_id) + + payload = self.get_payload('GET', url) + + self.assertNotIn('request_id', payload['initiator']) + self.assertNotIn('global_request_id', payload['initiator']) diff -Nru python-keystonemiddleware-5.3.0/keystonemiddleware/tests/unit/audit/test_audit_middleware.py python-keystonemiddleware-6.0.0/keystonemiddleware/tests/unit/audit/test_audit_middleware.py --- python-keystonemiddleware-5.3.0/keystonemiddleware/tests/unit/audit/test_audit_middleware.py 2018-10-24 17:22:09.000000000 +0000 +++ python-keystonemiddleware-6.0.0/keystonemiddleware/tests/unit/audit/test_audit_middleware.py 2019-02-28 18:01:33.000000000 +0000 @@ -84,7 +84,7 @@ def test_process_request_fail(self): req = webob.Request.blank('/foo/bar', environ=self.get_environ_header('GET')) - req.context = {} + req.environ['audit.context'] = {} self.create_simple_middleware()._process_request(req) self.assertTrue(self.notifier.notify.called) @@ -92,7 +92,7 @@ def test_process_response_fail(self): req = webob.Request.blank('/foo/bar', environ=self.get_environ_header('GET')) - req.context = {} + req.environ['audit.context'] = {} middleware = self.create_simple_middleware() middleware._process_response(req, webob.response.Response()) @@ -147,7 +147,7 @@ req = webob.Request.blank('/foo/bar', environ=self.get_environ_header('GET')) - req.context = {} + req.environ['audit.context'] = {} self.notifier.notify.side_effect = Exception('error') middleware(req) @@ -155,7 +155,7 @@ req2 = webob.Request.blank('/foo/bar', environ=self.get_environ_header('GET')) - req2.context = {} + req2.environ['audit.context'] = {} self.notifier.reset_mock() middleware._process_response(req2, webob.response.Response()) @@ -179,7 +179,7 @@ req = webob.Request.blank(url, environ=self.get_environ_header('GET'), remote_addr='192.168.0.1') - req.context = {} + req.environ['audit.context'] = {} middleware._process_request(req) payload = req.environ['cadf_event'].as_dict() middleware._process_response(req, None) @@ -197,7 +197,7 @@ req = webob.Request.blank('http://admin_host:8774/v2/' + str(uuid.uuid4()) + '/servers', environ=self.get_environ_header('GET')) - req.context = {} + req.environ['audit.context'] = {} self.assertNotIn('cadf_event', req.environ) self.create_simple_middleware()._process_response(req, diff -Nru python-keystonemiddleware-5.3.0/keystonemiddleware/tests/unit/auth_token/test_auth_token_middleware.py python-keystonemiddleware-6.0.0/keystonemiddleware/tests/unit/auth_token/test_auth_token_middleware.py --- python-keystonemiddleware-5.3.0/keystonemiddleware/tests/unit/auth_token/test_auth_token_middleware.py 2018-10-24 17:22:09.000000000 +0000 +++ python-keystonemiddleware-6.0.0/keystonemiddleware/tests/unit/auth_token/test_auth_token_middleware.py 2019-02-28 18:01:33.000000000 +0000 @@ -35,7 +35,6 @@ import pbr.version import six import testresources -import testtools from testtools import matchers import webob import webob.dec @@ -44,7 +43,6 @@ from keystonemiddleware.auth_token import _base from keystonemiddleware.auth_token import _cache from keystonemiddleware.auth_token import _exceptions as ksm_exceptions -from keystonemiddleware.auth_token import _revocations from keystonemiddleware.tests.unit.auth_token import base from keystonemiddleware.tests.unit import client_fixtures @@ -99,13 +97,7 @@ ERROR_TOKEN = '7ae290c2a06244c4b41692eb4e9225f2' TIMEOUT_TOKEN = '4ed1c5e53beee59458adcf8261a8cae2' - - -def cleanup_revoked_file(filename): - try: - os.remove(filename) - except OSError: - pass +ENDPOINT_NOT_FOUND_TOKEN = 'edf9fa62-5afd-4d64-89ac-f99b209bd995' def strtime(at=None): @@ -337,9 +329,6 @@ self.middleware = auth_token.AuthProtocol( self.fake_app(self.expected_env), self.conf) - self.middleware._revocations._list = jsonutils.dumps( - {"revoked": [], "extra": "success"}) - def update_expected_env(self, expected_env={}): self.middleware._app.expected_env.update(expected_env) @@ -476,27 +465,14 @@ self.assertThat(hashed_short_string_key, matchers.HasLength(len(hashed_long_string_key))) - def test_config_revocation_cache_timeout(self): - conf = { - 'revocation_cache_time': '24', - 'www_authenticate_uri': 'https://keystone.example.com:1234', - 'admin_user': uuid.uuid4().hex - } - middleware = auth_token.AuthProtocol(self.fake_app, conf) - self.assertEqual(middleware._revocations._cache_timeout, - datetime.timedelta(seconds=24)) - def test_conf_values_type_convert(self): conf = { - 'revocation_cache_time': '24', 'identity_uri': 'https://keystone.example.com:1234', 'include_service_catalog': '0', 'nonexsit_option': '0', } middleware = auth_token.AuthProtocol(self.fake_app, conf) - self.assertEqual(datetime.timedelta(seconds=24), - middleware._revocations._cache_timeout) self.assertFalse(middleware._include_service_catalog) self.assertEqual('0', middleware._conf.get('nonexsit_option')) @@ -514,7 +490,7 @@ conf = { 'wrong_key': '123' } - log = 'The option "wrong_key" in conf is not known to auth_token' + log = 'The option "wrong_key" is not known to keystonemiddleware' auth_token.AuthProtocol(self.fake_app, conf) self.assertThat(self.logger.output, matchers.Contains(log)) @@ -643,42 +619,6 @@ self.assert_valid_request_200(self.token_dict['uuid_token_default']) self.assert_valid_last_url(self.token_dict['uuid_token_default']) - def _test_cache_revoked(self, token, revoked_form=None): - # When the token is cached and revoked, 401 is returned. - self.middleware._check_revocations_for_cached = True - - # Token should be cached as ok after this. - self.call_middleware(headers={'X-Auth-Token': token}) - - # Put it in revocation list. - self.middleware._revocations._list = self.get_revocation_list_json( - token_ids=[revoked_form or token]) - - self.call_middleware(headers={'X-Auth-Token': token}, - expected_status=401) - - def test_cached_revoked_error(self): - # When the token is cached and revocation list retrieval fails, - # 503 is returned - token = self.token_dict['uuid_token_default'] - self.middleware._check_revocations_for_cached = True - - # Token should be cached as ok after this. - resp = self.call_middleware(headers={'X-Auth-Token': token}) - self.assertEqual(200, resp.status_int) - - # Cause the revocation list to be fetched again next time so we can - # test the case where that retrieval fails - self.middleware._revocations._fetched_time = datetime.datetime.min - with mock.patch.object(self.middleware._revocations, '_fetch', - side_effect=ksm_exceptions.RevocationListError): - self.call_middleware(headers={'X-Auth-Token': token}, - expected_status=503) - - def test_cached_revoked_uuid(self): - # When the UUID token is cached and revoked, 401 is returned. - self._test_cache_revoked(self.token_dict['uuid_token_default']) - def test_valid_signed_request(self): for _ in range(2): # Do it twice because first result was cached. self.assert_valid_request_200( @@ -692,176 +632,13 @@ # ensure that signed requests do not generate HTTP traffic self.assertLastPath(None) - def test_revoked_token_receives_401(self): - self.middleware._revocations._list = ( - self.get_revocation_list_json()) - - token = self.token_dict['revoked_token'] - self.call_middleware(headers={'X-Auth-Token': token}, - expected_status=401) - - def test_revoked_token_receives_401_sha256(self): - self.conf['hash_algorithms'] = ','.join(['sha256', 'md5']) - self.set_middleware() - self.middleware._revocations._list = ( - self.get_revocation_list_json(mode='sha256')) - - token = self.token_dict['revoked_token'] - self.call_middleware(headers={'X-Auth-Token': token}, - expected_status=401) - - def test_cached_revoked_pki(self): - # When the PKI token is cached and revoked, 401 is returned. - token = self.token_dict['signed_token_scoped'] - revoked_form = cms.cms_hash_token(token) - self._test_cache_revoked(token, revoked_form) - - def test_cached_revoked_pkiz(self): - # When the PKIZ token is cached and revoked, 401 is returned. - token = self.token_dict['signed_token_scoped_pkiz'] - revoked_form = cms.cms_hash_token(token) - self._test_cache_revoked(token, revoked_form) - - def test_revoked_token_receives_401_md5_secondary(self): - # When hash_algorithms has 'md5' as the secondary hash and the - # revocation list contains the md5 hash for a token, that token is - # considered revoked so returns 401. - self.conf['hash_algorithms'] = ','.join(['sha256', 'md5']) - self.set_middleware() - self.middleware._revocations._list = ( - self.get_revocation_list_json()) - - token = self.token_dict['revoked_token'] - self.call_middleware(headers={'X-Auth-Token': token}, - expected_status=401) - - def _test_revoked_hashed_token(self, token_name): - # If hash_algorithms is set as ['sha256', 'md5'], - # and check_revocations_for_cached is True, - # and a token is in the cache because it was successfully validated - # using the md5 hash, then - # if the token is in the revocation list by md5 hash, it'll be - # rejected and auth_token returns 401. - self.conf['hash_algorithms'] = ','.join(['sha256', 'md5']) - self.conf['check_revocations_for_cached'] = 'true' - self.set_middleware() - - token = self.token_dict[token_name] - - # Put the token in the revocation list. - token_hashed = cms.cms_hash_token(token) - self.middleware._revocations._list = self.get_revocation_list_json( - token_ids=[token_hashed]) - - # First, request is using the hashed token, is valid so goes in - # cache using the given hash. - self.call_middleware(headers={'X-Auth-Token': token_hashed}) - - # This time use the PKI(Z) token - # Should find the token in the cache and revocation list. - self.call_middleware(headers={'X-Auth-Token': token}, - expected_status=401) - - def test_revoked_hashed_pki_token(self): - self._test_revoked_hashed_token('signed_token_scoped') - - def test_revoked_hashed_pkiz_token(self): - self._test_revoked_hashed_token('signed_token_scoped_pkiz') - - def test_revoked_pki_token_by_audit_id(self): - # When the audit ID is in the revocation list, the token is invalid. - self.set_middleware() - token = self.token_dict['signed_token_scoped'] - - # Put the token audit ID in the revocation list, - # the entry will have a false token ID so the token ID doesn't match. - fake_token_id = uuid.uuid4().hex - # The audit_id value is in examples/pki/cms/auth_*_token_scoped.json. - audit_id = 'SLIXlXQUQZWUi9VJrqdXqA' - revocation_list_data = { - 'revoked': [ - { - 'id': fake_token_id, - 'audit_id': audit_id - }, - ] - } - self.middleware._revocations._list = jsonutils.dumps( - revocation_list_data) - - self.call_middleware(headers={'X-Auth-Token': token}, - expected_status=401) - - def get_revocation_list_json(self, token_ids=None, mode=None): - if token_ids is None: - key = 'revoked_token_hash' + (('_' + mode) if mode else '') - token_ids = [self.token_dict[key]] - revocation_list = {'revoked': [{'id': x, 'expires': timeutils.utcnow()} - for x in token_ids]} - return jsonutils.dumps(revocation_list) - - def test_is_signed_token_revoked_returns_false(self): - # explicitly setting an empty revocation list here to document intent - self.middleware._revocations._list = jsonutils.dumps( - {"revoked": [], "extra": "success"}) - result = self.middleware._revocations._any_revoked( - [self.token_dict['revoked_token_hash']]) - self.assertFalse(result) - - def test_is_signed_token_revoked_returns_true(self): - self.middleware._revocations._list = ( - self.get_revocation_list_json()) - result = self.middleware._revocations._any_revoked( - [self.token_dict['revoked_token_hash']]) - self.assertTrue(result) - - def test_is_signed_token_revoked_returns_true_sha256(self): - self.conf['hash_algorithms'] = ','.join(['sha256', 'md5']) - self.set_middleware() - self.middleware._revocations._list = ( - self.get_revocation_list_json(mode='sha256')) - result = self.middleware._revocations._any_revoked( - [self.token_dict['revoked_token_hash_sha256']]) - self.assertTrue(result) - - def test_validate_offline_raises_exception_for_revoked_token(self): - self.middleware._revocations._list = ( - self.get_revocation_list_json()) - self.assertRaises(ksm_exceptions.InvalidToken, - self.middleware._validate_offline, - self.token_dict['revoked_token'], - [self.token_dict['revoked_token_hash']]) - - def test_validate_offline_raises_exception_for_revoked_token_s256(self): - self.conf['hash_algorithms'] = ','.join(['sha256', 'md5']) - self.set_middleware() - self.middleware._revocations._list = ( - self.get_revocation_list_json(mode='sha256')) - self.assertRaises(ksm_exceptions.InvalidToken, - self.middleware._validate_offline, - self.token_dict['revoked_token'], - [self.token_dict['revoked_token_hash_sha256'], - self.token_dict['revoked_token_hash']]) - - def test_validate_offline_raises_exception_for_revoked_pkiz_token(self): - self.middleware._revocations._list = ( - self.examples.REVOKED_TOKEN_PKIZ_LIST_JSON) - self.assertRaises(ksm_exceptions.InvalidToken, - self.middleware._validate_offline, - self.token_dict['revoked_token_pkiz'], - [self.token_dict['revoked_token_pkiz_hash']]) - def test_validate_offline_succeeds_for_unrevoked_token(self): - self.middleware._revocations._list = ( - self.get_revocation_list_json()) token = self.middleware._validate_offline( self.token_dict['signed_token_scoped'], [self.token_dict['signed_token_scoped_hash']]) self.assertIsInstance(token, dict) def test_verify_signed_compressed_token_succeeds_for_unrevoked_token(self): - self.middleware._revocations._list = ( - self.get_revocation_list_json()) token = self.middleware._validate_offline( self.token_dict['signed_token_scoped_pkiz'], [self.token_dict['signed_token_scoped_hash']]) @@ -870,84 +647,12 @@ def test_validate_offline_token_succeeds_for_unrevoked_token_sha256(self): self.conf['hash_algorithms'] = ','.join(['sha256', 'md5']) self.set_middleware() - self.middleware._revocations._list = ( - self.get_revocation_list_json(mode='sha256')) token = self.middleware._validate_offline( self.token_dict['signed_token_scoped'], [self.token_dict['signed_token_scoped_hash_sha256'], self.token_dict['signed_token_scoped_hash']]) self.assertIsInstance(token, dict) - def test_get_token_revocation_list_fetched_time_returns_min(self): - self.middleware._revocations._fetched_time = None - - # Get rid of the revoked file - revoked_path = self.middleware._signing_directory.calc_path( - _revocations.Revocations._FILE_NAME) - os.remove(revoked_path) - - self.assertEqual(self.middleware._revocations._fetched_time, - datetime.datetime.min) - - # FIXME(blk-u): move the unit tests into unit/test_auth_token.py - def test_get_token_revocation_list_fetched_time_returns_mtime(self): - self.middleware._revocations._fetched_time = None - revoked_path = self.middleware._signing_directory.calc_path( - _revocations.Revocations._FILE_NAME) - mtime = os.path.getmtime(revoked_path) - fetched_time = datetime.datetime.utcfromtimestamp(mtime) - self.assertEqual(fetched_time, - self.middleware._revocations._fetched_time) - - @testtools.skipUnless(TimezoneFixture.supported(), - 'TimezoneFixture not supported') - def test_get_token_revocation_list_fetched_time_returns_utc(self): - with TimezoneFixture('UTC-1'): - self.middleware._revocations._list = jsonutils.dumps( - self.examples.REVOCATION_LIST) - self.middleware._revocations._fetched_time = None - fetched_time = self.middleware._revocations._fetched_time - self.assertTrue(timeutils.is_soon(fetched_time, 1)) - - def test_get_token_revocation_list_fetched_time_returns_value(self): - expected = self.middleware._revocations._fetched_time - self.assertEqual(self.middleware._revocations._fetched_time, - expected) - - def test_get_revocation_list_returns_fetched_list(self): - # auth_token uses v2 to fetch this, so don't allow the v3 - # tests to override the fake http connection - self.middleware._revocations._fetched_time = None - - # Get rid of the revoked file - revoked_path = self.middleware._signing_directory.calc_path( - _revocations.Revocations._FILE_NAME) - os.remove(revoked_path) - - self.assertEqual(self.middleware._revocations._list, - self.examples.REVOCATION_LIST) - - def test_get_revocation_list_returns_current_list_from_memory(self): - self.assertEqual(self.middleware._revocations._list, - self.middleware._revocations._list_prop) - - def test_get_revocation_list_returns_current_list_from_disk(self): - in_memory_list = self.middleware._revocations._list - self.middleware._revocations._list_prop = None - self.assertEqual(self.middleware._revocations._list, - in_memory_list) - - def test_invalid_revocation_list_raises_error(self): - self.requests_mock.get(self.revocation_url, json={}) - self.assertRaises(ksm_exceptions.RevocationListError, - self.middleware._revocations._fetch) - - def test_fetch_revocation_list(self): - # auth_token uses v2 to fetch this, so don't allow the v3 - # tests to override the fake http connection - fetched = jsonutils.loads(self.middleware._revocations._fetch()) - self.assertEqual(fetched, self.examples.REVOCATION_LIST) - def test_request_invalid_uuid_token(self): # remember because we are testing the middleware we stub the connection # to the keystone server, but this is not what gets returned @@ -1604,13 +1309,6 @@ self.examples.SIGNED_TOKEN_SCOPED_HASH_SHA256, 'signed_token_scoped_expired': self.examples.SIGNED_TOKEN_SCOPED_EXPIRED, - 'revoked_token': self.examples.REVOKED_TOKEN, - 'revoked_token_pkiz': self.examples.REVOKED_TOKEN_PKIZ, - 'revoked_token_pkiz_hash': - self.examples.REVOKED_TOKEN_PKIZ_HASH, - 'revoked_token_hash': self.examples.REVOKED_TOKEN_HASH, - 'revoked_token_hash_sha256': - self.examples.REVOKED_TOKEN_HASH_SHA256, 'uuid_service_token_default': self.examples.UUID_SERVICE_TOKEN_DEFAULT, } @@ -1622,10 +1320,6 @@ self.requests_mock.post('%s/v2.0/tokens' % BASE_URI, text=FAKE_ADMIN_TOKEN) - self.revocation_url = '%s/v2.0/tokens/revoked' % BASE_URI - self.requests_mock.get(self.revocation_url, - text=self.examples.SIGNED_REVOCATION_LIST) - for token in (self.examples.UUID_TOKEN_DEFAULT, self.examples.UUID_TOKEN_UNSCOPED, self.examples.UUID_TOKEN_BIND, @@ -1812,13 +1506,6 @@ self.examples.SIGNED_v3_TOKEN_SCOPED_HASH_SHA256, 'signed_token_scoped_expired': self.examples.SIGNED_TOKEN_SCOPED_EXPIRED, - 'revoked_token': self.examples.REVOKED_v3_TOKEN, - 'revoked_token_pkiz': self.examples.REVOKED_v3_TOKEN_PKIZ, - 'revoked_token_hash': self.examples.REVOKED_v3_TOKEN_HASH, - 'revoked_token_hash_sha256': - self.examples.REVOKED_v3_TOKEN_HASH_SHA256, - 'revoked_token_pkiz_hash': - self.examples.REVOKED_v3_PKIZ_TOKEN_HASH, 'uuid_service_token_default': self.examples.v3_UUID_SERVICE_TOKEN_DEFAULT, } @@ -1832,10 +1519,6 @@ self.requests_mock.post('%s/v2.0/tokens' % BASE_URI, text=FAKE_ADMIN_TOKEN) - self.revocation_url = '%s/v3/auth/tokens/OS-PKI/revoked' % BASE_URI - self.requests_mock.get(self.revocation_url, - text=self.examples.SIGNED_REVOCATION_LIST) - self.requests_mock.get('%s/v3/auth/tokens' % BASE_URI, text=self.token_response, headers={'X-Subject-Token': uuid.uuid4().hex}) @@ -1852,6 +1535,8 @@ raise ksa_exceptions.ConnectFailure(msg) elif token_id == TIMEOUT_TOKEN: request_timeout_response(request, context) + elif token_id == ENDPOINT_NOT_FOUND_TOKEN: + raise ksa_exceptions.EndpointNotFound() try: response = self.examples.JSON_TOKEN_RESPONSES[token_id] @@ -1944,7 +1629,6 @@ self.token_dict['signed_token_scoped_pkiz']) def test_fallback_to_online_validation_with_revocation_list_error(self): - self.requests_mock.get(self.revocation_url, status_code=404) self.assert_valid_request_200(self.token_dict['signed_token_scoped']) self.assert_valid_request_200( self.token_dict['signed_token_scoped_pkiz']) @@ -2005,6 +1689,16 @@ new_data = self.middleware.fetch_token(token) self.assertEqual(data, new_data) + def test_endpoint_not_found_in_token(self): + token = ENDPOINT_NOT_FOUND_TOKEN + self.set_middleware() + self.middleware._token_cache.initialize({}) + with mock.patch.object(self.middleware._identity_server, 'invalidate', + new=mock.Mock()): + self.assertRaises(ksa_exceptions.EndpointNotFound, + self.middleware.fetch_token, token) + self.assertTrue(self.middleware._identity_server.invalidate.called) + def test_not_is_admin_project(self): token = self.examples.v3_NOT_IS_ADMIN_PROJECT self.set_middleware(expected_env={'HTTP_X_IS_ADMIN_PROJECT': 'False'}) @@ -2398,10 +2092,6 @@ self.requests_mock.post('%s/v2.0/tokens' % BASE_URI, text=FAKE_ADMIN_TOKEN) - self.requests_mock.get('%s/v2.0/tokens/revoked' % BASE_URI, - text=self.examples.SIGNED_REVOCATION_LIST, - status_code=200) - for token in (self.examples.UUID_TOKEN_DEFAULT, self.examples.UUID_SERVICE_TOKEN_DEFAULT, self.examples.UUID_TOKEN_BIND, @@ -2455,9 +2145,6 @@ self.requests_mock.post('%s/v2.0/tokens' % BASE_URI, text=FAKE_ADMIN_TOKEN) - self.requests_mock.get('%s/v3/auth/tokens/OS-PKI/revoked' % BASE_URI, - text=self.examples.SIGNED_REVOCATION_LIST) - self.requests_mock.get('%s/v3/auth/tokens' % BASE_URI, text=self.token_response, headers={'X-Subject-Token': uuid.uuid4().hex}) diff -Nru python-keystonemiddleware-5.3.0/keystonemiddleware/tests/unit/auth_token/test_revocations.py python-keystonemiddleware-6.0.0/keystonemiddleware/tests/unit/auth_token/test_revocations.py --- python-keystonemiddleware-5.3.0/keystonemiddleware/tests/unit/auth_token/test_revocations.py 2018-10-24 17:22:09.000000000 +0000 +++ python-keystonemiddleware-6.0.0/keystonemiddleware/tests/unit/auth_token/test_revocations.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,104 +0,0 @@ -# Copyright 2014 IBM Corp. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import datetime -import json -import shutil -import uuid - -import mock - -from keystonemiddleware.auth_token import _exceptions as exc -from keystonemiddleware.auth_token import _revocations -from keystonemiddleware.auth_token import _signing_dir -from keystonemiddleware.tests.unit import utils - - -class RevocationsTests(utils.BaseTestCase): - - def _setup_revocations(self, revoked_list): - directory_name = '/tmp/%s' % uuid.uuid4().hex - signing_directory = _signing_dir.SigningDirectory(directory_name) - self.addCleanup(shutil.rmtree, directory_name) - - identity_server = mock.Mock() - - verify_result_obj = {'revoked': revoked_list} - cms_verify = mock.Mock(return_value=json.dumps(verify_result_obj)) - - revocations = _revocations.Revocations( - timeout=datetime.timedelta(1), signing_directory=signing_directory, - identity_server=identity_server, cms_verify=cms_verify) - return revocations - - def _check_with_list(self, revoked_list, token_ids): - revoked_list = list({'id': r} for r in revoked_list) - revocations = self._setup_revocations(revoked_list) - revocations.check(token_ids) - - def test_check_empty_list(self): - # When the identity server returns an empty list, a token isn't - # revoked. - - revoked_tokens = [] - token_ids = [uuid.uuid4().hex] - # No assert because this would raise - self._check_with_list(revoked_tokens, token_ids) - - def test_check_revoked(self): - # When the identity server returns a list with a token in it, that - # token is revoked. - - token_id = uuid.uuid4().hex - revoked_tokens = [token_id] - token_ids = [token_id] - self.assertRaises(exc.InvalidToken, - self._check_with_list, revoked_tokens, token_ids) - - def test_check_by_audit_id_revoked(self): - # When the audit ID is in the revocation list, InvalidToken is raised. - audit_id = uuid.uuid4().hex - revoked_list = [{'id': uuid.uuid4().hex, 'audit_id': audit_id}] - revocations = self._setup_revocations(revoked_list) - self.assertRaises(exc.InvalidToken, - revocations.check_by_audit_id, [audit_id]) - - def test_check_by_audit_id_chain_revoked(self): - # When the token's audit chain ID is in the revocation list, - # InvalidToken is raised. - revoked_audit_id = uuid.uuid4().hex - revoked_list = [{'id': uuid.uuid4().hex, 'audit_id': revoked_audit_id}] - revocations = self._setup_revocations(revoked_list) - - token_audit_ids = [uuid.uuid4().hex, revoked_audit_id] - self.assertRaises(exc.InvalidToken, - revocations.check_by_audit_id, token_audit_ids) - - def test_check_by_audit_id_not_revoked(self): - # When the audit ID is not in the revocation list no exception. - revoked_list = [{'id': uuid.uuid4().hex, 'audit_id': uuid.uuid4().hex}] - revocations = self._setup_revocations(revoked_list) - - audit_id = uuid.uuid4().hex - revocations.check_by_audit_id([audit_id]) - - def test_check_by_audit_id_no_audit_ids(self): - # Older identity servers don't send audit_ids in the revocation list. - # When this happens, check_by_audit_id still works, just doesn't - # verify anything. - revoked_list = [{'id': uuid.uuid4().hex}] - revocations = self._setup_revocations(revoked_list) - - audit_id = uuid.uuid4().hex - revocations.check_by_audit_id([audit_id]) diff -Nru python-keystonemiddleware-5.3.0/keystonemiddleware/tests/unit/client_fixtures.py python-keystonemiddleware-6.0.0/keystonemiddleware/tests/unit/client_fixtures.py --- python-keystonemiddleware-5.3.0/keystonemiddleware/tests/unit/client_fixtures.py 2018-10-24 17:22:09.000000000 +0000 +++ python-keystonemiddleware-6.0.0/keystonemiddleware/tests/unit/client_fixtures.py 2019-02-28 18:01:33.000000000 +0000 @@ -20,7 +20,6 @@ from keystoneclient.common import cms from keystoneclient import utils from oslo_serialization import jsonutils -from oslo_utils import timeutils import six import testresources @@ -77,29 +76,17 @@ self.SIGNED_v3_TOKEN_SCOPED) self.SIGNED_v3_TOKEN_SCOPED_HASH_SHA256 = _hash_signed_token_safe( self.SIGNED_v3_TOKEN_SCOPED, mode='sha256') - with open(os.path.join(CMSDIR, 'auth_token_revoked.pem')) as f: - self.REVOKED_TOKEN = cms.cms_to_token(f.read()) with open(os.path.join(CMSDIR, 'auth_token_scoped_expired.pem')) as f: self.SIGNED_TOKEN_SCOPED_EXPIRED = cms.cms_to_token(f.read()) - with open(os.path.join(CMSDIR, 'auth_v3_token_revoked.pem')) as f: - self.REVOKED_v3_TOKEN = cms.cms_to_token(f.read()) with open(os.path.join(CMSDIR, 'auth_token_scoped.pkiz')) as f: self.SIGNED_TOKEN_SCOPED_PKIZ = cms.cms_to_token(f.read()) with open(os.path.join(CMSDIR, 'auth_token_unscoped.pkiz')) as f: self.SIGNED_TOKEN_UNSCOPED_PKIZ = cms.cms_to_token(f.read()) with open(os.path.join(CMSDIR, 'auth_v3_token_scoped.pkiz')) as f: self.SIGNED_v3_TOKEN_SCOPED_PKIZ = cms.cms_to_token(f.read()) - with open(os.path.join(CMSDIR, 'auth_token_revoked.pkiz')) as f: - self.REVOKED_TOKEN_PKIZ = cms.cms_to_token(f.read()) with open(os.path.join(CMSDIR, 'auth_token_scoped_expired.pkiz')) as f: self.SIGNED_TOKEN_SCOPED_EXPIRED_PKIZ = cms.cms_to_token(f.read()) - with open(os.path.join(CMSDIR, 'auth_v3_token_revoked.pkiz')) as f: - self.REVOKED_v3_TOKEN_PKIZ = cms.cms_to_token(f.read()) - with open(os.path.join(CMSDIR, 'revocation_list.json')) as f: - self.REVOCATION_LIST = jsonutils.loads(f.read()) - with open(os.path.join(CMSDIR, 'revocation_list.pem')) as f: - self.SIGNED_REVOCATION_LIST = jsonutils.dumps({'signed': f.read()}) self.SIGNING_CERT_FILE = os.path.join(CERTDIR, 'signing_cert.pem') with open(self.SIGNING_CERT_FILE) as f: @@ -134,50 +121,6 @@ self.v3_UUID_SERVICE_TOKEN_DEFAULT = 'g431071bbc2f492748596c1b53cb229' self.v3_UUID_SERVICE_TOKEN_BIND = 'be705e4426d0449a89e35ae21c380a05' self.v3_NOT_IS_ADMIN_PROJECT = uuid.uuid4().hex - - revoked_token = self.REVOKED_TOKEN - if isinstance(revoked_token, six.text_type): - revoked_token = revoked_token.encode('utf-8') - self.REVOKED_TOKEN_HASH = utils.hash_signed_token(revoked_token) - self.REVOKED_TOKEN_HASH_SHA256 = utils.hash_signed_token(revoked_token, - mode='sha256') - self.REVOKED_TOKEN_LIST = ( - {'revoked': [{'id': self.REVOKED_TOKEN_HASH, - 'expires': timeutils.utcnow()}]}) - self.REVOKED_TOKEN_LIST_JSON = jsonutils.dumps(self.REVOKED_TOKEN_LIST) - - revoked_v3_token = self.REVOKED_v3_TOKEN - if isinstance(revoked_v3_token, six.text_type): - revoked_v3_token = revoked_v3_token.encode('utf-8') - self.REVOKED_v3_TOKEN_HASH = utils.hash_signed_token(revoked_v3_token) - hash = utils.hash_signed_token(revoked_v3_token, mode='sha256') - self.REVOKED_v3_TOKEN_HASH_SHA256 = hash - self.REVOKED_v3_TOKEN_LIST = ( - {'revoked': [{'id': self.REVOKED_v3_TOKEN_HASH, - 'expires': timeutils.utcnow()}]}) - self.REVOKED_v3_TOKEN_LIST_JSON = jsonutils.dumps( - self.REVOKED_v3_TOKEN_LIST) - - revoked_token_pkiz = self.REVOKED_TOKEN_PKIZ - if isinstance(revoked_token_pkiz, six.text_type): - revoked_token_pkiz = revoked_token_pkiz.encode('utf-8') - self.REVOKED_TOKEN_PKIZ_HASH = utils.hash_signed_token( - revoked_token_pkiz) - revoked_v3_token_pkiz = self.REVOKED_v3_TOKEN_PKIZ - if isinstance(revoked_v3_token_pkiz, six.text_type): - revoked_v3_token_pkiz = revoked_v3_token_pkiz.encode('utf-8') - self.REVOKED_v3_PKIZ_TOKEN_HASH = utils.hash_signed_token( - revoked_v3_token_pkiz) - - self.REVOKED_TOKEN_PKIZ_LIST = ( - {'revoked': [{'id': self.REVOKED_TOKEN_PKIZ_HASH, - 'expires': timeutils.utcnow()}, - {'id': self.REVOKED_v3_PKIZ_TOKEN_HASH, - 'expires': timeutils.utcnow()}, - ]}) - self.REVOKED_TOKEN_PKIZ_LIST_JSON = jsonutils.dumps( - self.REVOKED_TOKEN_PKIZ_LIST) - self.SIGNED_TOKEN_SCOPED_KEY = cms.cms_hash_token( self.SIGNED_TOKEN_SCOPED) self.SIGNED_TOKEN_UNSCOPED_KEY = cms.cms_hash_token( diff -Nru python-keystonemiddleware-5.3.0/keystonemiddleware/tests/unit/test_opts.py python-keystonemiddleware-6.0.0/keystonemiddleware/tests/unit/test_opts.py --- python-keystonemiddleware-5.3.0/keystonemiddleware/tests/unit/test_opts.py 2018-10-24 17:22:09.000000000 +0000 +++ python-keystonemiddleware-6.0.0/keystonemiddleware/tests/unit/test_opts.py 2019-02-28 18:01:33.000000000 +0000 @@ -55,7 +55,6 @@ 'signing_dir', 'memcached_servers', 'token_cache_time', - 'revocation_cache_time', 'memcache_security_strategy', 'memcache_secret_key', 'memcache_use_advanced_pool', @@ -66,7 +65,6 @@ 'memcache_pool_socket_timeout', 'include_service_catalog', 'enforce_token_bind', - 'check_revocations_for_cached', 'hash_algorithms', 'auth_type', 'auth_section', @@ -102,7 +100,6 @@ 'signing_dir', 'memcached_servers', 'token_cache_time', - 'revocation_cache_time', 'memcache_security_strategy', 'memcache_secret_key', 'memcache_use_advanced_pool', @@ -113,7 +110,6 @@ 'memcache_pool_socket_timeout', 'include_service_catalog', 'enforce_token_bind', - 'check_revocations_for_cached', 'hash_algorithms', 'auth_type', 'auth_section', diff -Nru python-keystonemiddleware-5.3.0/keystonemiddleware.egg-info/pbr.json python-keystonemiddleware-6.0.0/keystonemiddleware.egg-info/pbr.json --- python-keystonemiddleware-5.3.0/keystonemiddleware.egg-info/pbr.json 2018-10-24 17:26:17.000000000 +0000 +++ python-keystonemiddleware-6.0.0/keystonemiddleware.egg-info/pbr.json 2019-02-28 18:03:58.000000000 +0000 @@ -1 +1 @@ -{"git_version": "fc51082", "is_release": true} \ No newline at end of file +{"git_version": "fca37ea", "is_release": true} \ No newline at end of file diff -Nru python-keystonemiddleware-5.3.0/keystonemiddleware.egg-info/PKG-INFO python-keystonemiddleware-6.0.0/keystonemiddleware.egg-info/PKG-INFO --- python-keystonemiddleware-5.3.0/keystonemiddleware.egg-info/PKG-INFO 2018-10-24 17:26:17.000000000 +0000 +++ python-keystonemiddleware-6.0.0/keystonemiddleware.egg-info/PKG-INFO 2019-02-28 18:03:58.000000000 +0000 @@ -1,10 +1,10 @@ Metadata-Version: 2.1 Name: keystonemiddleware -Version: 5.3.0 +Version: 6.0.0 Summary: Middleware for OpenStack Identity Home-page: https://docs.openstack.org/keystonemiddleware/latest/ Author: OpenStack -Author-email: openstack-dev@lists.openstack.org +Author-email: openstack-discuss@lists.openstack.org License: UNKNOWN Description: ======================== Team and repository tags @@ -19,11 +19,11 @@ ==================================================== .. image:: https://img.shields.io/pypi/v/keystonemiddleware.svg - :target: https://pypi.python.org/pypi/keystonemiddleware/ + :target: https://pypi.org/project/keystonemiddleware/ :alt: Latest Version .. image:: https://img.shields.io/pypi/dm/keystonemiddleware.svg - :target: https://pypi.python.org/pypi/keystonemiddleware/ + :target: https://pypi.org/project/keystonemiddleware/ :alt: Downloads This package contains middleware modules designed to provide authentication and diff -Nru python-keystonemiddleware-5.3.0/keystonemiddleware.egg-info/SOURCES.txt python-keystonemiddleware-6.0.0/keystonemiddleware.egg-info/SOURCES.txt --- python-keystonemiddleware-5.3.0/keystonemiddleware.egg-info/SOURCES.txt 2018-10-24 17:26:17.000000000 +0000 +++ python-keystonemiddleware-6.0.0/keystonemiddleware.egg-info/SOURCES.txt 2019-02-28 18:03:58.000000000 +0000 @@ -1,6 +1,5 @@ .coveragerc .stestr.conf -.testr.conf .zuul.yaml AUTHORS CONTRIBUTING.rst @@ -89,7 +88,6 @@ keystonemiddleware/auth_token/_memcache_crypt.py keystonemiddleware/auth_token/_opts.py keystonemiddleware/auth_token/_request.py -keystonemiddleware/auth_token/_revocations.py keystonemiddleware/auth_token/_signing_dir.py keystonemiddleware/auth_token/_user_plugin.py keystonemiddleware/echo/__init__.py @@ -122,7 +120,6 @@ keystonemiddleware/tests/unit/auth_token/test_connection_pool.py keystonemiddleware/tests/unit/auth_token/test_memcache_crypt.py keystonemiddleware/tests/unit/auth_token/test_request.py -keystonemiddleware/tests/unit/auth_token/test_revocations.py keystonemiddleware/tests/unit/auth_token/test_signing_dir.py keystonemiddleware/tests/unit/auth_token/test_user_auth_plugin.py releasenotes/notes/.placeholder @@ -133,6 +130,7 @@ releasenotes/notes/bug-1583690-da67472d7afff0bf.yaml releasenotes/notes/bug-1583699-dba4fe6c057e2be5.yaml releasenotes/notes/bug-1583702-a4469dc1556878b9.yaml +releasenotes/notes/bug-1649735-3c68f3243e474775.yaml releasenotes/notes/bug-1677308-a2fa7de67f21cd84.yaml releasenotes/notes/bug-1695038-2cbedcabf8ecc057.yaml releasenotes/notes/bug-1737115-fa3d41e3d3cd7177.yaml @@ -142,9 +140,14 @@ releasenotes/notes/bug-1766731-3b29192cfeb77964.yaml releasenotes/notes/bug-1782404-c4e37bbc83756a89.yaml releasenotes/notes/bug-1789351-102e2e5119be38b4.yaml +releasenotes/notes/bug-1800017-0e5a9b8f62b5ca60.yaml +releasenotes/notes/bug-1803940-9a39c66014763af0.yaml +releasenotes/notes/bug-1809101-6b5088443d5970ba.yaml +releasenotes/notes/bug-1813739-80eae72371903119.yaml releasenotes/notes/bug_1540115-677cf5016bc46348.yaml releasenotes/notes/delay_auth_instead_of_503-f9b46bf4fbc11455.yaml releasenotes/notes/deprecate-caching-tokens-in-process-a412b0f1dea84cb9.yaml +releasenotes/notes/fix-audit-no-service-endpoint-ports-72b2009d631dcf19.yaml releasenotes/notes/ksm_4.1.0-3cd78446d8e63616.yaml releasenotes/notes/remove_kwargs_to_fetch_token-20e3451ed192ab6a.yaml releasenotes/notes/rename-auth-uri-d223d883f5898aee.yaml diff -Nru python-keystonemiddleware-5.3.0/PKG-INFO python-keystonemiddleware-6.0.0/PKG-INFO --- python-keystonemiddleware-5.3.0/PKG-INFO 2018-10-24 17:26:17.000000000 +0000 +++ python-keystonemiddleware-6.0.0/PKG-INFO 2019-02-28 18:03:58.000000000 +0000 @@ -1,10 +1,10 @@ Metadata-Version: 2.1 Name: keystonemiddleware -Version: 5.3.0 +Version: 6.0.0 Summary: Middleware for OpenStack Identity Home-page: https://docs.openstack.org/keystonemiddleware/latest/ Author: OpenStack -Author-email: openstack-dev@lists.openstack.org +Author-email: openstack-discuss@lists.openstack.org License: UNKNOWN Description: ======================== Team and repository tags @@ -19,11 +19,11 @@ ==================================================== .. image:: https://img.shields.io/pypi/v/keystonemiddleware.svg - :target: https://pypi.python.org/pypi/keystonemiddleware/ + :target: https://pypi.org/project/keystonemiddleware/ :alt: Latest Version .. image:: https://img.shields.io/pypi/dm/keystonemiddleware.svg - :target: https://pypi.python.org/pypi/keystonemiddleware/ + :target: https://pypi.org/project/keystonemiddleware/ :alt: Downloads This package contains middleware modules designed to provide authentication and diff -Nru python-keystonemiddleware-5.3.0/README.rst python-keystonemiddleware-6.0.0/README.rst --- python-keystonemiddleware-5.3.0/README.rst 2018-10-24 17:22:09.000000000 +0000 +++ python-keystonemiddleware-6.0.0/README.rst 2019-02-28 18:01:33.000000000 +0000 @@ -11,11 +11,11 @@ ==================================================== .. image:: https://img.shields.io/pypi/v/keystonemiddleware.svg - :target: https://pypi.python.org/pypi/keystonemiddleware/ + :target: https://pypi.org/project/keystonemiddleware/ :alt: Latest Version .. image:: https://img.shields.io/pypi/dm/keystonemiddleware.svg - :target: https://pypi.python.org/pypi/keystonemiddleware/ + :target: https://pypi.org/project/keystonemiddleware/ :alt: Downloads This package contains middleware modules designed to provide authentication and diff -Nru python-keystonemiddleware-5.3.0/releasenotes/notes/bug-1649735-3c68f3243e474775.yaml python-keystonemiddleware-6.0.0/releasenotes/notes/bug-1649735-3c68f3243e474775.yaml --- python-keystonemiddleware-5.3.0/releasenotes/notes/bug-1649735-3c68f3243e474775.yaml 1970-01-01 00:00:00.000000000 +0000 +++ python-keystonemiddleware-6.0.0/releasenotes/notes/bug-1649735-3c68f3243e474775.yaml 2019-02-28 18:01:33.000000000 +0000 @@ -0,0 +1,8 @@ +--- +fixes: + - > + [`bug 1649735 `_] + The auth_token middleware no longer attempts to retrieve the revocation + list from the Keystone server. The deprecated options + `check_revocations_for_cached` and `check_revocations_for_cached` have been + removed. diff -Nru python-keystonemiddleware-5.3.0/releasenotes/notes/bug-1800017-0e5a9b8f62b5ca60.yaml python-keystonemiddleware-6.0.0/releasenotes/notes/bug-1800017-0e5a9b8f62b5ca60.yaml --- python-keystonemiddleware-5.3.0/releasenotes/notes/bug-1800017-0e5a9b8f62b5ca60.yaml 1970-01-01 00:00:00.000000000 +0000 +++ python-keystonemiddleware-6.0.0/releasenotes/notes/bug-1800017-0e5a9b8f62b5ca60.yaml 2019-02-28 18:01:33.000000000 +0000 @@ -0,0 +1,7 @@ +--- +fixes: + - | + [`bug 1800017 `_] + Fix audit middleware service catalog parsing for the scenario where a + service does not contain any endpoints. In that case, we should just skip + over that service. diff -Nru python-keystonemiddleware-5.3.0/releasenotes/notes/bug-1803940-9a39c66014763af0.yaml python-keystonemiddleware-6.0.0/releasenotes/notes/bug-1803940-9a39c66014763af0.yaml --- python-keystonemiddleware-5.3.0/releasenotes/notes/bug-1803940-9a39c66014763af0.yaml 1970-01-01 00:00:00.000000000 +0000 +++ python-keystonemiddleware-6.0.0/releasenotes/notes/bug-1803940-9a39c66014763af0.yaml 2019-02-28 18:01:33.000000000 +0000 @@ -0,0 +1,5 @@ +--- +features: + - > + [`bug 1803940 `_] + Request ID and global request ID have been added to CADF notifications. diff -Nru python-keystonemiddleware-5.3.0/releasenotes/notes/bug-1809101-6b5088443d5970ba.yaml python-keystonemiddleware-6.0.0/releasenotes/notes/bug-1809101-6b5088443d5970ba.yaml --- python-keystonemiddleware-5.3.0/releasenotes/notes/bug-1809101-6b5088443d5970ba.yaml 1970-01-01 00:00:00.000000000 +0000 +++ python-keystonemiddleware-6.0.0/releasenotes/notes/bug-1809101-6b5088443d5970ba.yaml 2019-02-28 18:01:33.000000000 +0000 @@ -0,0 +1,7 @@ +--- +fixes: + - | + [`bug 1809101 `_] + Fix req.context of Keystone audit middleware and Glance conflict with each + other issue. The audit middleware now stores the admin context to + req.environ['audit.context']. diff -Nru python-keystonemiddleware-5.3.0/releasenotes/notes/bug-1813739-80eae72371903119.yaml python-keystonemiddleware-6.0.0/releasenotes/notes/bug-1813739-80eae72371903119.yaml --- python-keystonemiddleware-5.3.0/releasenotes/notes/bug-1813739-80eae72371903119.yaml 1970-01-01 00:00:00.000000000 +0000 +++ python-keystonemiddleware-6.0.0/releasenotes/notes/bug-1813739-80eae72371903119.yaml 2019-02-28 18:01:33.000000000 +0000 @@ -0,0 +1,9 @@ +--- +fixes: + - | + [`bug 1813739 `_] + When admin identity endpoint is not created yet, keystonemiddleware emit + EndpointNotFound exception. Even after admin identity endpoint created, + auth_token middleware could not be notified of update since it does not + invalidate existing auth. Add an invalidation step so that endpoint + updates can be detected. diff -Nru python-keystonemiddleware-5.3.0/releasenotes/notes/fix-audit-no-service-endpoint-ports-72b2009d631dcf19.yaml python-keystonemiddleware-6.0.0/releasenotes/notes/fix-audit-no-service-endpoint-ports-72b2009d631dcf19.yaml --- python-keystonemiddleware-5.3.0/releasenotes/notes/fix-audit-no-service-endpoint-ports-72b2009d631dcf19.yaml 1970-01-01 00:00:00.000000000 +0000 +++ python-keystonemiddleware-6.0.0/releasenotes/notes/fix-audit-no-service-endpoint-ports-72b2009d631dcf19.yaml 2019-02-28 18:01:33.000000000 +0000 @@ -0,0 +1,6 @@ +--- +fixes: + - | + [`bug 1797584 `_] + Fixed a bug where the audit code would select the wrong target service + if the OpenStack service endpoints were not using unique TCP ports. diff -Nru python-keystonemiddleware-5.3.0/setup.cfg python-keystonemiddleware-6.0.0/setup.cfg --- python-keystonemiddleware-5.3.0/setup.cfg 2018-10-24 17:26:17.000000000 +0000 +++ python-keystonemiddleware-6.0.0/setup.cfg 2019-02-28 18:03:58.000000000 +0000 @@ -4,7 +4,7 @@ description-file = README.rst author = OpenStack -author-email = openstack-dev@lists.openstack.org +author-email = openstack-discuss@lists.openstack.org home-page = https://docs.openstack.org/keystonemiddleware/latest/ classifier = Environment :: OpenStack diff -Nru python-keystonemiddleware-5.3.0/.testr.conf python-keystonemiddleware-6.0.0/.testr.conf --- python-keystonemiddleware-5.3.0/.testr.conf 2018-10-24 17:22:09.000000000 +0000 +++ python-keystonemiddleware-6.0.0/.testr.conf 1970-01-01 00:00:00.000000000 +0000 @@ -1,8 +0,0 @@ -[DEFAULT] -test_command= - OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \ - OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \ - OS_LOG_CAPTURE=${OS_LOG_CAPTURE:-1} \ - ${PYTHON:-python} -m subunit.run discover -t ./ ./keystonemiddleware/tests $LISTOPT $IDOPTION -test_id_option=--load-list $IDFILE -test_list_option=--list diff -Nru python-keystonemiddleware-5.3.0/tox.ini python-keystonemiddleware-6.0.0/tox.ini --- python-keystonemiddleware-5.3.0/tox.ini 2018-10-24 17:22:09.000000000 +0000 +++ python-keystonemiddleware-6.0.0/tox.ini 2019-02-28 18:01:33.000000000 +0000 @@ -1,7 +1,7 @@ [tox] minversion = 2.0 skipsdist = True -envlist = py35,py27,pep8,releasenotes +envlist = py36,py35,py27,pep8,releasenotes [testenv] usedevelop = True diff -Nru python-keystonemiddleware-5.3.0/.zuul.yaml python-keystonemiddleware-6.0.0/.zuul.yaml --- python-keystonemiddleware-5.3.0/.zuul.yaml 2018-10-24 17:22:09.000000000 +0000 +++ python-keystonemiddleware-6.0.0/.zuul.yaml 2019-02-28 18:01:33.000000000 +0000 @@ -5,6 +5,7 @@ - openstack-python-jobs - openstack-python35-jobs - openstack-python36-jobs + - openstack-python37-jobs - publish-openstack-docs-pti - check-requirements - lib-forward-testing