001
014
015 package com.liferay.portal.security.ldap;
016
017 import com.liferay.portal.PwdEncryptorException;
018 import com.liferay.portal.kernel.exception.SystemException;
019 import com.liferay.portal.kernel.log.Log;
020 import com.liferay.portal.kernel.log.LogFactoryUtil;
021 import com.liferay.portal.kernel.util.GetterUtil;
022 import com.liferay.portal.kernel.util.PropsKeys;
023 import com.liferay.portal.kernel.util.StringBundler;
024 import com.liferay.portal.kernel.util.StringPool;
025 import com.liferay.portal.kernel.util.Validator;
026 import com.liferay.portal.model.Contact;
027 import com.liferay.portal.model.Image;
028 import com.liferay.portal.model.User;
029 import com.liferay.portal.model.UserGroup;
030 import com.liferay.portal.security.pwd.PwdEncryptor;
031 import com.liferay.portal.service.ImageLocalServiceUtil;
032 import com.liferay.portal.util.PrefsPropsUtil;
033 import com.liferay.portlet.expando.model.ExpandoBridge;
034 import com.liferay.portlet.expando.util.ExpandoConverterUtil;
035
036 import java.io.Serializable;
037
038 import java.util.HashMap;
039 import java.util.List;
040 import java.util.Map;
041 import java.util.Properties;
042
043 import javax.naming.Binding;
044 import javax.naming.directory.Attribute;
045 import javax.naming.directory.Attributes;
046 import javax.naming.directory.BasicAttribute;
047 import javax.naming.directory.BasicAttributes;
048 import javax.naming.directory.DirContext;
049
050 import org.apache.commons.beanutils.PropertyUtils;
051
052
058 public class DefaultPortalToLDAPConverter implements PortalToLDAPConverter {
059
060 public DefaultPortalToLDAPConverter() {
061 _reservedUserFieldNames.put(
062 UserConverterKeys.GROUP, UserConverterKeys.GROUP);
063 _reservedUserFieldNames.put(
064 UserConverterKeys.PASSWORD, UserConverterKeys.PASSWORD);
065 _reservedUserFieldNames.put(
066 UserConverterKeys.PORTRAIT, UserConverterKeys.PORTRAIT);
067 _reservedUserFieldNames.put(
068 UserConverterKeys.SCREEN_NAME, UserConverterKeys.SCREEN_NAME);
069 }
070
071 public String getGroupDNName(
072 long ldapServerId, UserGroup userGroup, Properties groupMappings)
073 throws Exception {
074
075 Binding groupBinding = PortalLDAPUtil.getGroup(
076 ldapServerId, userGroup.getCompanyId(), userGroup.getName());
077
078 if (groupBinding != null) {
079 return PortalLDAPUtil.getNameInNamespace(
080 ldapServerId, userGroup.getCompanyId(), groupBinding);
081 }
082
083 StringBundler sb = new StringBundler(5);
084
085 sb.append(
086 GetterUtil.getString(
087 groupMappings.getProperty(_groupDNFieldName), _DEFAULT_DN));
088 sb.append(StringPool.EQUAL);
089 sb.append(userGroup.getName());
090 sb.append(StringPool.COMMA);
091 sb.append(
092 PortalLDAPUtil.getGroupsDN(ldapServerId, userGroup.getCompanyId()));
093
094 return sb.toString();
095 }
096
097 public Modifications getLDAPContactModifications(
098 Contact contact, Map<String, Serializable> contactExpandoAttributes,
099 Properties contactMappings, Properties contactExpandoMappings)
100 throws Exception {
101
102 if (contactMappings.isEmpty() && contactExpandoMappings.isEmpty()) {
103 return null;
104 }
105
106 Modifications modifications = getModifications(
107 contact, contactMappings, _reservedContactFieldNames);
108
109 populateCustomAttributeModifications(
110 contact, contact.getExpandoBridge(), contactExpandoAttributes,
111 contactExpandoMappings, modifications);
112
113 return modifications;
114 }
115
116 public Attributes getLDAPGroupAttributes(
117 long ldapServerId, UserGroup userGroup, User user,
118 Properties groupMappings, Properties userMappings)
119 throws Exception {
120
121 Attributes attributes = new BasicAttributes(true);
122
123 Attribute objectClass = new BasicAttribute(_OBJECT_CLASS);
124
125 String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
126
127 String[] defaultObjectClasses = PrefsPropsUtil.getStringArray(
128 userGroup.getCompanyId(),
129 PropsKeys.LDAP_GROUP_DEFAULT_OBJECT_CLASSES + postfix,
130 StringPool.COMMA);
131
132 for (int i = 0; i < defaultObjectClasses.length; i++) {
133 objectClass.add(defaultObjectClasses[i]);
134 }
135
136 attributes.put(objectClass);
137
138 addAttributeMapping(
139 groupMappings.getProperty(GroupConverterKeys.GROUP_NAME),
140 userGroup.getName(), attributes);
141 addAttributeMapping(
142 groupMappings.getProperty(GroupConverterKeys.DESCRIPTION),
143 userGroup.getDescription(), attributes);
144 addAttributeMapping(
145 groupMappings.getProperty(GroupConverterKeys.USER),
146 getUserDNName(ldapServerId, user, userMappings), attributes);
147
148 return attributes;
149 }
150
151 public Modifications getLDAPGroupModifications(
152 long ldapServerId, UserGroup userGroup, User user,
153 Properties groupMappings, Properties userMappings,
154 LDAPOperation ldapOperation)
155 throws Exception {
156
157 Modifications modifications = Modifications.getInstance();
158
159 String groupDN = getGroupDNName(ldapServerId, userGroup, groupMappings);
160 String userDN = getUserDNName(ldapServerId, user, userMappings);
161
162 if (PortalLDAPUtil.isGroupMember(
163 ldapServerId, user.getCompanyId(), groupDN, userDN)) {
164
165 if (ldapOperation == LDAPOperation.REMOVE) {
166 modifications.addItem(
167 DirContext.REMOVE_ATTRIBUTE,
168 groupMappings.getProperty(GroupConverterKeys.USER), userDN);
169 }
170 }
171 else {
172 if (ldapOperation == LDAPOperation.ADD) {
173 modifications.addItem(
174 DirContext.ADD_ATTRIBUTE,
175 groupMappings.getProperty(GroupConverterKeys.USER), userDN);
176 }
177 }
178
179 return modifications;
180 }
181
182 public Attributes getLDAPUserAttributes(
183 long ldapServerId, User user, Properties userMappings)
184 throws SystemException {
185
186 Attributes attributes = new BasicAttributes(true);
187
188 Attribute objectClass = new BasicAttribute(_OBJECT_CLASS);
189
190 String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
191
192 String[] defaultObjectClasses = PrefsPropsUtil.getStringArray(
193 user.getCompanyId(),
194 PropsKeys.LDAP_USER_DEFAULT_OBJECT_CLASSES + postfix,
195 StringPool.COMMA);
196
197 for (int i = 0; i < defaultObjectClasses.length; i++) {
198 objectClass.add(defaultObjectClasses[i]);
199 }
200
201 attributes.put(objectClass);
202
203 addAttributeMapping(
204 userMappings.getProperty(UserConverterKeys.UUID), user.getUuid(),
205 attributes);
206 addAttributeMapping(
207 userMappings.getProperty(UserConverterKeys.SCREEN_NAME),
208 user.getScreenName(), attributes);
209 addAttributeMapping(
210 userMappings.getProperty(UserConverterKeys.PASSWORD),
211 getEncryptedPasswordForLDAP(user), attributes);
212 addAttributeMapping(
213 userMappings.getProperty(UserConverterKeys.EMAIL_ADDRESS),
214 user.getEmailAddress(), attributes);
215 addAttributeMapping(
216 userMappings.getProperty(UserConverterKeys.FULL_NAME),
217 user.getFullName(), attributes);
218 addAttributeMapping(
219 userMappings.getProperty(UserConverterKeys.FIRST_NAME),
220 user.getFirstName(), attributes);
221 addAttributeMapping(
222 userMappings.getProperty(UserConverterKeys.MIDDLE_NAME),
223 user.getMiddleName(), attributes);
224 addAttributeMapping(
225 userMappings.getProperty(UserConverterKeys.LAST_NAME),
226 user.getLastName(), attributes);
227 addAttributeMapping(
228 userMappings.getProperty(UserConverterKeys.JOB_TITLE),
229 user.getJobTitle(), attributes);
230 addAttributeMapping(
231 userMappings.getProperty(UserConverterKeys.PORTRAIT),
232 getUserPortrait(user), attributes);
233 addAttributeMapping(
234 userMappings.getProperty(UserConverterKeys.STATUS),
235 String.valueOf(user.getStatus()), attributes);
236
237 return attributes;
238 }
239
240 public Modifications getLDAPUserGroupModifications(
241 long ldapServerId, List<UserGroup> userGroups, User user,
242 Properties userMappings)
243 throws Exception {
244
245 Modifications modifications = Modifications.getInstance();
246
247 Properties groupMappings = LDAPSettingsUtil.getGroupMappings(
248 ldapServerId, user.getCompanyId());
249
250 String userDN = getUserDNName(ldapServerId, user, userMappings);
251
252 for (UserGroup userGroup : userGroups) {
253 String groupDN = getGroupDNName(
254 ldapServerId, userGroup, groupMappings);
255
256 if (PortalLDAPUtil.isUserGroupMember(
257 ldapServerId, user.getCompanyId(), groupDN, userDN)) {
258
259 continue;
260 }
261
262 modifications.addItem(
263 DirContext.ADD_ATTRIBUTE,
264 userMappings.getProperty(UserConverterKeys.GROUP), groupDN);
265 }
266
267 return modifications;
268 }
269
270 public Modifications getLDAPUserModifications(
271 User user, Map<String, Serializable> userExpandoAttributes,
272 Properties userMappings, Properties userExpandoMappings)
273 throws Exception {
274
275 Modifications modifications = getModifications(
276 user, userMappings, _reservedUserFieldNames);
277
278 if (user.isPasswordModified() &&
279 Validator.isNotNull(user.getPasswordUnencrypted())) {
280
281 String newPassword = getEncryptedPasswordForLDAP(user);
282
283 String passwordKey = userMappings.getProperty(
284 UserConverterKeys.PASSWORD);
285
286 if (passwordKey.equals("unicodePwd")) {
287 String newQuotedPassword = StringPool.QUOTE.concat(
288 newPassword).concat(StringPool.QUOTE);
289
290 byte[] newUnicodePassword = newQuotedPassword.getBytes(
291 "UTF-16LE");
292
293 addModificationItem(
294 new BasicAttribute(passwordKey, newUnicodePassword),
295 modifications);
296 }
297 else {
298 addModificationItem(passwordKey, newPassword, modifications);
299 }
300 }
301
302 String portraitKey = userMappings.getProperty(
303 UserConverterKeys.PORTRAIT);
304
305 if (Validator.isNotNull(portraitKey)) {
306 addModificationItem(
307 new BasicAttribute(portraitKey, getUserPortrait(user)),
308 modifications);
309 }
310
311 populateCustomAttributeModifications(
312 user, user.getExpandoBridge(), userExpandoAttributes,
313 userExpandoMappings, modifications);
314
315 return modifications;
316 }
317
318 public String getUserDNName(
319 long ldapServerId, User user, Properties userMappings)
320 throws Exception {
321
322 Binding userBinding = PortalLDAPUtil.getUser(
323 ldapServerId, user.getCompanyId(), user.getScreenName(),
324 user.getEmailAddress());
325
326 if (userBinding != null) {
327 return PortalLDAPUtil.getNameInNamespace(
328 ldapServerId, user.getCompanyId(), userBinding);
329 }
330
331 StringBundler sb = new StringBundler(5);
332
333 sb.append(
334 GetterUtil.getString(
335 userMappings.getProperty(_userDNFieldName), _DEFAULT_DN));
336 sb.append(StringPool.EQUAL);
337 sb.append(PropertyUtils.getProperty(user, _userDNFieldName));
338 sb.append(StringPool.COMMA);
339 sb.append(PortalLDAPUtil.getUsersDN(ldapServerId, user.getCompanyId()));
340
341 return sb.toString();
342 }
343
344 public void setContactReservedFieldNames(
345 List<String> reservedContactFieldNames) {
346
347 for (String reservedContactFieldName : reservedContactFieldNames) {
348 _reservedContactFieldNames.put(
349 reservedContactFieldName, reservedContactFieldName);
350 }
351 }
352
353 public void setUserDNFieldName(String userDNFieldName) {
354 _userDNFieldName = userDNFieldName;
355 }
356
357 public void setUserReservedFieldNames(List<String> reservedUserFieldNames) {
358 for (String reservedUserFieldName : reservedUserFieldNames) {
359 _reservedUserFieldNames.put(
360 reservedUserFieldName, reservedUserFieldName);
361 }
362 }
363
364 protected void addAttributeMapping(
365 String attributeName, Object attributeValue, Attributes attributes) {
366
367 if (Validator.isNotNull(attributeName) && (attributeValue != null)) {
368 attributes.put(attributeName, attributeValue);
369 }
370 }
371
372 protected void addAttributeMapping(
373 String attributeName, String attributeValue, Attributes attributes) {
374
375 if (Validator.isNotNull(attributeName) &&
376 Validator.isNotNull(attributeValue)) {
377
378 attributes.put(attributeName, attributeValue);
379 }
380 }
381
382 protected void addModificationItem(
383 BasicAttribute basicAttribute, Modifications modifications) {
384
385 if (Validator.isNotNull(basicAttribute)) {
386 modifications.addItem(basicAttribute);
387 }
388 }
389
390 protected void addModificationItem(
391 String attributeName, String attributeValue,
392 Modifications modifications) {
393
394 if (Validator.isNotNull(attributeName) &&
395 Validator.isNotNull(attributeValue)) {
396
397 modifications.addItem(attributeName, attributeValue);
398 }
399 }
400
401 protected String getEncryptedPasswordForLDAP(User user)
402 throws SystemException {
403
404 String password = user.getPasswordUnencrypted();
405
406 String algorithm = PrefsPropsUtil.getString(
407 user.getCompanyId(),
408 PropsKeys.LDAP_AUTH_PASSWORD_ENCRYPTION_ALGORITHM);
409
410 if (Validator.isNotNull(algorithm)) {
411 try {
412 StringBundler sb = new StringBundler(4);
413
414 sb.append(StringPool.OPEN_CURLY_BRACE);
415 sb.append(algorithm);
416 sb.append(StringPool.CLOSE_CURLY_BRACE);
417 sb.append(PwdEncryptor.encrypt(algorithm, password, null));
418
419 password = sb.toString();
420 }
421 catch (PwdEncryptorException pee) {
422 throw new SystemException(pee);
423 }
424 }
425
426 return password;
427 }
428
429 protected Modifications getModifications(
430 Object object, Properties objectMappings,
431 Map<String, String> reservedFieldNames) {
432
433 Modifications modifications = Modifications.getInstance();
434
435 for (Map.Entry<Object, Object> entry : objectMappings.entrySet()) {
436 String fieldName = (String)entry.getKey();
437
438 if (reservedFieldNames.containsKey(fieldName)) {
439 continue;
440 }
441
442 String ldapAttributeName = (String)entry.getValue();
443
444 try {
445 Object attributeValue = PropertyUtils.getProperty(
446 object, fieldName);
447
448 if (attributeValue != null) {
449 addModificationItem(
450 ldapAttributeName, attributeValue.toString(),
451 modifications);
452 }
453 }
454 catch (Exception e) {
455 if (_log.isWarnEnabled()) {
456 _log.warn(
457 "Unable to map field " + fieldName + " to class " +
458 object.getClass(),
459 e);
460 }
461 }
462 }
463
464 return modifications;
465 }
466
467 protected byte[] getUserPortrait(User user) {
468 byte[] bytes = null;
469
470 if (user.getPortraitId() == 0) {
471 return bytes;
472 }
473
474 Image image = null;
475
476 try {
477 image = ImageLocalServiceUtil.getImage(user.getPortraitId());
478
479 if (image != null) {
480 bytes = image.getTextObj();
481 }
482 }
483 catch (Exception e) {
484 if (_log.isWarnEnabled()) {
485 _log.warn(
486 "Unable to get the portrait for user " + user.getUserId(),
487 e);
488 }
489 }
490
491 return bytes;
492 }
493
494 protected void populateCustomAttributeModifications(
495 Object object, ExpandoBridge expandoBridge,
496 Map<String, Serializable> expandoAttributes, Properties expandoMappings,
497 Modifications modifications) {
498
499 if ((expandoAttributes == null) || expandoAttributes.isEmpty()) {
500 return;
501 }
502
503 for (Map.Entry<Object, Object> entry : expandoMappings.entrySet()) {
504 String fieldName = (String)entry.getKey();
505 String ldapAttributeName = (String)entry.getValue();
506
507 Serializable fieldValue = expandoAttributes.get(fieldName);
508
509 if (fieldValue == null) {
510 continue;
511 }
512
513 try {
514 int type = expandoBridge.getAttributeType(fieldName);
515
516 String value = ExpandoConverterUtil.getStringFromAttribute(
517 type, fieldValue);
518
519 addModificationItem(ldapAttributeName, value, modifications);
520 }
521 catch (Exception e) {
522 if (_log.isWarnEnabled()) {
523 _log.warn(
524 "Unable to map field " + fieldName + " to class " +
525 object.getClass(),
526 e);
527 }
528 }
529 }
530 }
531
532 private static final String _DEFAULT_DN = "cn";
533
534 private static final String _OBJECT_CLASS = "objectclass";
535
536 private static Log _log = LogFactoryUtil.getLog(
537 DefaultPortalToLDAPConverter.class);
538
539 private String _groupDNFieldName = GroupConverterKeys.GROUP_NAME;
540 private Map<String, String> _reservedContactFieldNames =
541 new HashMap<String, String>();
542 private Map<String, String> _reservedUserFieldNames =
543 new HashMap<String, String>();
544 private String _userDNFieldName = UserConverterKeys.SCREEN_NAME;
545
546 }