From 03bf0c32a0c656d4b91bebedc87a005e6d7563bb Mon Sep 17 00:00:00 2001 From: WuKong Date: Wed, 1 Jul 2015 08:54:55 +0200 Subject: migrate openstack hook to opnfv Change-Id: I1e828dae38820fdff93966e57691b344af01140f Signed-off-by: WuKong --- .../keystonemiddleware/ec2_token.py | 130 +++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 keystonemiddleware-moon/keystonemiddleware/ec2_token.py (limited to 'keystonemiddleware-moon/keystonemiddleware/ec2_token.py') diff --git a/keystonemiddleware-moon/keystonemiddleware/ec2_token.py b/keystonemiddleware-moon/keystonemiddleware/ec2_token.py new file mode 100644 index 00000000..df3bb6b0 --- /dev/null +++ b/keystonemiddleware-moon/keystonemiddleware/ec2_token.py @@ -0,0 +1,130 @@ +# Copyright 2012 OpenStack Foundation +# Copyright 2010 United States Government as represented by the +# Administrator of the National Aeronautics and Space Administration. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +""" +Starting point for routing EC2 requests. + +""" + +from oslo_config import cfg +from oslo_serialization import jsonutils +import requests +import webob.dec +import webob.exc + +keystone_ec2_opts = [ + cfg.StrOpt('url', + default='http://localhost:5000/v2.0/ec2tokens', + help='URL to get token from ec2 request.'), + cfg.StrOpt('keyfile', + help='Required if EC2 server requires client certificate.'), + cfg.StrOpt('certfile', + help='Client certificate key filename. Required if EC2 server ' + 'requires client certificate.'), + cfg.StrOpt('cafile', + help='A PEM encoded certificate authority to use when ' + 'verifying HTTPS connections. Defaults to the system ' + 'CAs.'), + cfg.BoolOpt('insecure', default=False, + help='Disable SSL certificate verification.'), +] + +CONF = cfg.CONF +CONF.register_opts(keystone_ec2_opts, group='keystone_ec2_token') + + +class EC2Token(object): + """Authenticate an EC2 request with keystone and convert to token.""" + + def __init__(self, application): + super(EC2Token, self).__init__() + self._application = application + + @webob.dec.wsgify() + def __call__(self, req): + # Read request signature and access id. + try: + signature = req.params['Signature'] + access = req.params['AWSAccessKeyId'] + except KeyError: + raise webob.exc.HTTPBadRequest() + + # Make a copy of args for authentication and signature verification. + auth_params = dict(req.params) + # Not part of authentication args + auth_params.pop('Signature') + + # Authenticate the request. + creds = { + 'ec2Credentials': { + 'access': access, + 'signature': signature, + 'host': req.host, + 'verb': req.method, + 'path': req.path, + 'params': auth_params, + } + } + creds_json = jsonutils.dumps(creds) + headers = {'Content-Type': 'application/json'} + + verify = True + if CONF.keystone_ec2_token.insecure: + verify = False + elif CONF.keystone_ec2_token.cafile: + verify = CONF.keystone_ec2_token.cafile + + cert = None + if (CONF.keystone_ec2_token.certfile and + CONF.keystone_ec2_token.keyfile): + cert = (CONF.keystone_ec2_certfile, + CONF.keystone_ec2_token.keyfile) + elif CONF.keystone_ec2_token.certfile: + cert = CONF.keystone_ec2_token.certfile + + response = requests.post(CONF.keystone_ec2_token.url, data=creds_json, + headers=headers, verify=verify, cert=cert) + + # NOTE(vish): We could save a call to keystone by + # having keystone return token, tenant, + # user, and roles from this call. + + result = response.json() + try: + token_id = result['access']['token']['id'] + except (AttributeError, KeyError): + raise webob.exc.HTTPBadRequest() + + # Authenticated! + req.headers['X-Auth-Token'] = token_id + return self._application + + +def filter_factory(global_conf, **local_conf): + """Returns a WSGI filter app for use with paste.deploy.""" + conf = global_conf.copy() + conf.update(local_conf) + + def auth_filter(app): + return EC2Token(app, conf) + return auth_filter + + +def app_factory(global_conf, **local_conf): + conf = global_conf.copy() + conf.update(local_conf) + return EC2Token(None, conf) -- cgit 1.2.3-korg