From d594764f20bedea12071fb83762b32f0a137e4cc Mon Sep 17 00:00:00 2001 From: Patrick Uiterwijk Date: Oct 05 2016 19:12:40 +0000 Subject: Add test case for root bound Ipsilon instance Signed-off-by: Patrick Uiterwijk Reviewed-by: Howard Johnson --- diff --git a/Makefile b/Makefile index 6867694..594aada 100644 --- a/Makefile +++ b/Makefile @@ -90,6 +90,7 @@ TESTDIR := $(shell mktemp --directory /tmp/ipsilon-testdir.XXXXXXXX) tests: wrappers echo "Testdir: $(TESTDIR)" PYTHONPATH=./ ./tests/tests.py --path=$(TESTDIR) --test=test1 + PYTHONPATH=./ ./tests/tests.py --path=$(TESTDIR) --test=testroot PYTHONPATH=./ ./tests/tests.py --path=$(TESTDIR) --test=testlogout PYTHONPATH=./ ./tests/tests.py --path=$(TESTDIR) --test=testnameid PYTHONPATH=./ ./tests/tests.py --path=$(TESTDIR) --test=testrest diff --git a/tests/helpers/http.py b/tests/helpers/http.py index 1f8ab47..2fad577 100755 --- a/tests/helpers/http.py +++ b/tests/helpers/http.py @@ -80,6 +80,12 @@ class HttpSessions(object): raise ValueError("Unknown URL: %s" % url) + def get_idp_uri(self, idp): + if idp == 'root': + return '' + else: + return '/%s' % idp + def get(self, url, krb=False, **kwargs): session = self.get_session(url) allow_redirects = False @@ -336,7 +342,7 @@ class HttpSessions(object): def auth_to_idp(self, idp, krb=False, rule=None, expected=None): srv = self.servers[idp] - target_url = '%s/%s/' % (srv['baseuri'], idp) + target_url = '%s%s/' % (srv['baseuri'], self.get_idp_uri(idp)) r = self.access('get', target_url, krb=krb) if r.status_code != 200: @@ -359,7 +365,7 @@ class HttpSessions(object): def logout_from_idp(self, idp): srv = self.servers[idp] - target_url = '%s/%s/logout' % (srv['baseuri'], idp) + target_url = '%s%s/logout' % (srv['baseuri'], self.get_idp_uri(idp)) r = self.access('get', target_url) if r.status_code != 200: @@ -378,7 +384,8 @@ class HttpSessions(object): expected_status = 200 idpsrv = self.servers[idp] idpuri = idpsrv['baseuri'] - url = '%s/%s/admin/providers/saml2/admin/new' % (idpuri, idp) + url = '%s%s/admin/providers/saml2/admin/new' % (idpuri, + self.get_idp_uri(idp)) headers = {'referer': url} if rest: expected_status = 201 @@ -390,7 +397,9 @@ class HttpSessions(object): 'splink': 'https://test.example.com/secret/', } headers['content-type'] = 'application/x-www-form-urlencoded' - url = '%s/%s/rest/providers/saml2/SPS/%s' % (idpuri, idp, desc) + url = '%s%s/rest/providers/saml2/SPS/%s' % (idpuri, + self.get_idp_uri(idp), + desc) r = self.post(url, headers=headers, data=urlencode(payload)) else: metafile = {'metafile': m} @@ -410,7 +419,8 @@ class HttpSessions(object): """ idpsrv = self.servers[idp] idpuri = idpsrv['baseuri'] - url = '%s/%s/admin/providers/saml2/admin/sp/%s' % (idpuri, idp, sp) + url = '%s%s/admin/providers/saml2/admin/sp/%s' % ( + idpuri, self.get_idp_uri(idp), sp) headers = {'referer': url} headers['content-type'] = 'application/x-www-form-urlencoded' payload = {'submit': 'Submit', @@ -439,8 +449,8 @@ class HttpSessions(object): idpsrv = self.servers[idp] idpuri = idpsrv['baseuri'] if spname: # per-SP setting - url = '%s/%s/admin/providers/saml2/admin/sp/%s' % ( - idpuri, idp, spname) + url = '%s%s/admin/providers/saml2/admin/sp/%s' % ( + idpuri, self.get_idp_uri(idp), spname) mapname = 'Attribute Mapping' attrname = 'Allowed Attributes' else: # global default @@ -476,9 +486,9 @@ class HttpSessions(object): idpsrv = self.servers[idp] idpuri = idpsrv['baseuri'] - url = '%s/%s/admin/loginstack/%s/enable/%s' % ( - idpuri, idp, plugtype, plugin) - rurl = '%s/%s/admin/loginstack' % (idpuri, idp) + url = '%s%s/admin/loginstack/%s/enable/%s' % ( + idpuri, self.get_idp_uri(idp), plugtype, plugin) + rurl = '%s%s/admin/loginstack' % (idpuri, self.get_idp_uri(idp)) headers = {'referer': rurl} r = idpsrv['session'].get(url, headers=headers) if r.status_code != 200: @@ -495,9 +505,9 @@ class HttpSessions(object): idpsrv = self.servers[idp] idpuri = idpsrv['baseuri'] - url = '%s/%s/admin/loginstack/%s/disable/%s' % ( - idpuri, idp, plugtype, plugin) - rurl = '%s/%s/admin/loginstack' % (idpuri, idp) + url = '%s%s/admin/loginstack/%s/disable/%s' % ( + idpuri, self.get_idp_uri(idp), plugtype, plugin) + rurl = '%s%s/admin/loginstack' % (idpuri, self.get_idp_uri(idp)) headers = {'referer': rurl} r = idpsrv['session'].get(url, headers=headers) if r.status_code != 200: @@ -514,8 +524,8 @@ class HttpSessions(object): idpsrv = self.servers[idp] idpuri = idpsrv['baseuri'] - url = '%s/%s/admin/loginstack/%s/order' % ( - idpuri, idp, plugtype) + url = '%s%s/admin/loginstack/%s/order' % ( + idpuri, self.get_idp_uri(idp), plugtype) headers = {'referer': url} headers['content-type'] = 'application/x-www-form-urlencoded' payload = {'order': ','.join(order)} @@ -530,8 +540,8 @@ class HttpSessions(object): idpsrv = self.servers[idp] idpuri = idpsrv['baseuri'] - url = '%s/%s/admin/providers/openidc/admin/client/%s/delete' % ( - idpuri, idp, client_id) + url = '%s%s/admin/providers/openidc/admin/client/%s/delete' % ( + idpuri, self.get_idp_uri(idp), client_id) headers = {'referer': url} headers['content-type'] = 'application/x-www-form-urlencoded' r = idpsrv['session'].get(url, headers=headers) @@ -560,8 +570,9 @@ class HttpSessions(object): def get_rest_sp(self, idpname, spname=None): if spname is None: - uri = '/%s/rest/providers/saml2/SPS/' % idpname + uri = '%s/rest/providers/saml2/SPS/' % self.get_idp_uri(idpname) else: - uri = '/%s/rest/providers/saml2/SPS/%s' % (idpname, spname) + uri = '%s/rest/providers/saml2/SPS/%s' % ( + self.get_idp_uri(idpname), spname) return self.fetch_rest_page(idpname, uri) diff --git a/tests/testroot.py b/tests/testroot.py new file mode 100755 index 0000000..353de5a --- /dev/null +++ b/tests/testroot.py @@ -0,0 +1,196 @@ +#!/usr/bin/python +# +# Copyright (C) 2014 Ipsilon project Contributors, for license see COPYING + +from helpers.common import IpsilonTestBase # pylint: disable=relative-import +from helpers.http import HttpSessions # pylint: disable=relative-import +import os +import pwd +import sys +from string import Template + +idp_g = {'TEMPLATES': '${TESTDIR}/templates/install', + 'CONFDIR': '${TESTDIR}/etc', + 'DATADIR': '${TESTDIR}/lib', + 'CACHEDIR': '${TESTDIR}/cache', + 'HTTPDCONFD': '${TESTDIR}/${NAME}/conf.d', + 'STATICDIR': '${ROOTDIR}', + 'BINDIR': '${ROOTDIR}/ipsilon', + 'WSGI_SOCKET_PREFIX': '${TESTDIR}/${NAME}/logs/wsgi'} + + +idp_a = {'hostname': '${ADDRESS}:${PORT}', + 'admin_user': '${TEST_USER}', + 'system_user': '${TEST_USER}', + 'root_instance': True, + 'testauth': 'yes', + 'pam': 'no', + 'gssapi': 'no', + 'ipa': 'no', + 'server_debugging': 'True'} + + +sp_g = {'HTTPDCONFD': '${TESTDIR}/${NAME}/conf.d', + 'SAML2_TEMPLATE': '${TESTDIR}/templates/install/saml2/sp.conf', + 'CONFFILE': '${TESTDIR}/${NAME}/conf.d/ipsilon-%s.conf', + 'HTTPDIR': '${TESTDIR}/${NAME}/%s'} + + +sp_a = {'hostname': '${ADDRESS}', + 'saml_idp_metadata': 'https://127.0.0.10:45080/saml2/metadata', + 'saml_auth': '/sp', + 'httpd_user': '${TEST_USER}'} + +sp2_g = {'HTTPDCONFD': '${TESTDIR}/${NAME}/conf.d', + 'SAML2_TEMPLATE': '${TESTDIR}/templates/install/saml2/sp.conf', + 'CONFFILE': '${TESTDIR}/${NAME}/conf.d/ipsilon-%s.conf', + 'HTTPDIR': '${TESTDIR}/${NAME}/%s'} + +sp2_a = {'hostname': '${ADDRESS}', + 'saml_idp_url': 'https://127.0.0.10:45080/', + 'admin_user': '${TEST_USER}', + 'admin_password': '${TESTDIR}/pw.txt', + 'saml_sp_name': 'sp2-test.example.com', + 'saml_auth': '/sp', + 'httpd_user': '${TEST_USER}'} + +keyless_metadata = """ + + + + +urn:oasis:names:tc:SAML:2.0:nameid-format:transient + + +""" + + +def fixup_sp_httpd(httpdir): + location = """ + +Alias /sp ${HTTPDIR}/sp + + + + Require all granted + + + Order Allow,Deny + Allow from All + + +""" + index = """WORKS!""" + + t = Template(location) + text = t.substitute({'HTTPDIR': httpdir}) + with open(httpdir + '/conf.d/ipsilon-saml.conf', 'a') as f: + f.write(text) + + os.mkdir(httpdir + '/sp') + with open(httpdir + '/sp/index.html', 'w') as f: + f.write(index) + + +class IpsilonTest(IpsilonTestBase): + + def __init__(self): + super(IpsilonTest, self).__init__('testroot', __file__) + + def setup_servers(self, env=None): + print "Installing IDP server" + name = 'root' + addr = '127.0.0.10' + port = '45080' + idp = self.generate_profile(idp_g, idp_a, name, addr, port) + conf = self.setup_idp_server(idp, name, addr, port, env) + + print "Starting IDP's httpd server" + self.start_http_server(conf, env) + + print "Installing first SP server" + name = 'sp1' + addr = '127.0.0.11' + port = '45081' + sp = self.generate_profile(sp_g, sp_a, name, addr, port) + conf = self.setup_sp_server(sp, name, addr, port, env) + fixup_sp_httpd(os.path.dirname(conf)) + + print "Starting first SP's httpd server" + self.start_http_server(conf, env) + + print "Installing second SP server" + name = 'sp2-test.example.com' + addr = '127.0.0.11' + port = '45082' + sp = self.generate_profile(sp2_g, sp2_a, name, addr, port) + with open(os.path.dirname(sp) + '/pw.txt', 'a') as f: + f.write('ipsilon') + conf = self.setup_sp_server(sp, name, addr, port, env) + os.remove(os.path.dirname(sp) + '/pw.txt') + fixup_sp_httpd(os.path.dirname(conf)) + + print "Starting second SP's httpd server" + self.start_http_server(conf, env) + + +if __name__ == '__main__': + + idpname = 'root' + sp1name = 'sp1' + sp2name = 'sp2-test.example.com' + user = pwd.getpwuid(os.getuid())[0] + + sess = HttpSessions() + sess.add_server(idpname, 'https://127.0.0.10:45080', user, 'ipsilon') + sess.add_server(sp1name, 'https://127.0.0.11:45081') + sess.add_server(sp2name, 'https://127.0.0.11:45082') + + print "testroot: Authenticate to IDP ...", + try: + sess.auth_to_idp(idpname) + except Exception, e: # pylint: disable=broad-except + print >> sys.stderr, " ERROR: %s" % repr(e) + sys.exit(1) + print " SUCCESS" + + print "testroot: Add first SP Metadata to IDP ...", + try: + sess.add_sp_metadata(idpname, sp1name) + except Exception, e: # pylint: disable=broad-except + print >> sys.stderr, " ERROR: %s" % repr(e) + sys.exit(1) + print " SUCCESS" + + print "testroot: Access first SP Protected Area ...", + try: + page = sess.fetch_page(idpname, 'https://127.0.0.11:45081/sp/') + page.expected_value('text()', 'WORKS!') + except ValueError, e: + print >> sys.stderr, " ERROR: %s" % repr(e) + sys.exit(1) + print " SUCCESS" + + print "testroot: Access second SP Protected Area ...", + try: + page = sess.fetch_page(idpname, 'https://127.0.0.11:45082/sp/') + page.expected_value('text()', 'WORKS!') + except ValueError, e: + print >> sys.stderr, " ERROR: %s" % repr(e) + sys.exit(1) + print " SUCCESS" + + print "testroot: Try authentication failure ...", + newsess = HttpSessions() + newsess.add_server(idpname, 'https://127.0.0.10:45080', user, 'wrong') + try: + newsess.auth_to_idp(idpname) + print >> sys.stderr, " ERROR: Authentication should have failed" + sys.exit(1) + except Exception, e: # pylint: disable=broad-except + print " SUCCESS"