001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.security.ldap;
016    
017    import com.liferay.portal.NoSuchRoleException;
018    import com.liferay.portal.NoSuchUserException;
019    import com.liferay.portal.NoSuchUserGroupException;
020    import com.liferay.portal.kernel.bean.BeanPropertiesUtil;
021    import com.liferay.portal.kernel.cache.PortalCache;
022    import com.liferay.portal.kernel.cache.SingleVMPoolUtil;
023    import com.liferay.portal.kernel.exception.PortalException;
024    import com.liferay.portal.kernel.exception.SystemException;
025    import com.liferay.portal.kernel.ldap.LDAPUtil;
026    import com.liferay.portal.kernel.log.Log;
027    import com.liferay.portal.kernel.log.LogFactoryUtil;
028    import com.liferay.portal.kernel.util.CalendarFactoryUtil;
029    import com.liferay.portal.kernel.util.GetterUtil;
030    import com.liferay.portal.kernel.util.LocaleUtil;
031    import com.liferay.portal.kernel.util.PropsKeys;
032    import com.liferay.portal.kernel.util.SetUtil;
033    import com.liferay.portal.kernel.util.StringBundler;
034    import com.liferay.portal.kernel.util.StringPool;
035    import com.liferay.portal.kernel.util.StringUtil;
036    import com.liferay.portal.kernel.util.Validator;
037    import com.liferay.portal.model.Company;
038    import com.liferay.portal.model.CompanyConstants;
039    import com.liferay.portal.model.Contact;
040    import com.liferay.portal.model.Group;
041    import com.liferay.portal.model.Role;
042    import com.liferay.portal.model.RoleConstants;
043    import com.liferay.portal.model.User;
044    import com.liferay.portal.model.UserGroup;
045    import com.liferay.portal.security.auth.CompanyThreadLocal;
046    import com.liferay.portal.security.auth.ScreenNameGenerator;
047    import com.liferay.portal.security.auth.ScreenNameGeneratorFactory;
048    import com.liferay.portal.service.CompanyLocalServiceUtil;
049    import com.liferay.portal.service.GroupLocalServiceUtil;
050    import com.liferay.portal.service.LockLocalServiceUtil;
051    import com.liferay.portal.service.RoleLocalServiceUtil;
052    import com.liferay.portal.service.ServiceContext;
053    import com.liferay.portal.service.UserGroupLocalServiceUtil;
054    import com.liferay.portal.service.UserLocalServiceUtil;
055    import com.liferay.portal.util.PrefsPropsUtil;
056    import com.liferay.portal.util.PropsValues;
057    import com.liferay.portlet.expando.model.ExpandoBridge;
058    import com.liferay.portlet.expando.model.ExpandoTableConstants;
059    import com.liferay.portlet.expando.service.ExpandoValueLocalServiceUtil;
060    import com.liferay.portlet.expando.util.ExpandoConverterUtil;
061    
062    import java.io.Serializable;
063    
064    import java.text.ParseException;
065    
066    import java.util.ArrayList;
067    import java.util.Calendar;
068    import java.util.Date;
069    import java.util.HashMap;
070    import java.util.LinkedHashSet;
071    import java.util.List;
072    import java.util.Locale;
073    import java.util.Map;
074    import java.util.Properties;
075    import java.util.Set;
076    
077    import javax.naming.Binding;
078    import javax.naming.NameNotFoundException;
079    import javax.naming.NamingEnumeration;
080    import javax.naming.directory.Attribute;
081    import javax.naming.directory.Attributes;
082    import javax.naming.directory.SearchControls;
083    import javax.naming.directory.SearchResult;
084    import javax.naming.ldap.LdapContext;
085    
086    /**
087     * @author Michael C. Han
088     * @author Brian Wing Shun Chan
089     * @author Wesley Gong
090     * @author Hugo Huijser
091     */
092    public class PortalLDAPImporterImpl implements PortalLDAPImporter {
093    
094            public void importFromLDAP() throws Exception {
095                    List<Company> companies = CompanyLocalServiceUtil.getCompanies(false);
096    
097                    for (Company company : companies) {
098                            importFromLDAP(company.getCompanyId());
099                    }
100            }
101    
102            public void importFromLDAP(long companyId) throws Exception {
103                    if (!LDAPSettingsUtil.isImportEnabled(companyId)) {
104                            return;
105                    }
106    
107                    long defaultUserId = UserLocalServiceUtil.getDefaultUserId(companyId);
108    
109                    if (LockLocalServiceUtil.hasLock(
110                                    defaultUserId, PortalLDAPImporterUtil.class.getName(),
111                                    companyId)) {
112    
113                            if (_log.isDebugEnabled()) {
114                                    _log.debug(
115                                            "Skipping LDAP import for company " + companyId +
116                                                    "because another LDAP import is in process");
117                            }
118    
119                            return;
120                    }
121    
122                    LockLocalServiceUtil.lock(
123                            defaultUserId, PortalLDAPImporterUtil.class.getName(), companyId,
124                            PortalLDAPImporterImpl.class.getName(), false,
125                            PropsValues.LDAP_IMPORT_LOCK_EXPIRATION_TIME);
126    
127                    long threadLocalCompanyId = CompanyThreadLocal.getCompanyId();
128    
129                    try {
130                            if (threadLocalCompanyId == CompanyConstants.SYSTEM) {
131                                    CompanyThreadLocal.setCompanyId(companyId);
132                            }
133    
134                            long[] ldapServerIds = StringUtil.split(
135                                    PrefsPropsUtil.getString(companyId, "ldap.server.ids"), 0L);
136    
137                            for (long ldapServerId : ldapServerIds) {
138                                    importFromLDAP(ldapServerId, companyId);
139                            }
140    
141                            for (int ldapServerId = 0;; ldapServerId++) {
142                                    String postfix = LDAPSettingsUtil.getPropertyPostfix(
143                                            ldapServerId);
144    
145                                    String providerUrl = PrefsPropsUtil.getString(
146                                            companyId, PropsKeys.LDAP_BASE_PROVIDER_URL + postfix);
147    
148                                    if (Validator.isNull(providerUrl)) {
149                                            break;
150                                    }
151    
152                                    importFromLDAP(ldapServerId, companyId);
153                            }
154                    }
155                    finally {
156                            LockLocalServiceUtil.unlock(
157                                    PortalLDAPImporterUtil.class.getName(), companyId);
158    
159                            CompanyThreadLocal.setCompanyId(threadLocalCompanyId);
160                    }
161            }
162    
163            public void importFromLDAP(long ldapServerId, long companyId)
164                    throws Exception {
165    
166                    if (!LDAPSettingsUtil.isImportEnabled(companyId)) {
167                            return;
168                    }
169    
170                    LdapContext ldapContext = PortalLDAPUtil.getContext(
171                            ldapServerId, companyId);
172    
173                    if (ldapContext == null) {
174                            return;
175                    }
176    
177                    try {
178                            Properties userMappings = LDAPSettingsUtil.getUserMappings(
179                                    ldapServerId, companyId);
180                            Properties userExpandoMappings =
181                                    LDAPSettingsUtil.getUserExpandoMappings(
182                                            ldapServerId, companyId);
183                            Properties contactMappings = LDAPSettingsUtil.getContactMappings(
184                                    ldapServerId, companyId);
185                            Properties contactExpandoMappings =
186                                    LDAPSettingsUtil.getContactExpandoMappings(
187                                            ldapServerId, companyId);
188                            Properties groupMappings = LDAPSettingsUtil.getGroupMappings(
189                                    ldapServerId, companyId);
190    
191                            String importMethod = PrefsPropsUtil.getString(
192                                    companyId, PropsKeys.LDAP_IMPORT_METHOD);
193    
194                            if (importMethod.equals(_IMPORT_BY_GROUP)) {
195                                    importFromLDAPByGroup(
196                                            ldapServerId, companyId, ldapContext, userMappings,
197                                            userExpandoMappings, contactMappings,
198                                            contactExpandoMappings, groupMappings);
199                            }
200                            else if (importMethod.equals(_IMPORT_BY_USER)) {
201                                    importFromLDAPByUser(
202                                            ldapServerId, companyId, ldapContext, userMappings,
203                                            userExpandoMappings, contactMappings,
204                                            contactExpandoMappings, groupMappings);
205                            }
206                    }
207                    catch (Exception e) {
208                            _log.error("Error importing LDAP users and groups", e);
209                    }
210                    finally {
211                            if (ldapContext != null) {
212                                    ldapContext.close();
213                            }
214                    }
215            }
216    
217            public User importLDAPUser(
218                            long ldapServerId, long companyId, LdapContext ldapContext,
219                            Attributes attributes, String password)
220                    throws Exception {
221    
222                    Properties userMappings = LDAPSettingsUtil.getUserMappings(
223                            ldapServerId, companyId);
224                    Properties userExpandoMappings =
225                            LDAPSettingsUtil.getUserExpandoMappings(ldapServerId, companyId);
226                    Properties contactMappings = LDAPSettingsUtil.getContactMappings(
227                            ldapServerId, companyId);
228                    Properties contactExpandoMappings =
229                            LDAPSettingsUtil.getContactExpandoMappings(ldapServerId, companyId);
230    
231                    User user = importUser(
232                            ldapServerId, companyId, attributes, userMappings,
233                            userExpandoMappings, contactMappings, contactExpandoMappings,
234                            password);
235    
236                    Properties groupMappings = LDAPSettingsUtil.getGroupMappings(
237                            ldapServerId, companyId);
238    
239                    importGroups(
240                            ldapServerId, companyId, ldapContext, attributes, user,
241                            userMappings, groupMappings);
242    
243                    return user;
244            }
245    
246            public User importLDAPUser(
247                            long ldapServerId, long companyId, String emailAddress,
248                            String screenName)
249                    throws Exception {
250    
251                    LdapContext ldapContext = null;
252    
253                    NamingEnumeration<SearchResult> enu = null;
254    
255                    try {
256                            String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
257    
258                            String baseDN = PrefsPropsUtil.getString(
259                                    companyId, PropsKeys.LDAP_BASE_DN + postfix);
260    
261                            ldapContext = PortalLDAPUtil.getContext(ldapServerId, companyId);
262    
263                            if (ldapContext == null) {
264                                    throw new SystemException("Failed to bind to the LDAP server");
265                            }
266    
267                            String filter = PrefsPropsUtil.getString(
268                                    companyId, PropsKeys.LDAP_AUTH_SEARCH_FILTER + postfix);
269    
270                            if (_log.isDebugEnabled()) {
271                                    _log.debug("Search filter before transformation " + filter);
272                            }
273    
274                            filter = StringUtil.replace(
275                                    filter,
276                                    new String[] {
277                                            "@company_id@", "@email_address@", "@screen_name@"
278                                    },
279                                    new String[] {
280                                            String.valueOf(companyId), emailAddress, screenName
281                                    });
282    
283                            LDAPUtil.validateFilter(filter);
284    
285                            if (_log.isDebugEnabled()) {
286                                    _log.debug("Search filter after transformation " + filter);
287                            }
288    
289                            Properties userMappings = LDAPSettingsUtil.getUserMappings(
290                                    ldapServerId, companyId);
291    
292                            String userMappingsScreenName = GetterUtil.getString(
293                                    userMappings.getProperty("screenName")).toLowerCase();
294    
295                            SearchControls searchControls = new SearchControls(
296                                    SearchControls.SUBTREE_SCOPE, 1, 0,
297                                    new String[] {userMappingsScreenName}, false, false);
298    
299                            enu = ldapContext.search(baseDN, filter, searchControls);
300    
301                            if (enu.hasMoreElements()) {
302                                    if (_log.isDebugEnabled()) {
303                                            _log.debug("Search filter returned at least one result");
304                                    }
305    
306                                    Binding binding = enu.nextElement();
307    
308                                    Attributes attributes = PortalLDAPUtil.getUserAttributes(
309                                            ldapServerId, companyId, ldapContext,
310                                            PortalLDAPUtil.getNameInNamespace(
311                                                    ldapServerId, companyId, binding));
312    
313                                    return importLDAPUser(
314                                            ldapServerId, companyId, ldapContext, attributes,
315                                            StringPool.BLANK);
316                            }
317                            else {
318                                    return null;
319                            }
320                    }
321                    catch (Exception e) {
322                            if (_log.isWarnEnabled()) {
323                                    _log.warn("Problem accessing LDAP server " + e.getMessage());
324                            }
325    
326                            if (_log.isDebugEnabled()) {
327                                    _log.debug(e, e);
328                            }
329    
330                            throw new SystemException(
331                                    "Problem accessing LDAP server " + e.getMessage());
332                    }
333                    finally {
334                            if (enu != null) {
335                                    enu.close();
336                            }
337    
338                            if (ldapContext != null) {
339                                    ldapContext.close();
340                            }
341                    }
342            }
343    
344            public User importLDAPUser(
345                            long companyId, String emailAddress, String screenName)
346                    throws Exception {
347    
348                    long[] ldapServerIds = StringUtil.split(
349                            PrefsPropsUtil.getString(companyId, "ldap.server.ids"), 0L);
350    
351                    for (long ldapServerId : ldapServerIds) {
352                            User user = importLDAPUser(
353                                    ldapServerId, companyId, emailAddress, screenName);
354    
355                            if (user != null) {
356                                    return user;
357                            }
358                    }
359    
360                    for (int ldapServerId = 0;; ldapServerId++) {
361                            String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
362    
363                            String providerUrl = PrefsPropsUtil.getString(
364                                    companyId, PropsKeys.LDAP_BASE_PROVIDER_URL + postfix);
365    
366                            if (Validator.isNull(providerUrl)) {
367                                    break;
368                            }
369    
370                            User user = importLDAPUser(
371                                    ldapServerId, companyId, emailAddress, screenName);
372    
373                            if (user != null) {
374                                    return user;
375                            }
376                    }
377    
378                    if (_log.isDebugEnabled()) {
379                            if (Validator.isNotNull(emailAddress)) {
380                                    _log.debug(
381                                            "User with the email address " + emailAddress +
382                                    " was not found in any LDAP servers");
383                            }
384                            else {
385                                    _log.debug(
386                                            "User with the screen name " + screenName +
387                                    " was not found in any LDAP servers");
388                            }
389                    }
390    
391                    return null;
392            }
393    
394            public User importLDAPUserByScreenName(long companyId, String screenName)
395                    throws Exception {
396    
397                    long ldapServerId = PortalLDAPUtil.getLdapServerId(
398                            companyId, screenName, StringPool.BLANK);
399    
400                    SearchResult result = (SearchResult)PortalLDAPUtil.getUser(
401                            ldapServerId, companyId, screenName, StringPool.BLANK);
402    
403                    if (result == null) {
404                            if (_log.isWarnEnabled()) {
405                                    _log.warn(
406                                            "No user was found in LDAP with screenName " + screenName);
407                            }
408    
409                            return null;
410                    }
411    
412                    LdapContext ldapContext = PortalLDAPUtil.getContext(
413                            ldapServerId, companyId);
414    
415                    String fullUserDN = PortalLDAPUtil.getNameInNamespace(
416                            ldapServerId, companyId, result);
417    
418                    Attributes attributes = PortalLDAPUtil.getUserAttributes(
419                            ldapServerId, companyId, ldapContext, fullUserDN);
420    
421                    User user = importLDAPUser(
422                            ldapServerId, companyId, ldapContext, attributes, StringPool.BLANK);
423    
424                    ldapContext.close();
425    
426                    return user;
427            }
428    
429            public void setLDAPToPortalConverter(
430                    LDAPToPortalConverter ldapToPortalConverter) {
431    
432                    _ldapToPortalConverter = ldapToPortalConverter;
433            }
434    
435            protected void addRole(
436                            long companyId, LDAPGroup ldapGroup, UserGroup userGroup)
437                    throws Exception {
438    
439                    if (!PropsValues.LDAP_IMPORT_CREATE_ROLE_PER_GROUP) {
440                            return;
441                    }
442    
443                    Role role = null;
444    
445                    try {
446                            role = RoleLocalServiceUtil.getRole(
447                                    companyId, ldapGroup.getGroupName());
448                    }
449                    catch (NoSuchRoleException nsre) {
450                            User defaultUser = UserLocalServiceUtil.getDefaultUser(companyId);
451    
452                            Map<Locale, String> descriptionMap = new HashMap<Locale, String>();
453    
454                            descriptionMap.put(
455                                    LocaleUtil.getDefault(), "Autogenerated role from LDAP import");
456    
457                            role = RoleLocalServiceUtil.addRole(
458                                    defaultUser.getUserId(), null, 0, ldapGroup.getGroupName(),
459                                    null, descriptionMap, RoleConstants.TYPE_REGULAR, null);
460                    }
461    
462                    Group group = userGroup.getGroup();
463    
464                    if (GroupLocalServiceUtil.hasRoleGroup(
465                                    role.getRoleId(), group.getGroupId())) {
466    
467                            return;
468                    }
469    
470                    GroupLocalServiceUtil.addRoleGroups(
471                            role.getRoleId(), new long[] {group.getGroupId()});
472            }
473    
474            protected User addUser(long companyId, LDAPUser ldapUser, String password)
475                    throws Exception {
476    
477                    if (_log.isDebugEnabled()) {
478                            _log.debug("Adding user " + ldapUser.getEmailAddress());
479                    }
480    
481                    boolean autoPassword = ldapUser.isAutoPassword();
482    
483                    if (!PropsValues.LDAP_IMPORT_USER_PASSWORD_ENABLED) {
484                            autoPassword =
485                                    PropsValues.LDAP_IMPORT_USER_PASSWORD_AUTOGENERATED &&
486                                    !PropsValues.AUTH_PIPELINE_ENABLE_LIFERAY_CHECK;
487    
488                            if (!autoPassword) {
489                                    String defaultPassword =
490                                            PropsValues.LDAP_IMPORT_USER_PASSWORD_DEFAULT;
491    
492                                    if (defaultPassword.equalsIgnoreCase(
493                                                    _USER_PASSWORD_SCREEN_NAME)) {
494    
495                                            defaultPassword = ldapUser.getScreenName();
496                                    }
497    
498                                    password = defaultPassword;
499                            }
500                    }
501    
502                    Calendar birthdayCal = CalendarFactoryUtil.getCalendar();
503    
504                    birthdayCal.setTime(ldapUser.getBirthday());
505    
506                    int birthdayMonth = birthdayCal.get(Calendar.MONTH);
507                    int birthdayDay = birthdayCal.get(Calendar.DAY_OF_MONTH);
508                    int birthdayYear = birthdayCal.get(Calendar.YEAR);
509    
510                    User user = UserLocalServiceUtil.addUser(
511                            ldapUser.getCreatorUserId(), companyId, autoPassword, password,
512                            password, ldapUser.isAutoScreenName(), ldapUser.getScreenName(),
513                            ldapUser.getEmailAddress(), 0, StringPool.BLANK,
514                            ldapUser.getLocale(), ldapUser.getFirstName(),
515                            ldapUser.getMiddleName(), ldapUser.getLastName(), 0, 0,
516                            ldapUser.isMale(), birthdayMonth, birthdayDay, birthdayYear,
517                            StringPool.BLANK, ldapUser.getGroupIds(),
518                            ldapUser.getOrganizationIds(), ldapUser.getRoleIds(),
519                            ldapUser.getUserGroupIds(), ldapUser.isSendEmail(),
520                            ldapUser.getServiceContext());
521    
522                    if (ldapUser.isUpdatePortrait()) {
523                            byte[] portraitBytes = ldapUser.getPortraitBytes();
524    
525                            if ((portraitBytes != null) && (portraitBytes.length > 0)) {
526                                    user = UserLocalServiceUtil.updatePortrait(
527                                            user.getUserId(), portraitBytes);
528                            }
529                    }
530    
531                    return user;
532            }
533    
534            protected void addUserGroupsNotAddedByLDAPImport(
535                            long userId, Set<Long> userGroupIds)
536                    throws Exception {
537    
538                    List<UserGroup> userGroups =
539                            UserGroupLocalServiceUtil.getUserUserGroups(userId);
540    
541                    for (UserGroup userGroup : userGroups) {
542                            if (!userGroup.isAddedByLDAPImport()) {
543                                    userGroupIds.add(userGroup.getUserGroupId());
544                            }
545                    }
546            }
547    
548            protected String escapeValue(String value) {
549                    return StringUtil.replace(value, "\\,", "\\\\,");
550            }
551    
552            protected User getUser(long companyId, LDAPUser ldapUser) throws Exception {
553                    User user = null;
554    
555                    try {
556                            String authType = PrefsPropsUtil.getString(
557                                    companyId, PropsKeys.COMPANY_SECURITY_AUTH_TYPE,
558                                    PropsValues.COMPANY_SECURITY_AUTH_TYPE);
559    
560                            if (authType.equals(CompanyConstants.AUTH_TYPE_SN) &&
561                                    !ldapUser.isAutoScreenName()) {
562    
563                                    user = UserLocalServiceUtil.getUserByScreenName(
564                                            companyId, ldapUser.getScreenName());
565                            }
566                            else {
567                                    user = UserLocalServiceUtil.getUserByEmailAddress(
568                                            companyId, ldapUser.getEmailAddress());
569                            }
570                    }
571                    catch (NoSuchUserException nsue) {
572                    }
573    
574                    return user;
575            }
576    
577            protected Attribute getUsers(
578                            long ldapServerId, long companyId, LdapContext ldapContext,
579                            Attributes attributes, UserGroup userGroup,
580                            Properties groupMappings)
581                    throws Exception {
582    
583                    Attribute attribute = attributes.get(groupMappings.getProperty("user"));
584    
585                    if (attribute == null) {
586                            return null;
587                    }
588    
589                    String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
590    
591                    String baseDN = PrefsPropsUtil.getString(
592                            companyId, PropsKeys.LDAP_BASE_DN + postfix);
593    
594                    StringBundler sb = new StringBundler(7);
595    
596                    sb.append("(&");
597                    sb.append(
598                            PrefsPropsUtil.getString(
599                                    companyId,
600                                    PropsKeys.LDAP_IMPORT_GROUP_SEARCH_FILTER + postfix));
601                    sb.append("(");
602                    sb.append(groupMappings.getProperty("groupName"));
603                    sb.append("=");
604                    sb.append(escapeValue(userGroup.getName()));
605                    sb.append("))");
606    
607                    return PortalLDAPUtil.getMultivaluedAttribute(
608                            companyId, ldapContext, baseDN, sb.toString(), attribute);
609            }
610    
611            protected void importFromLDAPByGroup(
612                            long ldapServerId, long companyId, LdapContext ldapContext,
613                            Properties userMappings, Properties userExpandoMappings,
614                            Properties contactMappings, Properties contactExpandoMappings,
615                            Properties groupMappings)
616                    throws Exception {
617    
618                    byte[] cookie = new byte[0];
619    
620                    while (cookie != null) {
621                            List<SearchResult> searchResults = new ArrayList<SearchResult>();
622    
623                            String groupMappingsGroupName = GetterUtil.getString(
624                                    groupMappings.getProperty("groupName")).toLowerCase();
625    
626                            cookie = PortalLDAPUtil.getGroups(
627                                    ldapServerId, companyId, ldapContext, cookie, 0,
628                                    new String[] {groupMappingsGroupName}, searchResults);
629    
630                            for (SearchResult searchResult : searchResults) {
631                                    try {
632                                            Attributes attributes = PortalLDAPUtil.getGroupAttributes(
633                                                    ldapServerId, companyId, ldapContext,
634                                                    PortalLDAPUtil.getNameInNamespace(
635                                                            ldapServerId, companyId, searchResult),
636                                                    true);
637    
638                                            UserGroup userGroup = importUserGroup(
639                                                    companyId, attributes, groupMappings);
640    
641                                            Attribute usersAttribute = getUsers(
642                                                    ldapServerId, companyId, ldapContext, attributes,
643                                                    userGroup, groupMappings);
644    
645                                            if (usersAttribute == null) {
646                                                    if (_log.isInfoEnabled()) {
647                                                            _log.info(
648                                                                    "No users found in " + userGroup.getName());
649                                                    }
650    
651                                                    continue;
652                                            }
653    
654                                            importUsers(
655                                                    ldapServerId, companyId, ldapContext, userMappings,
656                                                    userExpandoMappings, contactMappings,
657                                                    contactExpandoMappings, userGroup.getUserGroupId(),
658                                                    usersAttribute);
659                                    }
660                                    catch (Exception e) {
661                                            _log.error("Unable to import group " + searchResult, e);
662                                    }
663                            }
664                    }
665            }
666    
667            protected void importFromLDAPByUser(
668                            long ldapServerId, long companyId, LdapContext ldapContext,
669                            Properties userMappings, Properties userExpandoMappings,
670                            Properties contactMappings, Properties contactExpandoMappings,
671                            Properties groupMappings)
672                    throws Exception {
673    
674                    byte[] cookie = new byte[0];
675    
676                    while (cookie != null) {
677                            List<SearchResult> searchResults = new ArrayList<SearchResult>();
678    
679                            String userMappingsScreenName = GetterUtil.getString(
680                                    userMappings.getProperty("screenName")).toLowerCase();
681    
682                            cookie = PortalLDAPUtil.getUsers(
683                                    ldapServerId, companyId, ldapContext, cookie, 0,
684                                    new String[] {userMappingsScreenName}, searchResults);
685    
686                            for (SearchResult searchResult : searchResults) {
687                                    try {
688                                            Attributes userAttributes =
689                                                    PortalLDAPUtil.getUserAttributes(
690                                                            ldapServerId, companyId, ldapContext,
691                                                            PortalLDAPUtil.getNameInNamespace(
692                                                                    ldapServerId, companyId, searchResult));
693    
694                                            User user = importUser(
695                                                    ldapServerId, companyId, userAttributes, userMappings,
696                                                    userExpandoMappings, contactMappings,
697                                                    contactExpandoMappings, StringPool.BLANK);
698    
699                                            importGroups(
700                                                    ldapServerId, companyId, ldapContext, userAttributes,
701                                                    user, userMappings, groupMappings);
702                                    }
703                                    catch (Exception e) {
704                                            _log.error("Unable to import user " + searchResult, e);
705                                    }
706                            }
707                    }
708            }
709    
710            protected Set<Long> importGroup(
711                            long ldapServerId, long companyId, LdapContext ldapContext,
712                            String fullGroupDN, User user, Properties groupMappings,
713                            Set<Long> newUserGroupIds)
714                    throws Exception {
715    
716                    String userGroupIdKey = null;
717    
718                    Long userGroupId = null;
719    
720                    if (PropsValues.LDAP_IMPORT_GROUP_CACHE_ENABLED) {
721                            StringBundler sb = new StringBundler(5);
722    
723                            sb.append(ldapServerId);
724                            sb.append(StringPool.UNDERLINE);
725                            sb.append(companyId);
726                            sb.append(StringPool.UNDERLINE);
727                            sb.append(fullGroupDN);
728    
729                            userGroupIdKey = sb.toString();
730    
731                            userGroupId = _portalCache.get(userGroupIdKey);
732                    }
733    
734                    if (userGroupId != null) {
735                            if (_log.isDebugEnabled()) {
736                                    _log.debug("Skipping reimport of full group DN " + fullGroupDN);
737                            }
738                    }
739                    else {
740                            if (_log.isDebugEnabled()) {
741                                    _log.debug("Importing full group DN " + fullGroupDN);
742                            }
743    
744                            Attributes groupAttributes = null;
745    
746                            try {
747                                    groupAttributes = PortalLDAPUtil.getGroupAttributes(
748                                            ldapServerId, companyId, ldapContext, fullGroupDN);
749                            }
750                            catch (NameNotFoundException nnfe) {
751                                    _log.error(
752                                            "LDAP group not found with full group DN " + fullGroupDN,
753                                            nnfe);
754                            }
755    
756                            UserGroup userGroup = importUserGroup(
757                                    companyId, groupAttributes, groupMappings);
758    
759                            userGroupId = userGroup.getUserGroupId();
760    
761                            if (PropsValues.LDAP_IMPORT_GROUP_CACHE_ENABLED) {
762                                    _portalCache.put(userGroupIdKey, userGroupId);
763                            }
764                    }
765    
766                    if (userGroupId != null) {
767                            if (_log.isDebugEnabled()) {
768                                    _log.debug(
769                                            "Adding " + user.getUserId() + " to group " + userGroupId);
770                            }
771    
772                            newUserGroupIds.add(userGroupId);
773                    }
774    
775                    return newUserGroupIds;
776            }
777    
778            protected void importGroups(
779                            long ldapServerId, long companyId, LdapContext ldapContext,
780                            Attributes attributes, User user, Properties userMappings,
781                            Properties groupMappings)
782                    throws Exception {
783    
784                    Set<Long> newUserGroupIds = new LinkedHashSet<Long>();
785    
786                    if (PrefsPropsUtil.getBoolean(
787                                    companyId, PropsKeys.LDAP_IMPORT_GROUP_SEARCH_FILTER_ENABLED)) {
788    
789                            String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
790    
791                            String baseDN = PrefsPropsUtil.getString(
792                                    companyId, PropsKeys.LDAP_BASE_DN + postfix);
793    
794                            Binding binding = PortalLDAPUtil.getUser(
795                                    ldapServerId, companyId, user.getScreenName(),
796                                    user.getEmailAddress());
797    
798                            String fullUserDN = PortalLDAPUtil.getNameInNamespace(
799                                    ldapServerId, companyId, binding);
800    
801                            StringBundler sb = new StringBundler(9);
802    
803                            sb.append(StringPool.OPEN_PARENTHESIS);
804                            sb.append(StringPool.AMPERSAND);
805                            sb.append(
806                                    PrefsPropsUtil.getString(
807                                            companyId,
808                                            PropsKeys.LDAP_IMPORT_GROUP_SEARCH_FILTER + postfix));
809                            sb.append(StringPool.OPEN_PARENTHESIS);
810                            sb.append(groupMappings.getProperty("user"));
811                            sb.append(StringPool.EQUAL);
812                            sb.append(escapeValue(fullUserDN));
813                            sb.append(StringPool.CLOSE_PARENTHESIS);
814                            sb.append(StringPool.CLOSE_PARENTHESIS);
815    
816                            byte[] cookie = new byte[0];
817    
818                            while (cookie != null) {
819                                    List<SearchResult> searchResults =
820                                            new ArrayList<SearchResult>();
821    
822                                    String groupMappingsGroupName = GetterUtil.getString(
823                                            groupMappings.getProperty("groupName")).toLowerCase();
824    
825                                    cookie = PortalLDAPUtil.searchLDAP(
826                                            companyId, ldapContext, cookie, 0, baseDN, sb.toString(),
827                                            new String[] {groupMappingsGroupName}, searchResults);
828    
829                                    for (SearchResult searchResult : searchResults) {
830                                            String fullGroupDN = PortalLDAPUtil.getNameInNamespace(
831                                                    ldapServerId, companyId, searchResult);
832    
833                                            newUserGroupIds = importGroup(
834                                                    ldapServerId, companyId, ldapContext, fullGroupDN, user,
835                                                    groupMappings, newUserGroupIds);
836                                    }
837                            }
838                    }
839                    else {
840                            String userMappingsGroup = userMappings.getProperty("group");
841    
842                            if (Validator.isNull(userMappingsGroup)) {
843                                    return;
844                            }
845    
846                            Attribute userGroupAttribute = attributes.get(userMappingsGroup);
847    
848                            if (userGroupAttribute == null) {
849                                    return;
850                            }
851    
852                            for (int i = 0; i < userGroupAttribute.size(); i++) {
853                                    String fullGroupDN = (String)userGroupAttribute.get(i);
854    
855                                    newUserGroupIds = importGroup(
856                                            ldapServerId, companyId, ldapContext, fullGroupDN, user,
857                                            groupMappings, newUserGroupIds);
858                            }
859                    }
860    
861                    addUserGroupsNotAddedByLDAPImport(user.getUserId(), newUserGroupIds);
862    
863                    for (long newUserGroupId : newUserGroupIds) {
864                            UserLocalServiceUtil.addUserGroupUsers(
865                                    newUserGroupId, new long[] {user.getUserId()});
866                    }
867    
868                    List<UserGroup> userUserGroups =
869                            UserGroupLocalServiceUtil.getUserUserGroups(user.getUserId());
870    
871                    for (UserGroup userGroup : userUserGroups) {
872                            if (!newUserGroupIds.contains(userGroup.getUserGroupId())) {
873                                    UserLocalServiceUtil.deleteUserGroupUser(
874                                            userGroup.getUserGroupId(), user.getUserId());
875                            }
876                    }
877            }
878    
879            protected User importUser(
880                            long ldapServerId, long companyId, Attributes attributes,
881                            Properties userMappings, Properties userExpandoMappings,
882                            Properties contactMappings, Properties contactExpandoMappings,
883                            String password)
884                    throws Exception {
885    
886                    LDAPUserTransactionThreadLocal.setOriginatesFromLDAP(true);
887    
888                    try {
889                            AttributesTransformer attributesTransformer =
890                                    AttributesTransformerFactory.getInstance();
891    
892                            attributes = attributesTransformer.transformUser(attributes);
893    
894                            LDAPUser ldapUser = _ldapToPortalConverter.importLDAPUser(
895                                    companyId, attributes, userMappings, userExpandoMappings,
896                                    contactMappings, contactExpandoMappings, password);
897    
898                            User user = getUser(companyId, ldapUser);
899    
900                            if ((user != null) && user.isDefaultUser()) {
901                                    return user;
902                            }
903    
904                            ServiceContext serviceContext = ldapUser.getServiceContext();
905                            serviceContext.setAttribute("ldapServerId", ldapServerId);
906    
907                            if (user == null) {
908                                    user = addUser(companyId, ldapUser, password);
909                            }
910    
911                            String modifiedDate = LDAPUtil.getAttributeString(
912                                    attributes, "modifyTimestamp");
913    
914                            user = updateUser(
915                                    companyId, ldapUser, user, password, modifiedDate);
916    
917                            updateExpandoAttributes(user, ldapUser);
918    
919                            return user;
920                    }
921                    finally {
922                            LDAPUserTransactionThreadLocal.setOriginatesFromLDAP(false);
923                    }
924            }
925    
926            protected UserGroup importUserGroup(
927                            long companyId, Attributes attributes, Properties groupMappings)
928                    throws Exception {
929    
930                    AttributesTransformer attributesTransformer =
931                            AttributesTransformerFactory.getInstance();
932    
933                    attributes = attributesTransformer.transformGroup(attributes);
934    
935                    LDAPGroup ldapGroup = _ldapToPortalConverter.importLDAPGroup(
936                            companyId, attributes, groupMappings);
937    
938                    UserGroup userGroup = null;
939    
940                    try {
941                            userGroup = UserGroupLocalServiceUtil.getUserGroup(
942                                    companyId, ldapGroup.getGroupName());
943    
944                            UserGroupLocalServiceUtil.updateUserGroup(
945                                    companyId, userGroup.getUserGroupId(), ldapGroup.getGroupName(),
946                                    ldapGroup.getDescription(), null);
947                    }
948                    catch (NoSuchUserGroupException nsuge) {
949                            if (_log.isDebugEnabled()) {
950                                    _log.debug(
951                                            "Adding user group to portal " + ldapGroup.getGroupName());
952                            }
953    
954                            long defaultUserId = UserLocalServiceUtil.getDefaultUserId(
955                                    companyId);
956    
957                            LDAPUserGroupTransactionThreadLocal.setOriginatesFromLDAP(true);
958    
959                            try {
960                                    userGroup = UserGroupLocalServiceUtil.addUserGroup(
961                                            defaultUserId, companyId, ldapGroup.getGroupName(),
962                                            ldapGroup.getDescription(), null);
963                            }
964                            catch (Exception e) {
965                                    if (_log.isWarnEnabled()) {
966                                            _log.warn(
967                                                    "Unable to create user group " +
968                                                            ldapGroup.getGroupName());
969                                    }
970    
971                                    if (_log.isDebugEnabled()) {
972                                            _log.debug(e, e);
973                                    }
974                            }
975                            finally {
976                                    LDAPUserGroupTransactionThreadLocal.setOriginatesFromLDAP(
977                                            false);
978                            }
979                    }
980    
981                    addRole(companyId, ldapGroup, userGroup);
982    
983                    return userGroup;
984            }
985    
986            protected void importUsers(
987                            long ldapServerId, long companyId, LdapContext ldapContext,
988                            Properties userMappings, Properties userExpandoMappings,
989                            Properties contactMappings, Properties contactExpandoMappings,
990                            long userGroupId, Attribute attribute)
991                    throws Exception {
992    
993                    Set<Long> newUserIds = new LinkedHashSet<Long>(attribute.size());
994    
995                    for (int i = 0; i < attribute.size(); i++) {
996                            String fullUserDN = (String)attribute.get(i);
997    
998                            Attributes userAttributes = null;
999    
1000                            try {
1001                                    userAttributes = PortalLDAPUtil.getUserAttributes(
1002                                            ldapServerId, companyId, ldapContext, fullUserDN);
1003                            }
1004                            catch (NameNotFoundException nnfe) {
1005                                    _log.error(
1006                                            "LDAP user not found with fullUserDN " + fullUserDN, nnfe);
1007    
1008                                    continue;
1009                            }
1010    
1011                            try {
1012                                    User user = importUser(
1013                                            ldapServerId, companyId, userAttributes, userMappings,
1014                                            userExpandoMappings, contactMappings,
1015                                            contactExpandoMappings, StringPool.BLANK);
1016    
1017                                    if (user != null) {
1018                                            if (_log.isDebugEnabled()) {
1019                                                    _log.debug(
1020                                                            "Adding " + user.getUserId() + " to group " +
1021                                                                    userGroupId);
1022                                            }
1023    
1024                                            UserLocalServiceUtil.addUserGroupUsers(
1025                                                    userGroupId, new long[] {user.getUserId()});
1026    
1027                                            newUserIds.add(user.getUserId());
1028                                    }
1029                            }
1030                            catch (Exception e) {
1031                                    _log.error("Unable to load user " + userAttributes, e);
1032                            }
1033                    }
1034    
1035                    List<User> userGroupUsers = UserLocalServiceUtil.getUserGroupUsers(
1036                            userGroupId);
1037    
1038                    for (User user : userGroupUsers) {
1039                            if (!newUserIds.contains(user.getUserId())) {
1040                                    UserLocalServiceUtil.deleteUserGroupUser(
1041                                            userGroupId, user.getUserId());
1042                            }
1043                    }
1044            }
1045    
1046            protected void populateExpandoAttributes(
1047                    ExpandoBridge expandoBridge, Map<String, String[]> expandoAttributes) {
1048    
1049                    if (expandoAttributes.isEmpty()) {
1050                            return;
1051                    }
1052    
1053                    Map<String, Serializable> serializedExpandoAttributes =
1054                            new HashMap<String, Serializable>();
1055    
1056                    for (Map.Entry<String, String[]> expandoAttribute :
1057                                    expandoAttributes.entrySet()) {
1058    
1059                            String name = expandoAttribute.getKey();
1060    
1061                            if (!expandoBridge.hasAttribute(name)) {
1062                                    continue;
1063                            }
1064    
1065                            int type = expandoBridge.getAttributeType(name);
1066    
1067                            Serializable value =
1068                                    ExpandoConverterUtil.getAttributeFromStringArray(
1069                                            type, expandoAttribute.getValue());
1070    
1071                            serializedExpandoAttributes.put(name, value);
1072                    }
1073    
1074                    try {
1075                            ExpandoValueLocalServiceUtil.addValues(
1076                                    expandoBridge.getCompanyId(), expandoBridge.getClassName(),
1077                                    ExpandoTableConstants.DEFAULT_TABLE_NAME,
1078                                    expandoBridge.getClassPK(), serializedExpandoAttributes);
1079                    }
1080                    catch (Exception e) {
1081                            if (_log.isWarnEnabled()) {
1082                                    _log.warn("Unable to populate expando attributes");
1083                            }
1084    
1085                            if (_log.isDebugEnabled()) {
1086                                    _log.debug(e, e);
1087                            }
1088                    }
1089            }
1090    
1091            protected void setProperty(
1092                    Object bean1, Object bean2, String propertyName) {
1093    
1094                    Object value = BeanPropertiesUtil.getObject(bean1, propertyName);
1095                    Object defaultValue = BeanPropertiesUtil.getObject(bean2, propertyName);
1096    
1097                    if ((value == null) || value.equals(StringPool.BLANK)) {
1098                            BeanPropertiesUtil.setProperty(bean1, propertyName, defaultValue);
1099                    }
1100            }
1101    
1102            protected void updateExpandoAttributes(User user, LDAPUser ldapUser)
1103                    throws Exception {
1104    
1105                    ExpandoBridge userExpandoBridge = user.getExpandoBridge();
1106    
1107                    populateExpandoAttributes(
1108                            userExpandoBridge, ldapUser.getUserExpandoAttributes());
1109    
1110                    Contact contact = user.getContact();
1111    
1112                    ExpandoBridge contactExpandoBridge = contact.getExpandoBridge();
1113    
1114                    populateExpandoAttributes(
1115                            contactExpandoBridge, ldapUser.getContactExpandoAttributes());
1116            }
1117    
1118            protected void updateLDAPUser(User ldapUser, Contact ldapContact, User user)
1119                    throws PortalException, SystemException {
1120    
1121                    Contact contact = user.getContact();
1122    
1123                    for (String propertyName : _CONTACT_PROPERTY_NAMES) {
1124                            setProperty(ldapContact, contact, propertyName);
1125                    }
1126    
1127                    for (String propertyName : _USER_PROPERTY_NAMES) {
1128                            setProperty(ldapUser, user, propertyName);
1129                    }
1130            }
1131    
1132            protected User updateUser(
1133                            long companyId, LDAPUser ldapUser, User user, String password,
1134                            String modifiedDate)
1135                    throws Exception {
1136    
1137                    Date ldapUserModifiedDate = null;
1138    
1139                    try {
1140                            if (Validator.isNull(modifiedDate)) {
1141                                    if (_log.isInfoEnabled()) {
1142                                            _log.info(
1143                                                    "LDAP entry never modified, skipping user " +
1144                                                            user.getEmailAddress());
1145                                    }
1146    
1147                                    return user;
1148                            }
1149                            else {
1150                                    ldapUserModifiedDate = LDAPUtil.parseDate(modifiedDate);
1151                            }
1152    
1153                            if (ldapUserModifiedDate.equals(user.getModifiedDate()) &&
1154                                    ldapUser.isAutoPassword()) {
1155    
1156                                    if (_log.isDebugEnabled()) {
1157                                            _log.debug(
1158                                                    "User is already synchronized, skipping user " +
1159                                                            user.getEmailAddress());
1160                                    }
1161    
1162                                    return user;
1163                            }
1164                    }
1165                    catch (ParseException pe) {
1166                            if (_log.isDebugEnabled()) {
1167                                    _log.debug(
1168                                            "Unable to parse LDAP modify timestamp " + modifiedDate,
1169                                            pe);
1170                            }
1171                    }
1172    
1173                    boolean passwordReset = ldapUser.isPasswordReset();
1174    
1175                    if (PrefsPropsUtil.getBoolean(
1176                                    companyId, PropsKeys.LDAP_EXPORT_ENABLED,
1177                                    PropsValues.LDAP_EXPORT_ENABLED)) {
1178    
1179                            passwordReset = user.isPasswordReset();
1180                    }
1181    
1182                    if (!PropsValues.LDAP_IMPORT_USER_PASSWORD_ENABLED) {
1183                            password = PropsValues.LDAP_IMPORT_USER_PASSWORD_DEFAULT;
1184    
1185                            if (password.equalsIgnoreCase(_USER_PASSWORD_SCREEN_NAME)) {
1186                                    password = ldapUser.getScreenName();
1187                            }
1188                    }
1189    
1190                    if (Validator.isNull(ldapUser.getScreenName())) {
1191                            ldapUser.setAutoScreenName(true);
1192                    }
1193    
1194                    if (ldapUser.isAutoScreenName()) {
1195                            ScreenNameGenerator screenNameGenerator =
1196                                    ScreenNameGeneratorFactory.getInstance();
1197    
1198                            ldapUser.setScreenName(
1199                                    screenNameGenerator.generate(
1200                                            companyId, user.getUserId(), ldapUser.getEmailAddress()));
1201                    }
1202    
1203                    Calendar birthdayCal = CalendarFactoryUtil.getCalendar();
1204    
1205                    birthdayCal.setTime(user.getContact().getBirthday());
1206    
1207                    int birthdayMonth = birthdayCal.get(Calendar.MONTH);
1208                    int birthdayDay = birthdayCal.get(Calendar.DAY_OF_MONTH);
1209                    int birthdayYear = birthdayCal.get(Calendar.YEAR);
1210    
1211                    if (ldapUser.isUpdatePassword()) {
1212                            UserLocalServiceUtil.updatePassword(
1213                                    user.getUserId(), password, password, passwordReset, true);
1214                    }
1215    
1216                    Contact contact = user.getContact();
1217    
1218                    Set<String> ldapIgnoreAttributes = SetUtil.fromArray(
1219                            PropsValues.LDAP_USER_IGNORE_ATTRIBUTES);
1220    
1221                    for (String attribute : ldapIgnoreAttributes) {
1222                            Object value = BeanPropertiesUtil.getObjectSilent(user, attribute);
1223    
1224                            if (value == null) {
1225                                    value = BeanPropertiesUtil.getObjectSilent(contact, attribute);
1226                            }
1227    
1228                            if (value != null) {
1229                                    BeanPropertiesUtil.setProperty(ldapUser, attribute, value);
1230                            }
1231                    }
1232    
1233                    updateLDAPUser(ldapUser.getUser(), ldapUser.getContact(), user);
1234    
1235                    user = UserLocalServiceUtil.updateUser(
1236                            user.getUserId(), password, StringPool.BLANK, StringPool.BLANK,
1237                            passwordReset, ldapUser.getReminderQueryQuestion(),
1238                            ldapUser.getReminderQueryAnswer(), ldapUser.getScreenName(),
1239                            ldapUser.getEmailAddress(), ldapUser.getFacebookId(),
1240                            ldapUser.getOpenId(), ldapUser.getLanguageId(),
1241                            ldapUser.getTimeZoneId(), ldapUser.getGreeting(),
1242                            ldapUser.getComments(), ldapUser.getFirstName(),
1243                            ldapUser.getMiddleName(), ldapUser.getLastName(),
1244                            ldapUser.getPrefixId(), ldapUser.getSuffixId(), ldapUser.isMale(),
1245                            birthdayMonth, birthdayDay, birthdayYear, ldapUser.getSmsSn(),
1246                            ldapUser.getAimSn(), ldapUser.getFacebookSn(), ldapUser.getIcqSn(),
1247                            ldapUser.getJabberSn(), ldapUser.getMsnSn(),
1248                            ldapUser.getMySpaceSn(), ldapUser.getSkypeSn(),
1249                            ldapUser.getTwitterSn(), ldapUser.getYmSn(), ldapUser.getJobTitle(),
1250                            ldapUser.getGroupIds(), ldapUser.getOrganizationIds(),
1251                            ldapUser.getRoleIds(), ldapUser.getUserGroupRoles(),
1252                            ldapUser.getUserGroupIds(), ldapUser.getServiceContext());
1253    
1254                    if (ldapUserModifiedDate != null) {
1255                            user = UserLocalServiceUtil.updateModifiedDate(
1256                                    user.getUserId(), ldapUserModifiedDate);
1257                    }
1258    
1259                    if (ldapUser.isUpdatePortrait()) {
1260                            byte[] portraitBytes = ldapUser.getPortraitBytes();
1261    
1262                            if ((portraitBytes != null) && (portraitBytes.length > 0)) {
1263                                    UserLocalServiceUtil.updatePortrait(
1264                                            user.getUserId(), portraitBytes);
1265                            }
1266                            else {
1267                                    UserLocalServiceUtil.deletePortrait(user.getUserId());
1268                            }
1269                    }
1270    
1271                    user = UserLocalServiceUtil.updateStatus(
1272                            user.getUserId(), ldapUser.getStatus());
1273    
1274                    return user;
1275            }
1276    
1277            private static final String[] _CONTACT_PROPERTY_NAMES = {
1278                    "aimSn", "facebookSn", "icqSn", "jabberSn", "male", "mySpaceSn",
1279                    "prefixId", "skypeSn", "smsSn", "suffixId", "twitterSn", "ymSn"
1280            };
1281    
1282            private static final String _IMPORT_BY_GROUP = "group";
1283    
1284            private static final String _IMPORT_BY_USER = "user";
1285    
1286            private static final String _USER_PASSWORD_SCREEN_NAME = "screenName";
1287    
1288            private static final String[] _USER_PROPERTY_NAMES = {
1289                    "comments", "greeting", "jobTitle", "languageId", "middleName",
1290                    "openId", "timeZoneId"
1291            };
1292    
1293            private static Log _log = LogFactoryUtil.getLog(
1294                    PortalLDAPImporterImpl.class);
1295    
1296            private LDAPToPortalConverter _ldapToPortalConverter;
1297            private PortalCache<String, Long> _portalCache = SingleVMPoolUtil.getCache(
1298                    PortalLDAPImporter.class.getName(), false);
1299    
1300    }