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