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.PasswordEncryptorUtil;
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 String groupMappingAttributeName = userMappings.getProperty(
248 UserConverterKeys.GROUP);
249
250 if (Validator.isNull(groupMappingAttributeName)) {
251 return modifications;
252 }
253
254 Properties groupMappings = LDAPSettingsUtil.getGroupMappings(
255 ldapServerId, user.getCompanyId());
256
257 String userDN = getUserDNName(ldapServerId, user, userMappings);
258
259 for (UserGroup userGroup : userGroups) {
260 String groupDN = getGroupDNName(
261 ldapServerId, userGroup, groupMappings);
262
263 if (PortalLDAPUtil.isUserGroupMember(
264 ldapServerId, user.getCompanyId(), groupDN, userDN)) {
265
266 continue;
267 }
268
269 modifications.addItem(
270 DirContext.ADD_ATTRIBUTE, groupMappingAttributeName, groupDN);
271 }
272
273 return modifications;
274 }
275
276 public Modifications getLDAPUserModifications(
277 User user, Map<String, Serializable> userExpandoAttributes,
278 Properties userMappings, Properties userExpandoMappings)
279 throws Exception {
280
281 Modifications modifications = getModifications(
282 user, userMappings, _reservedUserFieldNames);
283
284 if (user.isPasswordModified() &&
285 Validator.isNotNull(user.getPasswordUnencrypted())) {
286
287 String newPassword = getEncryptedPasswordForLDAP(user);
288
289 String passwordKey = userMappings.getProperty(
290 UserConverterKeys.PASSWORD);
291
292 if (passwordKey.equals("unicodePwd")) {
293 String newQuotedPassword = StringPool.QUOTE.concat(
294 newPassword).concat(StringPool.QUOTE);
295
296 byte[] newUnicodePassword = newQuotedPassword.getBytes(
297 "UTF-16LE");
298
299 addModificationItem(
300 new BasicAttribute(passwordKey, newUnicodePassword),
301 modifications);
302 }
303 else {
304 addModificationItem(passwordKey, newPassword, modifications);
305 }
306 }
307
308 String portraitKey = userMappings.getProperty(
309 UserConverterKeys.PORTRAIT);
310
311 if (Validator.isNotNull(portraitKey)) {
312 addModificationItem(
313 new BasicAttribute(portraitKey, getUserPortrait(user)),
314 modifications);
315 }
316
317 populateCustomAttributeModifications(
318 user, user.getExpandoBridge(), userExpandoAttributes,
319 userExpandoMappings, modifications);
320
321 return modifications;
322 }
323
324 public String getUserDNName(
325 long ldapServerId, User user, Properties userMappings)
326 throws Exception {
327
328 Binding userBinding = PortalLDAPUtil.getUser(
329 ldapServerId, user.getCompanyId(), user.getScreenName(),
330 user.getEmailAddress());
331
332 if (userBinding != null) {
333 return PortalLDAPUtil.getNameInNamespace(
334 ldapServerId, user.getCompanyId(), userBinding);
335 }
336
337 StringBundler sb = new StringBundler(5);
338
339 sb.append(
340 GetterUtil.getString(
341 userMappings.getProperty(_userDNFieldName), _DEFAULT_DN));
342 sb.append(StringPool.EQUAL);
343 sb.append(PropertyUtils.getProperty(user, _userDNFieldName));
344 sb.append(StringPool.COMMA);
345 sb.append(PortalLDAPUtil.getUsersDN(ldapServerId, user.getCompanyId()));
346
347 return sb.toString();
348 }
349
350 public void setContactReservedFieldNames(
351 List<String> reservedContactFieldNames) {
352
353 for (String reservedContactFieldName : reservedContactFieldNames) {
354 _reservedContactFieldNames.put(
355 reservedContactFieldName, reservedContactFieldName);
356 }
357 }
358
359 public void setUserDNFieldName(String userDNFieldName) {
360 _userDNFieldName = userDNFieldName;
361 }
362
363 public void setUserReservedFieldNames(List<String> reservedUserFieldNames) {
364 for (String reservedUserFieldName : reservedUserFieldNames) {
365 _reservedUserFieldNames.put(
366 reservedUserFieldName, reservedUserFieldName);
367 }
368 }
369
370 protected void addAttributeMapping(
371 String attributeName, Object attributeValue, Attributes attributes) {
372
373 if (Validator.isNotNull(attributeName) && (attributeValue != null)) {
374 attributes.put(attributeName, attributeValue);
375 }
376 }
377
378 protected void addAttributeMapping(
379 String attributeName, String attributeValue, Attributes attributes) {
380
381 if (Validator.isNotNull(attributeName) &&
382 Validator.isNotNull(attributeValue)) {
383
384 attributes.put(attributeName, attributeValue);
385 }
386 }
387
388 protected void addModificationItem(
389 BasicAttribute basicAttribute, Modifications modifications) {
390
391 if (Validator.isNotNull(basicAttribute)) {
392 modifications.addItem(basicAttribute);
393 }
394 }
395
396 protected void addModificationItem(
397 String attributeName, String attributeValue,
398 Modifications modifications) {
399
400 if (Validator.isNotNull(attributeName) &&
401 Validator.isNotNull(attributeValue)) {
402
403 modifications.addItem(attributeName, attributeValue);
404 }
405 }
406
407 protected String getEncryptedPasswordForLDAP(User user)
408 throws SystemException {
409
410 String password = user.getPasswordUnencrypted();
411
412 String algorithm = PrefsPropsUtil.getString(
413 user.getCompanyId(),
414 PropsKeys.LDAP_AUTH_PASSWORD_ENCRYPTION_ALGORITHM);
415
416 if (Validator.isNotNull(algorithm)) {
417 try {
418 StringBundler sb = new StringBundler(4);
419
420 sb.append(StringPool.OPEN_CURLY_BRACE);
421 sb.append(algorithm);
422 sb.append(StringPool.CLOSE_CURLY_BRACE);
423 sb.append(
424 PasswordEncryptorUtil.encrypt(algorithm, password, null));
425
426 password = sb.toString();
427 }
428 catch (PwdEncryptorException pee) {
429 throw new SystemException(pee);
430 }
431 }
432
433 return password;
434 }
435
436 protected Modifications getModifications(
437 Object object, Properties objectMappings,
438 Map<String, String> reservedFieldNames) {
439
440 Modifications modifications = Modifications.getInstance();
441
442 for (Map.Entry<Object, Object> entry : objectMappings.entrySet()) {
443 String fieldName = (String)entry.getKey();
444
445 if (reservedFieldNames.containsKey(fieldName)) {
446 continue;
447 }
448
449 String ldapAttributeName = (String)entry.getValue();
450
451 try {
452 Object attributeValue = PropertyUtils.getProperty(
453 object, fieldName);
454
455 if (attributeValue != null) {
456 addModificationItem(
457 ldapAttributeName, attributeValue.toString(),
458 modifications);
459 }
460 }
461 catch (Exception e) {
462 if (_log.isWarnEnabled()) {
463 _log.warn(
464 "Unable to map field " + fieldName + " to class " +
465 object.getClass(),
466 e);
467 }
468 }
469 }
470
471 return modifications;
472 }
473
474 protected byte[] getUserPortrait(User user) {
475 byte[] bytes = null;
476
477 if (user.getPortraitId() == 0) {
478 return bytes;
479 }
480
481 Image image = null;
482
483 try {
484 image = ImageLocalServiceUtil.getImage(user.getPortraitId());
485
486 if (image != null) {
487 bytes = image.getTextObj();
488 }
489 }
490 catch (Exception e) {
491 if (_log.isWarnEnabled()) {
492 _log.warn(
493 "Unable to get the portrait for user " + user.getUserId(),
494 e);
495 }
496 }
497
498 return bytes;
499 }
500
501 protected void populateCustomAttributeModifications(
502 Object object, ExpandoBridge expandoBridge,
503 Map<String, Serializable> expandoAttributes, Properties expandoMappings,
504 Modifications modifications) {
505
506 if ((expandoAttributes == null) || expandoAttributes.isEmpty()) {
507 return;
508 }
509
510 for (Map.Entry<Object, Object> entry : expandoMappings.entrySet()) {
511 String fieldName = (String)entry.getKey();
512 String ldapAttributeName = (String)entry.getValue();
513
514 Serializable fieldValue = expandoAttributes.get(fieldName);
515
516 if (fieldValue == null) {
517 continue;
518 }
519
520 try {
521 int type = expandoBridge.getAttributeType(fieldName);
522
523 String value = ExpandoConverterUtil.getStringFromAttribute(
524 type, fieldValue);
525
526 addModificationItem(ldapAttributeName, value, modifications);
527 }
528 catch (Exception e) {
529 if (_log.isWarnEnabled()) {
530 _log.warn(
531 "Unable to map field " + fieldName + " to class " +
532 object.getClass(),
533 e);
534 }
535 }
536 }
537 }
538
539 private static final String _DEFAULT_DN = "cn";
540
541 private static final String _OBJECT_CLASS = "objectclass";
542
543 private static Log _log = LogFactoryUtil.getLog(
544 DefaultPortalToLDAPConverter.class);
545
546 private String _groupDNFieldName = GroupConverterKeys.GROUP_NAME;
547 private Map<String, String> _reservedContactFieldNames =
548 new HashMap<String, String>();
549 private Map<String, String> _reservedUserFieldNames =
550 new HashMap<String, String>();
551 private String _userDNFieldName = UserConverterKeys.SCREEN_NAME;
552
553 }