diff options
author | Björn Baumbach <bb@sernet.de> | 2019-03-20 17:17:05 +0100 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2019-07-04 02:07:21 +0000 |
commit | 78e78a4092569978e79a661bcd6e6631e4868245 (patch) | |
tree | 13eb1b4e4ffb95cd32ce0ef57f8814a8cff59683 /python | |
parent | 3f10c8f25cf1655b4facf190f61acb4098919609 (diff) | |
download | samba-78e78a4092569978e79a661bcd6e6631e4868245.tar.gz |
samba-tool tests: add tests for contact management
Signed-off-by: Björn Baumbach <bb@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Diffstat (limited to 'python')
-rw-r--r-- | python/samba/tests/samba_tool/contact.py | 319 | ||||
-rwxr-xr-x | python/samba/tests/samba_tool/contact_edit.sh | 164 |
2 files changed, 483 insertions, 0 deletions
diff --git a/python/samba/tests/samba_tool/contact.py b/python/samba/tests/samba_tool/contact.py new file mode 100644 index 00000000000..626277ce8f1 --- /dev/null +++ b/python/samba/tests/samba_tool/contact.py @@ -0,0 +1,319 @@ +# Unix SMB/CIFS implementation. +# +# Tests for samba-tool contact management commands +# +# Copyright (C) Bjoern Baumbach <bbaumbach@samba.org> 2019 +# +# 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 <http://www.gnu.org/licenses/>. +# + +import os +import ldb +from samba.tests.samba_tool.base import SambaToolCmdTest + +class ContactCmdTestCase(SambaToolCmdTest): + """Tests for samba-tool contact subcommands""" + contacts = [] + samdb = None + + def setUp(self): + super(ContactCmdTestCase, self).setUp() + self.creds = "-U%s%%%s" % (os.environ["DC_USERNAME"], + os.environ["DC_PASSWORD"]) + self.samdb = self.getSamDB("-H", + "ldap://%s" % os.environ["DC_SERVER"], + self.creds) + contact = None + self.contacts = [] + + contact = self._randomContact({"expectedname": "contact1", + "name": "contact1"}) + self.contacts.append(contact) + + # No 'name' is given here, so the name will be made from givenname. + contact = self._randomContact({"expectedname": "contact2", + "givenName": "contact2"}) + self.contacts.append(contact) + + contact = self._randomContact({"expectedname": "contact3", + "name": "contact3", + "displayName": "contact3displayname", + "givenName": "not_contact3", + "initials": "I", + "sn": "not_contact3", + "mobile": "12345"}) + self.contacts.append(contact) + + # No 'name' is given here, so the name will be made from the the + # sn, initials and givenName attributes. + contact = self._randomContact({"expectedname": "James T. Kirk", + "sn": "Kirk", + "initials": "T", + "givenName": "James"}) + self.contacts.append(contact) + + # setup the 4 contacts and ensure they are correct + for contact in self.contacts: + (result, out, err) = self._create_contact(contact) + + self.assertCmdSuccess(result, out, err) + self.assertNotIn( + "ERROR", err, "There shouldn't be any error message") + self.assertIn("Contact '%s' created successfully" % + contact["expectedname"], out) + + found = self._find_contact(contact["expectedname"]) + + self.assertIsNotNone(found) + + contactname = contact["expectedname"] + self.assertEquals("%s" % found.get("name"), contactname) + self.assertEquals("%s" % found.get("description"), + contact["description"]) + + def tearDown(self): + super(ContactCmdTestCase, self).tearDown() + # clean up all the left over contacts, just in case + for contact in self.contacts: + if self._find_contact(contact["expectedname"]): + (result, out, err) = self.runsubcmd( + "contact", "delete", "%s" % contact["expectedname"]) + self.assertCmdSuccess(result, out, err, + "Failed to delete contact '%s'" % + contact["expectedname"]) + + def test_newcontact(self): + """This tests the "contact create" and "contact delete" commands""" + # try to create all the contacts again, this should fail + for contact in self.contacts: + (result, out, err) = self._create_contact(contact) + self.assertCmdFail(result, "Succeeded to create existing contact") + self.assertIn("already exists", err) + + # try to delete all the contacts we just created + for contact in self.contacts: + (result, out, err) = self.runsubcmd("contact", "delete", "%s" % + contact["expectedname"]) + self.assertCmdSuccess(result, out, err, + "Failed to delete contact '%s'" % + contact["expectedname"]) + found = self._find_contact(contact["expectedname"]) + self.assertIsNone(found, + "Deleted contact '%s' still exists" % + contact["expectedname"]) + + # test creating contacts in an specified OU + parentou = self._randomOU({"name": "testOU"}) + (result, out, err) = self._create_ou(parentou) + self.assertCmdSuccess(result, out, err) + + for contact in self.contacts: + (result, out, err) = self._create_contact(contact, ou="OU=testOU") + + self.assertCmdSuccess(result, out, err) + self.assertEquals(err, "", "There shouldn't be any error message") + self.assertIn("Contact '%s' created successfully" % + contact["expectedname"], out) + + found = self._find_contact(contact["expectedname"]) + + contactname = contact["expectedname"] + self.assertEquals("%s" % found.get("name"), contactname) + self.assertEquals("%s" % found.get("description"), + contact["description"]) + + # try to delete all the contacts we just created, by DN + for contact in self.contacts: + expecteddn = ldb.Dn(self.samdb, + "CN=%s,OU=%s,%s" % + (contact["expectedname"], + parentou["name"], + self.samdb.domain_dn())) + (result, out, err) = self.runsubcmd("contact", "delete", "%s" % + expecteddn) + self.assertCmdSuccess(result, out, err, + "Failed to delete contact '%s'" % + contact["expectedname"]) + found = self._find_contact(contact["expectedname"]) + self.assertIsNone(found, + "Deleted contact '%s' still exists" % + contact["expectedname"]) + + (result, out, err) = self.runsubcmd("ou", "delete", + "OU=%s" % parentou["name"]) + self.assertCmdSuccess(result, out, err, + "Failed to delete ou '%s'" % parentou["name"]) + + # creating contacts, again for further tests + for contact in self.contacts: + (result, out, err) = self._create_contact(contact) + + self.assertCmdSuccess(result, out, err) + self.assertEquals(err, "", "There shouldn't be any error message") + self.assertIn("Contact '%s' created successfully" % + contact["expectedname"], out) + + found = self._find_contact(contact["expectedname"]) + + contactname = contact["expectedname"] + self.assertEquals("%s" % found.get("name"), contactname) + self.assertEquals("%s" % found.get("description"), + contact["description"]) + + def test_list(self): + (result, out, err) = self.runsubcmd("contact", "list") + self.assertCmdSuccess(result, out, err, "Error running list") + + search_filter = "(objectClass=contact)" + contactlist = self.samdb.search(base=self.samdb.domain_dn(), + scope=ldb.SCOPE_SUBTREE, + expression=search_filter, + attrs=["name"]) + + self.assertTrue(len(contactlist) > 0, "no contacts found in samdb") + + for contactobj in contactlist: + name = contactobj.get("name", idx=0) + self.assertMatch(out, str(name), + "contact '%s' not found" % name) + + def test_list_full_dn(self): + (result, out, err) = self.runsubcmd("contact", "list", "--full-dn") + self.assertCmdSuccess(result, out, err, "Error running list") + + search_filter = "(objectClass=contact)" + contactlist = self.samdb.search(base=self.samdb.domain_dn(), + scope=ldb.SCOPE_SUBTREE, + expression=search_filter, + attrs=["dn"]) + + self.assertTrue(len(contactlist) > 0, "no contacts found in samdb") + + for contactobj in contactlist: + self.assertMatch(out, str(contactobj.dn), + "contact '%s' not found" % str(contactobj.dn)) + + def test_move(self): + parentou = self._randomOU({"name": "parentOU"}) + (result, out, err) = self._create_ou(parentou) + self.assertCmdSuccess(result, out, err) + + for contact in self.contacts: + olddn = self._find_contact(contact["expectedname"]).get("dn") + + (result, out, err) = self.runsubcmd("contact", "move", + "%s" % contact["expectedname"], + "OU=%s" % parentou["name"]) + self.assertCmdSuccess(result, out, err, + "Failed to move contact '%s'" % + contact["expectedname"]) + self.assertEquals(err, "", "There shouldn't be any error message") + self.assertIn('Moved contact "%s"' % contact["expectedname"], out) + + found = self._find_contact(contact["expectedname"]) + self.assertNotEquals(found.get("dn"), olddn, + ("Moved contact '%s' still exists with the " + "same dn" % contact["expectedname"])) + contactname = contact["expectedname"] + newexpecteddn = ldb.Dn(self.samdb, + "CN=%s,OU=%s,%s" % + (contactname, + parentou["name"], + self.samdb.domain_dn())) + self.assertEquals(found.get("dn"), newexpecteddn, + "Moved contact '%s' does not exist" % + contact["expectedname"]) + + (result, out, err) = self.runsubcmd("contact", "move", + "%s" % contact["expectedname"], + "%s" % olddn.parent()) + self.assertCmdSuccess(result, out, err, + "Failed to move contact '%s'" % + contact["expectedname"]) + + (result, out, err) = self.runsubcmd("ou", "delete", + "OU=%s" % parentou["name"]) + self.assertCmdSuccess(result, out, err, + "Failed to delete ou '%s'" % parentou["name"]) + + def _randomContact(self, base={}): + """Create a contact with random attribute values, you can specify base + attributes""" + + # No name attributes are given here, because the object name will + # be made from the sn, givenName and initials attributes, if no name + # is given. + contact = { + "description": self.randomName(count=100), + } + contact.update(base) + return contact + + def _randomOU(self, base={}): + """Create an ou with random attribute values, you can specify base + attributes.""" + + ou = { + "name": self.randomName(), + "description": self.randomName(count=100), + } + ou.update(base) + return ou + + def _create_contact(self, contact, ou=None): + args = "" + + if "name" in contact: + args += '{0}'.format(contact['name']) + + args += ' {0}'.format(self.creds) + + if ou is not None: + args += ' --ou={0}'.format(ou) + + if "description" in contact: + args += ' --description={0}'.format(contact["description"]) + if "sn" in contact: + args += ' --surname={0}'.format(contact["sn"]) + if "initials" in contact: + args += ' --initials={0}'.format(contact["initials"]) + if "givenName" in contact: + args += ' --given-name={0}'.format(contact["givenName"]) + if "displayName" in contact: + args += ' --display-name={0}'.format(contact["displayName"]) + if "mobile" in contact: + args += ' --mobile-number={0}'.format(contact["mobile"]) + + args = args.split() + + return self.runsubcmd('contact', 'create', *args) + + def _create_ou(self, ou): + return self.runsubcmd("ou", + "create", + "OU=%s" % ou["name"], + "--description=%s" % ou["description"]) + + def _find_contact(self, name): + contactname = name + search_filter = ("(&(objectClass=contact)(name=%s))" % + ldb.binary_encode(contactname)) + contactlist = self.samdb.search(base=self.samdb.domain_dn(), + scope=ldb.SCOPE_SUBTREE, + expression=search_filter, + attrs=[]) + if contactlist: + return contactlist[0] + else: + return None diff --git a/python/samba/tests/samba_tool/contact_edit.sh b/python/samba/tests/samba_tool/contact_edit.sh new file mode 100755 index 00000000000..ca38900062a --- /dev/null +++ b/python/samba/tests/samba_tool/contact_edit.sh @@ -0,0 +1,164 @@ +#!/bin/sh +# +# Test for 'samba-tool contact edit' + +if [ $# -lt 3 ]; then +cat <<EOF +Usage: contact_edit.sh SERVER USERNAME PASSWORD +EOF +exit 1; +fi + +SERVER="$1" +USERNAME="$2" +PASSWORD="$3" + +STpath=$(pwd) +. $STpath/testprogs/blackbox/subunit.sh + +display_name="Björn" +display_name_b64="QmrDtnJu" +display_name_new="Renamed Bjoern" +# attribute value including control character +# echo -e "test \a string" | base64 +display_name_con_b64="dGVzdCAHIHN0cmluZwo=" + +tmpeditor=$(mktemp --suffix .sh -p $STpath/bin samba-tool-editor-XXXXXXXX) +chmod +x $tmpeditor + +create_test_contact() { + $PYTHON ${STpath}/source4/scripting/bin/samba-tool \ + contact create testcontact1 \ + -H "ldap://$SERVER" "-U$USERNAME" "--password=$PASSWORD" +} + +# Test edit contact - add base64 attributes +add_attribute_base64() { + # create editor.sh + cat >$tmpeditor <<EOF +#!/usr/bin/env bash +contact_ldif="\$1" + +grep -v '^$' \$contact_ldif > \${contact_ldif}.tmp +echo "displayName:: $display_name_b64" >> \${contact_ldif}.tmp + +mv \${contact_ldif}.tmp \$contact_ldif +EOF + + $PYTHON ${STpath}/source4/scripting/bin/samba-tool contact edit \ + testcontact1 --editor=$tmpeditor \ + -H "ldap://$SERVER" "-U$USERNAME" "--password=$PASSWORD" +} + +get_attribute_base64() { + $PYTHON ${STpath}/source4/scripting/bin/samba-tool contact show \ + testcontact1 --attributes=displayName \ + -H "ldap://$SERVER" "-U$USERNAME" "--password=$PASSWORD" +} + +delete_attribute() { + # create editor.sh + cat >$tmpeditor <<EOF +#!/usr/bin/env bash +contact_ldif="\$1" + +grep -v '^displayName' \$contact_ldif >> \${contact_ldif}.tmp +mv \${contact_ldif}.tmp \$contact_ldif +EOF + $PYTHON ${STpath}/source4/scripting/bin/samba-tool contact edit \ + testcontact1 --editor=$tmpeditor \ + -H "ldap://$SERVER" "-U$USERNAME" "--password=$PASSWORD" +} + +# Test edit contact - add base64 attribute value including control character +add_attribute_base64_control() { + # create editor.sh + cat >$tmpeditor <<EOF +#!/usr/bin/env bash +contact_ldif="\$1" + +grep -v '^$' \$contact_ldif > \${contact_ldif}.tmp +echo "displayName:: $display_name_con_b64" >> \${contact_ldif}.tmp + +mv \${contact_ldif}.tmp \$contact_ldif +EOF + $PYTHON ${STpath}/source4/scripting/bin/samba-tool contact edit \ + testcontact1 --editor=$tmpeditor \ + -H "ldap://$SERVER" "-U$USERNAME" "--password=$PASSWORD" +} + +get_attribute_base64_control() { + $PYTHON ${STpath}/source4/scripting/bin/samba-tool contact show \ + testcontact1 --attributes=displayName \ + -H "ldap://$SERVER" "-U$USERNAME" "--password=$PASSWORD" +} + + +# Test edit contact - change base64 attribute value including control character +change_attribute_base64_control() { + # create editor.sh + cat >$tmpeditor <<EOF +#!/usr/bin/env bash +contact_ldif="\$1" + +sed -i -e 's/displayName:: $display_name_con_b64/displayName: $display_name/' \ + \$contact_ldif +EOF + $PYTHON ${STpath}/source4/scripting/bin/samba-tool contact edit \ + testcontact1 --editor=$tmpeditor \ + -H "ldap://$SERVER" "-U$USERNAME" "--password=$PASSWORD" +} + +get_attribute_base64_control() { + $PYTHON ${STpath}/source4/scripting/bin/samba-tool contact show \ + testcontact1 --attributes=displayName \ + -H "ldap://$SERVER" "-U$USERNAME" "--password=$PASSWORD" +} + +# Test edit contact - change attributes with LDB_FLAG_FORCE_NO_BASE64_LDIF +change_attribute_force_no_base64() { + # create editor.sh + # Expects that the original attribute is available as clear text, + # because the LDB_FLAG_FORCE_NO_BASE64_LDIF should be used here. + cat >$tmpeditor <<EOF +#!/usr/bin/env bash +contact_ldif="\$1" + +sed -i -e 's/displayName: $display_name/displayName: $display_name_new/' \ + \$contact_ldif +EOF + + $PYTHON ${STpath}/source4/scripting/bin/samba-tool contact edit \ + testcontact1 --editor=$tmpeditor \ + -H "ldap://$SERVER" "-U$USERNAME" "--password=$PASSWORD" +} + +get_changed_attribute_force_no_base64() { + $PYTHON ${STpath}/source4/scripting/bin/samba-tool contact show \ + testcontact1 --attributes=displayName \ + -H "ldap://$SERVER" "-U$USERNAME" "--password=$PASSWORD" +} + +delete_contact() { + $PYTHON ${STpath}/source4/scripting/bin/samba-tool \ + contact delete testcontact1 \ + -H "ldap://$SERVER" "-U$USERNAME" "--password=$PASSWORD" +} + +failed=0 + +testit "create_test_contact" create_test_contact || failed=`expr $failed + 1` +testit "add_attribute_base64" add_attribute_base64 || failed=`expr $failed + 1` +testit_grep "get_attribute_base64" "^displayName:: $display_name_b64" get_attribute_base64 || failed=`expr $failed + 1` +testit "delete_attribute" delete_attribute || failed=`expr $failed + 1` +testit "add_attribute_base64_control" add_attribute_base64_control || failed=`expr $failed + 1` +testit_grep "get_attribute_base64_control" "^displayName:: $display_name_con_b64" get_attribute_base64_control || failed=`expr $failed + 1` +testit "change_attribute_base64_control" change_attribute_base64_control || failed=`expr $failed + 1` +testit_grep "get_attribute_base64_control" "^displayName:: $display_name_b64" get_attribute_base64_control || failed=`expr $failed + 1` +testit "change_attribute_force_no_base64" change_attribute_force_no_base64 || failed=`expr $failed + 1` +testit_grep "get_changed_attribute_force_no_base64" "^displayName: $display_name_new" get_changed_attribute_force_no_base64 || failed=`expr $failed + 1` +testit "delete_contact" delete_contact || failed=`expr $failed + 1` + +rm -f $tmpeditor + +exit $failed |