auth.py 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. # Copyright 2016 Cloudbase Solutions Srl
  2. # All Rights Reserved.
  3. import webob
  4. from oslo_log import log as logging
  5. from oslo_middleware import request_id
  6. from oslo_serialization import jsonutils
  7. from coriolis.api import wsgi
  8. from coriolis import context
  9. from coriolis.i18n import _
  10. LOG = logging.getLogger(__name__)
  11. class CoriolisKeystoneContext(wsgi.Middleware):
  12. @webob.dec.wsgify(RequestClass=wsgi.Request)
  13. def __call__(self, req):
  14. user = req.headers.get('X_USER')
  15. user = req.headers.get('X_USER_ID', user)
  16. if user is None:
  17. LOG.debug("Neither X_USER_ID nor X_USER found in request")
  18. return webob.exc.HTTPUnauthorized()
  19. # get the roles
  20. roles = [r.strip() for r in req.headers.get('X_ROLE', '').split(',')]
  21. if 'X_TENANT_ID' in req.headers:
  22. # This is the new header since Keystone went to ID/Name
  23. tenant = req.headers['X_TENANT_ID']
  24. else:
  25. # This is for legacy compatibility
  26. tenant = req.headers['X_TENANT']
  27. project_name = req.headers.get('X_TENANT_NAME')
  28. project_domain_name = req.headers.get('X-Project-Domain-Name')
  29. user_domain_name = req.headers.get('X-User-Domain-Name')
  30. req_id = req.environ.get(request_id.ENV_REQUEST_ID)
  31. # TODO(alexpilotti): Check why it's not str
  32. if isinstance(req_id, bytes):
  33. req_id = req_id.decode()
  34. # Get the auth token
  35. auth_token = req.headers.get('X_AUTH_TOKEN')
  36. # Build a context, including the auth_token...
  37. remote_address = req.remote_addr
  38. service_catalog = None
  39. if req.headers.get('X_SERVICE_CATALOG') is not None:
  40. try:
  41. catalog_header = req.headers.get('X_SERVICE_CATALOG')
  42. service_catalog = jsonutils.loads(catalog_header)
  43. except ValueError:
  44. raise webob.exc.HTTPInternalServerError(
  45. explanation=_('Invalid service catalog json.'))
  46. ctx = context.RequestContext(user,
  47. tenant,
  48. project_name=project_name,
  49. project_domain=project_domain_name,
  50. user_domain=user_domain_name,
  51. roles=roles,
  52. auth_token=auth_token,
  53. remote_address=remote_address,
  54. service_catalog=service_catalog,
  55. request_id=req_id)
  56. req.environ['coriolis.context'] = ctx
  57. return self.application