Permalink
Browse files

Making slapd portable by running on configurable port, etc.

Adding more functional tests.
  • Loading branch information...
1 parent fc8b29e commit 191eb3eb78c47b74c01f3e85202149237d3b8aea @ozten committed Oct 11, 2011
Showing with 193 additions and 5 deletions.
  1. +4 −1 .gitignore
  2. +8 −1 test/config.py-dist
  3. +64 −3 test/functional_test.py
  4. +4 −0 test/sasl/no_browserid_slapd.conf
  5. +70 −0 test/slapd.py
  6. +22 −0 test/slapd/slapd.conf-dist
  7. +21 −0 test/slapd/users.ldif
View
@@ -12,4 +12,7 @@ config.log
config.status
# Makefile
stamp-h1
-*.pyc
+*.pyc
+test/config.py
+test/slapd/slapd.conf
+test/slapd/slapd.pid
View
@@ -5,5 +5,12 @@ MYSQL_HOST = '127.0.0.1'
#MYSQL_PORT = 883306
MYSQL_PORT = 3306
-LDAP_URI = 'ldap:///'
+LDAP_URI = 'ldap://:1389/'
#LDAP_URI = 'ldap://:881389'
+LDAP_ROOT_DN = 'cn=root,dc=example,dc=com'
+LDAP_ROOT_PASS = 'pass'
+SASL_BID_HOME = '/home/vagrant/sasl-browserid'
+SLAPD_DB_PATH = '/home/vagrant/openldap_db'
+SLAPD_CONFIG = '/home/vagrant/sasl-browserid/test/slapd'
+SLAPD_PID = '/home/vagrant/sasl-browserid/test/slapd/slapd.pid'
+SLAPD_LIB_PATH = '/usr/lib/sasl2'
View
@@ -13,9 +13,10 @@
import ldap
from ldap.sasl import sasl, CB_USER, CB_AUTHNAME
import MySQLdb
+import shutil
import config
-
+import slapd
class browserid(sasl):
"""This class handles SASL client input names for
@@ -55,15 +56,21 @@ def setUp(self):
cursor.close()
# OpenLDAP init
+ slapd.reset_db()
self.ldap_conn = ldap.initialize(config.LDAP_URI)
def tearDown(self):
self.db_conn.close()
self.ldap_conn.unbind_s()
+ # Replace normal good sasl2/slapd.conf
+ src = "%s/configs/slapd.conf" % config.SASL_BID_HOME
+ dest = "%s/slapd.conf" % config.SLAPD_LIB_PATH
+ shutil.copy(src, dest)
+
def test_cached_assertion(self):
assertion = '32lj432j4.some.really.long.string.23k4j23l4j'
- email = 'test@home.net'
+ email = 'jane@doe.com'
audience = 'example.com'
cur = self.db_conn.cursor()
try:
@@ -75,6 +82,31 @@ def test_cached_assertion(self):
cur.close()
sasl_creds = browserid(assertion, audience)
+
+ slapd.wait_for_jane()
+
+ self.ldap_conn.sasl_interactive_bind_s("", sasl_creds)
+
+ expected_dn = "dn:uid=%s,dc=example,dc=com" % email
+ self.assertEqual(expected_dn, self.ldap_conn.whoami_s())
+
+ def test_cached_assertion_unknown_user(self):
+ assertion = '32lj432j4.some_other.really.long.string.23k4j23l4j'
+ email = 'unknown@user.com'
+ audience = 'example.com'
+ cur = self.db_conn.cursor()
+ try:
+ insert_session_row(cur, assertion, email)
+ except Exception, e:
+ raise e
+ finally:
+ cur.close()
+
+ sasl_creds = browserid(assertion, audience)
+
+ # we don't need name, but let directory get loaded
+ slapd.wait_for_jane()
+
self.ldap_conn.sasl_interactive_bind_s("", sasl_creds)
expected_dn = "dn:uid=%s,cn=browser-id,cn=auth" % email
@@ -129,13 +161,42 @@ def test_bad_assertion_buffer_overflow_audience(self):
self.assertRaises(ldap.INVALID_CREDENTIALS, lambda:\
self.ldap_conn.sasl_interactive_bind_s("", sasl_creds))
+ def test_no_browserid_auth_mech(self):
+ """
+
+ """
+ # Replace normal good sasl2/slapd.conf
+ src = "%s/test/sasl/no_browserid_slapd.conf" %\
+ config.SASL_BID_HOME
+ dest = "%s/slapd.conf" % config.SLAPD_LIB_PATH
+ shutil.copy(src, dest)
+
+ slapd.kill_slapd()
+ slapd.start_slapd()
+
+ self.ldap_conn = ldap.initialize(config.LDAP_URI)
+
+ assertion = '32lj432j4.an.assertion.23k4j23l4j'
+ audience = 'example.com'
+
+ sasl_creds = browserid(assertion, audience)
+ self.ldap_conn.bind_s('', '')
+
+
+ self.assertRaises(ldap.STRONG_AUTH_NOT_SUPPORTED, lambda:\
+ self.ldap_conn.sasl_interactive_bind_s("", sasl_creds))
+
def xtest_to_write(self):
"""
TODO:
/usr/lib/sasl2/slapd.conf with no browserid_endpoint
+
+ Also fire up web server via python...
+ good json
+ bad json
+ etc
"""
pass
-
if __name__ == '__main__':
unittest.main()
@@ -0,0 +1,4 @@
+# test/sasl/no_browserid_slapd.conf
+mech_list: PLAIN
+
+# Compare to configs/slapd.conf for reference
View
@@ -0,0 +1,70 @@
+import ldap
+import os
+import shutil
+from subprocess import Popen, call
+
+import config as conf
+
+
+def reset_db():
+
+ kill_slapd()
+
+ shutil.rmtree(conf.SLAPD_DB_PATH)
+ os.mkdir(conf.SLAPD_DB_PATH)
+
+ start_slapd()
+
+ # load data
+ users = "%s/users.ldif" % conf.SLAPD_CONFIG
+ args = [
+ 'ldapmodify', '-x',
+ '-H', conf.LDAP_URI,
+ '-D', 'cn=root,dc=example,dc=com',
+ '-w', 'pass',
+ '-a', '-f', users
+ ]
+ Popen(args)
+
+
+def kill_slapd():
+ try:
+
+ f = open("%s/slapd.pid" % conf.SLAPD_CONFIG, 'r')
+ pid = f.readline().rstrip()
+ f.close()
+ Popen(['kill', pid])
+ os.remove("%s/slapd.pid" % conf.SLAPD_CONFIG)
+ return True
+ except Exception:
+ return False
+
+def start_slapd():
+ config = "%s/slapd.conf" % conf.SLAPD_CONFIG
+ call(['slapd', '-h', conf.LDAP_URI, '-f', config])
+
+ while True:
+ try:
+ conn = ldap.initialize(conf.LDAP_URI)
+ conn.bind('', '')
+ break
+ except ldap.SERVER_DOWN:
+ #print "still starting up"
+ continue
+
+def wait_for_jane():
+ """Function attempts to detect when jane@doe.com is in
+ the LDAP directory. Waits until the directory has been
+ populated, then returns."""
+ while True:
+ try:
+ conn = ldap.initialize(conf.LDAP_URI)
+ conn.bind(conf.LDAP_ROOT_DN, conf.LDAP_ROOT_PASS)
+ conn.search_s('dc=example,dc=com', ldap.SCOPE_SUBTREE, '(uid=jane@doe.com)')
+ break
+ except ldap.NO_SUCH_OBJECT:
+ print "still loading"
+ continue
+
+if __name__ == '__main__':
+ reset_db()
View
@@ -0,0 +1,22 @@
+pidfile /home/vagrant/sasl-browserid/test/slapd/slapd.pid
+
+modulepath /usr/lib/ldap
+moduleload back_bdb.la
+
+include /etc/ldap/schema/core.schema
+
+database bdb
+suffix "dc=example,dc=com"
+rootdn "cn=root,dc=example,dc=com"
+rootpw pass
+
+# Must not be in a VM shared directory
+directory /home/vagrant/openldap_db
+
+#######################################################################
+# SASL Mapping
+#######################################################################
+# dn:uid=jane@doe.com,cn=browser-id,cn=auth
+authz-regexp
+ uid=([^,]*),cn=browser-id,cn=auth
+ ldap:///dc=example,dc=com??sub?(uid=$1)
View
@@ -0,0 +1,21 @@
+####################
+# LDAP DIT structure
+####################
+#
+# The suffix (top of tree entry)
+#
+dn: dc=example,dc=com
+objectClass: top
+objectClass: dcObject
+objectclass: organization
+dc: example
+o: Examples
+
+
+dn: uid=jane@doe.com,dc=example,dc=com
+objectclass: person
+objectclass: uidObject
+cn: Jane Doe
+sn: Doe
+uid: jane@doe.com
+

0 comments on commit 191eb3e

Please sign in to comment.