summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRob Crittenden <rcritten@redhat.com>2015-07-20 16:42:36 -0400
committerPatrick Uiterwijk <puiterwijk@redhat.com>2015-08-18 20:50:43 +0200
commit5f591228346bd96561b693cae43b8f14e4c3b26d (patch)
treeaa811936e90768dc9eefeb3fff5194fb867758f6
parent9eaa965575ef31de52cef559c420ba7880756887 (diff)
downloadipsilon-5f591228346bd96561b693cae43b8f14e4c3b26d.tar.gz
ipsilon-5f591228346bd96561b693cae43b8f14e4c3b26d.tar.xz
ipsilon-5f591228346bd96561b693cae43b8f14e4c3b26d.zip
Report to user if an LDAP error occurs
Catch LDAP errors and display them properly rather than just dumping the exception. Rename variable authed to authok. Add test for case where LDAP server is not started to confirm the user receives the error alert. https://fedorahosted.org/ipsilon/ticket/55 Signed-off-by: Rob Crittenden <rcritten@redhat.com> Reviewed-by: Patrick Uiterwijk <puiterwijk@redhat.com>
-rw-r--r--Makefile1
-rw-r--r--ipsilon/login/authldap.py23
-rwxr-xr-xtests/helpers/http.py10
-rwxr-xr-xtests/ldapdown.py139
4 files changed, 164 insertions, 9 deletions
diff --git a/Makefile b/Makefile
index f7f7d16..d15ca4d 100644
--- a/Makefile
+++ b/Makefile
@@ -102,6 +102,7 @@ tests: wrappers
PYTHONPATH=./ ./tests/tests.py --test=pgdb
PYTHONPATH=./ ./tests/tests.py --test=fconf
PYTHONPATH=./ ./tests/tests.py --test=ldap
+ PYTHONPATH=./ ./tests/tests.py --test=ldapdown
PYTHONPATH=./ ./tests/tests.py --test=openid
test: lp-test unittests tests
diff --git a/ipsilon/login/authldap.py b/ipsilon/login/authldap.py
index ce096f4..321c461 100644
--- a/ipsilon/login/authldap.py
+++ b/ipsilon/login/authldap.py
@@ -61,21 +61,32 @@ class LDAP(LoginFormBase, Log):
username = kwargs.get("login_name")
password = kwargs.get("login_password")
userattrs = None
- authed = False
+ authok = False
errmsg = None
if username and password:
try:
userattrs = self._authenticate(username, password)
- authed = True
- except Exception, e: # pylint: disable=broad-except
+ authok = True
+ except ldap.INVALID_CREDENTIALS as e:
errmsg = "Authentication failed"
+ self.error(errmsg)
+ except ldap.LDAPError as e:
+ errmsg = 'Internal system error'
+ if isinstance(e, ldap.TIMEOUT):
+ self.error('LDAP request timed out')
+ else:
+ desc = e.args[0]['desc'].strip()
+ info = e.args[0].get('info', '').strip()
+ self.error("%s: %s %s" % (e.__class__.__name__,
+ desc, info))
+ except Exception as e: # pylint: disable=broad-except
+ errmsg = 'Internal system error'
self.error("Exception raised: [%s]" % repr(e))
else:
- errmsg = "Username or password is missing"
- self.error(errmsg)
+ self.error("Username or password is missing")
- if authed:
+ if authok:
return self.lm.auth_successful(self.trans, username, 'password',
userdata=userattrs)
diff --git a/tests/helpers/http.py b/tests/helpers/http.py
index 0643fb1..8c0a291 100755
--- a/tests/helpers/http.py
+++ b/tests/helpers/http.py
@@ -300,7 +300,7 @@ class HttpSessions(object):
raise ValueError("Unhandled status (%d) on url %s" % (
r.status_code, url))
- def auth_to_idp(self, idp, krb=False):
+ def auth_to_idp(self, idp, krb=False, rule=None, expected=None):
srv = self.servers[idp]
target_url = '%s/%s/' % (srv['baseuri'], idp)
@@ -316,8 +316,12 @@ class HttpSessions(object):
page = self.fetch_page(idp, url, krb=krb)
- page.expected_value('//div[@id="welcome"]/p/text()',
- 'Welcome %s!' % srv['user'])
+ if rule is None:
+ rule = '//div[@id="welcome"]/p/text()'
+ if expected is None:
+ expected = 'Welcome %s!' % srv['user']
+
+ page.expected_value(rule, expected)
def logout_from_idp(self, idp):
diff --git a/tests/ldapdown.py b/tests/ldapdown.py
new file mode 100755
index 0000000..2c7138c
--- /dev/null
+++ b/tests/ldapdown.py
@@ -0,0 +1,139 @@
+#!/usr/bin/python
+#
+# Copyright (C) 2015 Ipsilon project Contributors, for license see COPYING
+
+# Test that we get a reasonable error back when the LDAP backend is down
+
+from helpers.common import IpsilonTestBase # pylint: disable=relative-import
+from helpers.http import HttpSessions # pylint: disable=relative-import
+import os
+import sys
+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': 'tuser',
+ 'system_user': '${TEST_USER}',
+ 'instance': '${NAME}',
+ 'secure': 'no',
+ 'pam': 'no',
+ 'gssapi': 'no',
+ 'ipa': 'no',
+ 'ldap': 'yes',
+ 'ldap_server_url': 'ldap://${ADDRESS}:45389/',
+ 'ldap_bind_dn_template':
+ 'uid=%(username)s,ou=People,dc=example,dc=com',
+ 'ldap_tls_level': 'NoTLS',
+ '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',
+ 'httpd_user': '${TEST_USER}'}
+
+
+def fixup_sp_httpd(httpdir):
+ merge = """
+ MellonSetEnv "GROUPS" "groups"
+ MellonMergeEnvVars On
+</Location>"""
+ with open(httpdir + '/conf.d/ipsilon-saml.conf', 'r') as f:
+ conf = f.read()
+ conf = conf.replace('</Location>', merge, 1)
+ with open(httpdir + '/conf.d/ipsilon-saml.conf', 'w') as f:
+ f.write(conf)
+
+ location = """
+
+Alias /sp ${HTTPDIR}/sp
+
+<Directory ${HTTPDIR}/sp>
+ Require all granted
+ Options +Includes
+</Directory>
+"""
+ t = Template(location)
+ text = t.substitute({'HTTPDIR': httpdir})
+ with open(httpdir + '/conf.d/ipsilon-saml.conf', 'a') as f:
+ f.write(text)
+
+ index = """<!--#echo var="MELLON_GROUPS" -->"""
+ os.mkdir(httpdir + '/sp')
+ with open(httpdir + '/sp/index.shtml', 'w') as f:
+ f.write(index)
+
+
+class IpsilonTest(IpsilonTestBase):
+
+ def __init__(self):
+ super(IpsilonTest, self).__init__('ldapdown', __file__)
+
+ def setup_servers(self, env=None):
+
+ print "Installing IDP's ldap server"
+ addr = '127.0.0.10'
+ port = '45389'
+ conf = self.setup_ldap(env)
+
+ print "Not starting IDP's ldap server"
+
+ 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)
+
+ 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)
+
+
+if __name__ == '__main__':
+
+ idpname = 'idp1'
+ spname = 'sp1'
+ user = 'tuser'
+
+ sess = HttpSessions()
+ sess.add_server(idpname, 'http://127.0.0.10:45080', user, 'tuser')
+ sess.add_server(spname, 'http://127.0.0.11:45081')
+
+ print "ldapdown: Authenticate to IDP with no LDAP backend...",
+ try:
+ sess.auth_to_idp(
+ idpname,
+ rule='//div[@class="alert alert-danger"]/p/text()',
+ expected="Internal system error"
+ )
+ except Exception, e: # pylint: disable=broad-except
+ print >> sys.stderr, " ERROR: %s" % repr(e)
+ sys.exit(1)
+ print " SUCCESS"