From 9861ca3857b45fc70e333fdf321102824927e813 Mon Sep 17 00:00:00 2001 From: asteroide Date: Thu, 5 Nov 2015 14:36:16 +0100 Subject: Change middleware behaviour because of swift requests. Change-Id: Ibb5c25d40a2004701a20a8903e70f1a6c8704ae1 --- .../keystonemiddleware/authz.py | 65 ++++++++++++++++------ 1 file changed, 47 insertions(+), 18 deletions(-) diff --git a/keystonemiddleware-moon/keystonemiddleware/authz.py b/keystonemiddleware-moon/keystonemiddleware/authz.py index 8dbb60e9..f5f19079 100644 --- a/keystonemiddleware-moon/keystonemiddleware/authz.py +++ b/keystonemiddleware-moon/keystonemiddleware/authz.py @@ -39,24 +39,25 @@ _OPTS = [ _AUTHZ_GROUP = 'keystone_authz' CONF = cfg.CONF CONF.register_opts(_OPTS, group=_AUTHZ_GROUP) +CONF.debug = True # auth.register_conf_options(CONF, _AUTHZ_GROUP) # from http://developer.openstack.org/api-ref-objectstorage-v1.html SWIFT_API = ( - ("^/v1/(?P[\w-]+)$", "GET", "get_account_details"), - ("^/v1/(?P[\w-]+)$", "POST", "modify_account"), - ("^/v1/(?P[\w-]+)$", "HEAD", "get_account"), - ("^/v1/(?P[\w-]+)/(?P[\w-]+)$", "GET", "get_container"), - ("^/v1/(?P[\w-]+)/(?P[\w-]+)$", "PUT", "create_container"), - ("^/v1/(?P[\w-]+)/(?P[\w-]+)$", "POST", "update_container_metadata"), - ("^/v1/(?P[\w-]+)/(?P[\w-]+)$", "DELETE", "delete_container"), - ("^/v1/(?P[\w-]+)/(?P[\w-]+)$", "HEAD", "get_container_metadata"), - ("^/v1/(?P[\w-]+)/(?P[\w-]+)/(?P[\w-]+)$", "GET", "get_object"), - ("^/v1/(?P[\w-]+)/(?P[\w-]+)/(?P[\w-]+)$", "PUT", "create_object"), - ("^/v1/(?P[\w-]+)/(?P[\w-]+)/(?P[\w-]+)$", "COPY", "copy_object"), - ("^/v1/(?P[\w-]+)/(?P[\w-]+)/(?P[\w-]+)$", "POST", "update_object_metadata"), - ("^/v1/(?P[\w-]+)/(?P[\w-]+)/(?P[\w-]+)$", "DELETE", "delete_object"), - ("^/v1/(?P[\w-]+)/(?P[\w-]+)/(?P[\w-]+)$", "HEAD", "get_object_metadata"), + ("^/v1/(?P[\w_-]+)$", "GET", "get_account_details"), + ("^/v1/(?P[\w_-]+)$", "POST", "modify_account"), + ("^/v1/(?P[\w_-]+)$", "HEAD", "get_account"), + ("^/v1/(?P[\w_-]+)/(?P[\w-]+)$", "GET", "get_container"), + ("^/v1/(?P[\w_-]+)/(?P[\w-]+)$", "PUT", "create_container"), + ("^/v1/(?P[\w_-]+)/(?P[\w-]+)$", "POST", "update_container_metadata"), + ("^/v1/(?P[\w_-]+)/(?P[\w-]+)$", "DELETE", "delete_container"), + ("^/v1/(?P[\w_-]+)/(?P[\w-]+)$", "HEAD", "get_container_metadata"), + ("^/v1/(?P[\w_-]+)/(?P[\w-]+)/(?P.+)$", "GET", "get_object"), + ("^/v1/(?P[\w_-]+)/(?P[\w-]+)/(?P.+)$", "PUT", "create_object"), + ("^/v1/(?P[\w_-]+)/(?P[\w-]+)/(?P.+)$", "COPY", "copy_object"), + ("^/v1/(?P[\w_-]+)/(?P[\w-]+)/(?P.+)$", "POST", "update_object_metadata"), + ("^/v1/(?P[\w_-]+)/(?P[\w-]+)/(?P.+)$", "DELETE", "delete_object"), + ("^/v1/(?P[\w_-]+)/(?P[\w-]+)/(?P.+)$", "HEAD", "get_object_metadata"), ) @@ -269,6 +270,21 @@ class AuthZProtocol(object): for api in SWIFT_API: if re.match(api[0], path) and method == api[1]: action = api[2] + length = int(env.get('CONTENT_LENGTH', '0')) + # TODO (dthom): compute for Nova, Cinder, Neutron, ... + _action = "" + if length > 0: + try: + sub_action_object = env['wsgi.input'].read(length) + self.input = sub_action_object + _action = json.loads(sub_action_object).keys()[0] + body = StringIO(sub_action_object) + env['wsgi.input'] = body + self._LOG.debug("wsgi.input={}".format(_action)) + except ValueError: + self._LOG.error("Error in decoding sub-action") + except Exception as e: + self._LOG.error(str(e)) return action @staticmethod @@ -293,7 +309,7 @@ class AuthZProtocol(object): return elif component == "swift": # remove the "/v1/" part of the URL - return env.get("PATH_INFO").split("/", 2)[-1].replace("/", "-") + return env.get("PATH_INFO").split("/", 2)[-1].replace("/", "-").replace(".", "-") return "unknown" def __call__(self, env, start_response): @@ -306,25 +322,38 @@ class AuthZProtocol(object): # return self._app(env, start_response) subject_id = env.get("HTTP_X_USER_ID") + if not subject_id: + self._LOG.warning("No subject_id found for {}".format(env.get("PATH_INFO"))) + return self._app(env, start_response) tenant_id = env.get("HTTP_X_TENANT_ID") + if not tenant_id: + self._LOG.warning("No tenant_id found for {}".format(env.get("PATH_INFO"))) + return self._app(env, start_response) component = self._find_openstack_component(env) action_id = self._get_action(env, component) + self._LOG.debug("\033[1m\033[31mrequest={}\033[m".format(env["PATH_INFO"])) if action_id: object_id = self._get_object(env, component) if not object_id: object_id = "servers" + self._LOG.debug("object_id={}".format(object_id)) self.__set_token() resp = self._get_authz_from_moon(self.x_subject_token, tenant_id, subject_id, object_id, action_id) self.__unset_token() if resp.status_code == 200: answer = json.loads(resp.content) + self._LOG.debug("action_id={}/{}".format(component, action_id)) self._LOG.debug(answer) if "authz" in answer and answer["authz"]: return self._app(env, start_response) + self._LOG.error("You are not authorized to do that! ({})".format(unicode(answer["comment"]))) raise exception.Unauthorized(message="You are not authorized to do that! ({})".format(unicode(answer["comment"]))) - self._LOG.debug("No action_id found for {}".format(env.get("PATH_INFO"))) - # If action is not found, we can't raise an exception because a lots of action is missing - # in function self._get_action, it is not possible to get them all. + else: + self._LOG.error("Unable to request Moon ({}: {})".format(resp.status_code, resp.reason)) + else: + self._LOG.debug("No action_id found for {}".format(env.get("PATH_INFO"))) + # If action is not found, we can't raise an exception because a lots of action is missing + # in function self._get_action, it is not possible to get them all. return self._app(env, start_response) # raise exception.Unauthorized(message="You are not authorized to do that!") -- cgit 1.2.3-korg