diff --git a/manila/api/middleware/auth.py b/manila/api/middleware/auth.py index bdea028da2..b67f99c9e5 100644 --- a/manila/api/middleware/auth.py +++ b/manila/api/middleware/auth.py @@ -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 diff --git a/manila/context.py b/manila/context.py index c822346c34..1695e9ebe9 100644 --- a/manila/context.py +++ b/manila/context.py @@ -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.""" diff --git a/manila/policy.py b/manila/policy.py index 7c1bb13be5..05ac7be479 100644 --- a/manila/policy.py +++ b/manila/policy.py @@ -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):