keystone/keystone/middleware/core.py

145 lines
3.8 KiB
Python

# vim: tabstop=4 shiftwidth=4 softtabstop=4
import json
import webob
from keystone import config
from keystone.common import wsgi
CONF = config.CONF
# Header used to transmit the auth token
AUTH_TOKEN_HEADER = 'X-Auth-Token'
# Environment variable used to pass the request context
CONTEXT_ENV = 'openstack.context'
# Environment variable used to pass the request params
PARAMS_ENV = 'openstack.params'
class TokenAuthMiddleware(wsgi.Middleware):
def process_request(self, request):
token = request.headers.get(AUTH_TOKEN_HEADER)
context = request.environ.get(CONTEXT_ENV, {})
context['token_id'] = token
request.environ[CONTEXT_ENV] = context
class AdminTokenAuthMiddleware(wsgi.Middleware):
"""A trivial filter that checks for a pre-defined admin token.
Sets 'is_admin' to true in the context, expected to be checked by
methods that are admin-only.
"""
def process_request(self, request):
token = request.headers.get(AUTH_TOKEN_HEADER)
context = request.environ.get(CONTEXT_ENV, {})
context['is_admin'] = (token == CONF.admin_token)
request.environ[CONTEXT_ENV] = context
class PostParamsMiddleware(wsgi.Middleware):
"""Middleware to allow method arguments to be passed as POST parameters.
Filters out the parameters `self`, `context` and anything beginning with
an underscore.
"""
def process_request(self, request):
params_parsed = request.params
params = {}
for k, v in params_parsed.iteritems():
if k in ('self', 'context'):
continue
if k.startswith('_'):
continue
params[k] = v
request.environ[PARAMS_ENV] = params
class JsonBodyMiddleware(wsgi.Middleware):
"""Middleware to allow method arguments to be passed as serialized JSON.
Accepting arguments as JSON is useful for accepting data that may be more
complex than simple primitives.
In this case we accept it as urlencoded data under the key 'json' as in
json=<urlencoded_json> but this could be extended to accept raw JSON
in the POST body.
Filters out the parameters `self`, `context` and anything beginning with
an underscore.
"""
def process_request(self, request):
#if 'json' not in request.params:
# return
params_json = request.body
if not params_json:
return
params_parsed = {}
try:
params_parsed = json.loads(params_json)
finally:
if not params_parsed:
params_parsed = {}
params = {}
for k, v in params_parsed.iteritems():
if k in ('self', 'context'):
continue
if k.startswith('_'):
continue
params[k] = v
request.environ[PARAMS_ENV] = params
class Debug(wsgi.Middleware):
"""
Middleware that produces stream debugging traces to the console (stdout)
for HTTP requests and responses flowing through it.
"""
@webob.dec.wsgify
def __call__(self, req):
print ('*' * 40) + ' REQUEST ENVIRON'
for key, value in req.environ.items():
print key, '=', value
print
resp = req.get_response(self.application)
print ('*' * 40) + ' RESPONSE HEADERS'
for (key, value) in resp.headers.iteritems():
print key, '=', value
print
resp.app_iter = self.print_generator(resp.app_iter)
return resp
@staticmethod
def print_generator(app_iter):
"""
Iterator that prints the contents of a wrapper string iterator
when iterated.
"""
print ('*' * 40) + ' BODY'
for part in app_iter:
sys.stdout.write(part)
sys.stdout.flush()
yield part
print