X-Git-Url: http://git.cascardo.eti.br/?a=blobdiff_plain;f=tests%2Ftestlogout.py;h=268a6840b967cc3e20398c8d84ccd121b1b48408;hb=HEAD;hp=ecb8fdc153e1149cca20d1c23f352b68ccc77d4f;hpb=7b0f5a1d712090b19e8765ff4cf8f7242ccc3144;p=cascardo%2Fipsilon.git diff --git a/tests/testlogout.py b/tests/testlogout.py index ecb8fdc..268a684 100755 --- a/tests/testlogout.py +++ b/tests/testlogout.py @@ -1,22 +1,6 @@ #!/usr/bin/python # -# Copyright (C) 2015 Rob Crittenden -# -# see file 'COPYING' for use and warranty information -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - +# Copyright (C) 2015 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 @@ -29,6 +13,7 @@ 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', @@ -42,7 +27,7 @@ idp_a = {'hostname': '${ADDRESS}:${PORT}', 'secure': 'no', 'testauth': 'yes', 'pam': 'no', - 'krb': 'no', + 'gssapi': 'no', 'ipa': 'no', 'server_debugging': 'True'} @@ -60,6 +45,44 @@ sp_a = {'hostname': '${ADDRESS}:${PORT}', 'httpd_user': '${TEST_USER}'} +sp_b = {'hostname': '${ADDRESS}:${PORT}', + 'saml_idp_metadata': 'http://127.0.0.10:45080/idp1/saml2/metadata', + 'saml_secure_setup': 'False', + 'no_saml_soap_logout': 'True', + 'saml_auth': '/sp', + 'httpd_user': '${TEST_USER}'} + + +# Global list of SP's +splist = [ + { + 'nameid': 'sp1', + 'addr': '127.0.0.11', + 'port': '45081', + }, + { + 'nameid': 'sp2', + 'addr': '127.0.0.11', + 'port': '45082', + }, + { + 'nameid': 'sp3', + 'addr': '127.0.0.11', + 'port': '45083', + }, + { + 'nameid': 'sp4', + 'addr': '127.0.0.11', + 'port': '45084', + }, + { + 'nameid': 'sp5', + 'addr': '127.0.0.11', + 'port': '45085', + }, +] + + def fixup_sp_httpd(httpdir): location = """ @@ -90,6 +113,25 @@ Alias /open ${HTTPDIR}/open f.write(logged_out) +def ensure_logout(session, idp_name, sp_url): + """ + Fetch the secure page without following redirects. If we get + a 303 then we should be redirected to the IDP for authentication + which means we aren't logged in. + + Returns nothing or raises exception on error + """ + try: + logout_page = session.fetch_page(idp_name, sp_url, + follow_redirect=False) + if logout_page.result.status_code != 303: + raise ValueError('Still logged into url') + except ValueError: + raise + + return True + + class IpsilonTest(IpsilonTestBase): def __init__(self): @@ -106,27 +148,41 @@ class IpsilonTest(IpsilonTestBase): print "Starting IDP's httpd server" self.start_http_server(conf, env) - print "Installing 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 SP's httpd server" - self.start_http_server(conf, env) + for spdata in splist: + nameid = spdata['nameid'] + addr = spdata['addr'] + port = spdata['port'] + print "Installing SP server %s" % nameid + + # Configure sp3 and sp4 for only HTTP Redirect to test + # that a mix of SOAP and HTTP Redirect will play nice + # together. + if nameid in ['sp3', 'sp4']: + sp_prof = self.generate_profile( + sp_g, sp_b, nameid, addr, str(port), nameid + ) + else: + sp_prof = self.generate_profile( + sp_g, sp_a, nameid, addr, str(port), nameid + ) + conf = self.setup_sp_server(sp_prof, nameid, addr, str(port), env) + fixup_sp_httpd(os.path.dirname(conf)) + + print "Starting SP's httpd server" + self.start_http_server(conf, env) if __name__ == '__main__': idpname = 'idp1' - spname = 'sp1' user = pwd.getpwuid(os.getuid())[0] sess = HttpSessions() sess.add_server(idpname, 'http://127.0.0.10:45080', user, 'ipsilon') - sess.add_server(spname, 'http://127.0.0.11:45081') + for sp in splist: + spname = sp['nameid'] + spurl = 'http://%s:%s' % (sp['addr'], sp['port']) + sess.add_server(spname, spurl) print "testlogout: Authenticate to IDP ...", try: @@ -136,13 +192,15 @@ if __name__ == '__main__': sys.exit(1) print " SUCCESS" - print "testlogout: Add SP Metadata to IDP ...", - try: - sess.add_sp_metadata(idpname, spname) - except Exception, e: # pylint: disable=broad-except - print >> sys.stderr, " ERROR: %s" % repr(e) - sys.exit(1) - print " SUCCESS" + for sp in splist: + spname = sp['nameid'] + print "testlogout: Add SP Metadata for %s to IDP ..." % spname, + try: + sess.add_sp_metadata(idpname, spname) + except Exception, e: # pylint: disable=broad-except + print >> sys.stderr, " ERROR: %s" % repr(e) + sys.exit(1) + print " SUCCESS" print "testlogout: Logout without logging into SP ...", try: @@ -174,3 +232,137 @@ if __name__ == '__main__': print >> sys.stderr, " ERROR: %s" % repr(e) sys.exit(1) print " SUCCESS" + + print "testlogout: Try logout again ...", + try: + page = sess.fetch_page(idpname, '%s/%s?%s' % ( + 'http://127.0.0.11:45081', 'saml2/logout', + 'ReturnTo=http://127.0.0.11:45081/open/logged_out.html')) + page.expected_value('text()', 'Logged out') + except ValueError, e: + print >> sys.stderr, " ERROR: %s" % repr(e) + sys.exit(1) + print " SUCCESS" + + print "testlogout: Ensure logout ...", + try: + ensure_logout(sess, idpname, 'http://127.0.0.11:45081/sp/') + except ValueError, e: + print >> sys.stderr, " ERROR: %s" % repr(e) + sys.exit(1) + print " SUCCESS" + + # Test logout from each of the SP's in the list to ensure that the + # order of logout doesn't matter. + for sporder in splist: + print "testlogout: Access SP Protected Area of each SP ...", + for sp in splist: + spname = sp['nameid'] + spurl = 'http://%s:%s/sp/' % (sp['addr'], sp['port']) + try: + page = sess.fetch_page(idpname, spurl) + page.expected_value('text()', 'WORKS!') + except ValueError, e: + print >> sys.stderr, " ERROR: %s" % repr(e) + sys.exit(1) + print " SUCCESS" + + print "testlogout: Initiate logout from %s ..." % sporder['nameid'], + try: + logouturl = 'http://%s:%s' % (sp['addr'], sp['port']) + page = sess.fetch_page(idpname, '%s/%s?%s' % ( + logouturl, 'saml2/logout', + 'ReturnTo=http://127.0.0.11:45081/open/logged_out.html')) + page.expected_value('text()', 'Logged out') + except ValueError, e: + print >> sys.stderr, " ERROR: %s" % repr(e) + sys.exit(1) + print " SUCCESS" + + print "testlogout: Ensure logout of each SP ...", + for sp in splist: + spname = sp['nameid'] + spurl = 'http://%s:%s/sp/' % (sp['addr'], sp['port']) + try: + ensure_logout(sess, idpname, spurl) + except ValueError, e: + print >> sys.stderr, " ERROR: %s" % repr(e) + sys.exit(1) + print " SUCCESS" + + # Test IdP-initiated logout + print "testlogout: Access SP Protected Area of SP1...", + try: + page = sess.fetch_page(idpname, 'http://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 "testlogout: Access SP Protected Area of SP2...", + try: + page = sess.fetch_page(idpname, 'http://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 "testlogout: Access the IdP...", + try: + page = sess.fetch_page(idpname, 'http://127.0.0.10:45080/%s' % idpname) + page.expected_value('//div[@id="welcome"]/p/text()', + 'Welcome %s!' % user) + except ValueError, e: + print >> sys.stderr, " ERROR: %s" % repr(e) + sys.exit(1) + print " SUCCESS" + + print "testlogout: IdP-initiated logout ...", + try: + page = sess.fetch_page(idpname, + 'http://127.0.0.10:45080/%s/logout' % idpname) + page.expected_value('//div[@id="content"]/p/a/text()', 'Log In') + except ValueError, e: + print >> sys.stderr, " ERROR: %s" % repr(e) + sys.exit(1) + print " SUCCESS" + + print "testlogout: Ensure logout of SP1 ...", + try: + ensure_logout(sess, idpname, 'http://127.0.0.11:45081/sp/') + except ValueError, e: + print >> sys.stderr, " ERROR: %s" % repr(e) + sys.exit(1) + print " SUCCESS" + + print "testlogout: Ensure logout of SP2 ...", + try: + ensure_logout(sess, idpname, 'http://127.0.0.11:45082/sp/') + except ValueError, e: + print >> sys.stderr, " ERROR: %s" % repr(e) + sys.exit(1) + print " SUCCESS" + + print "testlogout: Access the IdP...", + try: + page = sess.fetch_page(idpname, + 'http://127.0.0.10:45080/%s/login' % idpname) + page.expected_value('//div[@id="welcome"]/p/text()', + 'Welcome %s!' % user) + except ValueError, e: + print >> sys.stderr, " ERROR: %s" % repr(e) + sys.exit(1) + print " SUCCESS" + + print "testlogout: IdP-initiated logout with no SP sessions...", + try: + page = sess.fetch_page(idpname, + 'http://127.0.0.10:45080/%s/logout' % idpname) + page.expected_value('//div[@id="logout"]/p//text()', + 'Successfully logged out.') + except ValueError, e: + print >> sys.stderr, " ERROR: %s" % repr(e) + sys.exit(1) + print " SUCCESS"