From 20ecd99441ba8fc3d58b05d55c08eb17dd43b024 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 2 May 2011 13:26:46 +0530 Subject: Added latest changes to sirish branch with pagination for get tenants --- echo/echo/echo.py | 106 +++++++++++++++++++++++++++++++++-------------- echo/echo/echo_basic.ini | 36 ++++++++++++++++ echo/echo_client.py | 24 +++++++++++ 3 files changed, 134 insertions(+), 32 deletions(-) create mode 100644 echo/echo/echo_basic.ini (limited to 'echo') diff --git a/echo/echo/echo.py b/echo/echo/echo.py index ee950b37..e7fa38d3 100644 --- a/echo/echo/echo.py +++ b/echo/echo/echo.py @@ -14,13 +14,14 @@ # See the License for the specific language governing permissions and # limitations under the License. -import os -import sys - import eventlet from eventlet import wsgi from lxml import etree +import os from paste.deploy import loadapp +import sys +from webob.exc import HTTPUnauthorized + # If ../echo/__init__.py exists, add ../ to Python search path, so that # it will override what happens to be installed in /usr/(local/)lib/python... @@ -53,14 +54,27 @@ class EchoApp(object): self.transform = etree.XSLT(etree.parse(echo_xsl)) def __iter__(self): + # We expect an X_AUTHORIZATION header to be passed in + # We assume the request is coming from a trusted source. Middleware + # is used to perform that validation. if 'HTTP_X_AUTHORIZATION' not in self.envr: - return HTTPUnauthorized(self.envr, start_response) + self.start('401 Unauthorized', [('Content-Type', + 'application/json')]) + return iter(["401 Unauthorized"]) + + if 'HTTP_X_IDENTITY_STATUS' not in self.envr: + identity_status = "Unknown" + else: + identity_status = self.envr["HTTP_X_IDENTITY_STATUS"] print ' Received:' - if 'HTTP_X_IDENTITY_STATUS' in self.envr: print ' Auth Status:', self.envr['HTTP_X_IDENTITY_STATUS'] - if 'HTTP_X_AUTHORIZATION' in self.envr: print ' Identity :', self.envr['HTTP_X_AUTHORIZATION'] - if 'HTTP_X_TENANT' in self.envr: print ' Tenant :', self.envr['HTTP_X_TENANT'] - if 'HTTP_X_GROUP' in self.envr: print ' Group :', self.envr['HTTP_X_GROUP'] + print ' Auth Status:', identity_status + if 'HTTP_X_AUTHORIZATION' in self.envr: + print ' Identity :', self.envr['HTTP_X_AUTHORIZATION'] + if 'HTTP_X_TENANT' in self.envr: + print ' Tenant :', self.envr['HTTP_X_TENANT'] + if 'HTTP_X_GROUP' in self.envr: + print ' Group :', self.envr['HTTP_X_GROUP'] accept = self.envr.get("HTTP_ACCEPT", "application/json") if accept == "application/xml": @@ -80,8 +94,7 @@ class EchoApp(object): echo = etree.Element("{http://docs.openstack.org/echo/api/v1.0}echo", method=environ["REQUEST_METHOD"], pathInfo=environ["PATH_INFO"], - queryString=environ.get('QUERY_STRING', ""), - caller_identity=self.envr['HTTP_X_AUTHORIZATION']) + queryString=environ.get('QUERY_STRING', "")) content = etree.Element( "{http://docs.openstack.org/echo/api/v1.0}content") content.set("type", environ["CONTENT_TYPE"]) @@ -97,25 +110,54 @@ def app_factory(global_conf, **local_conf): return EchoApp if __name__ == "__main__": - remote_auth = False - if len(sys.argv) > 1: - remote_auth = sys.argv[1] == '--remote' - - if remote_auth: - # running auth remotely - print "Running for use with remote auth" - - app = loadapp("config:" + \ - os.path.join(os.path.abspath(os.path.dirname(__file__)), - "echo_remote.ini"), global_conf={"log_name": "echo.log"}) - - wsgi.server(eventlet.listen(('', 8100)), app) - - else: - print "Running all components locally." - print "Use --remote option to run with remote auth proxy" - app = loadapp("config:" + \ - os.path.join(os.path.abspath(os.path.dirname(__file__)), - "echo.ini"), global_conf={"log_name": "echo.log"}) - - wsgi.server(eventlet.listen(('', 8090)), app) + def usage(): + print "Runs Echo, the canonical OpenStack service, " \ + "with auth middleware" + print "Options:" + print "-h, --help : show this usage information" + print "-b, --basic : run with basic auth (uses echo_basic.ini)" + print "-r, --remote: run with remote auth on port 8100" \ + "(uses echo_remote.ini)" + print "-i, --ini filename: run with specified ini file" + print "-p, --port: specifies port to listen on (default is 8090)" + print "by default will run with local, token auth (uses echo.ini)" + + import getopt + try: + opts, args = getopt.getopt(sys.argv[1:], + "hbrp:i:", + ["help", "basic", "remote", "port", "ini"]) + except getopt.GetoptError: + usage() + sys.exit() + + port = 0 + ini = "echo.ini" + auth_name = "local Token Auth" + + for opt, arg in opts: + if opt in ["-h", "--help"]: + usage() + sys.exit() + elif opt in ["-p", "--port"]: + port = int(arg) + elif opt in ["-i", "--ini"]: + auth_name = "with custom ini: %s" % arg + ini = arg + elif opt in ["-b", "--basic"]: + auth_name = "Basic Auth" + ini = "echo_basic.ini" + elif opt in ["-r", "--remote"]: + auth_name = "remote Token Auth" + ini = "echo_remote.ini" + if not port: + port = 8100 + + if not port: + port = 8090 + print "Running with", auth_name + app = loadapp("config:" + \ + os.path.join(os.path.abspath(os.path.dirname(__file__)), + ini), global_conf={"log_name": "echo.log"}) + + wsgi.server(eventlet.listen(('', port)), app) diff --git a/echo/echo/echo_basic.ini b/echo/echo/echo_basic.ini new file mode 100644 index 00000000..38da0c66 --- /dev/null +++ b/echo/echo/echo_basic.ini @@ -0,0 +1,36 @@ +[DEFAULT] +;delegated means we still allow unauthenticated requests through so the +;service can make the final decision on authentication +delay_auth_decision = 0 + +;where to find the OpenStack service (if not in local WSGI chain) +service_protocol = http +service_host = 127.0.0.1 +service_port = 8090 +;used to verify this component with the OpenStack service (or PAPIAuth) +service_pass = dTpw + + +[app:echo] +paste.app_factory = echo:app_factory + +[pipeline:main] +pipeline = + basicauth + echo + +[filter:tokenauth] +paste.filter_factory = keystone:tokenauth_factory +;where to find the token auth service +auth_host = 127.0.0.1 +auth_port = 8080 +auth_protocol = http +;how to authenticate to the auth service for priviledged operations +;like validate token +admin_token = 999888777666 + +[filter:basicauth] +paste.filter_factory = keystone:basicauth_factory + +[filter:openidauth] +paste.filter_factory = keystone:openidauth_factory diff --git a/echo/echo_client.py b/echo/echo_client.py index 677e8ab9..a06adbe4 100644 --- a/echo/echo_client.py +++ b/echo/echo_client.py @@ -19,6 +19,7 @@ Implement a client for Echo service using Identity service import httplib import json +import sys def get_auth_token(username, password, tenant): @@ -46,6 +47,23 @@ def call_service(token): ret = data return ret + +def hack_attempt(token): + # Injecting headers in the request + headers = {"X-Auth-Token": token, + "Content-type": "application/json", + "Accept": "text/json\nX_AUTHORIZATION: someone else\n" + "X_IDENTITY_STATUS: Confirmed\nINJECTED_HEADER: aha!"} + params = '{"ping": "abcdefg"}' + conn = httplib.HTTPConnection("localhost:8090") + print headers + conn.request("POST", "/", params, headers=headers) + response = conn.getresponse() + data = response.read() + ret = data + return ret + + if __name__ == '__main__': # Call the keystone service to get a token # NOTE: assumes the test_setup.sql script has loaded this user @@ -60,6 +78,12 @@ if __name__ == '__main__': print "Response received:", data print + # Use the valid token, but inject some headers + print "\033[91mInjecting some headers >:-/ \033[0m" + data = hack_attempt(token) + print "Response received:", data + print + # Use bad token to call an OpenStack service (echo) print "\033[91mTrying with bad token...\033[0m" data = call_service("xxxx_invalid_token_xxxx") -- cgit