Catch up to changes in RequestContext
RequestContext has a helpful "from_environ" method that can handle all possible combinations of auth information users can send our way when manila is deployed with its Keystone auth middleware. We could switch to that, so that we don't have to maintain support for the full list of current and deprecated auth configuration options in our auth middleware. While we're there, we can also update the "to_dict" and "from_dict" methods in manila's context class to match the information we need. Change-Id: I5d554caf82a1fc4f1dcfede3ea61159ddaeb342e Closes-Bug: #1602081 Signed-off-by: Goutham Pacha Ravi <gouthampravi@gmail.com>
This commit is contained in:
parent
0d8f415e86
commit
c97f89f6e5
@ -73,24 +73,6 @@ class ManilaKeystoneContext(base_wsgi.Middleware):
|
||||
|
||||
@webob.dec.wsgify(RequestClass=base_wsgi.Request)
|
||||
def __call__(self, req):
|
||||
user_id = req.headers.get('X_USER')
|
||||
user_id = req.headers.get('X_USER_ID', user_id)
|
||||
if user_id is None:
|
||||
LOG.debug("Neither X_USER_ID nor X_USER found in request")
|
||||
return webob.exc.HTTPUnauthorized()
|
||||
# get the roles
|
||||
roles = [r.strip() for r in req.headers.get('X_ROLE', '').split(',')]
|
||||
if 'X_TENANT_ID' in req.headers:
|
||||
# This is the new header since Keystone went to ID/Name
|
||||
project_id = req.headers['X_TENANT_ID']
|
||||
else:
|
||||
# This is for legacy compatibility
|
||||
project_id = req.headers['X_TENANT']
|
||||
|
||||
# Get the auth token
|
||||
auth_token = req.headers.get('X_AUTH_TOKEN',
|
||||
req.headers.get('X_STORAGE_TOKEN'))
|
||||
|
||||
# Build a context, including the auth_token...
|
||||
remote_address = req.remote_addr
|
||||
if CONF.use_forwarded_for:
|
||||
@ -105,12 +87,26 @@ class ManilaKeystoneContext(base_wsgi.Middleware):
|
||||
raise webob.exc.HTTPInternalServerError(
|
||||
_('Invalid service catalog json.'))
|
||||
|
||||
ctx = context.RequestContext(user_id,
|
||||
project_id,
|
||||
roles=roles,
|
||||
auth_token=auth_token,
|
||||
remote_address=remote_address,
|
||||
service_catalog=service_catalog)
|
||||
ctx = context.RequestContext.from_environ(
|
||||
req.environ,
|
||||
remote_address=remote_address,
|
||||
service_catalog=service_catalog)
|
||||
|
||||
if ctx.user_id is None:
|
||||
LOG.debug("Neither X_USER_ID nor X_USER found in request")
|
||||
return webob.exc.HTTPUnauthorized()
|
||||
|
||||
if req.environ.get('X_PROJECT_DOMAIN_ID'):
|
||||
ctx.project_domain_id = req.environ['X_PROJECT_DOMAIN_ID']
|
||||
|
||||
if req.environ.get('X_PROJECT_DOMAIN_NAME'):
|
||||
ctx.project_domain_name = req.environ['X_PROJECT_DOMAIN_NAME']
|
||||
|
||||
if req.environ.get('X_USER_DOMAIN_ID'):
|
||||
ctx.user_domain_id = req.environ['X_USER_DOMAIN_ID']
|
||||
|
||||
if req.environ.get('X_USER_DOMAIN_NAME'):
|
||||
ctx.user_domain_name = req.environ['X_USER_DOMAIN_NAME']
|
||||
|
||||
req.environ['manila.context'] = ctx
|
||||
return self.application
|
||||
|
@ -21,7 +21,6 @@ import copy
|
||||
|
||||
from oslo_context import context
|
||||
from oslo_utils import timeutils
|
||||
import six
|
||||
|
||||
from manila.i18n import _
|
||||
from manila import policy
|
||||
@ -34,43 +33,26 @@ class RequestContext(context.RequestContext):
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, user_id, project_id, is_admin=None, read_deleted="no",
|
||||
roles=None, remote_address=None, timestamp=None,
|
||||
request_id=None, auth_token=None, overwrite=True,
|
||||
quota_class=None, service_catalog=None, **kwargs):
|
||||
def __init__(self, user_id=None, project_id=None, is_admin=None,
|
||||
read_deleted="no", project_name=None, remote_address=None,
|
||||
timestamp=None, quota_class=None, service_catalog=None,
|
||||
system_scope=None,
|
||||
**kwargs):
|
||||
"""Initialize RequestContext.
|
||||
|
||||
:param read_deleted: 'no' indicates deleted records are hidden, 'yes'
|
||||
indicates deleted records are visible, 'only' indicates that
|
||||
*only* deleted records are visible.
|
||||
|
||||
:param overwrite: Set to False to ensure that the greenthread local
|
||||
copy of the index is not overwritten.
|
||||
|
||||
:param kwargs: Extra arguments that might be present, but we ignore
|
||||
because they possibly came in from older rpc messages.
|
||||
:param kwargs: Extra arguments passed transparently to
|
||||
oslo_context.RequestContext.
|
||||
"""
|
||||
kwargs.setdefault('user_id', user_id)
|
||||
kwargs.setdefault('project_id', project_id)
|
||||
|
||||
user = kwargs.pop('user', None)
|
||||
tenant = kwargs.pop('tenant', None)
|
||||
super(RequestContext, self).__init__(
|
||||
auth_token=auth_token,
|
||||
user=user_id or user,
|
||||
tenant=project_id or tenant,
|
||||
domain=kwargs.pop('domain', None),
|
||||
user_domain=kwargs.pop('user_domain', None),
|
||||
project_domain=kwargs.pop('project_domain', None),
|
||||
is_admin=is_admin,
|
||||
read_only=kwargs.pop('read_only', False),
|
||||
show_deleted=kwargs.pop('show_deleted', False),
|
||||
request_id=request_id,
|
||||
resource_uuid=kwargs.pop('resource_uuid', None),
|
||||
overwrite=overwrite,
|
||||
roles=roles)
|
||||
|
||||
self.user_id = self.user
|
||||
self.project_id = self.tenant
|
||||
super(RequestContext, self).__init__(is_admin=is_admin, **kwargs)
|
||||
|
||||
self.project_name = project_name
|
||||
if self.is_admin is None:
|
||||
self.is_admin = policy.check_is_admin(self)
|
||||
elif self.is_admin and 'admin' not in self.roles:
|
||||
@ -79,17 +61,16 @@ class RequestContext(context.RequestContext):
|
||||
self.remote_address = remote_address
|
||||
if not timestamp:
|
||||
timestamp = timeutils.utcnow()
|
||||
if isinstance(timestamp, six.string_types):
|
||||
timestamp = timeutils.parse_strtime(timestamp)
|
||||
elif isinstance(timestamp, str):
|
||||
timestamp = timeutils.parse_isotime(timestamp)
|
||||
self.timestamp = timestamp
|
||||
self.quota_class = quota_class
|
||||
if service_catalog:
|
||||
self.service_catalog = [s for s in service_catalog
|
||||
if s.get('type') in ('compute', 'volume')]
|
||||
else:
|
||||
self.service_catalog = []
|
||||
|
||||
self.quota_class = quota_class
|
||||
|
||||
def _get_read_deleted(self):
|
||||
return self._read_deleted
|
||||
|
||||
@ -107,20 +88,37 @@ class RequestContext(context.RequestContext):
|
||||
|
||||
def to_dict(self):
|
||||
values = super(RequestContext, self).to_dict()
|
||||
values.update({
|
||||
'user_id': getattr(self, 'user_id', None),
|
||||
'project_id': getattr(self, 'project_id', None),
|
||||
'read_deleted': getattr(self, 'read_deleted', None),
|
||||
'remote_address': getattr(self, 'remote_address', None),
|
||||
'timestamp': self.timestamp.isoformat() if hasattr(
|
||||
self, 'timestamp') else None,
|
||||
'quota_class': getattr(self, 'quota_class', None),
|
||||
'service_catalog': getattr(self, 'service_catalog', None)})
|
||||
values['user_id'] = self.user_id
|
||||
values['project_id'] = self.project_id
|
||||
values['project_name'] = self.project_name
|
||||
values['domain_id'] = self.domain_id
|
||||
values['read_deleted'] = self.read_deleted
|
||||
values['remote_address'] = self.remote_address
|
||||
values['timestamp'] = self.timestamp.isoformat()
|
||||
values['quota_class'] = self.quota_class
|
||||
values['service_catalog'] = self.service_catalog
|
||||
values['request_id'] = self.request_id
|
||||
return values
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, values):
|
||||
return cls(**values)
|
||||
return cls(
|
||||
user_id=values.get('user_id'),
|
||||
project_id=values.get('project_id'),
|
||||
project_name=values.get('project_name'),
|
||||
domain_id=values.get('domain_id'),
|
||||
read_deleted=values.get('read_deleted'),
|
||||
remote_address=values.get('remote_address'),
|
||||
timestamp=values.get('timestamp'),
|
||||
quota_class=values.get('quota_class'),
|
||||
service_catalog=values.get('service_catalog'),
|
||||
request_id=values.get('request_id'),
|
||||
is_admin=values.get('is_admin'),
|
||||
roles=values.get('roles'),
|
||||
auth_token=values.get('auth_token'),
|
||||
user_domain_id=values.get('user_domain_id'),
|
||||
project_domain_id=values.get('project_domain_id')
|
||||
)
|
||||
|
||||
def elevated(self, read_deleted=None, overwrite=False):
|
||||
"""Return a version of this context with admin flag set."""
|
||||
|
@ -87,15 +87,13 @@ def enforce(context, action, target, do_raise=True):
|
||||
|
||||
"""
|
||||
init()
|
||||
if not isinstance(context, dict):
|
||||
context = context.to_dict()
|
||||
|
||||
# Add the exception arguments if asked to do a raise
|
||||
extra = {}
|
||||
if do_raise:
|
||||
extra.update(exc=exception.PolicyNotAuthorized, action=action,
|
||||
do_raise=do_raise)
|
||||
return _ENFORCER.enforce(action, target, context, **extra)
|
||||
return _ENFORCER.enforce(action,
|
||||
target,
|
||||
context.to_policy_values(),
|
||||
do_raise=do_raise,
|
||||
exc=exception.PolicyNotAuthorized,
|
||||
action=action)
|
||||
|
||||
|
||||
def set_rules(rules, overwrite=True, use_conf=False):
|
||||
|
Loading…
Reference in New Issue
Block a user