/**
* <a href="http://www.openolat.org">
* OpenOLAT - Online Learning and Training</a><br>
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); <br>
* you may not use this file except in compliance with the License.<br>
* You may obtain a copy of the License at the
* <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
* <p>
* Unless required by applicable law or agreed to in writing,<br>
* software distributed under the License is distributed on an "AS IS" BASIS, <br>
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
* See the License for the specific language governing permissions and <br>
* limitations under the License.
* <p>
* Initial code contributed and copyrighted by<br>
* frentix GmbH, http://www.frentix.com
* <p>
*/
package org.olat.ldap;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.ldap.LdapContext;
import org.junit.Assert;
import org.junit.Assume;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.olat.admin.user.delete.service.UserDeletionManager;
import org.olat.basesecurity.BaseSecurity;
import org.olat.basesecurity.SecurityGroup;
import org.olat.core.commons.persistence.DBFactory;
import org.olat.core.id.Identity;
import org.olat.core.id.User;
import org.olat.ldap.manager.LDAPDAO;
import org.olat.ldap.model.LDAPUser;
import org.olat.test.OlatTestCase;
import org.olat.user.UserManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.zapodot.junit.ldap.EmbeddedLdapRule;
import org.zapodot.junit.ldap.EmbeddedLdapRuleBuilder;
/**
* Description:<br>
* LDAP junit tests
*
* please import "olattest.ldif" into your configured LDAP directory
*
* <P>
* Initial Date: June 30, 2008 <br>
* @author Maurus Rohrer
*/
public class LDAPLoginTest extends OlatTestCase {
@Autowired
private LDAPDAO ldapDao;
@Autowired
private LDAPLoginManager ldapManager;
@Autowired
private BaseSecurity securityManager;
@Autowired
private LDAPLoginModule ldapLoginModule;
@Autowired
private LDAPSyncConfiguration syncConfiguration;
@Rule
public EmbeddedLdapRule embeddedLdapRule = EmbeddedLdapRuleBuilder
.newInstance()
.usingDomainDsn("dc=olattest,dc=org")
.importingLdifs("org/olat/ldap/junittestdata/olattest.ldif")
.bindingToAddress("localhost")
.bindingToPort(1389)
.build();
@Test
public void testSystemBind() {
Assume.assumeTrue(ldapLoginModule.isLDAPEnabled());
LdapContext ctx = ldapManager.bindSystem();
Assert.assertNotNull(ctx);
}
@Test
public void testUserBind() throws NamingException {
Assume.assumeTrue(ldapLoginModule.isLDAPEnabled());
LDAPError errors = new LDAPError();
String uid = "mrohrer";
String userPW = "olat";
//normal bind, should work
Attributes attrs = ldapManager.bindUser(uid, userPW, errors);
Assert.assertNotNull(attrs);
Assert.assertEquals("Rohrer", attrs.get("sn").get());
//wrong password, should fail
userPW = "haha";
attrs = ldapManager.bindUser(uid, userPW, errors);
Assert.assertNull(attrs);
Assert.assertEquals("Username or password incorrect", errors.get());
//wrong username, should fail
uid = "ruedisueli";
userPW = "olat";
attrs = ldapManager.bindUser(uid, userPW, errors);
Assert.assertNull(attrs);
Assert.assertEquals("Username or password incorrect", errors.get());
//no password, should fail
uid = "mrohrer";
userPW = null;
attrs = ldapManager.bindUser(uid, userPW, errors);
Assert.assertNull(attrs);
Assert.assertEquals("Username and password must be selected", errors.get());
}
@Test @Ignore //need to sync the user
public void testCheckUser() {
Assume.assumeTrue(ldapLoginModule.isLDAPEnabled());
LDAPError errors = new LDAPError();
//should create error entry
String uid = "Administrator";
Attributes attrs = ldapManager.bindUser(uid, "olat", errors);
Identity identity = ldapManager.findIdentityByLdapAuthentication(attrs, errors);
Assert.assertEquals("findIdentyByLdapAuthentication: attrs::null", errors.get());
//should return identity, since is existing in OLAT and Managed by LDAP
uid = "mrohrer";
attrs = ldapManager.bindUser(uid, "olat", errors);
identity = ldapManager.findIdentityByLdapAuthentication(attrs, errors);
Assert.assertEquals(uid, identity.getName());
Assert.assertTrue(errors.isEmpty());
}
@Test @Ignore //need to sync the user
public void testSyncUser(){
Assume.assumeTrue(ldapLoginModule.isLDAPEnabled());
Map<String,String> changedMap = new HashMap<String,String>();
LDAPError errors = new LDAPError();
changedMap.put("userID", "kmeier");
changedMap.put("firstName", "Klaus");
changedMap.put("email", "kmeier@olat.org");
changedMap.put("institutionalName", "Informatik");
changedMap.put("homepage", "http://www.olat.org");
Identity identity = securityManager.findIdentityByName("kmeier");
ldapManager.syncUser(changedMap, identity);
changedMap.put("userID", "kmeier");
Attributes attrs = ldapManager.bindUser("kmeier", "olat", errors);
changedMap = ldapManager.prepareUserPropertyForSync(attrs, identity);
assertEquals(true, (changedMap==null));
}
@Test @Ignore
public void testIdentityDeletedInLDAP(){
Assume.assumeTrue(ldapLoginModule.isLDAPEnabled());
List<Identity> deletList;
//should be empty
LdapContext ctx = ldapManager.bindSystem();
deletList = ldapManager.getIdentitysDeletedInLdap(ctx);
assertEquals(0, (deletList.size()));
// simulate closed session (user adding from startup job)
DBFactory.getInstance().intermediateCommit();
//create some users in LDAPSecurityGroup
User user = UserManager.getInstance().createUser("grollia", "wa", "gorrila@olat.org");
Identity identity = securityManager.createAndPersistIdentityAndUser("gorilla", null,user, "LDAP", "gorrila");
SecurityGroup secGroup1 = securityManager.findSecurityGroupByName(LDAPConstants.SECURITY_GROUP_LDAP);
securityManager.addIdentityToSecurityGroup(identity, secGroup1);
user = UserManager.getInstance().createUser("wer", "immer", "immer@olat.org");
identity = securityManager.createAndPersistIdentityAndUser("der", null, user, "LDAP", "der");
securityManager.addIdentityToSecurityGroup(identity, secGroup1);
user = UserManager.getInstance().createUser("die", "da", "chaspi@olat.org");
identity = securityManager.createAndPersistIdentityAndUser("das", null, user, "LDAP", "das");
securityManager.addIdentityToSecurityGroup(identity, secGroup1);
// simulate closed session
DBFactory.getInstance().intermediateCommit();
//3 members in LDAP group but not existing in OLAT
deletList = ldapManager.getIdentitysDeletedInLdap(ctx);
assertEquals(3, (deletList.size()));
//delete user in OLAT
securityManager.removeIdentityFromSecurityGroup(identity, secGroup1);
UserDeletionManager.getInstance().deleteIdentity(identity);
// simulate closed session
DBFactory.getInstance().intermediateCommit();
//2 members in LDAP group but not existing in OLAT
deletList = ldapManager.getIdentitysDeletedInLdap(ctx);
assertEquals(2, (deletList.size()));
}
@Test @Ignore
public void testCreateUser() {
Assume.assumeTrue(ldapLoginModule.isLDAPEnabled());
String uid = "mrohrer";
String userPW = "olat";
LDAPError errors = new LDAPError();
boolean usersSyncedAtStartup = ldapLoginModule.isLdapSyncOnStartup();
//user should not exits in OLAT when not synced during startup
assertEquals(usersSyncedAtStartup, (securityManager.findIdentityByName(uid) != null));
// bind user
Attributes attrs = ldapManager.bindUser(uid, userPW, errors);
assertEquals(usersSyncedAtStartup, (securityManager.findIdentityByName(uid) != null));
//user should be created
ldapManager.createAndPersistUser(attrs);
assertEquals(true, (securityManager.findIdentityByName(uid) != null));
//should fail, user is existing
ldapManager.createAndPersistUser(attrs);
assertEquals(true, (securityManager.findIdentityByName(uid) != null));
}
@Test @Ignore
public void testCreateChangedAttrMap() {
Assume.assumeTrue(ldapLoginModule.isLDAPEnabled());
// simulate closed session (user adding from startup job)
DBFactory.getInstance().intermediateCommit();
String uid = "kmeier";
String pwd = "olat";
LDAPError errors = new LDAPError();
boolean usersSyncedAtStartup = ldapLoginModule.isLdapSyncOnStartup();
if (usersSyncedAtStartup) {
try {
//create user but with different attributes - must fail since user already exists
User user = UserManager.getInstance().createUser("klaus", "Meier", "klaus@meier.ch");
Identity identity = securityManager.createAndPersistIdentityAndUser("kmeier", null, user, "LDAP", "kmeier");
SecurityGroup secGroup = securityManager.findSecurityGroupByName(LDAPConstants.SECURITY_GROUP_LDAP);
securityManager.addIdentityToSecurityGroup(identity, secGroup);
// simulate closed session (user adding from startup job)
DBFactory.getInstance().intermediateCommit();
fail("Expected constrant violation becaus of doupliate entry");
} catch (Exception e) {
// success, this is what we expected
}
//changedAttrMap empty since already synchronized
Attributes attrs = ldapManager.bindUser(uid, pwd, errors);
Identity identitys = securityManager.findIdentityByName(uid);
Map<String, String> changedAttrMap = ldapManager.prepareUserPropertyForSync(attrs, identitys);
// map is empty - no attributes to sync
assertNull(changedAttrMap);
} else {
//create user but with different attributes - must fail since user already exists
User user = UserManager.getInstance().createUser("klaus", "Meier", "klaus@meier.ch");
Identity identity = securityManager.createAndPersistIdentityAndUser("kmeier", null, user, "LDAP", "kmeier");
SecurityGroup secGroup = securityManager.findSecurityGroupByName(LDAPConstants.SECURITY_GROUP_LDAP);
securityManager.addIdentityToSecurityGroup(identity, secGroup);
// simulate closed session (user adding from startup job)
DBFactory.getInstance().intermediateCommit();
//changedAttrMap has 2 changes and uid as entrys (Klaus!=klaus, klaus@olat.org!=klaus@meier.ch)
Attributes attrs = ldapManager.bindUser(uid, pwd, errors);
Identity identitys = securityManager.findIdentityByName(uid);
Map<String, String> changedAttrMap = ldapManager.prepareUserPropertyForSync(attrs, identitys);
// result must be 3: 2 changed plus the user ID which is always in the map
assertEquals(3, changedAttrMap.keySet().size());
}
//nothing to change for this user
uid= "mrohrer";
Attributes attrs = ldapManager.bindUser(uid, pwd, errors);
Identity identitys = securityManager.findIdentityByName(uid);
Map<String, String> changedAttrMap = ldapManager.prepareUserPropertyForSync(attrs, identitys);
assertEquals(true, (changedAttrMap==null));
}
@Test @Ignore
public void testCronSync() throws Exception {
Assume.assumeTrue(ldapLoginModule.isLDAPEnabled());
LdapContext ctx;
List<LDAPUser> ldapUserList;
List<Attributes> newLdapUserList;
Map<Identity, Map<String, String>> changedMapIdenityMap;
List<Identity> deletedUserList;
LDAPError errors = new LDAPError();
//find user changed after 2010,01,09,00,00
ctx = ldapManager.bindSystem();
Calendar cal = Calendar.getInstance();
cal.set(2010, 0, 10, 0, 0, 0);
Date syncDate = cal.getTime();
ldapUserList = ldapDao.getUserAttributesModifiedSince(syncDate, ctx);
assertEquals(1, ldapUserList.size());
//find all users
syncDate = null;
ldapUserList = ldapDao.getUserAttributesModifiedSince(syncDate, ctx);
assertEquals(6, ldapUserList.size());
//prepare create- and sync-Lists for each user from defined syncTime
Identity idenity;
Map<String,String> changedAttrMap;
newLdapUserList = new LinkedList<Attributes>();
changedMapIdenityMap = new HashMap<Identity, Map<String, String>>();
for (int i = 0; i < ldapUserList.size(); i++) {
Attributes userAttrs = ldapUserList.get(i).getAttributes();
String user = getAttributeValue(userAttrs.get(syncConfiguration.getOlatPropertyToLdapAttribute("userID")));
idenity = ldapManager.findIdentityByLdapAuthentication(userAttrs, errors);
if (idenity != null) {
changedAttrMap = ldapManager.prepareUserPropertyForSync(userAttrs, idenity);
if(changedAttrMap!= null) changedMapIdenityMap.put(idenity, changedAttrMap);
} else {
if(errors.isEmpty()) {
String[] reqAttrs = syncConfiguration.checkRequestAttributes(userAttrs);
if(reqAttrs==null) newLdapUserList.add(userAttrs);
else System.out.println("Cannot create User " + user + " required Attributes are missing");
}
else System.out.println(errors.get());
}
}
//create Users in LDAP Group only existing in OLAT
User user1 = UserManager.getInstance().createUser("hansi", "hürlima", "hansi@hansli.com");
Identity identity1 = securityManager.createAndPersistIdentityAndUser("hansi", null, user1, "LDAP", "hansi");
SecurityGroup secGroup1 = securityManager.findSecurityGroupByName(LDAPConstants.SECURITY_GROUP_LDAP);
securityManager.addIdentityToSecurityGroup(identity1, secGroup1);
user1 = UserManager.getInstance().createUser("chaspi", "meier", "chaspi@hansli.com");
identity1 = securityManager.createAndPersistIdentityAndUser("chaspi", null, user1, "LDAP", "chaspi");
securityManager.addIdentityToSecurityGroup(identity1, secGroup1);
//create User to Delete List
deletedUserList = ldapManager.getIdentitysDeletedInLdap(ctx);
assertEquals(4, (deletedUserList.size()));
//sync users
Iterator<Identity> itrIdent = changedMapIdenityMap.keySet().iterator();
while(itrIdent.hasNext()){
Identity ident = itrIdent.next();
ldapManager.syncUser(changedMapIdenityMap.get(ident), ident);
}
//create all users
for (int i = 0; i < newLdapUserList.size(); i++) {
ldapManager.createAndPersistUser(newLdapUserList.get(i));
}
//delete all users
ldapManager.deletIdentities(deletedUserList);
//check if users are deleted
deletedUserList = ldapManager.getIdentitysDeletedInLdap(ctx);
assertEquals(0, (deletedUserList.size()));
}
private String getAttributeValue(Attribute attribute)
throws NamingException {
String attrValue = (String)attribute.get();
return attrValue;
}
}