/////////////////////////////////////////////////////////////////////////////
//
// 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.LinkedList;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.projectforge.common.BeanHelper;
import org.projectforge.common.ListHelper;
import org.projectforge.common.NumberHelper;
import org.projectforge.core.ConfigXml;
import org.projectforge.user.PFUserDO;
import org.projectforge.xml.stream.XmlObjectReader;
import org.projectforge.xml.stream.XmlObjectWriter;
/**
* @author Kai Reinhard (k.reinhard@micromata.de)
*/
public class PFUserDOConverter
{
static final String ID_PREFIX = "pf-id-";
public static Integer getId(final LdapUser user)
{
final String employeeNumber = user.getEmployeeNumber();
if (employeeNumber != null && employeeNumber.startsWith(ID_PREFIX) == true && employeeNumber.length() > ID_PREFIX.length()) {
final String id = employeeNumber.substring(ID_PREFIX.length());
return NumberHelper.parseInteger(id);
}
return null;
}
public static PFUserDO convert(final LdapUser ldapUser)
{
final PFUserDO user = new PFUserDO();
user.setLastname(ldapUser.getSurname());
user.setFirstname(ldapUser.getGivenName());
user.setUsername(ldapUser.getUid());
user.setId(getId(ldapUser));
user.setOrganization(ldapUser.getOrganization());
user.setDescription(ldapUser.getDescription());
user.setLastPasswordChange(ldapUser.getSambaPwdLastSet());
final String[] mails = ldapUser.getMail();
if (mails != null) {
for (final String mail : mails) {
if (StringUtils.isNotEmpty(mail) == true) {
user.setEmail(mail);
break;
}
}
}
if (ldapUser.isDeleted() == true) {
user.setDeleted(true);
}
if (ldapUser.isDeactivated() == true || LdapUserDao.isDeactivated(ldapUser) == true) {
user.setDeactivated(true);
}
if (ldapUser.isRestrictedUser() == true || LdapUserDao.isRestrictedUser(ldapUser) == true) {
user.setRestrictedUser(true);
}
if (isPosixAccountValuesEmpty(ldapUser) == false) {
user.setLdapValues(getLdapValuesAsXml(ldapUser));
}
return user;
}
public static LdapUser convert(final PFUserDO user)
{
final LdapUser ldapUser = new LdapUser();
ldapUser.setSurname(user.getLastname());
ldapUser.setGivenName(user.getFirstname());
ldapUser.setUid(user.getUsername());
if (user.getId() != null) {
ldapUser.setEmployeeNumber(buildEmployeeNumber(user));
}
ldapUser.setOrganization(user.getOrganization());
ldapUser.setDescription(user.getDescription());
ldapUser.setMail(user.getEmail());
ldapUser.setDeleted(user.isDeleted());
ldapUser.setDeactivated(user.isDeactivated());
if (user.isDeactivated() == true) {
ldapUser.setMail(LdapUserDao.DEACTIVATED_MAIL);
}
ldapUser.setRestrictedUser(user.isRestrictedUser());
setLdapValues(ldapUser, user.getLdapValues());
ldapUser.setSambaPwdLastSet(user.getLastPasswordChange() != null ? user.getLastPasswordChange() : user.getCreated());
return ldapUser;
}
public static boolean isPosixAccountValuesEmpty(final LdapUser ldapUser)
{
return ldapUser.getUidNumber() == null
&& StringUtils.isBlank(ldapUser.getHomeDirectory()) == true
&& StringUtils.isBlank(ldapUser.getLoginShell()) == true
&& ldapUser.getGidNumber() == null;
}
public static boolean isSambaAccountValuesEmpty(final LdapUser ldapUser)
{
return ldapUser.getSambaSIDNumber() == null && ldapUser.getSambaPrimaryGroupSIDNumber() == null;
}
/**
* Sets the LDAP values such as posix account properties of the given ldapUser configured in the given xml string.
* @param ldapUser
* @param ldapValuesAsXml Posix account values as xml.
*/
public static void setLdapValues(final LdapUser ldapUser, final String ldapValuesAsXml)
{
if (StringUtils.isBlank(ldapValuesAsXml) == true) {
return;
}
final LdapConfig ldapConfig = ConfigXml.getInstance().getLdapConfig();
final LdapPosixAccountsConfig posixAccountsConfig = ldapConfig != null ? ldapConfig.getPosixAccountsConfig() : null;
if (posixAccountsConfig == null) {
// No posix account default values configured
return;
}
final LdapUserValues values = readLdapUserValues(ldapValuesAsXml);
if (values == null) {
return;
}
if (values.getUidNumber() != null) {
ldapUser.setUidNumber(values.getUidNumber());
} else {
ldapUser.setUidNumber(-1);
}
if (values.getGidNumber() != null) {
ldapUser.setGidNumber(values.getGidNumber());
} else {
ldapUser.setGidNumber(posixAccountsConfig.getDefaultGidNumber());
}
if (StringUtils.isNotBlank(values.getHomeDirectory()) == true) {
ldapUser.setHomeDirectory(values.getHomeDirectory());
} else {
ldapUser.setHomeDirectory(posixAccountsConfig.getHomeDirectoryPrefix() + ldapUser.getUid());
}
if (StringUtils.isNotBlank(values.getLoginShell()) == true) {
ldapUser.setLoginShell(values.getLoginShell());
} else {
ldapUser.setLoginShell(posixAccountsConfig.getDefaultLoginShell());
}
if (values.getSambaSIDNumber() != null) {
ldapUser.setSambaSIDNumber(values.getSambaSIDNumber());
} else {
ldapUser.setSambaSIDNumber(null);
}
if (values.getSambaPrimaryGroupSIDNumber() != null) {
ldapUser.setSambaPrimaryGroupSIDNumber(values.getSambaPrimaryGroupSIDNumber());
} else {
ldapUser.setSambaPrimaryGroupSIDNumber(null);
}
}
public static LdapUserValues readLdapUserValues(final String ldapValuesAsXml)
{
if (StringUtils.isBlank(ldapValuesAsXml) == true) {
return null;
}
final XmlObjectReader reader = new XmlObjectReader();
reader.initialize(LdapUserValues.class);
final LdapUserValues values = (LdapUserValues) reader.read(ldapValuesAsXml);
return values;
}
/**
* Exports the LDAP values such as posix account properties of the given ldapUser as xml string.
* @param ldapUser
*/
public static String getLdapValuesAsXml(final LdapUser ldapUser)
{
final LdapConfig ldapConfig = ConfigXml.getInstance().getLdapConfig();
final LdapPosixAccountsConfig posixAccountsConfig = ldapConfig != null ? ldapConfig.getPosixAccountsConfig() : null;
final LdapSambaAccountsConfig sambaAccountsConfig = ldapConfig != null ? ldapConfig.getSambaAccountsConfig() : null;
LdapUserValues values = null;
if (posixAccountsConfig != null) {
values = new LdapUserValues();
if (ldapUser.getUidNumber() != null) {
values.setUidNumber(ldapUser.getUidNumber());
}
if (ldapUser.getGidNumber() != null) {
values.setGidNumber(ldapUser.getGidNumber());
}
values.setHomeDirectory(ldapUser.getHomeDirectory());
values.setLoginShell(ldapUser.getLoginShell());
}
if (sambaAccountsConfig != null) {
if (values == null) {
values = new LdapUserValues();
}
if (ldapUser.getSambaSIDNumber() != null) {
values.setSambaSIDNumber(ldapUser.getSambaSIDNumber());
}
if (ldapUser.getSambaPrimaryGroupSIDNumber() != null) {
values.setSambaPrimaryGroupSIDNumber(ldapUser.getSambaPrimaryGroupSIDNumber());
}
}
return getLdapValuesAsXml(values);
}
/**
* Exports the LDAP values such as posix account properties of the given ldapUser as xml string.
* @param ldapUser
*/
public static String getLdapValuesAsXml(final LdapUserValues values)
{
final XmlObjectReader reader = new XmlObjectReader();
reader.initialize(LdapUserValues.class);
final String xml = XmlObjectWriter.writeAsXml(values);
return xml;
}
public static String buildEmployeeNumber(final PFUserDO user)
{
return ID_PREFIX + user.getId();
}
/**
* Copies the fields shared with ldap.
* @param src
* @param dest
* @return true if any modification is detected, otherwise false.
*/
public static boolean copyUserFields(final PFUserDO src, final PFUserDO dest)
{
final boolean modified = BeanHelper.copyProperties(src, dest, true, "username", "firstname", "lastname", "email", "description",
"organization", "deactivated", "restrictedUser");
return modified;
}
/**
* Copies the fields. The field commonName is also copied because the dn is built from the uid, ou and dc. The cn isn't part of the dn.
* @param src
* @param dest
* @return true if any modification is detected, otherwise false.
*/
public static boolean copyUserFields(final LdapUser src, final LdapUser dest)
{
setMailNullArray(src);
setMailNullArray(dest);
boolean modified;
final List<String> properties = new LinkedList<String>();
ListHelper.addAll(properties, "commonName", "givenName", "surname", "mail", "description", "organization", "deactivated",
"restrictedUser");
if (LdapUserDao.isPosixAccountsConfigured() == true && isPosixAccountValuesEmpty(src) == false) {
ListHelper.addAll(properties, "uidNumber", "gidNumber", "homeDirectory", "loginShell");
}
if (LdapUserDao.isSambaAccountsConfigured() == true && isSambaAccountValuesEmpty(src) == false) {
ListHelper.addAll(properties, "sambaSIDNumber", "sambaPrimaryGroupSIDNumber", "sambaNTPassword");
}
modified = BeanHelper.copyProperties(src, dest, true, properties.toArray(new String[0]));
if (LdapUserDao.isSambaAccountsConfigured() == true && isSambaAccountValuesEmpty(src) == false) {
final long diffSambaPwdLastSet = dest.getSambaPwdLastSetAsUnixEpochSeconds() - src.getSambaPwdLastSetAsUnixEpochSeconds();
if (diffSambaPwdLastSet > 10 || diffSambaPwdLastSet < -10) {
// Difference is more then 10 seconds:
modified = true;
}
}
return modified;
}
static void setMailNullArray(final LdapUser ldapUser)
{
if (ldapUser.getMail() == null) {
return;
}
for (final String mail : ldapUser.getMail()) {
if (mail != null) {
return;
}
}
// All array entries are null, therefore set the mail value itself to null:
ldapUser.setMail((String[]) null);
}
}