/*
* (C) Copyright 2006-2007 Nuxeo SA (http://nuxeo.com/) and others.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Contributors:
* Nuxeo - initial API and implementation
*
* $Id: JOOoConvertPluginImpl.java 18651 2007-05-13 20:28:53Z sfermigier $
*/
package org.nuxeo.ecm.directory.ldap;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.junit.Assume.assumeTrue;
import java.io.File;
import java.io.Serializable;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.junit.Ignore;
import org.junit.Test;
import org.nuxeo.common.utils.FileUtils;
import org.nuxeo.ecm.core.api.Blob;
import org.nuxeo.ecm.core.api.Blobs;
import org.nuxeo.ecm.core.api.DocumentModel;
import org.nuxeo.ecm.core.api.DocumentModelList;
import org.nuxeo.ecm.core.api.model.PropertyNotFoundException;
import org.nuxeo.ecm.core.management.api.ProbeStatus;
import org.nuxeo.ecm.directory.BaseSession;
import org.nuxeo.ecm.directory.DirectoryException;
import org.nuxeo.ecm.directory.Session;
import org.nuxeo.ecm.directory.ldap.management.LDAPDirectoriesProbe;
/**
* @author <a href="mailto:ogrisel@nuxeo.com">Olivier Grisel</a>
*/
public class TestLDAPSession extends LDAPDirectoryTestCase {
protected static final String USER_SCHEMANAME = "user";
protected static final String GROUP_SCHEMANAME = "group";
@SuppressWarnings("unchecked")
@Test
public void testGetEntry() throws Exception {
try (Session session = getLDAPDirectory("userDirectory").getSession()) {
DocumentModel entry = session.getEntry("Administrator");
assertNotNull(entry);
assertEquals("Administrator", entry.getId());
assertEquals("Manager", entry.getProperty(USER_SCHEMANAME, "lastName"));
if (USE_EXTERNAL_TEST_LDAP_SERVER) {
assertEquals(Long.valueOf(1), entry.getProperty(USER_SCHEMANAME, "intField"));
assertEquals("uid=Administrator,ou=people,dc=example,dc=com", entry.getProperty(USER_SCHEMANAME, "dn"));
}
assertEquals("Administrator", entry.getProperty(USER_SCHEMANAME, "firstName"));
assertNull(entry.getProperty(USER_SCHEMANAME, "password"));
List<String> val = (List<String>) entry.getProperty(USER_SCHEMANAME, "employeeType");
assertTrue(val.isEmpty());
if (USE_EXTERNAL_TEST_LDAP_SERVER) {
// LDAP references do not work with the internal test server
List<String> groups = (List<String>) entry.getProperty(USER_SCHEMANAME, "groups");
assertEquals(2, groups.size());
assertTrue(groups.contains("members"));
assertTrue(groups.contains("administrators"));
}
DocumentModel entry2 = session.getEntry("user1");
assertNotNull(entry2);
assertEquals("user1", entry2.getId());
assertEquals("One", entry2.getProperty(USER_SCHEMANAME, "lastName"));
assertEquals("User", entry2.getProperty(USER_SCHEMANAME, "firstName"));
assertNull(entry2.getProperty(USER_SCHEMANAME, "password"));
try {
entry2.getProperty(USER_SCHEMANAME, "userPassword");
fail();
} catch (PropertyNotFoundException ce) {
// expected
}
assertEquals(Arrays.asList("Boss"), entry2.getProperty(USER_SCHEMANAME, "employeeType"));
if (USE_EXTERNAL_TEST_LDAP_SERVER) {
// default value for missing attribute
assertEquals(Long.valueOf(0), entry2.getProperty(USER_SCHEMANAME, "intField"));
// LDAP references do not work with the internal test server
if (HAS_DYNGROUP_SCHEMA) {
assertEquals(Arrays.asList("dyngroup1", "dyngroup2", "dyngroup3", "members", "subgroup"),
entry2.getProperty(USER_SCHEMANAME, "groups"));
} else {
assertEquals(Arrays.asList("members", "subgroup"), entry2.getProperty(USER_SCHEMANAME, "groups"));
}
if (!(this instanceof TestLDAPPOSIXSession)) {
Blob avatar = (Blob) entry2.getProperty(USER_SCHEMANAME, "avatar");
assertNotNull(avatar);
File file = FileUtils.getResourceFileFromContext("sample.jpg");
assertNotNull(file);
Blob expectedBlob = Blobs.createBlob(file);
assertTrue(Arrays.equals(expectedBlob.getByteArray(), avatar.getByteArray()));
}
}
DocumentModel entry3 = session.getEntry("UnexistingEntry");
assertNull(entry3);
// test special character escaping
if (USE_EXTERNAL_TEST_LDAP_SERVER) {
// for some reason this do not work with the internal
// ApacheDS server (bug?)
DocumentModel entry4 = session.getEntry("Admi*");
assertNull(entry4);
DocumentModel entry5 = session.getEntry("");
assertNull(entry5);
DocumentModel entry6 = session.getEntry("(objectClass=*)");
assertNull(entry6);
}
}
}
@SuppressWarnings("unchecked")
@Test
public void testGetEntry2() {
try (Session session = getLDAPDirectory("groupDirectory").getSession()) {
DocumentModel entry = session.getEntry("administrators");
assertNotNull(entry);
assertEquals("administrators", entry.getId());
assertEquals("administrators", entry.getProperty(GROUP_SCHEMANAME, "groupname"));
if (USE_EXTERNAL_TEST_LDAP_SERVER) {
// LDAP references do not work with the internal test server
List<String> members = (List<String>) entry.getProperty(GROUP_SCHEMANAME, "members");
assertNotNull(members);
assertEquals(1, members.size());
assertTrue(members.contains("Administrator"));
List<String> subGroups = (List<String>) entry.getProperty(GROUP_SCHEMANAME, "subGroups");
assertNotNull(subGroups);
assertEquals(0, subGroups.size());
List<String> parentGroups = (List<String>) entry.getProperty(GROUP_SCHEMANAME, "parentGroups");
assertNotNull(parentGroups);
assertEquals(0, parentGroups.size());
}
entry = session.getEntry("members");
assertNotNull(entry);
assertEquals("members", entry.getId());
assertEquals("members", entry.getProperty(GROUP_SCHEMANAME, "groupname"));
if (USE_EXTERNAL_TEST_LDAP_SERVER) {
// LDAP references do not work with the internal test server
List<String> members = (List<String>) entry.getProperty(GROUP_SCHEMANAME, "members");
assertEquals(3, members.size());
assertTrue(members.contains("Administrator"));
assertTrue(members.contains("user1"));
List<String> subGroups = (List<String>) entry.getProperty(GROUP_SCHEMANAME, "subGroups");
assertEquals(1, subGroups.size());
assertTrue(subGroups.contains("submembers"));
List<String> parentGroups = (List<String>) entry.getProperty(GROUP_SCHEMANAME, "parentGroups");
assertEquals(0, parentGroups.size());
}
entry = session.getEntry("submembers");
assertNotNull(entry);
assertEquals("submembers", entry.getId());
assertEquals("submembers", entry.getProperty(GROUP_SCHEMANAME, "groupname"));
if (USE_EXTERNAL_TEST_LDAP_SERVER) {
// LDAP references do not work with the internal test server
assertEquals(Arrays.asList("user2"), entry.getProperty(GROUP_SCHEMANAME, "members"));
assertEquals(Arrays.asList(), entry.getProperty(GROUP_SCHEMANAME, "subGroups"));
if (HAS_DYNGROUP_SCHEMA) {
assertEquals(Arrays.asList("dyngroup1", "members"),
entry.getProperty(GROUP_SCHEMANAME, "parentGroups"));
} else {
assertEquals(Arrays.asList("members"), entry.getProperty(GROUP_SCHEMANAME, "parentGroups"));
}
}
}
}
@SuppressWarnings("unchecked")
@Test
public void testGetEntry3() {
assumeTrue(HAS_DYNGROUP_SCHEMA);
try (Session session = getLDAPDirectory("groupDirectory").getSession()) {
DocumentModel entry = session.getEntry("dyngroup1");
assertNotNull(entry);
assertEquals("dyngroup1", entry.getId());
assertEquals("dyngroup1", entry.getProperty(GROUP_SCHEMANAME, "groupname"));
List<String> members = (List<String>) entry.getProperty(GROUP_SCHEMANAME, "members");
assertEquals(Arrays.asList("user1", "user3"), members);
List<String> subGroups = (List<String>) entry.getProperty(GROUP_SCHEMANAME, "subGroups");
assertEquals(Arrays.asList("subgroup", "submembers", "subsubgroup", "subsubsubgroup"), subGroups);
List<String> parentGroups = (List<String>) entry.getProperty(GROUP_SCHEMANAME, "parentGroups");
assertNotNull(parentGroups);
assertEquals(0, parentGroups.size());
entry = session.getEntry("dyngroup2");
assertNotNull(entry);
assertEquals("dyngroup2", entry.getId());
assertEquals("dyngroup2", entry.getProperty(GROUP_SCHEMANAME, "groupname"));
members = (List<String>) entry.getProperty(GROUP_SCHEMANAME, "members");
assertEquals(Arrays.asList("user1", "user3"), members);
// user4 is not there since userDirectory is scoped 'onelevel'
subGroups = (List<String>) entry.getProperty(GROUP_SCHEMANAME, "subGroups");
assertNotNull(subGroups);
assertEquals(0, subGroups.size());
parentGroups = (List<String>) entry.getProperty(GROUP_SCHEMANAME, "parentGroups");
assertNotNull(parentGroups);
assertEquals(0, parentGroups.size());
// test that submembers is a subgroup of dyngroup1 (inverse
// reference resolution)
entry = session.getEntry("submembers");
assertNotNull(entry);
assertEquals("submembers", entry.getId());
assertEquals("submembers", entry.getProperty(GROUP_SCHEMANAME, "groupname"));
members = (List<String>) entry.getProperty(GROUP_SCHEMANAME, "members");
assertEquals(Arrays.asList("user2"), members);
subGroups = (List<String>) entry.getProperty(GROUP_SCHEMANAME, "subGroups");
assertNotNull(subGroups);
assertEquals(0, subGroups.size());
parentGroups = (List<String>) entry.getProperty(GROUP_SCHEMANAME, "parentGroups");
assertEquals(Arrays.asList("dyngroup1", "members"), parentGroups);
}
}
// NXP-2730: ldap queries are case-insensitive => test entry retrieval is ok
// when using other cases (lower or upper)
@SuppressWarnings({ "unchecked", "rawtypes" })
@Test
public void testGetEntryWithIdInDifferentCase() {
try (Session session = getLDAPDirectory("userDirectory").getSession()) {
DocumentModel entry = session.getEntry("Administrator");
assertNotNull(entry);
assertEquals("Administrator", entry.getId());
List<String> profiles = (List) entry.getProperty(USER_SCHEMANAME, "profiles");
assertNotNull(profiles);
assertEquals(1, profiles.size());
assertEquals("FUNCTIONAL_ADMINISTRATOR", profiles.get(0));
// retrieve again in upper case
entry = session.getEntry("ADMINISTRATOR");
assertNotNull(entry);
assertEquals("Administrator", entry.getId());
profiles = (List) entry.getProperty(USER_SCHEMANAME, "profiles");
assertNotNull(profiles);
assertEquals(1, profiles.size());
assertEquals("FUNCTIONAL_ADMINISTRATOR", profiles.get(0));
}
}
@SuppressWarnings("unchecked")
@Test
public void testGetEntryWithLdapTreeRef() {
assumeTrue(USE_EXTERNAL_TEST_LDAP_SERVER);
try (Session session = getLDAPDirectory("groupDirectory").getSession();
Session unitSession = getLDAPDirectory("unitDirectory").getSession()) {
DocumentModel entry = session.getEntry("subgroup");
assertNotNull(entry);
assertEquals("subgroup", entry.getId());
assertEquals("subgroup", entry.getProperty(GROUP_SCHEMANAME, "groupname"));
// LDAP references do not work with the internal test server
List<String> members = (List<String>) entry.getProperty(GROUP_SCHEMANAME, "members");
assertNotNull(members);
assertEquals(1, members.size());
List<String> subGroups = (List<String>) entry.getProperty(GROUP_SCHEMANAME, "subGroups");
assertNotNull(subGroups);
assertEquals(0, subGroups.size());
List<String> parentGroups = (List<String>) entry.getProperty(GROUP_SCHEMANAME, "parentGroups");
assertNotNull(parentGroups);
if (HAS_DYNGROUP_SCHEMA) {
assertEquals(1, parentGroups.size());
assertEquals(Arrays.asList("dyngroup1"), parentGroups);
} else {
assertEquals(0, parentGroups.size());
}
List<String> ldapDirectChildren = (List<String>) entry.getProperty(GROUP_SCHEMANAME, "ldapDirectChildren");
assertNotNull(ldapDirectChildren);
assertEquals(1, ldapDirectChildren.size());
assertTrue(ldapDirectChildren.contains("subsubgroup"));
List<String> ldapChildren = (List<String>) entry.getProperty(GROUP_SCHEMANAME, "ldapChildren");
assertNotNull(ldapChildren);
assertEquals(2, ldapChildren.size());
assertTrue(ldapChildren.contains("subsubgroup"));
assertTrue(ldapChildren.contains("subsubsubgroup"));
List<String> ldapDirectParents = (List<String>) entry.getProperty(GROUP_SCHEMANAME, "ldapDirectParents");
assertNotNull(ldapDirectParents);
assertEquals(1, ldapDirectParents.size());
assertTrue(ldapDirectParents.contains("group"));
List<String> ldapParents = (List<String>) entry.getProperty(GROUP_SCHEMANAME, "ldapParents");
assertNotNull(ldapParents);
assertEquals(1, ldapParents.size());
assertTrue(ldapParents.contains("group"));
List<String> ldapUnitDirectChildren = (List<String>) entry.getProperty(GROUP_SCHEMANAME,
"ldapUnitDirectChildren");
assertNotNull(ldapUnitDirectChildren);
assertEquals(1, ldapUnitDirectChildren.size());
assertTrue(ldapUnitDirectChildren.contains("subunit"));
List<String> ldapUnitDirectParents = (List<String>) entry.getProperty(GROUP_SCHEMANAME,
"ldapUnitDirectParents");
assertNotNull(ldapUnitDirectParents);
assertEquals(0, ldapUnitDirectParents.size());
DocumentModel unitEntry = unitSession.getEntry("subunit");
assertNotNull(unitEntry);
assertEquals("subunit", unitEntry.getId());
assertEquals("subunit", unitEntry.getProperty(GROUP_SCHEMANAME, "groupname"));
ldapUnitDirectChildren = (List<String>) unitEntry.getProperty(GROUP_SCHEMANAME, "ldapUnitDirectChildren");
assertNotNull(ldapUnitDirectChildren);
assertEquals(0, ldapUnitDirectChildren.size());
ldapUnitDirectParents = (List<String>) unitEntry.getProperty(GROUP_SCHEMANAME, "ldapUnitDirectParents");
assertNotNull(ldapUnitDirectParents);
assertEquals(1, ldapUnitDirectParents.size());
assertTrue(ldapUnitDirectParents.contains("subgroup"));
}
}
@Test
public void testGetEntries() {
try (Session session = getLDAPDirectory("userDirectory").getSession()) {
DocumentModelList entries = session.getEntries();
assertNotNull(entries);
assertEquals(4, entries.size());
List<String> entryIds = new ArrayList<>();
for (DocumentModel entry : entries) {
entryIds.add(entry.getId());
}
Collections.sort(entryIds);
assertEquals("Administrator", entryIds.get(0));
assertEquals("user1", entryIds.get(1));
assertEquals("user2", entryIds.get(2));
assertEquals("user3", entryIds.get(3));
}
}
@Test
public void testCreateEntry() throws Exception {
assumeTrue(USE_EXTERNAL_TEST_LDAP_SERVER);
try (Session session = getLDAPDirectory("userDirectory").getSession()) {
assertNotNull(session);
Map<String, Object> map = new HashMap<>();
map.put("username", "user0");
map.put("password", "pass0");
map.put("firstName", "User");
map.put("lastName", "");
map.put("intField", Long.valueOf(0));
// special DN read only field should be ignored
map.put("dn", "cn=this,ou=is,ou=a,ou=fake,o=dn");
map.put("email", "nobody@nowhere.com");
map.put("employeeType", Arrays.asList("item1", "item2"));
map.put("groups", Arrays.asList("members", "administrators"));
DocumentModel dm = session.createEntry(map);
dm = session.getEntry("user0");
assertNotNull(dm);
String id = dm.getId();
assertNotNull(id);
String[] schemaNames = dm.getSchemas();
assertEquals(1, schemaNames.length);
assertEquals(USER_SCHEMANAME, schemaNames[0]);
assertEquals("user0", dm.getProperty(USER_SCHEMANAME, "username"));
assertEquals("User", dm.getProperty(USER_SCHEMANAME, "firstName"));
assertEquals("", dm.getProperty(USER_SCHEMANAME, "lastName"));
assertEquals(Long.valueOf(0), dm.getProperty(USER_SCHEMANAME, "intField"));
assertEquals("uid=user0,ou=people,dc=example,dc=com", dm.getProperty(USER_SCHEMANAME, "dn"));
assertEquals("nobody@nowhere.com", dm.getProperty(USER_SCHEMANAME, "email"));
assertEquals(Arrays.asList("item1", "item2"), dm.getProperty(USER_SCHEMANAME, "employeeType"));
assertEquals(Arrays.asList("administrators", "members"), dm.getProperty(USER_SCHEMANAME, "groups"));
assertTrue(session.authenticate("user0", "pass0"));
}
try (Session session = getLDAPDirectory("groupDirectory").getSession()) {
DocumentModel entry = session.getEntry("administrators");
assertNotNull(entry);
assertEquals(Arrays.asList("Administrator", "user0"), entry.getProperty(GROUP_SCHEMANAME, "members"));
entry = session.getEntry("members");
assertNotNull(entry);
assertEquals(Arrays.asList("Administrator", "user0", "user1", "user2"),
entry.getProperty(GROUP_SCHEMANAME, "members"));
}
}
@Test
public void testCreateEntry2() throws Exception {
assumeTrue(USE_EXTERNAL_TEST_LDAP_SERVER);
try (Session session = getLDAPDirectory("groupDirectory").getSession()) {
assertNotNull(session);
Map<String, Object> map = new HashMap<>();
map.put("groupname", "group2");
map.put("members", Arrays.asList("user1", "user2"));
DocumentModel dm = session.createEntry(map);
dm = session.getEntry("group2");
assertNotNull(dm);
assertEquals(Arrays.asList("user1", "user2"), dm.getProperty(GROUP_SCHEMANAME, "members"));
map = new HashMap<>();
map.put("groupname", "group1");
map.put("members", Arrays.asList("Administrator"));
map.put("subGroups", Arrays.asList("group2"));
dm = session.createEntry(map);
dm = session.getEntry("group1");
assertNotNull(dm);
assertEquals(Arrays.asList("Administrator"), dm.getProperty(GROUP_SCHEMANAME, "members"));
assertEquals(Arrays.asList("group2"), dm.getProperty(GROUP_SCHEMANAME, "subGroups"));
dm = session.getEntry("group2");
assertNotNull(dm);
assertEquals(Arrays.asList("group1"), dm.getProperty(GROUP_SCHEMANAME, "parentGroups"));
map = new HashMap<>();
map.put("groupname", "emptygroup");
map.put("members", new ArrayList<String>());
dm = session.createEntry(map);
dm = session.getEntry("emptygroup");
assertNotNull(dm);
assertEquals("emptygroup", dm.getId());
assertEquals("emptygroup", dm.getProperty(GROUP_SCHEMANAME, "groupname"));
assertEquals(Arrays.asList(), dm.getProperty(GROUP_SCHEMANAME, "members"));
assertEquals(Arrays.asList(), dm.getProperty(GROUP_SCHEMANAME, "subGroups"));
assertEquals(Arrays.asList(), dm.getProperty(GROUP_SCHEMANAME, "parentGroups"));
}
}
@Test
public void testCreateEntry3() throws Exception {
try (Session session = getLDAPDirectory("userDirectory").getSession()) {
assumeTrue(USE_EXTERNAL_TEST_LDAP_SERVER);
assertNotNull(session);
Map<String, Object> map = new HashMap<>();
map.put("username", "user123");
map.put("password", "pwd123");
map.put("firstName", "John");
map.put("lastName", "Doh");
// special DN read only field should be ignored
map.put("dn", "cn=this,ou=is,ou=a,ou=fake,o=dn");
map.put("employeeType", new ArrayList<Serializable>());
DocumentModel user = session.getEntry(session.createEntry(map).getId());
assertNotNull(user);
assertEquals(Collections.<String> emptyList(), user.getProperty(USER_SCHEMANAME, "employeeType"));
map = new HashMap<>();
map.put("username", "anotherUser");
map.put("password", "secret");
map.put("firstName", "Mister");
map.put("lastName", "Untel");
map.put("dn", "cn=this,ou=is,ou=a,ou=fake,o=dn");
map.put("employeeType", Collections.<String> emptyList());
if (!(this instanceof TestLDAPPOSIXSession)) {
// Create a fake certificate for the test
X509Certificate myCert = createCertificate("cn=Mister Untel");
Blob cert = Blobs.createBlob(myCert.getEncoded());
map.put("certificate", cert);
user = session.getEntry(session.createEntry(map).getId());
assertNotNull(user);
assertEquals(Collections.<String> emptyList(), user.getProperty(USER_SCHEMANAME, "employeeType"));
// Get the certificate to compare it with the one created
// above
Blob cert2 = (Blob) user.getProperty(USER_SCHEMANAME, "certificate");
assertEquals(new String(cert.getByteArray()), new String(cert2.getByteArray()));
}
}
}
@Test
public void testUpdateEntry() throws Exception {
assumeTrue(USE_EXTERNAL_TEST_LDAP_SERVER);
try (Session session = getLDAPDirectory("userDirectory").getSession();
Session groupSession = getLDAPDirectory("groupDirectory").getSession()) {
DocumentModel entry = session.getEntry("user1");
assertNotNull(entry);
// check that this entry is editable:
assertFalse(BaseSession.isReadOnlyEntry(entry));
entry.setProperty(USER_SCHEMANAME, "firstName", "toto");
entry.setProperty(USER_SCHEMANAME, "lastName", "");
entry.setProperty(USER_SCHEMANAME, "password", "toto");
entry.setProperty(USER_SCHEMANAME, "intField", Long.valueOf(123));
// try to tweak the DN read-only field
entry.setProperty(USER_SCHEMANAME, "dn", "cn=this,ou=is,ou=a,ou=fake,o=dn");
entry.setProperty(USER_SCHEMANAME, "employeeType", Arrays.asList("item3", "item4"));
List<String> groups = Arrays.asList("administrators", "members");
entry.setProperty(USER_SCHEMANAME, "groups", groups);
session.updateEntry(entry);
entry = session.getEntry("user1");
assertNotNull(entry);
assertEquals("toto", entry.getProperty(USER_SCHEMANAME, "firstName"));
assertEquals("", entry.getProperty(USER_SCHEMANAME, "lastName"));
assertEquals(Long.valueOf(123), entry.getProperty(USER_SCHEMANAME, "intField"));
assertEquals(Arrays.asList("item3", "item4"), entry.getProperty(USER_SCHEMANAME, "employeeType"));
if (HAS_DYNGROUP_SCHEMA) {
assertEquals(Arrays.asList("administrators", "dyngroup1", "dyngroup2", "dyngroup3", "members"),
entry.getProperty(USER_SCHEMANAME, "groups"));
} else {
assertEquals(Arrays.asList("administrators", "members"), entry.getProperty(USER_SCHEMANAME, "groups"));
}
// check that the referenced groups where edited properly
entry = groupSession.getEntry("administrators");
assertNotNull(entry);
assertEquals(Arrays.asList("Administrator", "user1"), entry.getProperty(GROUP_SCHEMANAME, "members"));
assertEquals(Arrays.asList(), entry.getProperty(GROUP_SCHEMANAME, "subGroups"));
entry = groupSession.getEntry("members");
assertNotNull(entry);
assertEquals(Arrays.asList("Administrator", "user1", "user2"),
entry.getProperty(GROUP_SCHEMANAME, "members"));
assertEquals(Arrays.asList("submembers"), entry.getProperty(GROUP_SCHEMANAME, "subGroups"));
}
try (Session session = getLDAPDirectory("groupDirectory").getSession()) {
DocumentModel entry = session.getEntry("administrators");
assertNotNull(entry);
assertEquals(Arrays.asList("Administrator", "user1"), entry.getProperty(GROUP_SCHEMANAME, "members"));
}
}
@Test
public void testUpdateEntry2() throws Exception {
assumeTrue(USE_EXTERNAL_TEST_LDAP_SERVER);
try (Session session = getLDAPDirectory("groupDirectory").getSession()) {
DocumentModel entry = session.getEntry("members");
assertNotNull(entry);
// check that this entry is editable:
assertFalse(BaseSession.isReadOnlyEntry(entry));
assertEquals("cn=members,ou=editable,ou=groups,dc=example,dc=com",
entry.getProperty(GROUP_SCHEMANAME, "dn"));
assertEquals(Arrays.asList("submembers"), entry.getProperty(GROUP_SCHEMANAME, "subGroups"));
// edit description and members but not subGroups
entry.setProperty(GROUP_SCHEMANAME, "description", "blablabla");
entry.setProperty(GROUP_SCHEMANAME, "members", Arrays.asList("user1", "user2"));
session.updateEntry(entry);
entry = session.getEntry("members");
assertNotNull(entry);
assertEquals("blablabla", entry.getProperty(GROUP_SCHEMANAME, "description"));
assertEquals(Arrays.asList("user1", "user2"), entry.getProperty(GROUP_SCHEMANAME, "members"));
assertEquals(Arrays.asList("submembers"), entry.getProperty(GROUP_SCHEMANAME, "subGroups"));
// edit both members and subGroups at the same time
entry.setProperty(GROUP_SCHEMANAME, "members", Arrays.asList("user1", "user3"));
entry.setProperty(GROUP_SCHEMANAME, "subGroups", Arrays.asList("submembers", "administrators"));
session.updateEntry(entry);
entry = session.getEntry("members");
assertNotNull(entry);
assertEquals("blablabla", entry.getProperty(GROUP_SCHEMANAME, "description"));
assertEquals(Arrays.asList("user1", "user3"), entry.getProperty(GROUP_SCHEMANAME, "members"));
assertEquals(Arrays.asList("administrators", "submembers"),
entry.getProperty(GROUP_SCHEMANAME, "subGroups"));
}
}
@Test
public void testUpdateEntry3() throws Exception {
assumeTrue(USE_EXTERNAL_TEST_LDAP_SERVER);
assumeTrue(HAS_DYNGROUP_SCHEMA);
try (Session session = getLDAPDirectory("groupDirectory").getSession()) {
DocumentModel entry = session.getEntry("dyngroup1");
// check that this entry is editable:
assertFalse(BaseSession.isReadOnlyEntry(entry));
assertEquals("cn=dyngroup1,ou=dyngroups,ou=editable,ou=groups,dc=example,dc=com",
entry.getProperty(GROUP_SCHEMANAME, "dn"));
assertNotNull(entry);
assertEquals(Arrays.asList("user1", "user3"), entry.getProperty(GROUP_SCHEMANAME, "members"));
if (HAS_DYNGROUP_SCHEMA) {
assertEquals(Arrays.asList("subgroup", "submembers", "subsubgroup", "subsubsubgroup"),
entry.getProperty(GROUP_SCHEMANAME, "subGroups"));
} else {
assertEquals(Arrays.asList("submembers"), entry.getProperty(GROUP_SCHEMANAME, "subGroups"));
}
// try to edit dynamic references values along with regular
// fields
entry.setProperty(GROUP_SCHEMANAME, "description", "blablabla");
entry.setProperty(GROUP_SCHEMANAME, "members", Arrays.asList("user1", "user2"));
entry.setProperty(GROUP_SCHEMANAME, "subGroups", Arrays.asList());
session.updateEntry(entry);
entry = session.getEntry("dyngroup1");
assertNotNull(entry);
// the stored field has been edited
assertEquals("blablabla", entry.getProperty(GROUP_SCHEMANAME, "description"));
// dynamically resolved references have not been edited
assertEquals(Arrays.asList("user1", "user3"), entry.getProperty(GROUP_SCHEMANAME, "members"));
if (HAS_DYNGROUP_SCHEMA) {
assertEquals(Arrays.asList("subgroup", "submembers", "subsubgroup", "subsubsubgroup"),
entry.getProperty(GROUP_SCHEMANAME, "subGroups"));
} else {
assertEquals(Arrays.asList("submembers"), entry.getProperty(GROUP_SCHEMANAME, "subGroups"));
}
// edit both members and subGroups at the same time
entry.setProperty(GROUP_SCHEMANAME, "members", Arrays.asList("user1", "user3"));
entry.setProperty(GROUP_SCHEMANAME, "subGroups", Arrays.asList("submembers", "administrators"));
session.updateEntry(entry);
}
}
@Test
public void testUpdateEntry4() throws Exception {
assumeTrue(USE_EXTERNAL_TEST_LDAP_SERVER);
assumeTrue(HAS_DYNGROUP_SCHEMA);
try (Session userSession = getLDAPDirectory("userDirectory").getSession();
Session groupSession = getLDAPDirectory("groupDirectory").getSession()) {
DocumentModel entry = groupSession.getEntry("readonlygroup1");
assertNotNull(entry);
// check that this entry is NOT editable:
assertTrue(BaseSession.isReadOnlyEntry(entry));
assertEquals("cn=readonlygroup1,ou=readonly,ou=groups,dc=example,dc=com",
entry.getProperty(GROUP_SCHEMANAME, "dn"));
assertEquals("Statically defined group that is not editable",
entry.getProperty(GROUP_SCHEMANAME, "description"));
assertEquals(Arrays.asList("user2"), entry.getProperty(GROUP_SCHEMANAME, "members"));
// check that updates to a readonly entry are not taken into
// account
// edit description and members but not subGroups
entry.setProperty(GROUP_SCHEMANAME, "description", "blablabla");
entry.setProperty(GROUP_SCHEMANAME, "members", Arrays.asList("user1", "user2"));
groupSession.updateEntry(entry);
// fetch the entry again
entry = groupSession.getEntry("readonlygroup1");
assertNotNull(entry);
// values should not have changed
assertEquals("Statically defined group that is not editable",
entry.getProperty(GROUP_SCHEMANAME, "description"));
assertEquals(Arrays.asList("user2"), entry.getProperty(GROUP_SCHEMANAME, "members"));
// check that we cannot edit readonlygroup1 indirectly by adding
// it as a group of user1
DocumentModel user1 = userSession.getEntry("user1");
user1.setProperty(USER_SCHEMANAME, "groups", Arrays.asList("readonlygroup1"));
userSession.updateEntry(user1);
// fetch the group entry again
entry = groupSession.getEntry("readonlygroup1");
assertNotNull(entry);
// values should not have changed
assertEquals("Statically defined group that is not editable",
entry.getProperty(GROUP_SCHEMANAME, "description"));
assertEquals(Arrays.asList("user2"), entry.getProperty(GROUP_SCHEMANAME, "members"));
}
}
@Test
public void testDeleteEntry() {
assumeTrue("The internal server has a suffixed context that prevents it from looking up the entry to delete",
USE_EXTERNAL_TEST_LDAP_SERVER);
try (Session session = getLDAPDirectory("userDirectory").getSession()) {
session.deleteEntry("user1");
DocumentModel entry = session.getEntry("user1");
assertNull(entry);
DocumentModelList entries = session.getEntries();
assertEquals(3, entries.size());
session.deleteEntry("user2");
entry = session.getEntry("user2");
assertNull(entry);
entries = session.getEntries();
assertEquals(2, entries.size());
session.deleteEntry("Administrator");
entry = session.getEntry("Administrator");
assertNull(entry);
entries = session.getEntries();
assertEquals(1, entries.size());
session.deleteEntry("user3");
entry = session.getEntry("user3");
assertNull(entry);
entries = session.getEntries();
assertEquals(0, entries.size());
}
}
@Test
public void testDeleteEntry2() {
assumeTrue("The internal server has a suffixed context that prevents it from looking up the entry to delete",
USE_EXTERNAL_TEST_LDAP_SERVER);
try (Session session = getLDAPDirectory("groupDirectory").getSession()) {
session.deleteEntry("submembers");
DocumentModel entry = session.getEntry("submembers");
assertNull(entry);
DocumentModelList entries = session.getEntries();
if (HAS_DYNGROUP_SCHEMA) {
// 3 dynamic groups
assertEquals(10, entries.size());
} else {
assertEquals(7, entries.size());
}
}
}
@Test
public void testRollback() {
// As a LDAP is not transactional, rollbacking is useless
// this is just a smoke test
try (Session session = getLDAPDirectory("userDirectory").getSession()) {
session.getEntries();
}
}
@Test
public void testQuery1() {
try (Session session = getLDAPDirectory("userDirectory").getSession()) {
Map<String, Serializable> filter = new HashMap<>();
DocumentModelList entries;
// empty filter means everything (like getEntries)
if (USE_EXTERNAL_TEST_LDAP_SERVER) {
// empty filters do not work with ApacheDS
entries = session.query(filter);
assertNotNull(entries);
assertEquals(4, entries.size());
List<String> entryIds = new ArrayList<>();
for (DocumentModel entry : entries) {
entryIds.add(entry.getId());
}
Collections.sort(entryIds);
assertEquals("Administrator", entryIds.get(0));
assertEquals("user1", entryIds.get(1));
assertEquals("user2", entryIds.get(2));
assertEquals("user3", entryIds.get(3));
// trying to query users with no surnames
filter.put("lastName", "");
entries = session.query(filter);
assertEquals(0, entries.size());
// trying to cheat on the search engine
filter.put("lastName", "Man*");
entries = session.query(filter);
assertEquals(0, entries.size());
}
// adding some filter that try to do unauthorized fullext
filter.put("lastName", "Man");
entries = session.query(filter);
assertEquals(0, entries.size());
// same request without cheating
filter.put("lastName", "Manager");
entries = session.query(filter);
assertEquals(1, entries.size());
assertEquals("Administrator", entries.get(0).getId());
// impossible request (too restrictive)
filter.put("firstName", "User");
entries = session.query(filter);
assertEquals(0, entries.size());
}
}
@Test
public void testQuery2() {
assumeTrue("query does not work at all with internal apache", USE_EXTERNAL_TEST_LDAP_SERVER);
try (Session session = getLDAPDirectory("userDirectory").getSession()) {
Map<String, Serializable> filter = new HashMap<>();
Set<String> fulltext = new HashSet<>();
// empty filter means everything (like getEntries)
DocumentModelList entries = session.query(filter, fulltext);
assertNotNull(entries);
assertEquals(4, entries.size());
// trying to do fulltext without the permission
filter.put("firstName", "Use");
entries = session.query(filter, fulltext);
assertEquals(0, entries.size());
// trying to do fulltext with the permission
fulltext.add("firstName");
entries = session.query(filter, fulltext);
assertEquals(3, entries.size());
assertEquals("user1", entries.get(0).getId());
assertEquals("user2", entries.get(1).getId());
assertEquals("user3", entries.get(2).getId());
// more fulltext without the permission
filter.put("lastName", "n");
entries = session.query(filter, fulltext);
assertEquals(0, entries.size());
// trying to cheat
filter.put("lastName", "*");
entries = session.query(filter, fulltext);
assertEquals(0, entries.size());
// more fulltext with the permission
filter.put("lastName", "on");
fulltext.add("lastName");
entries = session.query(filter, fulltext);
assertEquals(2, entries.size());
assertEquals("user1", entries.get(0).getId());
assertEquals("user2", entries.get(1).getId());
// empty filter marked fulltext should match all
filter.clear();
fulltext.clear();
filter.put("lastName", "");
fulltext.add("lastName");
entries = session.query(filter, fulltext);
assertEquals(4, entries.size());
}
}
@Test
public void testQueryWithNullFilter() {
try (Session session = getLDAPDirectory("userDirectory").getSession()) {
Map<String, Serializable> filter = new HashMap<>();
DocumentModelList entries;
// negative filter
filter.put("initials", null);
entries = session.query(filter);
assertEquals(1, entries.size());
assertEquals("user3", entries.get(0).getId());
filter.put("employeeType", null);
filter.put("employeeNumber", null);
entries = session.query(filter);
assertEquals(1, entries.size());
assertEquals("user3", entries.get(0).getId());
}
}
@Test
public void testQueryOrderBy() {
try (Session session = getLDAPDirectory("userDirectory").getSession()) {
Map<String, Serializable> filter = new HashMap<>();
Map<String, String> orderBy = new HashMap<>();
DocumentModelList entries;
orderBy.put("company", "asc");
entries = session.query(filter, Collections.<String> emptySet(), orderBy);
assertEquals(4, entries.size());
// user3: creole
// Administrator: nuxeo
// user2: super
// user1: viral prod
assertEquals("user3", entries.get(0).getId());
assertEquals("Administrator", entries.get(1).getId());
assertEquals("user2", entries.get(2).getId());
assertEquals("user1", entries.get(3).getId());
}
}
@Test
public void testAuthenticate() {
assumeTrue("authenticate does not work at all with internal apache", USE_EXTERNAL_TEST_LDAP_SERVER);
try (Session session = getLDAPDirectory("userDirectory").getSession()) {
assertTrue(session.authenticate("Administrator", "Administrator"));
assertTrue(session.authenticate("user1", "user1"));
assertFalse(session.authenticate("Administrator", "BAD password"));
assertFalse(session.authenticate("user1", "*"));
assertFalse(session.authenticate("NotExistingUser", "whatever"));
assertFalse(session.authenticate("*", "*"));
// ensure workaround to avoid anonymous binding is setup
// NXP-1980
assertFalse(session.authenticate("Administrator", ""));
assertFalse(session.authenticate("user1", ""));
}
}
@Test
public void testGetMandatoryAttributes() {
assumeTrue(USE_EXTERNAL_TEST_LDAP_SERVER);
try (LDAPSession session = (LDAPSession) getLDAPDirectory("userDirectory").getSession()) {
List<String> mandatoryAttributes = session.getMandatoryAttributes();
assertEquals(Arrays.asList("sn", "cn"), mandatoryAttributes);
}
try (LDAPSession session = (LDAPSession) getLDAPDirectory("groupDirectory").getSession()) {
List<String> mandatoryAttributes = session.getMandatoryAttributes();
if (mandatoryAttributes.size() == 2) {
Collections.sort(mandatoryAttributes);
assertEquals(Arrays.asList("cn", "uniqueMember"), mandatoryAttributes);
} else {
// on some LDAP servers, the default schema does not make
// uniqueMember a mandatory attribute
assertEquals(Arrays.asList("cn"), mandatoryAttributes);
}
}
}
@Ignore
public void testDateField() {
// To make this test working:
// - in the file slapd.conf, uncomment the line include /etc/ldap/schema/testdateperson.schema
// - copy the file ldaptools/testdateperson.schema in the folder /etc/ldap/schema
// - in the file TestDirectoriesWithExternalOpenLDAP.xml, uncomment the lines
// <creationClass>testDatePerson</creationClass>
// and <fieldMapping name="dateField">mydate</fieldMapping>
assumeTrue(USE_EXTERNAL_TEST_LDAP_SERVER);
try (Session session = getLDAPDirectory("userDirectory").getSession()) {
assertNotNull(session);
Map<String, Object> map = new HashMap<>();
map.put("username", "user3");
map.put("password", "pass3");
map.put("firstName", "User");
map.put("lastName", "Three");
Calendar cal1 = Calendar.getInstance();
cal1.set(2007, 2, 25, 12, 34, 56);
map.put("dateField", cal1);
session.createEntry(map);
DocumentModel entry = session.getEntry("user3");
assertNotNull(entry);
assertEquals("user3", entry.getId());
Calendar cal2 = (Calendar) entry.getProperty(USER_SCHEMANAME, "dateField");
assertEquals(cal1.getTimeInMillis() / 1000, cal2.getTimeInMillis() / 1000);
cal2.add(Calendar.HOUR, 1);
entry.setProperty(USER_SCHEMANAME, "dateField", cal2);
session.updateEntry(entry);
assertTrue(((Calendar) entry.getProperty(USER_SCHEMANAME, "dateField")).after(cal1));
}
}
@Test
public void testCreateFromModel() throws Exception {
if (USE_EXTERNAL_TEST_LDAP_SERVER) {
try (Session dir = getLDAPDirectory("userDirectory").getSession()) {
String schema = "user";
DocumentModel entry = BaseSession.createEntryModel(null, schema, null, null);
entry.setProperty(schema, "username", "omar");
// XXX: some values are mandatory on real LDAP
entry.setProperty(schema, "password", "sesame");
entry.setProperty(schema, "employeeType", new String[] { "Slave" });
assertNull(dir.getEntry("omar"));
dir.createEntry(entry);
assertNotNull(dir.getEntry("omar"));
// create one with existing same id, must fail
entry.setProperty(schema, "username", "Administrator");
try {
entry = dir.createEntry(entry);
fail("Should raise an error, entry already exists");
} catch (DirectoryException e) {
}
}
}
}
@Test
public void testHasEntry() throws Exception {
try (Session dir = getLDAPDirectory("userDirectory").getSession()) {
assertTrue(dir.hasEntry("Administrator"));
assertFalse(dir.hasEntry("foo"));
}
}
@Test
public void testQueryEmptyString() throws Exception {
Session session = getLDAPDirectory("userDirectory").getSession();
Map<String, Serializable> filter = new HashMap<>();
filter.put("cn", "");
List<DocumentModel> docs = session.query(filter);
assertNotNull(docs);
}
@Test
public void testProbe() {
LDAPDirectoriesProbe probe = new LDAPDirectoriesProbe();
ProbeStatus status = probe.run();
assertTrue(status.isSuccess());
}
@Test
public void testPseudoNormalizeDn() throws Exception {
String normalizedDN = LDAPReference.pseudoNormalizeDn("cn=Lamerand\\, Quentin,OU=developper,ou=PEOPLE, dc=nuxeo,dc=com");
assertEquals("cn=lamerand\\, quentin,ou=developper,ou=people,dc=nuxeo,dc=com", normalizedDN);
}
}