Merge "Enforce policy on oslo-context"
This commit is contained in:
commit
6c3e444a61
|
@ -156,6 +156,8 @@ class AuthContextMiddleware(auth_token.BaseAuthProtocol):
|
|||
|
||||
if resp:
|
||||
return resp
|
||||
if request.token_auth.user is not None:
|
||||
request.set_user_headers(request.token_auth.user)
|
||||
|
||||
# NOTE(jamielennox): function is split so testing can check errors from
|
||||
# fill_context. There is no actual reason for fill_context to raise
|
||||
|
@ -164,13 +166,28 @@ class AuthContextMiddleware(auth_token.BaseAuthProtocol):
|
|||
# and the middleware_exceptions helper removed.
|
||||
self.fill_context(request)
|
||||
|
||||
def _keystone_specific_values(self, token, request_context):
|
||||
if token.domain_scoped:
|
||||
# Domain scoped tokens should never have is_admin_project set
|
||||
# Even if KSA defaults it otherwise. The two mechanisms are
|
||||
# parallel; only ione or the other should be used for access.
|
||||
request_context.is_admin_project = False
|
||||
request_context.domain_id = token.domain_id
|
||||
request_context.domain_name = token.domain_name
|
||||
if token.oauth_scoped:
|
||||
request_context.is_delegated_auth = True
|
||||
request_context.oauth_consumer_id = token.oauth_consumer_id
|
||||
request_context.oauth_access_token_id = token.oauth_access_token_id
|
||||
if token.trust_scoped:
|
||||
request_context.is_delegated_auth = True
|
||||
request_context.trust_id = token.trust_id
|
||||
if token.is_federated_user:
|
||||
request_context.group_ids = token.federation_group_ids
|
||||
else:
|
||||
request_context.group_ids = []
|
||||
|
||||
def fill_context(self, request):
|
||||
# The request context stores itself in thread-local memory for logging.
|
||||
request_context = context.RequestContext(
|
||||
request_id=request.environ.get('openstack.request_id'),
|
||||
authenticated=False,
|
||||
overwrite=True)
|
||||
request.environ[context.REQUEST_CONTEXT_ENV] = request_context
|
||||
|
||||
if authorization.AUTH_CONTEXT_ENV in request.environ:
|
||||
msg = ('Auth context already exists in the request '
|
||||
|
@ -179,6 +196,13 @@ class AuthContextMiddleware(auth_token.BaseAuthProtocol):
|
|||
LOG.warning(msg)
|
||||
return
|
||||
|
||||
kwargs = {
|
||||
'authenticated': False,
|
||||
'overwrite': True}
|
||||
request_context = context.RequestContext.from_environ(
|
||||
request.environ, **kwargs)
|
||||
request.environ[context.REQUEST_CONTEXT_ENV] = request_context
|
||||
|
||||
# NOTE(gyee): token takes precedence over SSL client certificates.
|
||||
# This will preserve backward compatibility with the existing
|
||||
# behavior. Tokenless authorization with X.509 SSL client
|
||||
|
@ -190,10 +214,23 @@ class AuthContextMiddleware(auth_token.BaseAuthProtocol):
|
|||
auth_context = {}
|
||||
|
||||
elif request.token_auth.has_user_token:
|
||||
# Keystone enforces policy on some values that other services
|
||||
# do not, and should not, use. This adds them in to the context.
|
||||
token = token_model.KeystoneToken(token_id=request.user_token,
|
||||
token_data=request.token_info)
|
||||
self._keystone_specific_values(token, request_context)
|
||||
request_context.auth_token = request.user_token
|
||||
ref = token_model.KeystoneToken(token_id=request.user_token,
|
||||
token_data=request.token_info)
|
||||
auth_context = authorization.token_to_auth_context(ref)
|
||||
auth_context = request_context.to_policy_values()
|
||||
additional = {
|
||||
'trust_id': request_context.trust_id,
|
||||
'trustor_id': request_context.trustor_id,
|
||||
'trustee_id': request_context.trustee_id,
|
||||
'domain_id': request_context._domain_id,
|
||||
'domain_name': request_context.domain_name,
|
||||
'group_ids': request_context.group_ids,
|
||||
'token': token
|
||||
}
|
||||
auth_context.update(additional)
|
||||
|
||||
elif self._validate_trusted_issuer(request):
|
||||
auth_context = self._build_tokenless_auth_context(request)
|
||||
|
@ -207,34 +244,6 @@ class AuthContextMiddleware(auth_token.BaseAuthProtocol):
|
|||
# set authenticated to flag to keystone that a token has been validated
|
||||
request_context.authenticated = True
|
||||
|
||||
# The attributes of request_context are put into the logs. This is a
|
||||
# common pattern for all the OpenStack services. In all the other
|
||||
# projects these are IDs, so set the attributes to IDs here rather than
|
||||
# the name.
|
||||
request_context.user_id = auth_context.get('user_id')
|
||||
request_context.project_id = auth_context.get('project_id')
|
||||
request_context.domain_id = auth_context.get('domain_id')
|
||||
request_context.domain_name = auth_context.get('domain_name')
|
||||
request_context.user_domain_id = auth_context.get('user_domain_id')
|
||||
request_context.roles = auth_context.get('roles')
|
||||
|
||||
is_admin_project = auth_context.get('is_admin_project', True)
|
||||
request_context.is_admin_project = is_admin_project
|
||||
|
||||
project_domain_id = auth_context.get('project_domain_id')
|
||||
request_context.project_domain_id = project_domain_id
|
||||
|
||||
is_delegated_auth = auth_context.get('is_delegated_auth', False)
|
||||
request_context.is_delegated_auth = is_delegated_auth
|
||||
|
||||
request_context.trust_id = auth_context.get('trust_id')
|
||||
request_context.trustor_id = auth_context.get('trustor_id')
|
||||
request_context.trustee_id = auth_context.get('trustee_id')
|
||||
|
||||
access_token_id = auth_context.get('access_token_id')
|
||||
request_context.oauth_consumer_id = auth_context.get('consumer_id')
|
||||
request_context.oauth_acess_token_id = access_token_id
|
||||
|
||||
LOG.debug('RBAC: auth_context: %s', auth_context)
|
||||
request.environ[authorization.AUTH_CONTEXT_ENV] = auth_context
|
||||
|
||||
|
|
|
@ -1300,10 +1300,14 @@ class AuthContextMiddlewareTestCase(RestfulTestCase):
|
|||
def test_unscoped_token_auth_context(self):
|
||||
unscoped_token = self.get_unscoped_token()
|
||||
req = self._middleware_request(unscoped_token)
|
||||
# This check originally looked that the value was unset
|
||||
# but that was an artifact of the custom context keystone
|
||||
# used to create. Oslo-context will always provide the
|
||||
# same set of keys, but the values will be None in an
|
||||
# unscoped token
|
||||
for key in ['project_id', 'domain_id', 'domain_name']:
|
||||
self.assertNotIn(
|
||||
key,
|
||||
req.environ.get(authorization.AUTH_CONTEXT_ENV))
|
||||
self.assertIsNone(
|
||||
req.environ.get(authorization.AUTH_CONTEXT_ENV)[key])
|
||||
|
||||
def test_project_scoped_token_auth_context(self):
|
||||
project_scoped_token = self.get_scoped_token()
|
||||
|
|
Loading…
Reference in New Issue