/*
* Copyright 2012 Red Hat, Inc. and/or its affiliates.
*
* 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.jbpm.services.task.identity;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.stream.Collectors;
import org.kie.api.task.model.Group;
import org.kie.api.task.model.OrganizationalEntity;
import org.kie.api.task.model.User;
import org.kie.internal.task.api.TaskModelProvider;
import org.kie.internal.task.api.UserInfo;
public class LDAPUserInfoImpl extends AbstractLDAPUserGroupInfo implements UserInfo {
private static final String DEFAULT_PROPERTIES_NAME = "jbpm.user.info";
public static final String USER_CTX = "ldap.user.ctx";
public static final String ROLE_CTX = "ldap.role.ctx";
public static final String USER_FILTER = "ldap.user.filter";
public static final String ROLE_FILTER = "ldap.role.filter";
public static final String ROLE_MEMBERS_FILTER = "ldap.role.members.filter";
public static final String EMAIL_ATTR_ID = "ldap.email.attr.id";
public static final String NAME_ATTR_ID = "ldap.name.attr.id";
public static final String LANG_ATTR_ID = "ldap.lang.attr.id";
public static final String MEMBER_ATTR_ID = "ldap.member.attr.id";
public static final String USER_ATTR_ID = "ldap.user.attr.id";
public static final String ROLE_ATTR_ID = "ldap.role.attr.id";
public static final String IS_ENTITY_ID_DN = "ldap.entity.id.dn";
public static final String SEARCH_SCOPE = "ldap.search.scope";
private static final String[] REQUIRED_PROPERTIES = {USER_CTX, ROLE_CTX, USER_FILTER, ROLE_FILTER};
private static final String DEFAULT_EMAIL_ATTR_ID = "mail";
private static final String DEFAULT_ENTITY_ID_DN = "false";
private static final String DEFAULT_LANG_ATTR_ID = "locale";
private static final String DEFAULT_MEMBER_ATTR_ID = "member";
private static final String DEFAULT_NAME_ATTR_ID = "displayName";
private static final String DEFAULT_LOCALE = "en-UK";
/**
* Constructor needs to have at least one (unused) parameter in order to prevent CDI from automatic deployment.
* Configuration properties are loaded from a file specified by jbpm.user.info system property or
* classpath:/jbpm.user.info.properties file.
* @param activate ignored
*/
public LDAPUserInfoImpl(boolean activate) {
super(REQUIRED_PROPERTIES, DEFAULT_PROPERTIES_NAME);
}
/**
* @param config LDAP configuration properties
*/
public LDAPUserInfoImpl(Properties config) {
super(REQUIRED_PROPERTIES, config);
}
@Override
public String getDisplayName(OrganizationalEntity entity) {
return getAttributeValueForEntity(entity, NAME_ATTR_ID, DEFAULT_NAME_ATTR_ID);
}
@Override
public Iterator<OrganizationalEntity> getMembersForGroup(Group group) {
String roleContext = getConfigProperty(ROLE_CTX);
String roleFilter = getConfigProperty(ROLE_MEMBERS_FILTER, getConfigProperty(ROLE_FILTER));
String roleAttrId = getConfigProperty(MEMBER_ATTR_ID, DEFAULT_MEMBER_ATTR_ID);
String entityId = extractEntityId(group);
List<String> memberIds = ldapSearcher.search(roleContext, roleFilter, entityId).getAttributeResults(roleAttrId);
return memberIds.stream()
.filter(memberId -> memberId != null)
.map(memberId -> (OrganizationalEntity) TaskModelProvider.getFactory().newUser(memberId))
.collect(Collectors.toList())
.iterator();
}
@Override
public boolean hasEmail(Group group) {
return getEmailForEntity(group) != null;
}
@Override
public String getEmailForEntity(OrganizationalEntity entity) {
return getAttributeValueForEntity(entity, EMAIL_ATTR_ID, DEFAULT_EMAIL_ATTR_ID);
}
@Override
public String getLanguageForEntity(OrganizationalEntity entity) {
String result = getAttributeValueForEntity(entity, LANG_ATTR_ID, DEFAULT_LANG_ATTR_ID);
return result == null ? DEFAULT_LOCALE : result;
}
private String getAttributeValueForEntity(OrganizationalEntity entity, String attributeName, String defaultValue) {
String context = getConfigPropertyByEntity(entity, USER_CTX, ROLE_CTX);
String filter = getConfigPropertyByEntity(entity, USER_FILTER, ROLE_FILTER);
String attrId = getConfigProperty(attributeName, defaultValue);
String entityId = extractEntityId(entity);
return ldapSearcher.search(context, filter, entityId).getSingleAttributeResult(attrId);
}
private String getConfigPropertyByEntity(OrganizationalEntity entity, String userKey, String roleKey) {
if (entity instanceof User) {
return getConfigProperty(userKey);
} else if (entity instanceof Group) {
return getConfigProperty(roleKey);
} else {
throw new IllegalArgumentException("Unknown organizational entity: " + entity);
}
}
private String extractEntityId(OrganizationalEntity entity) {
if (!isEntityIdDn()) {
return entity.getId();
}
String entityDN = entity.getId();
String[] attributes = entityDN.split(",");
if (attributes.length == 1) {
return entityDN;
}
String entityAttrId = null;
if (entity instanceof User) {
entityAttrId = getConfigProperty(USER_ATTR_ID, DEFAULT_USER_ATTR_ID);
} else if (entity instanceof Group) {
entityAttrId = getConfigProperty(ROLE_ATTR_ID, DEFAULT_ROLE_ATTR_ID);
}
for (String attribute : attributes) {
String[] keyValue = attribute.split("=");
if (keyValue[0].equalsIgnoreCase(entityAttrId)) {
return keyValue[1];
}
}
throw new RuntimeException("Cannot parse '" + entityAttrId + "' attribute from entity DN '" + entityDN + "'");
}
private boolean isEntityIdDn() {
return Boolean.parseBoolean(getConfigProperty(IS_ENTITY_ID_DN, DEFAULT_ENTITY_ID_DN));
}
}