/* 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.
*/
package org.activiti.ldap;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import org.activiti.engine.ActivitiException;
import org.activiti.engine.ActivitiIllegalArgumentException;
import org.activiti.engine.identity.Group;
import org.activiti.engine.identity.GroupQuery;
import org.activiti.engine.impl.GroupQueryImpl;
import org.activiti.engine.impl.Page;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.persistence.AbstractManager;
import org.activiti.engine.impl.persistence.entity.GroupEntity;
import org.activiti.engine.impl.persistence.entity.GroupIdentityManager;
/**
* Implementation of the {@link GroupIdentityManager} interface specifically for LDAP.
*
* Note that only a few methods are actually implemented, as many of the operations
* (save, update, etc.) are done on the LDAP system directly.
*
* @author Joram Barrez
*/
public class LDAPGroupManager extends AbstractManager implements GroupIdentityManager {
protected LDAPConfigurator ldapConfigurator;
protected LDAPGroupCache ldapGroupCache;
public LDAPGroupManager(LDAPConfigurator ldapConfigurator) {
this.ldapConfigurator = ldapConfigurator;
}
public LDAPGroupManager(LDAPConfigurator ldapConfigurator, LDAPGroupCache ldapGroupCache) {
this.ldapConfigurator = ldapConfigurator;
this.ldapGroupCache = ldapGroupCache;
}
@Override
public Group createNewGroup(String groupId) {
throw new ActivitiException("LDAP group manager doesn't support creating a new group");
}
@Override
public void insertGroup(Group group) {
throw new ActivitiException("LDAP group manager doesn't support inserting a group");
}
@Override
public void updateGroup(Group updatedGroup) {
throw new ActivitiException("LDAP group manager doesn't support updating a group");
}
@Override
public boolean isNewGroup(Group group) {
throw new ActivitiException("LDAP group manager doesn't support inserting or updating a group");
}
@Override
public void deleteGroup(String groupId) {
throw new ActivitiException("LDAP group manager doesn't support deleting a group");
}
@Override
public GroupQuery createNewGroupQuery() {
return new GroupQueryImpl(Context.getProcessEngineConfiguration().getCommandExecutor());
}
@Override
public List<Group> findGroupByQueryCriteria(GroupQueryImpl query, Page page) {
// Only support for groupMember() at the moment
if (query.getUserId() != null) {
return findGroupsByUser(query.getUserId());
} else {
throw new ActivitiIllegalArgumentException("This query is not supported by the LDAPGroupManager");
}
}
@Override
public long findGroupCountByQueryCriteria(GroupQueryImpl query) {
return findGroupByQueryCriteria(query, null).size(); // Is there a generic way to do a count(*) in ldap?
}
@Override
public List<Group> findGroupsByUser(final String userId) {
// First try the cache (if one is defined)
if (ldapGroupCache != null) {
List<Group> groups = ldapGroupCache.get(userId);
if (groups != null) {
return groups;
}
}
// Do the search against Ldap
LDAPTemplate ldapTemplate = new LDAPTemplate(ldapConfigurator);
return ldapTemplate.execute(new LDAPCallBack<List<Group>>() {
public List<Group> executeInContext(InitialDirContext initialDirContext) {
String searchExpression = ldapConfigurator.getLdapQueryBuilder().buildQueryGroupsForUser(ldapConfigurator, userId);
List<Group> groups = new ArrayList<Group>();
try {
String baseDn = ldapConfigurator.getGroupBaseDn() != null ? ldapConfigurator.getGroupBaseDn() : ldapConfigurator.getBaseDn();
NamingEnumeration< ? > namingEnum = initialDirContext.search(baseDn, searchExpression, createSearchControls());
while (namingEnum.hasMore()) { // Should be only one
SearchResult result = (SearchResult) namingEnum.next();
GroupEntity group = new GroupEntity();
if (ldapConfigurator.getGroupIdAttribute() != null) {
group.setId(result.getAttributes().get(ldapConfigurator.getGroupIdAttribute()).get().toString());
}
if (ldapConfigurator.getGroupNameAttribute() != null) {
group.setName(result.getAttributes().get(ldapConfigurator.getGroupNameAttribute()).get().toString());
}
if (ldapConfigurator.getGroupTypeAttribute() != null) {
group.setType(result.getAttributes().get(ldapConfigurator.getGroupTypeAttribute()).get().toString());
}
groups.add(group);
}
namingEnum.close();
// Cache results for later
if (ldapGroupCache != null) {
ldapGroupCache.add(userId, groups);
}
return groups;
} catch (NamingException e) {
throw new ActivitiException("Could not find groups for user " + userId, e);
}
}
});
}
@Override
public List<Group> findGroupsByNativeQuery(Map<String, Object> parameterMap, int firstResult, int maxResults) {
throw new ActivitiException("LDAP group manager doesn't support querying");
}
@Override
public long findGroupCountByNativeQuery(Map<String, Object> parameterMap) {
throw new ActivitiException("LDAP group manager doesn't support querying");
}
protected SearchControls createSearchControls() {
SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
searchControls.setTimeLimit(ldapConfigurator.getSearchTimeLimit());
return searchControls;
}
}