/////////////////////////////////////////////////////////////////////////////
//
// Project ProjectForge Community Edition
// www.projectforge.org
//
// Copyright (C) 2001-2014 Kai Reinhard (k.reinhard@micromata.de)
//
// ProjectForge is dual-licensed.
//
// This community edition 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; version 3 of the License.
//
// This community edition 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/.
//
/////////////////////////////////////////////////////////////////////////////
package org.projectforge.ldap;
import java.util.List;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.ModificationItem;
import org.apache.commons.collections.CollectionUtils;
import org.projectforge.common.NumberHelper;
/**
* @author Kai Reinhard (k.reinhard@micromata.de)
*/
public class LdapGroupDao extends LdapDao<String, LdapGroup>
{
private static final String[] ADDITIONAL_OBJECT_CLASSES = { "top"};
private static final String[] ADDITIONAL_OBJECT_CLASSES_WITH_POSIX_SUPPORT = { "top", "posixGroup"};
private static final String NONE_UNIQUE_MEMBER_ID = "cn=none";
/**
* Since member of groups can't be null, "cn=none" if the group has no real members.
* @param group
* @return
*/
public static boolean hasMembers(final LdapGroup group)
{
if (group.getMembers() == null || group.getMembers().size() == 0) {
return false;
}
if (group.getMembers().size() > 1) {
return true;
}
return group.getMembers().iterator().next().startsWith(NONE_UNIQUE_MEMBER_ID) == false;
}
/**
* @see org.projectforge.ldap.LdapDao#getObjectClass()
*/
@Override
protected String getObjectClass()
{
return "groupOfUniqueNames";
}
/**
* @see org.projectforge.ldap.LdapDao#getAdditionalObjectClasses()
*/
@Override
protected String[] getAdditionalObjectClasses()
{
throw new UnsupportedOperationException("Call getAdditionalObjectClasses(LdapGroup) instead.");
}
/**
* @see org.projectforge.ldap.LdapDao#getAdditionalObjectClasses(org.projectforge.ldap.LdapObject)
*/
@Override
protected String[] getAdditionalObjectClasses(final LdapGroup obj)
{
final boolean posixAccount = isPosixAccountsConfigured() == true && GroupDOConverter.isPosixAccountValuesEmpty(obj) == false;
if (posixAccount == true) {
return ADDITIONAL_OBJECT_CLASSES_WITH_POSIX_SUPPORT;
}
return ADDITIONAL_OBJECT_CLASSES;
}
/**
* @see org.projectforge.ldap.LdapDao#getIdAttrId()
*/
@Override
public String getIdAttrId()
{
return "businessCategory";
}
/**
* @see org.projectforge.ldap.LdapDao#getId(org.projectforge.ldap.LdapObject)
*/
@Override
public String getId(final LdapGroup obj)
{
return obj.getBusinessCategory();
}
/**
* Used for bind and update.
* @param person
* @return
* @see org.projectforge.ldap.LdapDao#getModificationItems(org.projectforge.ldap.LdapObject)
*/
@Override
protected List<ModificationItem> getModificationItems(final List<ModificationItem> list, final LdapGroup group)
{
createAndAddModificationItems(list, "businessCategory", group.getBusinessCategory());
createAndAddModificationItems(list, "o", group.getOrganization());
createAndAddModificationItems(list, "description", group.getDescription());
if (CollectionUtils.isNotEmpty(group.getMembers()) == true) {
createAndAddModificationItems(list, "uniqueMember", group.getMembers());
} else {
createAndAddModificationItems(list, "uniqueMember", NONE_UNIQUE_MEMBER_ID);
}
final boolean modifyPosixAccount = isPosixAccountsConfigured() == true && GroupDOConverter.isPosixAccountValuesEmpty(group) == false;
if (modifyPosixAccount == true) {
if (group.getObjectClasses() != null) {
final List<String> missedObjectClasses = LdapUtils.getMissedObjectClasses(getAdditionalObjectClasses(group), getObjectClass(),
group.getObjectClasses());
if (CollectionUtils.isNotEmpty(missedObjectClasses) == true) {
for (final String missedObjectClass : missedObjectClasses) {
list.add(createModificationItem(DirContext.ADD_ATTRIBUTE, "objectClass", missedObjectClass));
}
}
}
}
if (modifyPosixAccount == true) {
createAndAddModificationItems(list, "gidNumber", String.valueOf(group.getGidNumber()));
}
return list;
}
/**
* @see org.projectforge.ldap.LdapDao#mapToObject(java.lang.String, javax.naming.directory.Attributes)
*/
@Override
protected LdapGroup mapToObject(final String dn, final Attributes attributes) throws NamingException
{
final LdapGroup group = new LdapGroup();
group.setBusinessCategory(LdapUtils.getAttributeStringValue(attributes, "businessCategory"));
group.setDescription(LdapUtils.getAttributeStringValue(attributes, "description"));
group.setOrganization(LdapUtils.getAttributeStringValue(attributes, "o"));
final String[] members = LdapUtils.getAttributeStringValues(attributes, "uniqueMember");
if (members != null) {
for (final String member : members) {
group.addMember(member, ldapConfig.getBaseDN());
}
}
final boolean posixAccountsConfigured = isPosixAccountsConfigured();
if (posixAccountsConfigured == true) {
final String no = LdapUtils.getAttributeStringValue(attributes, "gidNumber");
group.setGidNumber(NumberHelper.parseInteger(no));
}
return group;
}
/**
* @see org.projectforge.ldap.LdapDao#buildId(java.lang.Object)
*/
@Override
protected String buildId(final Object id)
{
if (id == null) {
return null;
}
if (id instanceof String && ((String) id).startsWith(GroupDOConverter.ID_PREFIX) == true) {
return String.valueOf(id);
}
return GroupDOConverter.ID_PREFIX + id;
}
/**
* @see org.projectforge.ldap.LdapDao#getOuBase()
*/
@Override
protected String getOuBase()
{
return ldapConfig.getGroupBase();
}
public static boolean isPosixAccountsConfigured()
{
return LdapUserDao.isPosixAccountsConfigured();
}
}