001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.security.ldap;
016    
017    import com.liferay.portal.kernel.exception.SystemException;
018    import com.liferay.portal.kernel.log.Log;
019    import com.liferay.portal.kernel.log.LogFactoryUtil;
020    import com.liferay.portal.kernel.util.GetterUtil;
021    import com.liferay.portal.kernel.util.PropsKeys;
022    import com.liferay.portal.kernel.util.StringBundler;
023    import com.liferay.portal.kernel.util.StringPool;
024    import com.liferay.portal.kernel.util.Validator;
025    import com.liferay.portal.model.Contact;
026    import com.liferay.portal.model.User;
027    import com.liferay.portal.util.PrefsPropsUtil;
028    import com.liferay.portlet.expando.model.ExpandoBridge;
029    import com.liferay.portlet.expando.util.ExpandoConverterUtil;
030    
031    import java.io.Serializable;
032    
033    import java.util.HashMap;
034    import java.util.List;
035    import java.util.Map;
036    import java.util.Properties;
037    
038    import javax.naming.directory.Attribute;
039    import javax.naming.directory.Attributes;
040    import javax.naming.directory.BasicAttribute;
041    import javax.naming.directory.BasicAttributes;
042    
043    import org.apache.commons.beanutils.PropertyUtils;
044    
045    /**
046     * @author Michael C. Han
047     * @author Brian Wing Shun Chan
048     */
049    public class BasePortalToLDAPConverter implements PortalToLDAPConverter {
050    
051            public BasePortalToLDAPConverter() {
052                    _reservedUserFieldNames.put(
053                            UserConverterKeys.GROUP, UserConverterKeys.GROUP);
054                    _reservedUserFieldNames.put(
055                            UserConverterKeys.PASSWORD, UserConverterKeys.PASSWORD);
056                    _reservedUserFieldNames.put(
057                            UserConverterKeys.SCREEN_NAME, UserConverterKeys.SCREEN_NAME);
058            }
059    
060            public Modifications getLDAPContactModifications(
061                            Contact contact, Map<String, Serializable> contactExpandoAttributes,
062                            Properties contactMappings, Properties contactExpandoMappings)
063                    throws Exception {
064    
065                    if (contactMappings.isEmpty() && contactExpandoMappings.isEmpty()) {
066                            return null;
067                    }
068    
069                    Modifications modifications = getModifications(
070                            contact, contactMappings, _reservedContactFieldNames);
071    
072                    populateCustomAttributeModifications(
073                            contact, contact.getExpandoBridge(), contactExpandoAttributes,
074                            contactExpandoMappings, modifications);
075    
076                    return modifications;
077            }
078    
079            public Attributes getLDAPUserAttributes(
080                            long ldapServerId, User user, Properties userMappings)
081                    throws SystemException {
082    
083                    Attributes attributes = new BasicAttributes(true);
084    
085                    Attribute objectClass = new BasicAttribute(_USER_OBJECT_CLASS);
086    
087                    String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
088    
089                    String[] defaultObjectClasses = PrefsPropsUtil.getStringArray(
090                            user.getCompanyId(),
091                            PropsKeys.LDAP_USER_DEFAULT_OBJECT_CLASSES + postfix,
092                            StringPool.COMMA);
093    
094                    for (int i = 0; i < defaultObjectClasses.length; i++) {
095                            objectClass.add(defaultObjectClasses[i]);
096                    }
097    
098                    attributes.put(objectClass);
099    
100                    addAttributeMapping(
101                            userMappings.getProperty(UserConverterKeys.FIRST_NAME),
102                            user.getFirstName(), attributes);
103                    addAttributeMapping(
104                            userMappings.getProperty(UserConverterKeys.LAST_NAME),
105                            user.getLastName(), attributes);
106                    addAttributeMapping(
107                            userMappings.getProperty(UserConverterKeys.PASSWORD),
108                            user.getPasswordUnencrypted(), attributes);
109                    addAttributeMapping(
110                            userMappings.getProperty(UserConverterKeys.EMAIL_ADDRESS),
111                            user.getEmailAddress(), attributes);
112    
113                    return attributes;
114            }
115    
116            public Modifications getLDAPUserModifications(
117                            User user, Map<String, Serializable> userExpandoAttributes,
118                            Properties userMappings, Properties userExpandoMappings)
119                    throws Exception {
120    
121                    Modifications modifications = getModifications(
122                            user, userMappings, _reservedUserFieldNames);
123    
124                    if (user.isPasswordModified() &&
125                            Validator.isNotNull(user.getPasswordUnencrypted())) {
126    
127                            addModificationItem(
128                                    userMappings.getProperty(UserConverterKeys.PASSWORD),
129                                    user.getPasswordUnencrypted(), modifications);
130                    }
131    
132                    populateCustomAttributeModifications(
133                            user, user.getExpandoBridge(), userExpandoAttributes,
134                            userExpandoMappings, modifications);
135    
136                    return modifications;
137            }
138    
139            public String getUserDNName(
140                            long ldapServerId, User user, Properties userMappings)
141                    throws Exception {
142    
143                    StringBundler sb = new StringBundler(5);
144    
145                    sb.append(
146                            GetterUtil.getString(
147                                    userMappings.getProperty(_userDNFieldName), _DEFAULT_DN));
148                    sb.append(StringPool.EQUAL);
149                    sb.append(PropertyUtils.getProperty(user, _userDNFieldName));
150                    sb.append(StringPool.COMMA);
151                    sb.append(PortalLDAPUtil.getUsersDN(ldapServerId, user.getCompanyId()));
152    
153                    return sb.toString();
154            }
155    
156            public void setContactReservedFieldNames(
157                    List<String> reservedContactFieldNames) {
158    
159                    for (String reservedContactFieldName : reservedContactFieldNames) {
160                            _reservedContactFieldNames.put(
161                                    reservedContactFieldName, reservedContactFieldName);
162                    }
163            }
164    
165            public void setUserDNFieldName(String userDNFieldName) {
166                    _userDNFieldName = userDNFieldName;
167            }
168    
169            public void setUserReservedFieldNames(List<String> reservedUserFieldNames) {
170                    for (String reservedUserFieldName : reservedUserFieldNames) {
171                            _reservedUserFieldNames.put(
172                                    reservedUserFieldName, reservedUserFieldName);
173                    }
174            }
175    
176            protected void addAttributeMapping(
177                    String attributeName, String attributeValue, Attributes attributes) {
178    
179                    if (Validator.isNotNull(attributeName) &&
180                            Validator.isNotNull(attributeValue)) {
181    
182                            attributes.put(attributeName, attributeValue);
183                    }
184            }
185            protected void addModificationItem(
186                    String attributeName, String attributeValue,
187                    Modifications modifications) {
188    
189                    if (Validator.isNotNull(attributeName) &&
190                            Validator.isNotNull(attributeValue)) {
191    
192                            modifications.addItem(attributeName, attributeValue);
193                    }
194            }
195    
196            protected Modifications getModifications(
197                    Object object, Properties objectMappings,
198                    Map<String, String> reservedFieldNames) {
199    
200                    Modifications modifications = Modifications.getInstance();
201    
202                    for (Map.Entry<Object, Object> entry : objectMappings.entrySet()) {
203                            String fieldName = (String)entry.getKey();
204    
205                            if (reservedFieldNames.containsKey(fieldName)) {
206                                    continue;
207                            }
208    
209                            String ldapAttributeName = (String)entry.getValue();
210    
211                            try {
212                                    Object attributeValue = PropertyUtils.getProperty(
213                                            object, fieldName);
214    
215                                    if (attributeValue != null) {
216                                            addModificationItem(
217                                                    ldapAttributeName, attributeValue.toString(),
218                                                    modifications);
219                                    }
220                            }
221                            catch (Exception e) {
222                                    if (_log.isWarnEnabled()) {
223                                            _log.warn(
224                                                    "Unable to map field " + fieldName + " to class " +
225                                                            object.getClass(),
226                                                    e);
227                                    }
228                            }
229                    }
230    
231                    return modifications;
232            }
233    
234            protected void populateCustomAttributeModifications(
235                    Object object, ExpandoBridge expandoBridge,
236                    Map<String, Serializable> expandoAttributes,
237                    Properties expandoMappings, Modifications modifications) {
238    
239                    if ((expandoAttributes == null) || expandoAttributes.isEmpty()) {
240                            return;
241                    }
242    
243                    for (Map.Entry<Object, Object> entry : expandoMappings.entrySet()) {
244                            String fieldName = (String)entry.getKey();
245                            String ldapAttributeName = (String)entry.getValue();
246    
247                            Serializable fieldValue = expandoAttributes.get(fieldName);
248    
249                            if (fieldValue == null) {
250                                    continue;
251                            }
252    
253                            try {
254                                    int type = expandoBridge.getAttributeType(fieldName);
255    
256                                    String value = ExpandoConverterUtil.getStringFromAttribute(
257                                            type, fieldValue);
258    
259                                    addModificationItem(ldapAttributeName, value, modifications);
260                            }
261                            catch (Exception e) {
262                                    if (_log.isWarnEnabled()) {
263                                            _log.warn(
264                                                    "Unable to map field " + fieldName + " to class " +
265                                                            object.getClass(),
266                                                    e);
267                                    }
268                            }
269                    }
270            }
271    
272            private static final String _DEFAULT_DN = "cn";
273    
274            private static final String _USER_OBJECT_CLASS = "objectclass";
275    
276            private static Log _log = LogFactoryUtil.getLog(
277                    BasePortalToLDAPConverter.class);
278    
279            private Map<String, String> _reservedContactFieldNames =
280                    new HashMap<String, String>();
281            private Map<String, String> _reservedUserFieldNames =
282                    new HashMap<String, String>();
283    
284            private String _userDNFieldName = UserConverterKeys.SCREEN_NAME;
285    
286    }