diff options
author | Rob Crittenden <rcritten@redhat.com> | 2015-07-20 16:42:36 -0400 |
---|---|---|
committer | Patrick Uiterwijk <puiterwijk@redhat.com> | 2015-08-18 20:50:43 +0200 |
commit | 5f591228346bd96561b693cae43b8f14e4c3b26d (patch) | |
tree | aa811936e90768dc9eefeb3fff5194fb867758f6 | |
parent | 9eaa965575ef31de52cef559c420ba7880756887 (diff) | |
download | ipsilon-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-- | Makefile | 1 | ||||
-rw-r--r-- | ipsilon/login/authldap.py | 23 | ||||
-rwxr-xr-x | tests/helpers/http.py | 10 | ||||
-rwxr-xr-x | tests/ldapdown.py | 139 |
4 files changed, 164 insertions, 9 deletions
@@ -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" |