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