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