From be55bdf7ee36ad38b25b5f79fc4b82edb2557148 Mon Sep 17 00:00:00 2001 From: John Dennis Date: Mon, 26 Jan 2015 16:04:40 -0500 Subject: Implement ECP in Ipsilon * add saml2/SSO/SOAP endpoint. * add check for lasso version, ECP endpoint only exposed in metadata if lasso has full ECP support. * add SSO_SOAP soap authentication handler (used for ECP). * add SAML binding to transaction so we can determine if cookies and other HTTP concepts are expected. Each handler is responsible for setting the binding. * add some constants needed for ECP https://fedorahosted.org/ipsilon/ticket/4 Signed-off-by: John Dennis Reviewed-by: Rob Crittenden --- ipsilon/util/http.py | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 ipsilon/util/http.py (limited to 'ipsilon/util/http.py') diff --git a/ipsilon/util/http.py b/ipsilon/util/http.py new file mode 100644 index 0000000..fa9d725 --- /dev/null +++ b/ipsilon/util/http.py @@ -0,0 +1,68 @@ +# Copyright (C) 2015 Ipsilon project Contributors, for license see COPYING + +import cherrypy +import fnmatch + + +def require_content_type(required=None, absent_ok=True, debug=False): + '''CherryPy Tool that validates request Content-Type. + + This is a CherryPy Tool that checks the Content-Type in a request and + raises HTTP Error 415 "Unsupported Media Type" if it does not match. + + The tool accepts a glob style pattern or list of patterns (see fnmatch) + and verifies the Content-Type in the request matches at least one of + the patterns, if not a HTTP Error 415 "Unsupported Media Type" is raised. + + If absent_ok is False and if the request does not contain a + Content-Type header a HTTP Error 415 "Unsupported Media Type" is + raised. + + The tool may be deployed use any of the standard methods for + invoking CherryPy tools, for example as a decorator: + + @cherrypy.tools.require_content_type(required='text/xml') + def POST(self, *args, **kwargs): + pass + + :param required: May be a single string or a list of strings. Each + string is interpreted as a glob style pattern (see fnmatch). + The Content-Type must match at least one pattern. + + :param absent_ok: Boolean specifying if the Content-Type header + must be present or if it is OK to be absent. + + ''' + if required is None: + return + + if isinstance(required, basestring): + required = [required] + + content_type = cherrypy.request.body.content_type.value + pattern = None + match = False + if content_type: + for pattern in required: + if fnmatch.fnmatch(content_type, pattern): + match = True + break + else: + if absent_ok: + return + + if debug: + cherrypy.log('require_content_type: required=%s, absent_ok=%s ' + 'content_type=%s match=%s pattern=%s' % + required, absent_ok, content_type, match, pattern) + + if not match: + acceptable = ', '.join(['"%s"' % x for x in required]) + if content_type: + content_type = '"%s"' % content_type + else: + content_type = 'not specified' + message = ('Content-Type must match one of following patterns [%s], ' + 'but the Content-Type was %s' % + (acceptable, content_type)) + raise cherrypy.HTTPError(415, message=message) -- cgit