1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.portal.security.ldap;
16  
17  import com.liferay.portal.kernel.exception.SystemException;
18  import com.liferay.portal.kernel.log.Log;
19  import com.liferay.portal.kernel.log.LogFactoryUtil;
20  import com.liferay.portal.kernel.util.GetterUtil;
21  import com.liferay.portal.kernel.util.PropsKeys;
22  import com.liferay.portal.kernel.util.StringBundler;
23  import com.liferay.portal.kernel.util.StringPool;
24  import com.liferay.portal.kernel.util.Validator;
25  import com.liferay.portal.model.Contact;
26  import com.liferay.portal.model.User;
27  import com.liferay.portal.util.PrefsPropsUtil;
28  import com.liferay.portlet.expando.model.ExpandoBridge;
29  import com.liferay.portlet.expando.util.ExpandoConverterUtil;
30  
31  import java.io.Serializable;
32  
33  import java.util.HashMap;
34  import java.util.List;
35  import java.util.Map;
36  import java.util.Properties;
37  
38  import javax.naming.directory.Attribute;
39  import javax.naming.directory.Attributes;
40  import javax.naming.directory.BasicAttribute;
41  import javax.naming.directory.BasicAttributes;
42  
43  import org.apache.commons.beanutils.PropertyUtils;
44  
45  /**
46   * <a href="BasePortalToLDAPConverter.java.html}"><b><i>View Source</i></b></a>
47   *
48   * @author Michael C. Han
49   * @author Brian Wing Shun Chan
50   */
51  public class BasePortalToLDAPConverter implements PortalToLDAPConverter {
52  
53      public BasePortalToLDAPConverter() {
54          _reservedUserFieldNames.put(
55              UserConverterKeys.GROUP, UserConverterKeys.GROUP);
56          _reservedUserFieldNames.put(
57              UserConverterKeys.PASSWORD, UserConverterKeys.PASSWORD);
58          _reservedUserFieldNames.put(
59              UserConverterKeys.SCREEN_NAME, UserConverterKeys.SCREEN_NAME);
60      }
61  
62      public Modifications getLDAPContactModifications(
63              Contact contact, Map<String, Serializable> contactExpandoAttributes,
64              Properties contactMappings, Properties contactExpandoMappings)
65          throws Exception {
66  
67          if (contactMappings.isEmpty() && contactExpandoMappings.isEmpty()) {
68              return null;
69          }
70  
71          Modifications modifications = getModifications(
72              contact, contactMappings, _reservedContactFieldNames);
73  
74          populateCustomAttributeModifications(
75              contact, contact.getExpandoBridge(), contactExpandoAttributes,
76              contactExpandoMappings, modifications);
77  
78          return modifications;
79      }
80  
81      public Attributes getLDAPUserAttributes(
82              long ldapServerId, User user, Properties userMappings)
83          throws SystemException {
84  
85          Attributes attributes = new BasicAttributes(true);
86  
87          Attribute objectClass = new BasicAttribute(_USER_OBJECT_CLASS);
88  
89          String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
90  
91          String[] defaultObjectClasses = PrefsPropsUtil.getStringArray(
92              user.getCompanyId(),
93              PropsKeys.LDAP_USER_DEFAULT_OBJECT_CLASSES + postfix,
94              StringPool.COMMA);
95  
96          for (int i = 0; i < defaultObjectClasses.length; i++) {
97              objectClass.add(defaultObjectClasses[i]);
98          }
99  
100         attributes.put(objectClass);
101 
102         addAttributeMapping(
103             userMappings.getProperty(UserConverterKeys.FIRST_NAME),
104             user.getFirstName(), attributes);
105         addAttributeMapping(
106             userMappings.getProperty(UserConverterKeys.LAST_NAME),
107             user.getLastName(), attributes);
108         addAttributeMapping(
109             userMappings.getProperty(UserConverterKeys.PASSWORD),
110             user.getPasswordUnencrypted(), attributes);
111         addAttributeMapping(
112             userMappings.getProperty(UserConverterKeys.EMAIL_ADDRESS),
113             user.getEmailAddress(), attributes);
114 
115         return attributes;
116     }
117 
118     public Modifications getLDAPUserModifications(
119             User user, Map<String, Serializable> userExpandoAttributes,
120             Properties userMappings, Properties userExpandoMappings)
121         throws Exception {
122 
123         Modifications modifications = getModifications(
124             user, userMappings, _reservedUserFieldNames);
125 
126         if (user.isPasswordModified() &&
127             Validator.isNotNull(user.getPasswordUnencrypted())) {
128 
129             addModificationItem(
130                 userMappings.getProperty(UserConverterKeys.PASSWORD),
131                 user.getPasswordUnencrypted(), modifications);
132         }
133 
134         populateCustomAttributeModifications(
135             user, user.getExpandoBridge(), userExpandoAttributes,
136             userExpandoMappings, modifications);
137 
138         return modifications;
139     }
140 
141     public String getUserDNName(
142             long ldapServerId, User user, Properties userMappings)
143         throws Exception {
144 
145         StringBundler sb = new StringBundler(5);
146 
147         sb.append(
148             GetterUtil.getString(
149                 userMappings.getProperty(_userDNFieldName), _DEFAULT_DN));
150         sb.append(StringPool.EQUAL);
151         sb.append(PropertyUtils.getProperty(user, _userDNFieldName));
152         sb.append(StringPool.COMMA);
153         sb.append(PortalLDAPUtil.getUsersDN(ldapServerId, user.getCompanyId()));
154 
155         return sb.toString();
156     }
157 
158     public void setContactReservedFieldNames(
159         List<String> reservedContactFieldNames) {
160 
161         for (String reservedContactFieldName : reservedContactFieldNames) {
162             _reservedContactFieldNames.put(
163                 reservedContactFieldName, reservedContactFieldName);
164         }
165     }
166 
167     public void setUserDNFieldName(String userDNFieldName) {
168         _userDNFieldName = userDNFieldName;
169     }
170 
171     public void setUserReservedFieldNames(List<String> reservedUserFieldNames) {
172         for (String reservedUserFieldName : reservedUserFieldNames) {
173             _reservedUserFieldNames.put(
174                 reservedUserFieldName, reservedUserFieldName);
175         }
176     }
177 
178     protected void addAttributeMapping(
179         String attributeName, String attributeValue, Attributes attributes) {
180 
181         if (Validator.isNotNull(attributeName) &&
182             Validator.isNotNull(attributeValue)) {
183 
184             attributes.put(attributeName, attributeValue);
185         }
186     }
187     protected void addModificationItem(
188         String attributeName, String attributeValue,
189         Modifications modifications) {
190 
191         if (Validator.isNotNull(attributeName) &&
192             Validator.isNotNull(attributeValue)) {
193 
194             modifications.addItem(attributeName, attributeValue);
195         }
196     }
197 
198     protected Modifications getModifications(
199         Object object, Properties objectMappings,
200         Map<String, String> reservedFieldNames) {
201 
202         Modifications modifications = Modifications.getInstance();
203 
204         for (Map.Entry<Object, Object> entry : objectMappings.entrySet()) {
205             String fieldName = (String)entry.getKey();
206 
207             if (reservedFieldNames.containsKey(fieldName)) {
208                 continue;
209             }
210 
211             String ldapAttributeName = (String)entry.getValue();
212 
213             try {
214                 Object attributeValue = PropertyUtils.getProperty(
215                     object, fieldName);
216 
217                 if (attributeValue != null) {
218                     addModificationItem(
219                         ldapAttributeName, attributeValue.toString(),
220                         modifications);
221                 }
222             }
223             catch (Exception e) {
224                 if (_log.isWarnEnabled()) {
225                     _log.warn(
226                         "Unable to map field " + fieldName + " to class " +
227                             object.getClass(),
228                         e);
229                 }
230             }
231         }
232 
233         return modifications;
234     }
235 
236     protected void populateCustomAttributeModifications(
237         Object object, ExpandoBridge expandoBridge,
238         Map<String, Serializable> expandoAttributes,
239         Properties expandoMappings, Modifications modifications) {
240 
241         if ((expandoAttributes == null) || expandoAttributes.isEmpty()) {
242             return;
243         }
244 
245         for (Map.Entry<Object, Object> entry : expandoMappings.entrySet()) {
246             String fieldName = (String)entry.getKey();
247             String ldapAttributeName = (String)entry.getValue();
248 
249             Serializable fieldValue = expandoAttributes.get(fieldName);
250 
251             if (fieldValue == null) {
252                 continue;
253             }
254 
255             try {
256                 int type = expandoBridge.getAttributeType(fieldName);
257 
258                 String value = ExpandoConverterUtil.getStringFromAttribute(
259                     type, fieldValue);
260 
261                 addModificationItem(ldapAttributeName, value, modifications);
262             }
263             catch (Exception e) {
264                 if (_log.isWarnEnabled()) {
265                     _log.warn(
266                         "Unable to map field " + fieldName + " to class " +
267                             object.getClass(),
268                         e);
269                 }
270             }
271         }
272     }
273 
274     private static final String _DEFAULT_DN = "cn";
275 
276     private static final String _USER_OBJECT_CLASS = "objectclass";
277 
278     private static Log _log = LogFactoryUtil.getLog(
279         BasePortalToLDAPConverter.class);
280 
281     private Map<String, String> _reservedContactFieldNames =
282         new HashMap<String, String>();
283     private Map<String, String> _reservedUserFieldNames =
284         new HashMap<String, String>();
285 
286     private String _userDNFieldName = UserConverterKeys.SCREEN_NAME;
287 
288 }