summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRob Crittenden <rcritten@redhat.com>2015-03-19 15:20:28 -0400
committerRob Crittenden <rcritten@redhat.com>2015-03-23 17:39:27 -0400
commita1b380865b4068eb5ed48204c041c3def09dc463 (patch)
tree3b84e6a0eb5e8164b5e3ec02579a4a89697681b8
parentd04f6d2bf4842d18a66325be4caa83ac2820330d (diff)
downloadipsilon.git-nameid_policy.tar.gz
ipsilon.git-nameid_policy.tar.xz
ipsilon.git-nameid_policy.zip
Add tests for Name ID functionalitynameid_policy
Some Name ID formats are not implemented so are expected to fail. Kerberos is implemented but the test is done using form authentication so no Kerberos principal is available so authentication is denied. https://fedorahosted.org/ipsilon/ticket/27 Signed-off-by: Rob Crittenden <rcritten@redhat.com>
-rwxr-xr-xtests/helpers/common.py4
-rwxr-xr-xtests/helpers/http.py16
-rw-r--r--tests/httpd.conf7
-rwxr-xr-xtests/testnameid.py336
4 files changed, 362 insertions, 1 deletions
diff --git a/tests/helpers/common.py b/tests/helpers/common.py
index 07a41fe..54702be 100755
--- a/tests/helpers/common.py
+++ b/tests/helpers/common.py
@@ -55,7 +55,8 @@ class IpsilonTestBase(object):
os.mkdir(os.path.join(self.testdir, 'lib', test.name))
os.mkdir(os.path.join(self.testdir, 'log'))
- def generate_profile(self, global_opts, args_opts, name, addr, port):
+ def generate_profile(self, global_opts, args_opts, name, addr, port,
+ nameid='transient'):
newconf = ConfigParser.ConfigParser()
newconf.add_section('globals')
for k in global_opts.keys():
@@ -71,6 +72,7 @@ class IpsilonTestBase(object):
text = t.substitute({'NAME': name, 'ADDRESS': addr, 'PORT': port,
'TESTDIR': self.testdir,
'ROOTDIR': self.rootdir,
+ 'NAMEID': nameid,
'TEST_USER': self.testuser})
filename = os.path.join(self.testdir, '%s_profile.cfg' % name)
diff --git a/tests/helpers/http.py b/tests/helpers/http.py
index cf59853..d8c56b3 100755
--- a/tests/helpers/http.py
+++ b/tests/helpers/http.py
@@ -266,6 +266,22 @@ class HttpSessions(object):
page.expected_value('//div[@class="alert alert-success"]/p/text()',
'SP Successfully added')
+ def set_sp_default_nameids(self, idp, sp, nameids):
+ """
+ nameids is a list of Name ID formats to enable
+ """
+ idpsrv = self.servers[idp]
+ idpuri = idpsrv['baseuri']
+ url = '%s/%s/admin/providers/saml2/admin/sp/%s' % (idpuri, idp, sp)
+ headers = {'referer': url}
+ headers['content-type'] = 'application/x-www-form-urlencoded'
+ payload = {'submit': 'Submit',
+ 'allowed_nameids': ', '.join(nameids)}
+ r = idpsrv['session'].post(url, headers=headers,
+ data=payload)
+ if r.status_code != 200:
+ raise ValueError('Failed to post SP data [%s]' % repr(r))
+
def fetch_rest_page(self, idpname, uri):
"""
idpname - the name of the IDP to fetch the page from
diff --git a/tests/httpd.conf b/tests/httpd.conf
index a326523..8d0949e 100644
--- a/tests/httpd.conf
+++ b/tests/httpd.conf
@@ -65,6 +65,13 @@ LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
LoadModule wsgi_module modules/mod_wsgi.so
LoadModule auth_mellon_module modules/mod_auth_mellon.so
+<IfModule mpm_worker_module>
+ LoadModule cgid_module modules/mod_cgid.so
+</IfModule>
+<IfModule mpm_prefork_module>
+ LoadModule cgi_module modules/mod_cgi.so
+</IfModule>
+
<Directory />
AllowOverride none
Require all denied
diff --git a/tests/testnameid.py b/tests/testnameid.py
new file mode 100755
index 0000000..a47e44b
--- /dev/null
+++ b/tests/testnameid.py
@@ -0,0 +1,336 @@
+#!/usr/bin/python
+# Copyright (C) 2015 Ipsilon Project Contributors
+
+from helpers.common import IpsilonTestBase # pylint: disable=relative-import
+from helpers.http import HttpSessions # pylint: disable=relative-import
+from ipsilon.tools.saml2metadata import SAML2_NAMEID_MAP
+import os
+import pwd
+import sys
+import re
+from string import Template
+
+
+idp_g = {'TEMPLATES': '${TESTDIR}/templates/install',
+ 'CONFDIR': '${TESTDIR}/etc',
+ 'DATADIR': '${TESTDIR}/lib',
+ '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}',
+ 'instance': '${NAME}',
+ 'secure': 'no',
+ 'testauth': 'yes',
+ 'pam': 'no',
+ 'krb': 'no',
+ 'ipa': 'no',
+ 'server_debugging': 'True'}
+
+
+sp_g = {'HTTPDCONFD': '${TESTDIR}/${NAME}/conf.d',
+ 'SAML2_TEMPLATE': '${TESTDIR}/templates/install/saml2/sp.conf',
+ 'SAML2_CONFFILE': '${TESTDIR}/${NAME}/conf.d/ipsilon-saml.conf',
+ 'SAML2_HTTPDIR': '${TESTDIR}/${NAME}/saml2'}
+
+
+sp_a = {'hostname': '${ADDRESS}:${PORT}',
+ 'saml_idp_metadata': 'http://127.0.0.10:45080/idp1/saml2/metadata',
+ 'saml_secure_setup': 'False',
+ 'saml_auth': '/sp',
+ 'saml_nameid': '${NAMEID}',
+ 'httpd_user': '${TEST_USER}'}
+
+
+def generate_sp_list():
+ splist = []
+ spport = 45081
+
+ for nameid in SAML2_NAMEID_MAP.keys():
+ nameid = nameid
+ spdata = {'nameid': nameid, 'addr': '127.0.0.11', 'port': str(spport)}
+ splist.append(spdata)
+ spport += 1
+
+ return splist
+
+
+def get_sp_by_nameid(splist, nameid):
+ for server in splist:
+ if server['nameid'] == nameid:
+ return server
+
+ return None
+
+
+def convert_to_dict(envlist):
+ values = {}
+ for pair in envlist.split('\n'):
+ if pair.find('=') > 0:
+ (key, value) = pair.split('=', 1)
+ values[key] = value
+ return values
+
+
+def fixup_sp_httpd(httpdir):
+ location = """
+
+AddOutputFilter INCLUDES .html
+
+Alias /sp ${HTTPDIR}/sp
+
+<Directory ${HTTPDIR}/sp>
+ Require all granted
+ Options +Includes
+</Directory>
+"""
+ index = """<!--#echo var="REMOTE_USER" -->"""
+
+ 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__('testnameid', __file__)
+
+ def setup_servers(self, env=None):
+ print "Installing IDP server"
+ name = 'idp1'
+ 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)
+
+ for spdata in generate_sp_list():
+ nameid = spdata['nameid']
+ addr = spdata['addr']
+ port = spdata['port']
+ print "Installing SP server %s" % nameid
+ 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'
+ user = pwd.getpwuid(os.getuid())[0]
+
+ expected = {
+ 'x509': False, # not supported
+ 'transient': True,
+ 'persistent': True,
+ 'windows': False, # not supported
+ 'encrypted': False, # not supported
+ 'kerberos': False, # no auth with kerberos, no princ
+ 'email': True,
+ 'unspecified': True,
+ 'entity': False, # not supported
+ }
+
+ expected_re = {
+ 'x509': None, # not supported
+ 'transient': '_[0-9a-f]{32}',
+ 'persistent': '_[0-9a-f]{128}',
+ 'windows': None, # not supported
+ 'encrypted': None, # not supported
+ 'kerberos': False, # no auth with kerberos, no princ
+ 'email': '%s@.*' % user,
+ 'unspecified': user,
+ 'entity': False, # not supported
+ }
+
+ sp_list = generate_sp_list()
+ for sp in sp_list:
+ spname = sp['nameid']
+ spurl = 'http://%s:%s' % (sp['addr'], sp['port'])
+ sess = HttpSessions()
+ sess.add_server(idpname, 'http://127.0.0.10:45080', user, 'ipsilon')
+ sess.add_server(spname, spurl)
+
+ print ""
+ print "testnameid: Testing NameID format %s ..." % spname
+
+ print "testnameid: 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 "testnameid: 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"
+
+ print "testnameid: Set supported Name ID formats ...",
+ try:
+ sess.set_sp_default_nameids(idpname, spname, [spname])
+ except Exception, e: # pylint: disable=broad-except
+ print >> sys.stderr, " ERROR: %s" % repr(e)
+ sys.exit(1)
+ print " SUCCESS"
+
+ print "testnameid: Access SP Protected Area ...",
+ try:
+ page = sess.fetch_page(idpname, '%s/sp/' % spurl)
+ if not re.match(expected_re[spname], page.text):
+ raise ValueError(
+ 'id %s did not match expression %s' %
+ (id, expected_re[spname])
+ )
+ except ValueError, e:
+ if expected[spname]:
+ print >> sys.stderr, " ERROR: %s" % repr(e)
+ sys.exit(1)
+ print " OK, EXPECTED TO FAIL"
+ else:
+ print " SUCCESS"
+
+ print "testnameid: Try authentication failure ...",
+ newsess = HttpSessions()
+ newsess.add_server(idpname, 'http://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"
+
+ # Ensure that transient names change with each authentication
+ sp = get_sp_by_nameid(sp_list, 'transient')
+ spname = sp['nameid']
+ spurl = 'http://%s:%s' % (sp['addr'], sp['port'])
+
+ print ""
+ print "testnameid: Testing NameID format %s ..." % spname
+
+ ids = []
+ for i in xrange(4):
+ sess = HttpSessions()
+ sess.add_server(idpname, 'http://127.0.0.10:45080', user, 'ipsilon')
+ sess.add_server(spname, spurl)
+ print "testnameid: 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)
+ else:
+ print " SUCCESS"
+
+ print "testnameid: Access SP ...",
+ try:
+ page = sess.fetch_page(idpname, '%s/sp/' % spurl)
+ t1 = page.text
+ except ValueError, e:
+ print >> sys.stderr, " ERROR: %s" % repr(e)
+ sys.exit(1)
+ else:
+ print " SUCCESS"
+
+ print "testnameid: Access SP again ...",
+ try:
+ page = sess.fetch_page(idpname, '%s/sp/' % spurl)
+ t2 = page.text
+ except ValueError, e:
+ print >> sys.stderr, " ERROR: %s" % repr(e)
+ sys.exit(1)
+ else:
+ print " SUCCESS"
+
+ print "testnameid: Ensure ID is consistent between requests ...",
+ if t1 != t2:
+ print >> sys.stderr, " ERROR: New ID between reqeusts"
+ else:
+ print " SUCCESS"
+
+ ids.append(t1)
+
+ print "testnameid: Ensure uniqueness across sessions ...",
+ if len(ids) != len(set(ids)):
+ print >> sys.stderr, " ERROR: IDs are not unique between sessions"
+ sys.exit(1)
+ else:
+ print " SUCCESS"
+
+ # Ensure that persistent names remain the same with each authentication
+ sp = get_sp_by_nameid(sp_list, 'persistent')
+ spname = sp['nameid']
+ spurl = 'http://%s:%s' % (sp['addr'], sp['port'])
+
+ print ""
+ print "testnameid: Testing NameID format %s ..." % spname
+
+ ids = []
+ for i in xrange(4):
+ sess = HttpSessions()
+ sess.add_server(idpname, 'http://127.0.0.10:45080', user, 'ipsilon')
+ sess.add_server(spname, spurl)
+ print "testnameid: 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)
+ else:
+ print " SUCCESS"
+
+ print "testnameid: Access SP ...",
+ try:
+ page = sess.fetch_page(idpname, '%s/sp/' % spurl)
+ t1 = page.text
+ except ValueError, e:
+ print >> sys.stderr, " ERROR: %s" % repr(e)
+ sys.exit(1)
+ else:
+ print " SUCCESS"
+
+ print "testnameid: Access SP again ...",
+ try:
+ page = sess.fetch_page(idpname, '%s/sp/' % spurl)
+ t2 = page.text
+ except ValueError, e:
+ print >> sys.stderr, " ERROR: %s" % repr(e)
+ sys.exit(1)
+ else:
+ print " SUCCESS"
+
+ print "testnameid: Ensure ID is consistent between requests ...",
+ if t1 != t2:
+ print >> sys.stderr, " ERROR: New ID between reqeusts"
+ else:
+ print " SUCCESS"
+
+ ids.append(t1)
+
+ print "testnameid: Ensure same ID across sessions ...",
+ if len(set(ids)) != 1:
+ print >> sys.stderr, " ERROR: IDs are not the same between sessions"
+ sys.exit(1)
+ else:
+ print " SUCCESS"