001    /**
002     * Copyright (c) 2000-present 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.service.impl;
016    
017    import com.liferay.mail.service.MailService;
018    import com.liferay.portal.CompanyMaxUsersException;
019    import com.liferay.portal.ContactBirthdayException;
020    import com.liferay.portal.ContactNameException;
021    import com.liferay.portal.DuplicateOpenIdException;
022    import com.liferay.portal.GroupFriendlyURLException;
023    import com.liferay.portal.ModelListenerException;
024    import com.liferay.portal.NoSuchImageException;
025    import com.liferay.portal.NoSuchOrganizationException;
026    import com.liferay.portal.NoSuchTicketException;
027    import com.liferay.portal.NoSuchUserException;
028    import com.liferay.portal.PasswordExpiredException;
029    import com.liferay.portal.RequiredUserException;
030    import com.liferay.portal.SendPasswordException;
031    import com.liferay.portal.UserEmailAddressException;
032    import com.liferay.portal.UserIdException;
033    import com.liferay.portal.UserLockoutException;
034    import com.liferay.portal.UserPasswordException;
035    import com.liferay.portal.UserReminderQueryException;
036    import com.liferay.portal.UserScreenNameException;
037    import com.liferay.portal.UserSmsException;
038    import com.liferay.portal.kernel.bean.BeanReference;
039    import com.liferay.portal.kernel.cache.PortalCache;
040    import com.liferay.portal.kernel.cache.PortalCacheMapSynchronizeUtil;
041    import com.liferay.portal.kernel.cache.PortalCacheMapSynchronizeUtil.Synchronizer;
042    import com.liferay.portal.kernel.dao.orm.EntityCacheUtil;
043    import com.liferay.portal.kernel.dao.orm.QueryUtil;
044    import com.liferay.portal.kernel.dao.orm.WildcardMode;
045    import com.liferay.portal.kernel.exception.PortalException;
046    import com.liferay.portal.kernel.exception.SystemException;
047    import com.liferay.portal.kernel.language.LanguageUtil;
048    import com.liferay.portal.kernel.log.Log;
049    import com.liferay.portal.kernel.log.LogFactoryUtil;
050    import com.liferay.portal.kernel.messaging.DestinationNames;
051    import com.liferay.portal.kernel.messaging.Message;
052    import com.liferay.portal.kernel.messaging.MessageBusUtil;
053    import com.liferay.portal.kernel.search.BaseModelSearchResult;
054    import com.liferay.portal.kernel.search.Hits;
055    import com.liferay.portal.kernel.search.Indexer;
056    import com.liferay.portal.kernel.search.IndexerRegistryUtil;
057    import com.liferay.portal.kernel.search.QueryConfig;
058    import com.liferay.portal.kernel.search.SearchContext;
059    import com.liferay.portal.kernel.search.SearchException;
060    import com.liferay.portal.kernel.search.Sort;
061    import com.liferay.portal.kernel.spring.aop.Skip;
062    import com.liferay.portal.kernel.transaction.Propagation;
063    import com.liferay.portal.kernel.transaction.TransactionCommitCallbackUtil;
064    import com.liferay.portal.kernel.transaction.Transactional;
065    import com.liferay.portal.kernel.util.ArrayUtil;
066    import com.liferay.portal.kernel.util.Digester;
067    import com.liferay.portal.kernel.util.DigesterUtil;
068    import com.liferay.portal.kernel.util.GetterUtil;
069    import com.liferay.portal.kernel.util.KeyValuePair;
070    import com.liferay.portal.kernel.util.ListUtil;
071    import com.liferay.portal.kernel.util.LocaleUtil;
072    import com.liferay.portal.kernel.util.LocalizationUtil;
073    import com.liferay.portal.kernel.util.MapUtil;
074    import com.liferay.portal.kernel.util.OrderByComparator;
075    import com.liferay.portal.kernel.util.ParamUtil;
076    import com.liferay.portal.kernel.util.PropsKeys;
077    import com.liferay.portal.kernel.util.PwdGenerator;
078    import com.liferay.portal.kernel.util.SetUtil;
079    import com.liferay.portal.kernel.util.StringBundler;
080    import com.liferay.portal.kernel.util.StringPool;
081    import com.liferay.portal.kernel.util.StringUtil;
082    import com.liferay.portal.kernel.util.UnicodeProperties;
083    import com.liferay.portal.kernel.util.Validator;
084    import com.liferay.portal.kernel.workflow.WorkflowConstants;
085    import com.liferay.portal.kernel.workflow.WorkflowHandlerRegistryUtil;
086    import com.liferay.portal.kernel.workflow.WorkflowThreadLocal;
087    import com.liferay.portal.model.Account;
088    import com.liferay.portal.model.Company;
089    import com.liferay.portal.model.CompanyConstants;
090    import com.liferay.portal.model.Contact;
091    import com.liferay.portal.model.ContactConstants;
092    import com.liferay.portal.model.Group;
093    import com.liferay.portal.model.GroupConstants;
094    import com.liferay.portal.model.Layout;
095    import com.liferay.portal.model.Organization;
096    import com.liferay.portal.model.PasswordPolicy;
097    import com.liferay.portal.model.ResourceConstants;
098    import com.liferay.portal.model.Role;
099    import com.liferay.portal.model.RoleConstants;
100    import com.liferay.portal.model.Team;
101    import com.liferay.portal.model.Ticket;
102    import com.liferay.portal.model.TicketConstants;
103    import com.liferay.portal.model.User;
104    import com.liferay.portal.model.UserGroup;
105    import com.liferay.portal.model.UserGroupRole;
106    import com.liferay.portal.model.impl.LayoutImpl;
107    import com.liferay.portal.model.impl.UserCacheModel;
108    import com.liferay.portal.model.impl.UserImpl;
109    import com.liferay.portal.security.auth.AuthPipeline;
110    import com.liferay.portal.security.auth.Authenticator;
111    import com.liferay.portal.security.auth.EmailAddressGenerator;
112    import com.liferay.portal.security.auth.EmailAddressGeneratorFactory;
113    import com.liferay.portal.security.auth.EmailAddressValidator;
114    import com.liferay.portal.security.auth.EmailAddressValidatorFactory;
115    import com.liferay.portal.security.auth.FullNameDefinition;
116    import com.liferay.portal.security.auth.FullNameDefinitionFactory;
117    import com.liferay.portal.security.auth.FullNameGenerator;
118    import com.liferay.portal.security.auth.FullNameGeneratorFactory;
119    import com.liferay.portal.security.auth.FullNameValidator;
120    import com.liferay.portal.security.auth.FullNameValidatorFactory;
121    import com.liferay.portal.security.auth.PrincipalException;
122    import com.liferay.portal.security.auth.PrincipalThreadLocal;
123    import com.liferay.portal.security.auth.ScreenNameGenerator;
124    import com.liferay.portal.security.auth.ScreenNameGeneratorFactory;
125    import com.liferay.portal.security.auth.ScreenNameValidator;
126    import com.liferay.portal.security.auth.ScreenNameValidatorFactory;
127    import com.liferay.portal.security.ldap.LDAPSettingsUtil;
128    import com.liferay.portal.security.permission.PermissionCacheUtil;
129    import com.liferay.portal.security.pwd.PasswordEncryptorUtil;
130    import com.liferay.portal.security.pwd.PwdAuthenticator;
131    import com.liferay.portal.security.pwd.PwdToolkitUtil;
132    import com.liferay.portal.security.pwd.RegExpToolkit;
133    import com.liferay.portal.service.BaseServiceImpl;
134    import com.liferay.portal.service.ServiceContext;
135    import com.liferay.portal.service.ServiceContextThreadLocal;
136    import com.liferay.portal.service.base.UserLocalServiceBaseImpl;
137    import com.liferay.portal.service.persistence.UserGroupRolePK;
138    import com.liferay.portal.util.PortalUtil;
139    import com.liferay.portal.util.PrefsPropsUtil;
140    import com.liferay.portal.util.PropsValues;
141    import com.liferay.portal.util.SubscriptionSender;
142    import com.liferay.portlet.messageboards.model.MBMessage;
143    import com.liferay.portlet.social.model.SocialRelation;
144    import com.liferay.portlet.social.model.SocialRelationConstants;
145    import com.liferay.portlet.usersadmin.util.UsersAdminUtil;
146    import com.liferay.util.Encryptor;
147    import com.liferay.util.EncryptorException;
148    
149    import java.io.Serializable;
150    
151    import java.util.ArrayList;
152    import java.util.Arrays;
153    import java.util.Calendar;
154    import java.util.Collections;
155    import java.util.Date;
156    import java.util.HashMap;
157    import java.util.HashSet;
158    import java.util.LinkedHashMap;
159    import java.util.LinkedHashSet;
160    import java.util.List;
161    import java.util.Locale;
162    import java.util.Map;
163    import java.util.Set;
164    import java.util.concurrent.Callable;
165    import java.util.concurrent.ConcurrentHashMap;
166    
167    import javax.portlet.PortletPreferences;
168    
169    /**
170     * Provides the local service for accessing, adding, authenticating, deleting,
171     * and updating users.
172     *
173     * @author Brian Wing Shun Chan
174     * @author Scott Lee
175     * @author Raymond Aug??
176     * @author Jorge Ferrer
177     * @author Julio Camarero
178     * @author Wesley Gong
179     * @author Zsigmond Rab
180     */
181    public class UserLocalServiceImpl extends UserLocalServiceBaseImpl {
182    
183            /**
184             * Adds a default admin user for the company.
185             *
186             * @param  companyId the primary key of the user's company
187             * @param  screenName the user's screen name
188             * @param  emailAddress the user's email address
189             * @param  locale the user's locale
190             * @param  firstName the user's first name
191             * @param  middleName the user's middle name
192             * @param  lastName the user's last name
193             * @return the new default admin user
194             */
195            @Override
196            public User addDefaultAdminUser(
197                            long companyId, String screenName, String emailAddress,
198                            Locale locale, String firstName, String middleName, String lastName)
199                    throws PortalException {
200    
201                    long creatorUserId = 0;
202                    boolean autoPassword = false;
203                    String password1 = PropsValues.DEFAULT_ADMIN_PASSWORD;
204                    String password2 = password1;
205                    boolean autoScreenName = false;
206    
207                    screenName = getLogin(screenName);
208    
209                    for (int i = 1;; i++) {
210                            User screenNameUser = userPersistence.fetchByC_SN(
211                                    companyId, screenName);
212    
213                            if (screenNameUser == null) {
214                                    break;
215                            }
216    
217                            screenName = screenName + i;
218                    }
219    
220                    long facebookId = 0;
221                    String openId = StringPool.BLANK;
222                    long prefixId = 0;
223                    long suffixId = 0;
224                    boolean male = true;
225                    int birthdayMonth = Calendar.JANUARY;
226                    int birthdayDay = 1;
227                    int birthdayYear = 1970;
228                    String jobTitle = StringPool.BLANK;
229    
230                    Group guestGroup = groupLocalService.getGroup(
231                            companyId, GroupConstants.GUEST);
232    
233                    long[] groupIds = {guestGroup.getGroupId()};
234    
235                    long[] organizationIds = null;
236    
237                    Role adminRole = roleLocalService.getRole(
238                            companyId, RoleConstants.ADMINISTRATOR);
239    
240                    Role powerUserRole = roleLocalService.getRole(
241                            companyId, RoleConstants.POWER_USER);
242    
243                    long[] roleIds = {adminRole.getRoleId(), powerUserRole.getRoleId()};
244    
245                    long[] userGroupIds = null;
246                    boolean sendEmail = false;
247                    ServiceContext serviceContext = new ServiceContext();
248    
249                    User defaultAdminUser = addUser(
250                            creatorUserId, companyId, autoPassword, password1, password2,
251                            autoScreenName, screenName, emailAddress, facebookId, openId,
252                            locale, firstName, middleName, lastName, prefixId, suffixId, male,
253                            birthdayMonth, birthdayDay, birthdayYear, jobTitle, groupIds,
254                            organizationIds, roleIds, userGroupIds, sendEmail, serviceContext);
255    
256                    updateEmailAddressVerified(defaultAdminUser.getUserId(), true);
257    
258                    updateLastLogin(
259                            defaultAdminUser.getUserId(), defaultAdminUser.getLoginIP());
260    
261                    updatePasswordReset(defaultAdminUser.getUserId(), false);
262    
263                    return defaultAdminUser;
264            }
265    
266            /**
267             * Adds the user to the default groups, unless the user is already in these
268             * groups. The default groups can be specified in
269             * <code>portal.properties</code> with the key
270             * <code>admin.default.group.names</code>.
271             *
272             * @param userId the primary key of the user
273             */
274            @Override
275            public void addDefaultGroups(long userId) throws PortalException {
276                    User user = userPersistence.findByPrimaryKey(userId);
277    
278                    Set<Long> groupIdsSet = new HashSet<>();
279    
280                    String[] defaultGroupNames = PrefsPropsUtil.getStringArray(
281                            user.getCompanyId(), PropsKeys.ADMIN_DEFAULT_GROUP_NAMES,
282                            StringPool.NEW_LINE, PropsValues.ADMIN_DEFAULT_GROUP_NAMES);
283    
284                    for (String defaultGroupName : defaultGroupNames) {
285                            Company company = companyPersistence.findByPrimaryKey(
286                                    user.getCompanyId());
287    
288                            Account account = company.getAccount();
289    
290                            if (StringUtil.equalsIgnoreCase(
291                                            defaultGroupName, account.getName())) {
292    
293                                    defaultGroupName = GroupConstants.GUEST;
294                            }
295    
296                            Group group = groupPersistence.fetchByC_GK(
297                                    user.getCompanyId(), defaultGroupName);
298    
299                            if ((group != null) &&
300                                    !userPersistence.containsGroup(
301                                            userId, group.getGroupId())) {
302    
303                                    groupIdsSet.add(group.getGroupId());
304                            }
305                    }
306    
307                    String[] defaultOrganizationGroupNames = PrefsPropsUtil.getStringArray(
308                            user.getCompanyId(),
309                            PropsKeys.ADMIN_DEFAULT_ORGANIZATION_GROUP_NAMES,
310                            StringPool.NEW_LINE,
311                            PropsValues.ADMIN_DEFAULT_ORGANIZATION_GROUP_NAMES);
312    
313                    for (String defaultOrganizationGroupName :
314                                    defaultOrganizationGroupNames) {
315    
316                            defaultOrganizationGroupName +=
317                                    GroupLocalServiceImpl.ORGANIZATION_NAME_SUFFIX;
318    
319                            Group group = groupPersistence.fetchByC_GK(
320                                    user.getCompanyId(), defaultOrganizationGroupName);
321    
322                            if ((group != null) &&
323                                    !userPersistence.containsGroup(
324                                            userId, group.getGroupId())) {
325    
326                                    groupIdsSet.add(group.getGroupId());
327                            }
328                    }
329    
330                    long[] groupIds = ArrayUtil.toArray(
331                            groupIdsSet.toArray(new Long[groupIdsSet.size()]));
332    
333                    groupLocalService.addUserGroups(userId, groupIds);
334            }
335    
336            /**
337             * Adds the user to the default roles, unless the user already has these
338             * roles. The default roles can be specified in
339             * <code>portal.properties</code> with the key
340             * <code>admin.default.role.names</code>.
341             *
342             * @param userId the primary key of the user
343             */
344            @Override
345            public void addDefaultRoles(long userId) throws PortalException {
346                    User user = userPersistence.findByPrimaryKey(userId);
347    
348                    Set<Long> roleIdSet = new HashSet<>();
349    
350                    String[] defaultRoleNames = PrefsPropsUtil.getStringArray(
351                            user.getCompanyId(), PropsKeys.ADMIN_DEFAULT_ROLE_NAMES,
352                            StringPool.NEW_LINE, PropsValues.ADMIN_DEFAULT_ROLE_NAMES);
353    
354                    for (String defaultRoleName : defaultRoleNames) {
355                            Role role = rolePersistence.fetchByC_N(
356                                    user.getCompanyId(), defaultRoleName);
357    
358                            if ((role != null) &&
359                                    !userPersistence.containsRole(userId, role.getRoleId())) {
360    
361                                    roleIdSet.add(role.getRoleId());
362                            }
363                    }
364    
365                    Set<Long> groupRoleIdsSet = new HashSet<>();
366                    Set<Long> regularRoleIdsSet = new HashSet<>();
367    
368                    long[] roleIds = ArrayUtil.toLongArray(roleIdSet);
369    
370                    roleIds = UsersAdminUtil.addRequiredRoles(user, roleIds);
371    
372                    for (long roleId : roleIds) {
373                            Role role = roleLocalService.getRole(roleId);
374    
375                            if (role.getType() == RoleConstants.TYPE_REGULAR) {
376                                    regularRoleIdsSet.add(roleId);
377                            }
378                            else {
379                                    groupRoleIdsSet.add(roleId);
380                            }
381                    }
382    
383                    long[] regularRoleIds = ArrayUtil.toLongArray(regularRoleIdsSet);
384    
385                    userPersistence.addRoles(userId, regularRoleIds);
386    
387                    Set<UserGroupRole> userGroupRolesSet = new LinkedHashSet<>();
388    
389                    long[] groupIds = user.getGroupIds();
390    
391                    for (long groupRoleId : groupRoleIdsSet) {
392                            for (long groupId : groupIds) {
393                                    UserGroupRolePK userGroupRolePK = new UserGroupRolePK(
394                                            userId, groupId, groupRoleId);
395    
396                                    UserGroupRole userGroupRole = userGroupRolePersistence.create(
397                                            userGroupRolePK);
398    
399                                    userGroupRolesSet.add(userGroupRole);
400                            }
401                    }
402    
403                    List<UserGroupRole> previousUserGroupRoles =
404                            userGroupRolePersistence.findByUserId(userId);
405    
406                    updateUserGroupRoles(
407                            user, groupIds, null, new ArrayList<>(userGroupRolesSet),
408                            previousUserGroupRoles);
409            }
410    
411            /**
412             * Adds the user to the default user groups, unless the user is already in
413             * these user groups. The default user groups can be specified in
414             * <code>portal.properties</code> with the property
415             * <code>admin.default.user.group.names</code>.
416             *
417             * @param userId the primary key of the user
418             */
419            @Override
420            @SuppressWarnings("deprecation")
421            public void addDefaultUserGroups(long userId) throws PortalException {
422                    User user = userPersistence.findByPrimaryKey(userId);
423    
424                    Set<Long> userGroupIdSet = new HashSet<>();
425    
426                    String[] defaultUserGroupNames = PrefsPropsUtil.getStringArray(
427                            user.getCompanyId(), PropsKeys.ADMIN_DEFAULT_USER_GROUP_NAMES,
428                            StringPool.NEW_LINE, PropsValues.ADMIN_DEFAULT_USER_GROUP_NAMES);
429    
430                    for (String defaultUserGroupName : defaultUserGroupNames) {
431                            UserGroup userGroup = userGroupPersistence.fetchByC_N(
432                                    user.getCompanyId(), defaultUserGroupName);
433    
434                            if ((userGroup != null) &&
435                                    !userPersistence.containsUserGroup(
436                                            userId, userGroup.getUserGroupId())) {
437    
438                                    userGroupIdSet.add(userGroup.getUserGroupId());
439                            }
440                    }
441    
442                    long[] userGroupIds = ArrayUtil.toArray(
443                            userGroupIdSet.toArray(new Long[userGroupIdSet.size()]));
444    
445                    if (PropsValues.USER_GROUPS_COPY_LAYOUTS_TO_USER_PERSONAL_SITE) {
446                            for (long userGroupId : userGroupIds) {
447                                    userGroupLocalService.copyUserGroupLayouts(userGroupId, userId);
448                            }
449                    }
450    
451                    userPersistence.addUserGroups(userId, userGroupIds);
452            }
453    
454            /**
455             * Adds the users to the group.
456             *
457             * @param groupId the primary key of the group
458             * @param userIds the primary keys of the users
459             */
460            @Override
461            public void addGroupUsers(long groupId, long[] userIds)
462                    throws PortalException {
463    
464                    groupPersistence.addUsers(groupId, userIds);
465    
466                    reindex(userIds);
467    
468                    PermissionCacheUtil.clearCache(userIds);
469    
470                    addDefaultRolesAndTeams(groupId, userIds);
471            }
472    
473            /**
474             * Adds the users to the organization.
475             *
476             * @param organizationId the primary key of the organization
477             * @param userIds the primary keys of the users
478             */
479            @Override
480            public void addOrganizationUsers(long organizationId, long[] userIds)
481                    throws PortalException {
482    
483                    organizationPersistence.addUsers(organizationId, userIds);
484    
485                    reindex(userIds);
486    
487                    PermissionCacheUtil.clearCache(userIds);
488            }
489    
490            /**
491             * Assigns the password policy to the users, removing any other currently
492             * assigned password policies.
493             *
494             * @param passwordPolicyId the primary key of the password policy
495             * @param userIds the primary keys of the users
496             */
497            @Override
498            public void addPasswordPolicyUsers(long passwordPolicyId, long[] userIds) {
499                    passwordPolicyRelLocalService.addPasswordPolicyRels(
500                            passwordPolicyId, User.class.getName(), userIds);
501            }
502    
503            /**
504             * Adds the users to the role.
505             *
506             * @param roleId the primary key of the role
507             * @param userIds the primary keys of the users
508             */
509            @Override
510            public void addRoleUsers(long roleId, long[] userIds)
511                    throws PortalException {
512    
513                    rolePersistence.addUsers(roleId, userIds);
514    
515                    reindex(userIds);
516    
517                    PermissionCacheUtil.clearCache(userIds);
518            }
519    
520            /**
521             * Adds the users to the team.
522             *
523             * @param teamId the primary key of the team
524             * @param userIds the primary keys of the users
525             */
526            @Override
527            public void addTeamUsers(long teamId, long[] userIds)
528                    throws PortalException {
529    
530                    teamPersistence.addUsers(teamId, userIds);
531    
532                    reindex(userIds);
533    
534                    PermissionCacheUtil.clearCache(userIds);
535            }
536    
537            /**
538             * Adds a user.
539             *
540             * <p>
541             * This method handles the creation and bookkeeping of the user including
542             * its resources, metadata, and internal data structures. It is not
543             * necessary to make subsequent calls to any methods to setup default
544             * groups, resources, etc.
545             * </p>
546             *
547             * @param  creatorUserId the primary key of the creator
548             * @param  companyId the primary key of the user's company
549             * @param  autoPassword whether a password should be automatically generated
550             *         for the user
551             * @param  password1 the user's password
552             * @param  password2 the user's password confirmation
553             * @param  autoScreenName whether a screen name should be automatically
554             *         generated for the user
555             * @param  screenName the user's screen name
556             * @param  emailAddress the user's email address
557             * @param  facebookId the user's facebook ID
558             * @param  openId the user's OpenID
559             * @param  locale the user's locale
560             * @param  firstName the user's first name
561             * @param  middleName the user's middle name
562             * @param  lastName the user's last name
563             * @param  prefixId the user's name prefix ID
564             * @param  suffixId the user's name suffix ID
565             * @param  male whether the user is male
566             * @param  birthdayMonth the user's birthday month (0-based, meaning 0 for
567             *         January)
568             * @param  birthdayDay the user's birthday day
569             * @param  birthdayYear the user's birthday year
570             * @param  jobTitle the user's job title
571             * @param  groupIds the primary keys of the user's groups
572             * @param  organizationIds the primary keys of the user's organizations
573             * @param  roleIds the primary keys of the roles this user possesses
574             * @param  userGroupIds the primary keys of the user's user groups
575             * @param  sendEmail whether to send the user an email notification about
576             *         their new account
577             * @param  serviceContext the service context to be applied (optionally
578             *         <code>null</code>). Can set the UUID (with the <code>uuid</code>
579             *         attribute), asset category IDs, asset tag names, and expando
580             *         bridge attributes for the user.
581             * @return the new user
582             */
583            @Override
584            public User addUser(
585                            long creatorUserId, long companyId, boolean autoPassword,
586                            String password1, String password2, boolean autoScreenName,
587                            String screenName, String emailAddress, long facebookId,
588                            String openId, Locale locale, String firstName, String middleName,
589                            String lastName, long prefixId, long suffixId, boolean male,
590                            int birthdayMonth, int birthdayDay, int birthdayYear,
591                            String jobTitle, long[] groupIds, long[] organizationIds,
592                            long[] roleIds, long[] userGroupIds, boolean sendEmail,
593                            ServiceContext serviceContext)
594                    throws PortalException {
595    
596                    boolean workflowEnabled = WorkflowThreadLocal.isEnabled();
597    
598                    try {
599                            WorkflowThreadLocal.setEnabled(false);
600    
601                            if (serviceContext == null) {
602                                    serviceContext = new ServiceContext();
603                            }
604    
605                            if (serviceContext.getWorkflowAction() !=
606                                            WorkflowConstants.ACTION_PUBLISH) {
607    
608                                    serviceContext.setWorkflowAction(
609                                            WorkflowConstants.ACTION_PUBLISH);
610                            }
611    
612                            return addUserWithWorkflow(
613                                    creatorUserId, companyId, autoPassword, password1, password2,
614                                    autoScreenName, screenName, emailAddress, facebookId, openId,
615                                    locale, firstName, middleName, lastName, prefixId, suffixId,
616                                    male, birthdayMonth, birthdayDay, birthdayYear, jobTitle,
617                                    groupIds, organizationIds, roleIds, userGroupIds, sendEmail,
618                                    serviceContext);
619                    }
620                    finally {
621                            WorkflowThreadLocal.setEnabled(workflowEnabled);
622                    }
623            }
624    
625            /**
626             * Adds the users to the user group.
627             *
628             * @param userGroupId the primary key of the user group
629             * @param userIds the primary keys of the users
630             */
631            @Override
632            @SuppressWarnings("deprecation")
633            public void addUserGroupUsers(long userGroupId, long[] userIds)
634                    throws PortalException {
635    
636                    if (PropsValues.USER_GROUPS_COPY_LAYOUTS_TO_USER_PERSONAL_SITE) {
637                            userGroupLocalService.copyUserGroupLayouts(userGroupId, userIds);
638                    }
639    
640                    userGroupPersistence.addUsers(userGroupId, userIds);
641    
642                    reindex(userIds);
643    
644                    PermissionCacheUtil.clearCache(userIds);
645            }
646    
647            /**
648             * Adds a user with workflow.
649             *
650             * <p>
651             * This method handles the creation and bookkeeping of the user including
652             * its resources, metadata, and internal data structures. It is not
653             * necessary to make subsequent calls to any methods to setup default
654             * groups, resources, etc.
655             * </p>
656             *
657             * @param  creatorUserId the primary key of the creator
658             * @param  companyId the primary key of the user's company
659             * @param  autoPassword whether a password should be automatically generated
660             *         for the user
661             * @param  password1 the user's password
662             * @param  password2 the user's password confirmation
663             * @param  autoScreenName whether a screen name should be automatically
664             *         generated for the user
665             * @param  screenName the user's screen name
666             * @param  emailAddress the user's email address
667             * @param  facebookId the user's facebook ID
668             * @param  openId the user's OpenID
669             * @param  locale the user's locale
670             * @param  firstName the user's first name
671             * @param  middleName the user's middle name
672             * @param  lastName the user's last name
673             * @param  prefixId the user's name prefix ID
674             * @param  suffixId the user's name suffix ID
675             * @param  male whether the user is male
676             * @param  birthdayMonth the user's birthday month (0-based, meaning 0 for
677             *         January)
678             * @param  birthdayDay the user's birthday day
679             * @param  birthdayYear the user's birthday year
680             * @param  jobTitle the user's job title
681             * @param  groupIds the primary keys of the user's groups
682             * @param  organizationIds the primary keys of the user's organizations
683             * @param  roleIds the primary keys of the roles this user possesses
684             * @param  userGroupIds the primary keys of the user's user groups
685             * @param  sendEmail whether to send the user an email notification about
686             *         their new account
687             * @param  serviceContext the service context to be applied (optionally
688             *         <code>null</code>). Can set the UUID (with the <code>uuid</code>
689             *         attribute), asset category IDs, asset tag names, and expando
690             *         bridge attributes for the user.
691             * @return the new user
692             */
693            @Override
694            @SuppressWarnings("deprecation")
695            public User addUserWithWorkflow(
696                            long creatorUserId, long companyId, boolean autoPassword,
697                            String password1, String password2, boolean autoScreenName,
698                            String screenName, String emailAddress, long facebookId,
699                            String openId, Locale locale, String firstName, String middleName,
700                            String lastName, long prefixId, long suffixId, boolean male,
701                            int birthdayMonth, int birthdayDay, int birthdayYear,
702                            String jobTitle, long[] groupIds, long[] organizationIds,
703                            long[] roleIds, long[] userGroupIds, boolean sendEmail,
704                            ServiceContext serviceContext)
705                    throws PortalException {
706    
707                    // User
708    
709                    Company company = companyPersistence.findByPrimaryKey(companyId);
710                    screenName = getLogin(screenName);
711                    openId = StringUtil.trim(openId);
712    
713                    if (PrefsPropsUtil.getBoolean(
714                                    companyId, PropsKeys.USERS_SCREEN_NAME_ALWAYS_AUTOGENERATE)) {
715    
716                            autoScreenName = true;
717                    }
718    
719                    // PLACEHOLDER 01
720    
721                    long userId = counterLocalService.increment();
722    
723                    EmailAddressGenerator emailAddressGenerator =
724                            EmailAddressGeneratorFactory.getInstance();
725    
726                    if ((emailAddress == null) ||
727                            emailAddressGenerator.isGenerated(emailAddress)) {
728    
729                            emailAddress = StringPool.BLANK;
730                    }
731                    else {
732                            emailAddress = StringUtil.toLowerCase(emailAddress.trim());
733                    }
734    
735                    if (!PrefsPropsUtil.getBoolean(
736                                    companyId, PropsKeys.USERS_EMAIL_ADDRESS_REQUIRED) &&
737                            Validator.isNull(emailAddress)) {
738    
739                            emailAddress = emailAddressGenerator.generate(companyId, userId);
740                    }
741    
742                    validate(
743                            companyId, userId, autoPassword, password1, password2,
744                            autoScreenName, screenName, emailAddress, openId, firstName,
745                            middleName, lastName, organizationIds, locale);
746    
747                    if (!autoPassword) {
748                            if (Validator.isNull(password1) || Validator.isNull(password2)) {
749                                    throw new UserPasswordException.MustNotBeNull(userId);
750                            }
751                    }
752    
753                    if (autoScreenName) {
754                            ScreenNameGenerator screenNameGenerator =
755                                    ScreenNameGeneratorFactory.getInstance();
756    
757                            try {
758                                    screenName = screenNameGenerator.generate(
759                                            companyId, userId, emailAddress);
760                            }
761                            catch (Exception e) {
762                                    throw new SystemException(e);
763                            }
764                    }
765    
766                    User defaultUser = getDefaultUser(companyId);
767    
768                    FullNameGenerator fullNameGenerator =
769                            FullNameGeneratorFactory.getInstance();
770    
771                    String fullName = fullNameGenerator.getFullName(
772                            firstName, middleName, lastName);
773    
774                    String greeting = LanguageUtil.format(
775                            locale, "welcome-x", fullName, false);
776    
777                    User user = userPersistence.create(userId);
778    
779                    if (serviceContext != null) {
780                            String uuid = serviceContext.getUuid();
781    
782                            if (Validator.isNotNull(uuid)) {
783                                    user.setUuid(uuid);
784                            }
785                    }
786    
787                    user.setCompanyId(companyId);
788                    user.setDefaultUser(false);
789                    user.setContactId(counterLocalService.increment());
790    
791                    if (Validator.isNotNull(password1)) {
792                            user.setPassword(PasswordEncryptorUtil.encrypt(password1));
793                            user.setPasswordUnencrypted(password1);
794                    }
795    
796                    user.setPasswordEncrypted(true);
797    
798                    PasswordPolicy passwordPolicy = defaultUser.getPasswordPolicy();
799    
800                    if ((passwordPolicy != null) && passwordPolicy.isChangeable() &&
801                            passwordPolicy.isChangeRequired()) {
802    
803                            user.setPasswordReset(true);
804                    }
805                    else {
806                            user.setPasswordReset(false);
807                    }
808    
809                    user.setDigest(StringPool.BLANK);
810                    user.setScreenName(screenName);
811                    user.setEmailAddress(emailAddress);
812                    user.setFacebookId(facebookId);
813    
814                    Long ldapServerId = null;
815    
816                    if (serviceContext != null) {
817                            ldapServerId = (Long)serviceContext.getAttribute("ldapServerId");
818                    }
819    
820                    if (ldapServerId != null) {
821                            user.setLdapServerId(ldapServerId);
822                    }
823                    else {
824                            user.setLdapServerId(-1);
825                    }
826    
827                    user.setOpenId(openId);
828                    user.setLanguageId(LocaleUtil.toLanguageId(locale));
829                    user.setTimeZoneId(defaultUser.getTimeZoneId());
830                    user.setGreeting(greeting);
831                    user.setFirstName(firstName);
832                    user.setMiddleName(middleName);
833                    user.setLastName(lastName);
834                    user.setJobTitle(jobTitle);
835                    user.setStatus(WorkflowConstants.STATUS_DRAFT);
836                    user.setExpandoBridgeAttributes(serviceContext);
837    
838                    userPersistence.update(user, serviceContext);
839    
840                    // Contact
841    
842                    String creatorUserName = StringPool.BLANK;
843    
844                    if (creatorUserId <= 0) {
845                            creatorUserId = user.getUserId();
846    
847                            // Don't grab the full name from the User object because it doesn't
848                            // have a corresponding Contact object yet
849    
850                            //creatorUserName = user.getFullName();
851                    }
852                    else {
853                            User creatorUser = userPersistence.findByPrimaryKey(creatorUserId);
854    
855                            creatorUserName = creatorUser.getFullName();
856                    }
857    
858                    Date birthday = getBirthday(birthdayMonth, birthdayDay, birthdayYear);
859    
860                    Contact contact = contactPersistence.create(user.getContactId());
861    
862                    contact.setCompanyId(user.getCompanyId());
863                    contact.setUserId(creatorUserId);
864                    contact.setUserName(creatorUserName);
865                    contact.setClassName(User.class.getName());
866                    contact.setClassPK(user.getUserId());
867                    contact.setAccountId(company.getAccountId());
868                    contact.setParentContactId(ContactConstants.DEFAULT_PARENT_CONTACT_ID);
869                    contact.setEmailAddress(user.getEmailAddress());
870                    contact.setFirstName(firstName);
871                    contact.setMiddleName(middleName);
872                    contact.setLastName(lastName);
873                    contact.setPrefixId(prefixId);
874                    contact.setSuffixId(suffixId);
875                    contact.setMale(male);
876                    contact.setBirthday(birthday);
877                    contact.setJobTitle(jobTitle);
878    
879                    contactPersistence.update(contact, serviceContext);
880    
881                    // Group
882    
883                    groupLocalService.addGroup(
884                            user.getUserId(), GroupConstants.DEFAULT_PARENT_GROUP_ID,
885                            User.class.getName(), user.getUserId(),
886                            GroupConstants.DEFAULT_LIVE_GROUP_ID, (Map<Locale, String>)null,
887                            null, 0, true, GroupConstants.DEFAULT_MEMBERSHIP_RESTRICTION,
888                            StringPool.SLASH + screenName, false, true, null);
889    
890                    // Groups
891    
892                    if (groupIds != null) {
893                            List<Group> groups = new ArrayList<>();
894    
895                            for (long groupId : groupIds) {
896                                    Group group = groupLocalService.fetchGroup(groupId);
897    
898                                    if (group != null) {
899                                            groups.add(group);
900                                    }
901                                    else {
902                                            if (_log.isWarnEnabled()) {
903                                                    _log.warn("Group " + groupId + " does not exist");
904                                            }
905                                    }
906                            }
907    
908                            groupLocalService.addUserGroups(userId, groups);
909                    }
910    
911                    addDefaultGroups(userId);
912    
913                    // Organizations
914    
915                    updateOrganizations(userId, organizationIds, false);
916    
917                    // Roles
918    
919                    if (roleIds != null) {
920                            roleIds = UsersAdminUtil.addRequiredRoles(user, roleIds);
921    
922                            userPersistence.setRoles(userId, roleIds);
923                    }
924    
925                    addDefaultRoles(userId);
926    
927                    // User groups
928    
929                    if (userGroupIds != null) {
930                            if (PropsValues.USER_GROUPS_COPY_LAYOUTS_TO_USER_PERSONAL_SITE) {
931                                    for (long userGroupId : userGroupIds) {
932                                            userGroupLocalService.copyUserGroupLayouts(
933                                                    userGroupId, new long[] {userId});
934                                    }
935                            }
936    
937                            userPersistence.setUserGroups(userId, userGroupIds);
938                    }
939    
940                    addDefaultUserGroups(userId);
941    
942                    // Resources
943    
944                    resourceLocalService.addResources(
945                            companyId, 0, creatorUserId, User.class.getName(), user.getUserId(),
946                            false, false, false);
947    
948                    // Asset
949    
950                    if (serviceContext != null) {
951                            updateAsset(
952                                    creatorUserId, user, serviceContext.getAssetCategoryIds(),
953                                    serviceContext.getAssetTagNames());
954                    }
955    
956                    // Indexer
957    
958                    if ((serviceContext == null) || serviceContext.isIndexingEnabled()) {
959                            reindex(user);
960                    }
961    
962                    // Workflow
963    
964                    long workflowUserId = creatorUserId;
965    
966                    if (workflowUserId == userId) {
967                            workflowUserId = defaultUser.getUserId();
968                    }
969    
970                    ServiceContext workflowServiceContext = serviceContext;
971    
972                    if (workflowServiceContext == null) {
973                            workflowServiceContext = new ServiceContext();
974                    }
975    
976                    workflowServiceContext.setAttribute("autoPassword", autoPassword);
977                    workflowServiceContext.setAttribute("passwordUnencrypted", password1);
978                    workflowServiceContext.setAttribute("sendEmail", sendEmail);
979    
980                    WorkflowHandlerRegistryUtil.startWorkflowInstance(
981                            companyId, workflowUserId, User.class.getName(), userId, user,
982                            workflowServiceContext);
983    
984                    if (serviceContext != null) {
985                            String passwordUnencrypted = (String)serviceContext.getAttribute(
986                                    "passwordUnencrypted");
987    
988                            if (Validator.isNotNull(passwordUnencrypted)) {
989                                    user.setPasswordUnencrypted(passwordUnencrypted);
990                            }
991                    }
992    
993                    return user;
994            }
995    
996            @Override
997            public void afterPropertiesSet() {
998                    super.afterPropertiesSet();
999    
1000                    PortalCache<Serializable, Serializable> portalCache =
1001                            EntityCacheUtil.getPortalCache(UserImpl.class);
1002    
1003                    PortalCacheMapSynchronizeUtil.synchronize(
1004                            portalCache, _defaultUsers,
1005                            new Synchronizer<Serializable, Serializable>() {
1006    
1007                                    @Override
1008                                    public void onSynchronize(
1009                                            Map<? extends Serializable, ? extends Serializable> map,
1010                                            Serializable key, Serializable value, int timeToLive) {
1011    
1012                                            if (!(value instanceof UserCacheModel)) {
1013                                                    return;
1014                                            }
1015    
1016                                            UserCacheModel userCacheModel = (UserCacheModel)value;
1017    
1018                                            if (userCacheModel.defaultUser) {
1019                                                    _defaultUsers.remove(userCacheModel.companyId);
1020                                            }
1021                                    }
1022    
1023                            });
1024            }
1025    
1026            /**
1027             * Attempts to authenticate the user by their email address and password,
1028             * while using the AuthPipeline.
1029             *
1030             * @param  companyId the primary key of the user's company
1031             * @param  emailAddress the user's email address
1032             * @param  password the user's password
1033             * @param  headerMap the header map from the authentication request
1034             * @param  parameterMap the parameter map from the authentication request
1035             * @param  resultsMap the map of authentication results (may be nil). After
1036             *         a successful authentication the user's primary key will be placed
1037             *         under the key <code>userId</code>.
1038             * @return the authentication status. This can be {@link
1039             *         Authenticator#FAILURE} indicating that the user's credentials are
1040             *         invalid, {@link Authenticator#SUCCESS} indicating a successful
1041             *         login, or {@link Authenticator#DNE} indicating that a user with
1042             *         that login does not exist.
1043             * @see    AuthPipeline
1044             */
1045            @Override
1046            public int authenticateByEmailAddress(
1047                            long companyId, String emailAddress, String password,
1048                            Map<String, String[]> headerMap, Map<String, String[]> parameterMap,
1049                            Map<String, Object> resultsMap)
1050                    throws PortalException {
1051    
1052                    return authenticate(
1053                            companyId, emailAddress, password, CompanyConstants.AUTH_TYPE_EA,
1054                            headerMap, parameterMap, resultsMap);
1055            }
1056    
1057            /**
1058             * Attempts to authenticate the user by their screen name and password,
1059             * while using the AuthPipeline.
1060             *
1061             * @param  companyId the primary key of the user's company
1062             * @param  screenName the user's screen name
1063             * @param  password the user's password
1064             * @param  headerMap the header map from the authentication request
1065             * @param  parameterMap the parameter map from the authentication request
1066             * @param  resultsMap the map of authentication results (may be nil). After
1067             *         a successful authentication the user's primary key will be placed
1068             *         under the key <code>userId</code>.
1069             * @return the authentication status. This can be {@link
1070             *         Authenticator#FAILURE} indicating that the user's credentials are
1071             *         invalid, {@link Authenticator#SUCCESS} indicating a successful
1072             *         login, or {@link Authenticator#DNE} indicating that a user with
1073             *         that login does not exist.
1074             * @see    AuthPipeline
1075             */
1076            @Override
1077            public int authenticateByScreenName(
1078                            long companyId, String screenName, String password,
1079                            Map<String, String[]> headerMap, Map<String, String[]> parameterMap,
1080                            Map<String, Object> resultsMap)
1081                    throws PortalException {
1082    
1083                    return authenticate(
1084                            companyId, screenName, password, CompanyConstants.AUTH_TYPE_SN,
1085                            headerMap, parameterMap, resultsMap);
1086            }
1087    
1088            /**
1089             * Attempts to authenticate the user by their primary key and password,
1090             * while using the AuthPipeline.
1091             *
1092             * @param  companyId the primary key of the user's company
1093             * @param  userId the user's primary key
1094             * @param  password the user's password
1095             * @param  headerMap the header map from the authentication request
1096             * @param  parameterMap the parameter map from the authentication request
1097             * @param  resultsMap the map of authentication results (may be nil). After
1098             *         a successful authentication the user's primary key will be placed
1099             *         under the key <code>userId</code>.
1100             * @return the authentication status. This can be {@link
1101             *         Authenticator#FAILURE} indicating that the user's credentials are
1102             *         invalid, {@link Authenticator#SUCCESS} indicating a successful
1103             *         login, or {@link Authenticator#DNE} indicating that a user with
1104             *         that login does not exist.
1105             * @see    AuthPipeline
1106             */
1107            @Override
1108            public int authenticateByUserId(
1109                            long companyId, long userId, String password,
1110                            Map<String, String[]> headerMap, Map<String, String[]> parameterMap,
1111                            Map<String, Object> resultsMap)
1112                    throws PortalException {
1113    
1114                    return authenticate(
1115                            companyId, String.valueOf(userId), password,
1116                            CompanyConstants.AUTH_TYPE_ID, headerMap, parameterMap, resultsMap);
1117            }
1118    
1119            /**
1120             * Attempts to authenticate the user using HTTP basic access authentication,
1121             * without using the AuthPipeline. Primarily used for authenticating users
1122             * of <code>tunnel-web</code>.
1123             *
1124             * <p>
1125             * Authentication type specifies what <code>login</code> contains.The valid
1126             * values are:
1127             * </p>
1128             *
1129             * <ul>
1130             * <li>
1131             * <code>CompanyConstants.AUTH_TYPE_EA</code> - <code>login</code> is the
1132             * user's email address
1133             * </li>
1134             * <li>
1135             * <code>CompanyConstants.AUTH_TYPE_SN</code> - <code>login</code> is the
1136             * user's screen name
1137             * </li>
1138             * <li>
1139             * <code>CompanyConstants.AUTH_TYPE_ID</code> - <code>login</code> is the
1140             * user's primary key
1141             * </li>
1142             * </ul>
1143             *
1144             * @param  companyId the primary key of the user's company
1145             * @param  authType the type of authentication to perform
1146             * @param  login either the user's email address, screen name, or primary
1147             *         key depending on the value of <code>authType</code>
1148             * @param  password the user's password
1149             * @return the user's primary key if authentication is successful;
1150             *         <code>0</code> otherwise
1151             */
1152            @Override
1153            @Transactional(propagation = Propagation.SUPPORTS)
1154            public long authenticateForBasic(
1155                            long companyId, String authType, String login, String password)
1156                    throws PortalException {
1157    
1158                    if (PropsValues.AUTH_LOGIN_DISABLED) {
1159                            return 0;
1160                    }
1161    
1162                    User user = null;
1163    
1164                    if (authType.equals(CompanyConstants.AUTH_TYPE_EA)) {
1165                            user = fetchUserByEmailAddress(companyId, login);
1166                    }
1167                    else if (authType.equals(CompanyConstants.AUTH_TYPE_SN)) {
1168                            user = fetchUserByScreenName(companyId, login);
1169                    }
1170                    else if (authType.equals(CompanyConstants.AUTH_TYPE_ID)) {
1171                            user = userPersistence.fetchByPrimaryKey(GetterUtil.getLong(login));
1172                    }
1173    
1174                    if (user == null) {
1175                            return 0;
1176                    }
1177    
1178                    if (!isUserAllowedToAuthenticate(user)) {
1179                            return 0;
1180                    }
1181    
1182                    if (!PropsValues.BASIC_AUTH_PASSWORD_REQUIRED) {
1183                            return user.getUserId();
1184                    }
1185    
1186                    String userPassword = user.getPassword();
1187    
1188                    if (!user.isPasswordEncrypted()) {
1189                            userPassword = PasswordEncryptorUtil.encrypt(userPassword);
1190                    }
1191    
1192                    String encPassword = PasswordEncryptorUtil.encrypt(
1193                            password, userPassword);
1194    
1195                    if (userPassword.equals(password) || userPassword.equals(encPassword)) {
1196                            resetFailedLoginAttempts(user);
1197    
1198                            return user.getUserId();
1199                    }
1200    
1201                    handleAuthenticationFailure(
1202                            login, authType, user, Collections.<String, String[]>emptyMap(),
1203                            Collections.<String, String[]>emptyMap());
1204    
1205                    return 0;
1206            }
1207    
1208            /**
1209             * Attempts to authenticate the user using HTTP digest access
1210             * authentication, without using the AuthPipeline. Primarily used for
1211             * authenticating users of <code>tunnel-web</code>.
1212             *
1213             * @param  companyId the primary key of the user's company
1214             * @param  username either the user's email address, screen name, or primary
1215             *         key
1216             * @param  realm unused
1217             * @param  nonce the number used once
1218             * @param  method the request method
1219             * @param  uri the request URI
1220             * @param  response the authentication response hash
1221             * @return the user's primary key if authentication is successful;
1222             *         <code>0</code> otherwise
1223             */
1224            @Override
1225            @Transactional(propagation = Propagation.SUPPORTS)
1226            public long authenticateForDigest(
1227                            long companyId, String username, String realm, String nonce,
1228                            String method, String uri, String response)
1229                    throws PortalException {
1230    
1231                    if (PropsValues.AUTH_LOGIN_DISABLED) {
1232                            return 0;
1233                    }
1234    
1235                    // Get User
1236    
1237                    User user = fetchUserByEmailAddress(companyId, username);
1238    
1239                    if (user == null) {
1240                            user = fetchUserByScreenName(companyId, username);
1241                    }
1242    
1243                    if (user == null) {
1244                            user = userPersistence.fetchByPrimaryKey(
1245                                    GetterUtil.getLong(username));
1246                    }
1247    
1248                    if (user == null) {
1249                            return 0;
1250                    }
1251    
1252                    if (!isUserAllowedToAuthenticate(user)) {
1253                            return 0;
1254                    }
1255    
1256                    // Verify digest
1257    
1258                    String digest = user.getDigest();
1259    
1260                    if (Validator.isNull(digest)) {
1261                            _log.error(
1262                                    "User must first login through the portal " + user.getUserId());
1263    
1264                            return 0;
1265                    }
1266    
1267                    String[] digestArray = StringUtil.split(user.getDigest());
1268    
1269                    for (String ha1 : digestArray) {
1270                            String ha2 = DigesterUtil.digestHex(Digester.MD5, method, uri);
1271    
1272                            String curResponse = DigesterUtil.digestHex(
1273                                    Digester.MD5, ha1, nonce, ha2);
1274    
1275                            if (response.equals(curResponse)) {
1276                                    resetFailedLoginAttempts(user);
1277    
1278                                    return user.getUserId();
1279                            }
1280                    }
1281    
1282                    Company company = companyPersistence.findByPrimaryKey(companyId);
1283    
1284                    handleAuthenticationFailure(
1285                            username, company.getAuthType(), user,
1286                            new HashMap<String, String[]>(), new HashMap<String, String[]>());
1287    
1288                    return 0;
1289            }
1290    
1291            /**
1292             * Attempts to authenticate the user using JAAS credentials, without using
1293             * the AuthPipeline.
1294             *
1295             * @param  userId the primary key of the user
1296             * @param  encPassword the encrypted password
1297             * @return <code>true</code> if authentication is successful;
1298             *         <code>false</code> otherwise
1299             */
1300            @Override
1301            @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
1302            public boolean authenticateForJAAS(long userId, String encPassword) {
1303                    if (PropsValues.AUTH_LOGIN_DISABLED) {
1304                            return false;
1305                    }
1306    
1307                    try {
1308                            User user = userPersistence.findByPrimaryKey(userId);
1309    
1310                            if (user.isDefaultUser()) {
1311                                    if (_log.isInfoEnabled()) {
1312                                            _log.info(
1313                                                    "JAAS authentication is disabled for the default user");
1314                                    }
1315    
1316                                    return false;
1317                            }
1318                            else if (!user.isActive()) {
1319                                    if (_log.isInfoEnabled()) {
1320                                            _log.info(
1321                                                    "JAAS authentication is disabled for inactive user " +
1322                                                            userId);
1323                                    }
1324    
1325                                    return false;
1326                            }
1327    
1328                            String userPassword = user.getPassword();
1329    
1330                            if (user.isPasswordEncrypted()) {
1331                                    if (userPassword.equals(encPassword)) {
1332                                            return true;
1333                                    }
1334    
1335                                    if (!PropsValues.PORTAL_JAAS_STRICT_PASSWORD) {
1336                                            encPassword = PasswordEncryptorUtil.encrypt(
1337                                                    encPassword, userPassword);
1338    
1339                                            if (userPassword.equals(encPassword)) {
1340                                                    return true;
1341                                            }
1342                                    }
1343                            }
1344                            else {
1345                                    if (!PropsValues.PORTAL_JAAS_STRICT_PASSWORD) {
1346                                            if (userPassword.equals(encPassword)) {
1347                                                    return true;
1348                                            }
1349                                    }
1350    
1351                                    userPassword = PasswordEncryptorUtil.encrypt(
1352                                            userPassword, encPassword);
1353    
1354                                    if (userPassword.equals(encPassword)) {
1355                                            return true;
1356                                    }
1357                            }
1358                    }
1359                    catch (Exception e) {
1360                            _log.error(e);
1361                    }
1362    
1363                    return false;
1364            }
1365    
1366            /**
1367             * Checks if the user is currently locked out based on the password policy,
1368             * and performs maintenance on the user's lockout and failed login data.
1369             *
1370             * @param user the user
1371             */
1372            @Override
1373            public void checkLockout(User user) throws PortalException {
1374                    if (LDAPSettingsUtil.isPasswordPolicyEnabled(user.getCompanyId())) {
1375                            return;
1376                    }
1377    
1378                    PasswordPolicy passwordPolicy = user.getPasswordPolicy();
1379    
1380                    if (!passwordPolicy.isLockout()) {
1381                            return;
1382                    }
1383    
1384                    // Reset failure count
1385    
1386                    Date now = new Date();
1387                    int failedLoginAttempts = user.getFailedLoginAttempts();
1388    
1389                    if (failedLoginAttempts > 0) {
1390                            long failedLoginTime = user.getLastFailedLoginDate().getTime();
1391                            long elapsedTime = now.getTime() - failedLoginTime;
1392                            long requiredElapsedTime =
1393                                    passwordPolicy.getResetFailureCount() * 1000;
1394    
1395                            if ((requiredElapsedTime != 0) &&
1396                                    (elapsedTime > requiredElapsedTime)) {
1397    
1398                                    user.setFailedLoginAttempts(0);
1399    
1400                                    userPersistence.update(user);
1401                            }
1402                    }
1403    
1404                    // Reset lockout
1405    
1406                    if (user.isLockout()) {
1407                            long lockoutTime = user.getLockoutDate().getTime();
1408                            long elapsedTime = now.getTime() - lockoutTime;
1409                            long requiredElapsedTime =
1410                                    passwordPolicy.getLockoutDuration() * 1000;
1411    
1412                            if ((requiredElapsedTime != 0) &&
1413                                    (elapsedTime > requiredElapsedTime)) {
1414    
1415                                    user.setLockout(false);
1416                                    user.setLockoutDate(null);
1417    
1418                                    userPersistence.update(user);
1419                            }
1420                    }
1421    
1422                    if (user.isLockout()) {
1423                            throw new UserLockoutException.PasswordPolicyLockout(
1424                                    user, passwordPolicy);
1425                    }
1426            }
1427    
1428            /**
1429             * Adds a failed login attempt to the user and updates the user's last
1430             * failed login date.
1431             *
1432             * @param user the user
1433             */
1434            @Override
1435            public void checkLoginFailure(User user) {
1436                    int failedLoginAttempts = user.getFailedLoginAttempts();
1437    
1438                    user.setLastFailedLoginDate(new Date());
1439                    user.setFailedLoginAttempts(++failedLoginAttempts);
1440    
1441                    userPersistence.update(user);
1442            }
1443    
1444            /**
1445             * Adds a failed login attempt to the user with the email address and
1446             * updates the user's last failed login date.
1447             *
1448             * @param companyId the primary key of the user's company
1449             * @param emailAddress the user's email address
1450             */
1451            @Override
1452            public void checkLoginFailureByEmailAddress(
1453                            long companyId, String emailAddress)
1454                    throws PortalException {
1455    
1456                    User user = getUserByEmailAddress(companyId, emailAddress);
1457    
1458                    checkLoginFailure(user);
1459            }
1460    
1461            /**
1462             * Adds a failed login attempt to the user and updates the user's last
1463             * failed login date.
1464             *
1465             * @param userId the primary key of the user
1466             */
1467            @Override
1468            public void checkLoginFailureById(long userId) throws PortalException {
1469                    User user = userPersistence.findByPrimaryKey(userId);
1470    
1471                    checkLoginFailure(user);
1472            }
1473    
1474            /**
1475             * Adds a failed login attempt to the user with the screen name and updates
1476             * the user's last failed login date.
1477             *
1478             * @param companyId the primary key of the user's company
1479             * @param screenName the user's screen name
1480             */
1481            @Override
1482            public void checkLoginFailureByScreenName(long companyId, String screenName)
1483                    throws PortalException {
1484    
1485                    User user = getUserByScreenName(companyId, screenName);
1486    
1487                    checkLoginFailure(user);
1488            }
1489    
1490            /**
1491             * Checks if the user's password is expired based on the password policy,
1492             * and performs maintenance on the user's grace login and password reset
1493             * data.
1494             *
1495             * @param user the user
1496             */
1497            @Override
1498            public void checkPasswordExpired(User user) throws PortalException {
1499                    if (LDAPSettingsUtil.isPasswordPolicyEnabled(user.getCompanyId())) {
1500                            return;
1501                    }
1502    
1503                    PasswordPolicy passwordPolicy = user.getPasswordPolicy();
1504    
1505                    // Check if password has expired
1506    
1507                    if (isPasswordExpired(user)) {
1508                            int graceLoginCount = user.getGraceLoginCount();
1509    
1510                            if (graceLoginCount < passwordPolicy.getGraceLimit()) {
1511                                    user.setGraceLoginCount(++graceLoginCount);
1512    
1513                                    userPersistence.update(user);
1514                            }
1515                            else {
1516                                    user.setDigest(StringPool.BLANK);
1517    
1518                                    userPersistence.update(user);
1519    
1520                                    throw new PasswordExpiredException();
1521                            }
1522                    }
1523    
1524                    // Check if user should be forced to change password on first login
1525    
1526                    if (passwordPolicy.isChangeable() &&
1527                            passwordPolicy.isChangeRequired()) {
1528    
1529                            if (user.getLastLoginDate() == null) {
1530                                    user.setPasswordReset(true);
1531    
1532                                    userPersistence.update(user);
1533                            }
1534                    }
1535            }
1536    
1537            /**
1538             * Removes all the users from the organization.
1539             *
1540             * @param organizationId the primary key of the organization
1541             */
1542            @Override
1543            public void clearOrganizationUsers(long organizationId) {
1544                    organizationPersistence.clearUsers(organizationId);
1545    
1546                    PermissionCacheUtil.clearCache();
1547            }
1548    
1549            /**
1550             * Removes all the users from the user group.
1551             *
1552             * @param userGroupId the primary key of the user group
1553             */
1554            @Override
1555            public void clearUserGroupUsers(long userGroupId) {
1556                    userGroupPersistence.clearUsers(userGroupId);
1557    
1558                    PermissionCacheUtil.clearCache();
1559            }
1560    
1561            /**
1562             * Completes the user's registration by generating a password and sending
1563             * the confirmation email.
1564             *
1565             * @param user the user
1566             * @param serviceContext the service context to be applied. You can specify
1567             *        an unencrypted custom password for the user via attribute
1568             *        <code>passwordUnencrypted</code>. You automatically generate a
1569             *        password for the user by setting attribute
1570             *        <code>autoPassword</code> to <code>true</code>. You can send a
1571             *        confirmation email to the user by setting attribute
1572             *        <code>sendEmail</code> to <code>true</code>.
1573             */
1574            @Override
1575            public void completeUserRegistration(
1576                            User user, ServiceContext serviceContext)
1577                    throws PortalException {
1578    
1579                    boolean autoPassword = ParamUtil.getBoolean(
1580                            serviceContext, "autoPassword");
1581    
1582                    String password = (String)serviceContext.getAttribute(
1583                            "passwordUnencrypted");
1584    
1585                    if (autoPassword) {
1586                            if (LDAPSettingsUtil.isPasswordPolicyEnabled(user.getCompanyId())) {
1587                                    if (_log.isWarnEnabled()) {
1588                                            StringBundler sb = new StringBundler(4);
1589    
1590                                            sb.append("When LDAP password policy is enabled, it is ");
1591                                            sb.append("possible that portal generated passwords will ");
1592                                            sb.append("not match the LDAP policy. Using ");
1593                                            sb.append("RegExpToolkit to generate new password.");
1594    
1595                                            _log.warn(sb.toString());
1596                                    }
1597    
1598                                    RegExpToolkit regExpToolkit = new RegExpToolkit();
1599    
1600                                    password = regExpToolkit.generate(null);
1601                            }
1602                            else {
1603                                    PasswordPolicy passwordPolicy =
1604                                            passwordPolicyLocalService.getPasswordPolicy(
1605                                                    user.getCompanyId(), user.getOrganizationIds());
1606    
1607                                    password = PwdToolkitUtil.generate(passwordPolicy);
1608                            }
1609    
1610                            serviceContext.setAttribute("passwordUnencrypted", password);
1611    
1612                            user.setPassword(PasswordEncryptorUtil.encrypt(password));
1613                            user.setPasswordUnencrypted(password);
1614                            user.setPasswordEncrypted(true);
1615                            user.setPasswordModified(true);
1616                            user.setPasswordModifiedDate(new Date());
1617    
1618                            userPersistence.update(user);
1619    
1620                            user.setPasswordModified(false);
1621                    }
1622    
1623                    if (user.hasCompanyMx()) {
1624                            mailService.addUser(
1625                                    user.getCompanyId(), user.getUserId(), password,
1626                                    user.getFirstName(), user.getMiddleName(), user.getLastName(),
1627                                    user.getEmailAddress());
1628                    }
1629    
1630                    boolean sendEmail = ParamUtil.getBoolean(serviceContext, "sendEmail");
1631    
1632                    if (sendEmail) {
1633                            notifyUser(user, password, serviceContext);
1634                    }
1635    
1636                    Company company = companyPersistence.findByPrimaryKey(
1637                            user.getCompanyId());
1638    
1639                    if (company.isStrangersVerify()) {
1640                            sendEmailAddressVerification(
1641                                    user, user.getEmailAddress(), serviceContext);
1642                    }
1643            }
1644    
1645            /**
1646             * Decrypts the user's primary key and password from their encrypted forms.
1647             * Used for decrypting a user's credentials from the values stored in an
1648             * automatic login cookie.
1649             *
1650             * @param  companyId the primary key of the user's company
1651             * @param  name the encrypted primary key of the user
1652             * @param  password the encrypted password of the user
1653             * @return the user's primary key and password
1654             */
1655            @Override
1656            public KeyValuePair decryptUserId(
1657                            long companyId, String name, String password)
1658                    throws PortalException {
1659    
1660                    Company company = companyPersistence.findByPrimaryKey(companyId);
1661    
1662                    try {
1663                            name = Encryptor.decrypt(company.getKeyObj(), name);
1664                    }
1665                    catch (EncryptorException ee) {
1666                            throw new SystemException(ee);
1667                    }
1668    
1669                    long userId = GetterUtil.getLong(name);
1670    
1671                    User user = userPersistence.findByPrimaryKey(userId);
1672    
1673                    try {
1674                            password = Encryptor.decrypt(company.getKeyObj(), password);
1675                    }
1676                    catch (EncryptorException ee) {
1677                            throw new SystemException(ee);
1678                    }
1679    
1680                    String userPassword = user.getPassword();
1681                    String encPassword = PasswordEncryptorUtil.encrypt(
1682                            password, userPassword);
1683    
1684                    if (userPassword.equals(encPassword)) {
1685                            if (isPasswordExpired(user)) {
1686                                    user.setPasswordReset(true);
1687    
1688                                    userPersistence.update(user);
1689                            }
1690    
1691                            return new KeyValuePair(name, password);
1692                    }
1693                    else {
1694                            throw new PrincipalException.MustBeAuthenticated(userId);
1695                    }
1696            }
1697    
1698            /**
1699             * Deletes the user's portrait image.
1700             *
1701             * @param userId the primary key of the user
1702             */
1703            @Override
1704            public void deletePortrait(long userId) throws PortalException {
1705                    User user = userPersistence.findByPrimaryKey(userId);
1706    
1707                    PortalUtil.updateImageId(user, false, null, "portraitId", 0, 0, 0);
1708            }
1709    
1710            /**
1711             * Removes the user from the role.
1712             *
1713             * @param roleId the primary key of the role
1714             * @param userId the primary key of the user
1715             */
1716            @Override
1717            public void deleteRoleUser(long roleId, long userId)
1718                    throws PortalException {
1719    
1720                    rolePersistence.removeUser(roleId, userId);
1721    
1722                    reindex(userId);
1723    
1724                    PermissionCacheUtil.clearCache(userId);
1725            }
1726    
1727            /**
1728             * Deletes the user.
1729             *
1730             * @param  userId the primary key of the user
1731             * @return the deleted user
1732             */
1733            @Override
1734            public User deleteUser(long userId) throws PortalException {
1735                    User user = userPersistence.findByPrimaryKey(userId);
1736    
1737                    return deleteUser(user);
1738            }
1739    
1740            /**
1741             * Deletes the user.
1742             *
1743             * @param  user the user
1744             * @return the deleted user
1745             */
1746            @Override
1747            public User deleteUser(User user) throws PortalException {
1748                    if (!PropsValues.USERS_DELETE) {
1749                            throw new RequiredUserException();
1750                    }
1751    
1752                    // Browser tracker
1753    
1754                    browserTrackerLocalService.deleteUserBrowserTracker(user.getUserId());
1755    
1756                    // Group
1757    
1758                    Group group = null;
1759    
1760                    if (!user.isDefaultUser()) {
1761                            group = user.getGroup();
1762                    }
1763    
1764                    if (group != null) {
1765                            groupLocalService.deleteGroup(group);
1766                    }
1767    
1768                    // Portrait
1769    
1770                    try {
1771                            imageLocalService.deleteImage(user.getPortraitId());
1772                    }
1773                    catch (NoSuchImageException nsie) {
1774                            if (_log.isWarnEnabled()) {
1775                                    _log.warn(
1776                                            "Unable to delete image " + user.getPortraitId(), nsie);
1777                            }
1778                    }
1779    
1780                    // Password policy relation
1781    
1782                    passwordPolicyRelLocalService.deletePasswordPolicyRel(
1783                            User.class.getName(), user.getUserId());
1784    
1785                    // Old passwords
1786    
1787                    passwordTrackerLocalService.deletePasswordTrackers(user.getUserId());
1788    
1789                    // Subscriptions
1790    
1791                    subscriptionLocalService.deleteSubscriptions(user.getUserId());
1792    
1793                    // External user ids
1794    
1795                    userIdMapperLocalService.deleteUserIdMappers(user.getUserId());
1796    
1797                    // Announcements
1798    
1799                    announcementsDeliveryLocalService.deleteDeliveries(user.getUserId());
1800    
1801                    // Asset
1802    
1803                    assetEntryLocalService.deleteEntry(
1804                            User.class.getName(), user.getUserId());
1805    
1806                    // Blogs
1807    
1808                    blogsStatsUserLocalService.deleteStatsUserByUserId(user.getUserId());
1809    
1810                    // Document library
1811    
1812                    dlFileRankLocalService.deleteFileRanksByUserId(user.getUserId());
1813    
1814                    // Expando
1815    
1816                    expandoRowLocalService.deleteRows(user.getUserId());
1817    
1818                    // Message boards
1819    
1820                    mbBanLocalService.deleteBansByBanUserId(user.getUserId());
1821                    mbStatsUserLocalService.deleteStatsUsersByUserId(user.getUserId());
1822                    mbThreadFlagLocalService.deleteThreadFlagsByUserId(user.getUserId());
1823    
1824                    // Membership requests
1825    
1826                    membershipRequestLocalService.deleteMembershipRequestsByUserId(
1827                            user.getUserId());
1828    
1829                    // Ratings
1830    
1831                    ratingsStatsLocalService.deleteStats(
1832                            User.class.getName(), user.getUserId());
1833    
1834                    // Social
1835    
1836                    socialActivityLocalService.deleteUserActivities(user.getUserId());
1837                    socialRequestLocalService.deleteReceiverUserRequests(user.getUserId());
1838                    socialRequestLocalService.deleteUserRequests(user.getUserId());
1839    
1840                    // Mail
1841    
1842                    mailService.deleteUser(user.getCompanyId(), user.getUserId());
1843    
1844                    // Contact
1845    
1846                    Contact contact = contactLocalService.fetchContact(user.getContactId());
1847    
1848                    if (contact != null) {
1849                            contactLocalService.deleteContact(contact);
1850                    }
1851    
1852                    // Group roles
1853    
1854                    userGroupRoleLocalService.deleteUserGroupRolesByUserId(
1855                            user.getUserId());
1856    
1857                    // Resources
1858    
1859                    resourceLocalService.deleteResource(
1860                            user.getCompanyId(), User.class.getName(),
1861                            ResourceConstants.SCOPE_INDIVIDUAL, user.getUserId());
1862    
1863                    // User
1864    
1865                    userPersistence.remove(user);
1866    
1867                    // Permission cache
1868    
1869                    PermissionCacheUtil.clearCache(user.getUserId());
1870    
1871                    // Workflow
1872    
1873                    workflowInstanceLinkLocalService.deleteWorkflowInstanceLinks(
1874                            user.getCompanyId(), 0, User.class.getName(), user.getUserId());
1875    
1876                    return user;
1877            }
1878    
1879            /**
1880             * Removes the user from the user group.
1881             *
1882             * @param userGroupId the primary key of the user group
1883             * @param userId the primary key of the user
1884             */
1885            @Override
1886            public void deleteUserGroupUser(long userGroupId, long userId)
1887                    throws PortalException {
1888    
1889                    userGroupPersistence.removeUser(userGroupId, userId);
1890    
1891                    reindex(userId);
1892    
1893                    PermissionCacheUtil.clearCache(userId);
1894            }
1895    
1896            /**
1897             * Encrypts the primary key of the user. Used when encrypting the user's
1898             * credentials for storage in an automatic login cookie.
1899             *
1900             * @param  name the primary key of the user
1901             * @return the user's encrypted primary key
1902             */
1903            @Override
1904            @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
1905            public String encryptUserId(String name) throws PortalException {
1906                    long userId = GetterUtil.getLong(name);
1907    
1908                    User user = userPersistence.findByPrimaryKey(userId);
1909    
1910                    Company company = companyPersistence.findByPrimaryKey(
1911                            user.getCompanyId());
1912    
1913                    try {
1914                            return Encryptor.encrypt(company.getKeyObj(), name);
1915                    }
1916                    catch (EncryptorException ee) {
1917                            throw new SystemException(ee);
1918                    }
1919            }
1920    
1921            /**
1922             * Returns the user with the contact ID.
1923             *
1924             * @param  contactId the user's contact ID
1925             * @return the user with the contact ID, or <code>null</code> if a user with
1926             *         the contact ID could not be found
1927             */
1928            @Override
1929            public User fetchUserByContactId(long contactId) {
1930                    return userPersistence.fetchByContactId(contactId);
1931            }
1932    
1933            /**
1934             * Returns the user with the email address.
1935             *
1936             * @param  companyId the primary key of the user's company
1937             * @param  emailAddress the user's email address
1938             * @return the user with the email address, or <code>null</code> if a user
1939             *         with the email address could not be found
1940             */
1941            @Override
1942            public User fetchUserByEmailAddress(long companyId, String emailAddress) {
1943                    emailAddress = getLogin(emailAddress);
1944    
1945                    return userPersistence.fetchByC_EA(companyId, emailAddress);
1946            }
1947    
1948            /**
1949             * Returns the user with the Facebook ID.
1950             *
1951             * @param  companyId the primary key of the user's company
1952             * @param  facebookId the user's Facebook ID
1953             * @return the user with the Facebook ID, or <code>null</code> if a user
1954             *         with the Facebook ID could not be found
1955             */
1956            @Override
1957            public User fetchUserByFacebookId(long companyId, long facebookId) {
1958                    return userPersistence.fetchByC_FID(companyId, facebookId);
1959            }
1960    
1961            /**
1962             * Returns the user with the primary key.
1963             *
1964             * @param  userId the primary key of the user
1965             * @return the user with the primary key, or <code>null</code> if a user
1966             *         with the primary key could not be found
1967             */
1968            @Override
1969            public User fetchUserById(long userId) {
1970                    return userPersistence.fetchByPrimaryKey(userId);
1971            }
1972    
1973            /**
1974             * Returns the user with the OpenID.
1975             *
1976             * @param  companyId the primary key of the user's company
1977             * @param  openId the user's OpenID
1978             * @return the user with the OpenID, or <code>null</code> if a user with the
1979             *         OpenID could not be found
1980             */
1981            @Override
1982            public User fetchUserByOpenId(long companyId, String openId) {
1983                    return userPersistence.fetchByC_O(companyId, openId);
1984            }
1985    
1986            /**
1987             * Returns the user with the portrait ID.
1988             *
1989             * @param  portraitId the user's portrait ID
1990             * @return the user with the portrait ID, or <code>null</code> if a user
1991             *         with the portrait ID could not be found
1992             */
1993            @Override
1994            public User fetchUserByPortraitId(long portraitId) {
1995                    return userPersistence.fetchByPortraitId(portraitId);
1996            }
1997    
1998            /**
1999             * Returns the user with the screen name.
2000             *
2001             * @param  companyId the primary key of the user's company
2002             * @param  screenName the user's screen name
2003             * @return the user with the screen name, or <code>null</code> if a user
2004             *         with the screen name could not be found
2005             */
2006            @Override
2007            public User fetchUserByScreenName(long companyId, String screenName) {
2008                    screenName = getLogin(screenName);
2009    
2010                    return userPersistence.fetchByC_SN(companyId, screenName);
2011            }
2012    
2013            /**
2014             * Returns a range of all the users belonging to the company.
2015             *
2016             * <p>
2017             * Useful when paginating results. Returns a maximum of <code>end -
2018             * start</code> instances. <code>start</code> and <code>end</code> are not
2019             * primary keys, they are indexes in the result set. Thus, <code>0</code>
2020             * refers to the first result in the set. Setting both <code>start</code>
2021             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
2022             * result set.
2023             * </p>
2024             *
2025             * @param  companyId the primary key of the company
2026             * @param  start the lower bound of the range of users
2027             * @param  end the upper bound of the range of users (not inclusive)
2028             * @return the range of users belonging to the company
2029             */
2030            @Override
2031            public List<User> getCompanyUsers(long companyId, int start, int end) {
2032                    return userPersistence.findByCompanyId(companyId, start, end);
2033            }
2034    
2035            /**
2036             * Returns the number of users belonging to the company.
2037             *
2038             * @param  companyId the primary key of the company
2039             * @return the number of users belonging to the company
2040             */
2041            @Override
2042            public int getCompanyUsersCount(long companyId) {
2043                    return userPersistence.countByCompanyId(companyId);
2044            }
2045    
2046            /**
2047             * Returns the default user for the company.
2048             *
2049             * @param  companyId the primary key of the company
2050             * @return the default user for the company
2051             */
2052            @Override
2053            @Skip
2054            public User getDefaultUser(long companyId) throws PortalException {
2055                    User userModel = _defaultUsers.get(companyId);
2056    
2057                    if (userModel == null) {
2058                            userModel = userLocalService.loadGetDefaultUser(companyId);
2059    
2060                            _defaultUsers.put(companyId, userModel);
2061                    }
2062    
2063                    return userModel;
2064            }
2065    
2066            /**
2067             * Returns the primary key of the default user for the company.
2068             *
2069             * @param  companyId the primary key of the company
2070             * @return the primary key of the default user for the company
2071             */
2072            @Override
2073            @Skip
2074            public long getDefaultUserId(long companyId) throws PortalException {
2075                    User user = getDefaultUser(companyId);
2076    
2077                    return user.getUserId();
2078            }
2079    
2080            /**
2081             * Returns the primary keys of all the users belonging to the group.
2082             *
2083             * @param  groupId the primary key of the group
2084             * @return the primary keys of the users belonging to the group
2085             */
2086            @Override
2087            public long[] getGroupUserIds(long groupId) {
2088                    return groupPersistence.getUserPrimaryKeys(groupId);
2089            }
2090    
2091            /**
2092             * Returns the number of users with the status belonging to the group.
2093             *
2094             * @param  groupId the primary key of the group
2095             * @param  status the workflow status
2096             * @return the number of users with the status belonging to the group
2097             */
2098            @Override
2099            public int getGroupUsersCount(long groupId, int status)
2100                    throws PortalException {
2101    
2102                    Group group = groupPersistence.findByPrimaryKey(groupId);
2103    
2104                    LinkedHashMap<String, Object> params = new LinkedHashMap<>();
2105    
2106                    params.put("usersGroups", Long.valueOf(groupId));
2107    
2108                    return searchCount(group.getCompanyId(), null, status, params);
2109            }
2110    
2111            @Override
2112            public List<User> getInheritedRoleUsers(
2113                            long roleId, int start, int end, OrderByComparator<User> obc)
2114                    throws PortalException {
2115    
2116                    Role role = rolePersistence.findByPrimaryKey(roleId);
2117    
2118                    LinkedHashMap<String, Object> params = new LinkedHashMap<>();
2119    
2120                    params.put("inherit", Boolean.TRUE);
2121                    params.put("usersRoles", roleId);
2122    
2123                    return search(
2124                            role.getCompanyId(), null, WorkflowConstants.STATUS_APPROVED,
2125                            params, start, end, obc);
2126            }
2127    
2128            /**
2129             * Returns all the users who have not had any announcements of the type
2130             * delivered, excluding the default user.
2131             *
2132             * @param  type the type of announcement
2133             * @return the users who have not had any annoucements of the type delivered
2134             */
2135            @Override
2136            public List<User> getNoAnnouncementsDeliveries(String type) {
2137                    return userFinder.findByNoAnnouncementsDeliveries(type);
2138            }
2139    
2140            /**
2141             * Returns all the users who do not have any contacts.
2142             *
2143             * @return the users who do not have any contacts
2144             */
2145            @Override
2146            public List<User> getNoContacts() {
2147                    return userFinder.findByNoContacts();
2148            }
2149    
2150            /**
2151             * Returns all the users who do not belong to any groups, excluding the
2152             * default user.
2153             *
2154             * @return the users who do not belong to any groups
2155             */
2156            @Override
2157            public List<User> getNoGroups() {
2158                    return userFinder.findByNoGroups();
2159            }
2160    
2161            /**
2162             * Returns the primary keys of all the users belonging to the organization.
2163             *
2164             * @param  organizationId the primary key of the organization
2165             * @return the primary keys of the users belonging to the organization
2166             */
2167            @Override
2168            public long[] getOrganizationUserIds(long organizationId) {
2169                    return organizationPersistence.getUserPrimaryKeys(organizationId);
2170            }
2171    
2172            /**
2173             * Returns the number of users with the status belonging to the
2174             * organization.
2175             *
2176             * @param  organizationId the primary key of the organization
2177             * @param  status the workflow status
2178             * @return the number of users with the status belonging to the organization
2179             */
2180            @Override
2181            public int getOrganizationUsersCount(long organizationId, int status)
2182                    throws PortalException {
2183    
2184                    Organization organization = organizationPersistence.findByPrimaryKey(
2185                            organizationId);
2186    
2187                    LinkedHashMap<String, Object> params = new LinkedHashMap<>();
2188    
2189                    params.put("usersOrgs", Long.valueOf(organizationId));
2190    
2191                    return searchCount(organization.getCompanyId(), null, status, params);
2192            }
2193    
2194            /**
2195             * Returns the primary keys of all the users belonging to the role.
2196             *
2197             * @param  roleId the primary key of the role
2198             * @return the primary keys of the users belonging to the role
2199             */
2200            @Override
2201            public long[] getRoleUserIds(long roleId) {
2202                    return rolePersistence.getUserPrimaryKeys(roleId);
2203            }
2204    
2205            /**
2206             * Returns the number of users with the status belonging to the role.
2207             *
2208             * @param  roleId the primary key of the role
2209             * @param  status the workflow status
2210             * @return the number of users with the status belonging to the role
2211             */
2212            @Override
2213            public int getRoleUsersCount(long roleId, int status)
2214                    throws PortalException {
2215    
2216                    Role role = rolePersistence.findByPrimaryKey(roleId);
2217    
2218                    LinkedHashMap<String, Object> params = new LinkedHashMap<>();
2219    
2220                    params.put("usersRoles", Long.valueOf(roleId));
2221    
2222                    return searchCount(role.getCompanyId(), null, status, params);
2223            }
2224    
2225            /**
2226             * Returns an ordered range of all the users with a social relation of the
2227             * type with the user.
2228             *
2229             * <p>
2230             * Useful when paginating results. Returns a maximum of <code>end -
2231             * start</code> instances. <code>start</code> and <code>end</code> are not
2232             * primary keys, they are indexes in the result set. Thus, <code>0</code>
2233             * refers to the first result in the set. Setting both <code>start</code>
2234             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
2235             * result set.
2236             * </p>
2237             *
2238             * @param      userId the primary key of the user
2239             * @param      socialRelationType the type of social relation. The possible
2240             *             types can be found in {@link SocialRelationConstants}.
2241             * @param      start the lower bound of the range of users
2242             * @param      end the upper bound of the range of users (not inclusive)
2243             * @param      obc the comparator to order the users by (optionally
2244             *             <code>null</code>)
2245             * @return     the ordered range of users with a social relation of the type
2246             *             with the user
2247             * @deprecated As of 7.0.0, replaced by {@link #getSocialUsers(long, int,
2248             *             String, int, int, OrderByComparator)}
2249             */
2250            @Deprecated
2251            @Override
2252            public List<User> getSocialUsers(
2253                            long userId, int socialRelationType, int start, int end,
2254                            OrderByComparator<User> obc)
2255                    throws PortalException {
2256    
2257                    return getSocialUsers(
2258                            userId, socialRelationType, StringPool.EQUAL, start, end, obc);
2259            }
2260    
2261            /**
2262             * Returns an ordered range of all the users with a social relation with the
2263             * user.
2264             *
2265             * <p>
2266             * Useful when paginating results. Returns a maximum of <code>end -
2267             * start</code> instances. <code>start</code> and <code>end</code> are not
2268             * primary keys, they are indexes in the result set. Thus, <code>0</code>
2269             * refers to the first result in the set. Setting both <code>start</code>
2270             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
2271             * result set.
2272             * </p>
2273             *
2274             * @param      userId the primary key of the user
2275             * @param      start the lower bound of the range of users
2276             * @param      end the upper bound of the range of users (not inclusive)
2277             * @param      obc the comparator to order the users by (optionally
2278             *             <code>null</code>)
2279             * @return     the ordered range of users with a social relation with the
2280             *             user
2281             * @deprecated As of 7.0.0, replaced by {@link #getSocialUsers(long, int,
2282             *             String, int, int, OrderByComparator)}
2283             */
2284            @Deprecated
2285            @Override
2286            public List<User> getSocialUsers(
2287                            long userId, int start, int end, OrderByComparator<User> obc)
2288                    throws PortalException {
2289    
2290                    return getSocialUsers(
2291                            userId, SocialRelationConstants.TYPE_UNI_ENEMY,
2292                            StringPool.NOT_EQUAL, start, end, obc);
2293            }
2294    
2295            @Override
2296            public List<User> getSocialUsers(
2297                            long userId, int socialRelationType,
2298                            String socialRelationTypeComparator, int start, int end,
2299                            OrderByComparator<User> obc)
2300                    throws PortalException {
2301    
2302                    if (!socialRelationTypeComparator.equals(StringPool.EQUAL) &&
2303                            !socialRelationTypeComparator.equals(StringPool.NOT_EQUAL)) {
2304    
2305                            throw new IllegalArgumentException(
2306                                    "Invalid social relation type comparator " +
2307                                            socialRelationTypeComparator);
2308                    }
2309    
2310                    if ((start == QueryUtil.ALL_POS) && (end == QueryUtil.ALL_POS)) {
2311                            List<SocialRelation> socialRelations =
2312                                    socialRelationPersistence.findByU1_T(
2313                                            userId, socialRelationType);
2314    
2315                            if (socialRelationTypeComparator.equals(StringPool.NOT_EQUAL)) {
2316                                    socialRelations = ListUtil.remove(
2317                                            socialRelationPersistence.findByUserId1(userId),
2318                                            socialRelations);
2319                            }
2320    
2321                            List<User> users = new ArrayList<>();
2322    
2323                            for (SocialRelation socialRelation : socialRelations) {
2324                                    User user = userPersistence.findByPrimaryKey(
2325                                            socialRelation.getUserId2());
2326    
2327                                    if (user.isDefaultUser() ||
2328                                            (user.getStatus() != WorkflowConstants.STATUS_APPROVED)) {
2329    
2330                                            continue;
2331                                    }
2332    
2333                                    if (!users.contains(user)) {
2334                                            users.add(user);
2335                                    }
2336                            }
2337    
2338                            if (obc != null) {
2339                                    users = ListUtil.sort(users, obc);
2340                            }
2341    
2342                            return users;
2343                    }
2344    
2345                    User user = userPersistence.findByPrimaryKey(userId);
2346    
2347                    return userFinder.findBySocialUsers(
2348                            user.getCompanyId(), userId, socialRelationType,
2349                            socialRelationTypeComparator, WorkflowConstants.STATUS_APPROVED,
2350                            start, end, obc);
2351            }
2352    
2353            /**
2354             * Returns an ordered range of all the users with a mutual social relation
2355             * of the type with both of the given users.
2356             *
2357             * <p>
2358             * Useful when paginating results. Returns a maximum of <code>end -
2359             * start</code> instances. <code>start</code> and <code>end</code> are not
2360             * primary keys, they are indexes in the result set. Thus, <code>0</code>
2361             * refers to the first result in the set. Setting both <code>start</code>
2362             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
2363             * result set.
2364             * </p>
2365             *
2366             * @param  userId1 the primary key of the first user
2367             * @param  userId2 the primary key of the second user
2368             * @param  socialRelationType the type of social relation. The possible
2369             *         types can be found in {@link SocialRelationConstants}.
2370             * @param  start the lower bound of the range of users
2371             * @param  end the upper bound of the range of users (not inclusive)
2372             * @param  obc the comparator to order the users by (optionally
2373             *         <code>null</code>)
2374             * @return the ordered range of users with a mutual social relation of the
2375             *         type with the user
2376             */
2377            @Override
2378            public List<User> getSocialUsers(
2379                            long userId1, long userId2, int socialRelationType, int start,
2380                            int end, OrderByComparator<User> obc)
2381                    throws PortalException {
2382    
2383                    User user1 = userPersistence.findByPrimaryKey(userId1);
2384    
2385                    LinkedHashMap<String, Object> params = new LinkedHashMap<>();
2386    
2387                    params.put(
2388                            "socialMutualRelationType",
2389                            new Long[] {userId1, Long.valueOf(socialRelationType), userId2,
2390                            Long.valueOf(socialRelationType)
2391                    });
2392    
2393                    return search(
2394                            user1.getCompanyId(), null, WorkflowConstants.STATUS_APPROVED,
2395                            params, start, end, obc);
2396            }
2397    
2398            /**
2399             * Returns an ordered range of all the users with a mutual social relation
2400             * with both of the given users.
2401             *
2402             * <p>
2403             * Useful when paginating results. Returns a maximum of <code>end -
2404             * start</code> instances. <code>start</code> and <code>end</code> are not
2405             * primary keys, they are indexes in the result set. Thus, <code>0</code>
2406             * refers to the first result in the set. Setting both <code>start</code>
2407             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
2408             * result set.
2409             * </p>
2410             *
2411             * @param  userId1 the primary key of the first user
2412             * @param  userId2 the primary key of the second user
2413             * @param  start the lower bound of the range of users
2414             * @param  end the upper bound of the range of users (not inclusive)
2415             * @param  obc the comparator to order the users by (optionally
2416             *         <code>null</code>)
2417             * @return the ordered range of users with a mutual social relation with the
2418             *         user
2419             */
2420            @Override
2421            public List<User> getSocialUsers(
2422                            long userId1, long userId2, int start, int end,
2423                            OrderByComparator<User> obc)
2424                    throws PortalException {
2425    
2426                    User user1 = userPersistence.findByPrimaryKey(userId1);
2427    
2428                    LinkedHashMap<String, Object> params = new LinkedHashMap<>();
2429    
2430                    params.put("socialMutualRelation", new Long[] {userId1, userId2});
2431    
2432                    return search(
2433                            user1.getCompanyId(), null, WorkflowConstants.STATUS_APPROVED,
2434                            params, start, end, obc);
2435            }
2436    
2437            /**
2438             * Returns the number of users with a social relation with the user.
2439             *
2440             * @param      userId the primary key of the user
2441             * @return     the number of users with a social relation with the user
2442             * @deprecated As of 7.0.0, replaced by {@link #getSocialUsersCount(long,
2443             *             int, String)}
2444             */
2445            @Deprecated
2446            @Override
2447            public int getSocialUsersCount(long userId) throws PortalException {
2448                    return getSocialUsersCount(
2449                            userId, SocialRelationConstants.TYPE_UNI_ENEMY,
2450                            StringPool.NOT_EQUAL);
2451            }
2452    
2453            /**
2454             * Returns the number of users with a social relation of the type with the
2455             * user.
2456             *
2457             * @param      userId the primary key of the user
2458             * @param      socialRelationType the type of social relation. The possible
2459             *             types can be found in {@link SocialRelationConstants}.
2460             * @return     the number of users with a social relation of the type with
2461             *             the user
2462             * @deprecated As of 7.0.0, replaced by {@link #getSocialUsersCount(long,
2463             *             int, String)}
2464             */
2465            @Deprecated
2466            @Override
2467            public int getSocialUsersCount(long userId, int socialRelationType)
2468                    throws PortalException {
2469    
2470                    return getSocialUsersCount(
2471                            userId, socialRelationType, StringPool.EQUAL);
2472            }
2473    
2474            /**
2475             * Returns the number of users with a social relation with the user.
2476             *
2477             * @param  userId the primary key of the user
2478             * @param  socialRelationType the type of social relation. The possible
2479             *         types can be found in {@link SocialRelationConstants}.
2480             * @return the number of users with a social relation with the user
2481             */
2482            @Override
2483            public int getSocialUsersCount(
2484                            long userId, int socialRelationType,
2485                            String socialRelationTypeComparator)
2486                    throws PortalException {
2487    
2488                    User user = userPersistence.findByPrimaryKey(userId);
2489    
2490                    if (!socialRelationTypeComparator.equals(StringPool.EQUAL) &&
2491                            !socialRelationTypeComparator.equals(StringPool.NOT_EQUAL)) {
2492    
2493                            throw new IllegalArgumentException(
2494                                    "Invalid social relation type comparator " +
2495                                            socialRelationTypeComparator);
2496                    }
2497    
2498                    return userFinder.countBySocialUsers(
2499                            user.getCompanyId(), user.getUserId(), socialRelationType,
2500                            socialRelationTypeComparator, WorkflowConstants.STATUS_APPROVED);
2501            }
2502    
2503            /**
2504             * Returns the number of users with a mutual social relation with both of
2505             * the given users.
2506             *
2507             * @param  userId1 the primary key of the first user
2508             * @param  userId2 the primary key of the second user
2509             * @return the number of users with a mutual social relation with the user
2510             */
2511            @Override
2512            public int getSocialUsersCount(long userId1, long userId2)
2513                    throws PortalException {
2514    
2515                    User user1 = userPersistence.findByPrimaryKey(userId1);
2516    
2517                    LinkedHashMap<String, Object> params = new LinkedHashMap<>();
2518    
2519                    params.put("socialMutualRelation", new Long[] {userId1, userId2});
2520    
2521                    return searchCount(
2522                            user1.getCompanyId(), null, WorkflowConstants.STATUS_APPROVED,
2523                            params);
2524            }
2525    
2526            /**
2527             * Returns the number of users with a mutual social relation of the type
2528             * with both of the given users.
2529             *
2530             * @param  userId1 the primary key of the first user
2531             * @param  userId2 the primary key of the second user
2532             * @param  socialRelationType the type of social relation. The possible
2533             *         types can be found in {@link SocialRelationConstants}.
2534             * @return the number of users with a mutual social relation of the type
2535             *         with the user
2536             */
2537            @Override
2538            public int getSocialUsersCount(
2539                            long userId1, long userId2, int socialRelationType)
2540                    throws PortalException {
2541    
2542                    User user1 = userPersistence.findByPrimaryKey(userId1);
2543    
2544                    LinkedHashMap<String, Object> params = new LinkedHashMap<>();
2545    
2546                    params.put(
2547                            "socialMutualRelationType",
2548                            new Long[] {userId1, Long.valueOf(socialRelationType), userId2,
2549                            Long.valueOf(socialRelationType)
2550                    });
2551    
2552                    return searchCount(
2553                            user1.getCompanyId(), null, WorkflowConstants.STATUS_APPROVED,
2554                            params);
2555            }
2556    
2557            /**
2558             * Returns the user with the contact ID.
2559             *
2560             * @param  contactId the user's contact ID
2561             * @return the user with the contact ID
2562             */
2563            @Override
2564            public User getUserByContactId(long contactId) throws PortalException {
2565                    return userPersistence.findByContactId(contactId);
2566            }
2567    
2568            /**
2569             * Returns the user with the email address.
2570             *
2571             * @param  companyId the primary key of the user's company
2572             * @param  emailAddress the user's email address
2573             * @return the user with the email address
2574             */
2575            @Override
2576            public User getUserByEmailAddress(long companyId, String emailAddress)
2577                    throws PortalException {
2578    
2579                    emailAddress = getLogin(emailAddress);
2580    
2581                    return userPersistence.findByC_EA(companyId, emailAddress);
2582            }
2583    
2584            /**
2585             * Returns the user with the Facebook ID.
2586             *
2587             * @param  companyId the primary key of the user's company
2588             * @param  facebookId the user's Facebook ID
2589             * @return the user with the Facebook ID
2590             */
2591            @Override
2592            public User getUserByFacebookId(long companyId, long facebookId)
2593                    throws PortalException {
2594    
2595                    return userPersistence.findByC_FID(companyId, facebookId);
2596            }
2597    
2598            /**
2599             * Returns the user with the primary key.
2600             *
2601             * @param  userId the primary key of the user
2602             * @return the user with the primary key
2603             */
2604            @Override
2605            public User getUserById(long userId) throws PortalException {
2606                    return userPersistence.findByPrimaryKey(userId);
2607            }
2608    
2609            /**
2610             * Returns the user with the primary key from the company.
2611             *
2612             * @param  companyId the primary key of the user's company
2613             * @param  userId the primary key of the user
2614             * @return the user with the primary key
2615             */
2616            @Override
2617            public User getUserById(long companyId, long userId)
2618                    throws PortalException {
2619    
2620                    return userPersistence.findByC_U(companyId, userId);
2621            }
2622    
2623            /**
2624             * Returns the user with the OpenID.
2625             *
2626             * @param  companyId the primary key of the user's company
2627             * @param  openId the user's OpenID
2628             * @return the user with the OpenID
2629             */
2630            @Override
2631            public User getUserByOpenId(long companyId, String openId)
2632                    throws PortalException {
2633    
2634                    return userPersistence.findByC_O(companyId, openId);
2635            }
2636    
2637            /**
2638             * Returns the user with the portrait ID.
2639             *
2640             * @param  portraitId the user's portrait ID
2641             * @return the user with the portrait ID
2642             */
2643            @Override
2644            public User getUserByPortraitId(long portraitId) throws PortalException {
2645                    return userPersistence.findByPortraitId(portraitId);
2646            }
2647    
2648            /**
2649             * Returns the user with the screen name.
2650             *
2651             * @param  companyId the primary key of the user's company
2652             * @param  screenName the user's screen name
2653             * @return the user with the screen name
2654             */
2655            @Override
2656            public User getUserByScreenName(long companyId, String screenName)
2657                    throws PortalException {
2658    
2659                    screenName = getLogin(screenName);
2660    
2661                    return userPersistence.findByC_SN(companyId, screenName);
2662            }
2663    
2664            /**
2665             * Returns the user with the UUID.
2666             *
2667             * @param      uuid the user's UUID
2668             * @return     the user with the UUID
2669             * @deprecated As of 6.2.0, replaced by {@link
2670             *             #getUserByUuidAndCompanyId(String, long)}
2671             */
2672            @Deprecated
2673            @Override
2674            public User getUserByUuid(String uuid) throws PortalException {
2675                    List<User> users = userPersistence.findByUuid(uuid);
2676    
2677                    if (users.isEmpty()) {
2678                            throw new NoSuchUserException("{uuid=" + uuid + "}");
2679                    }
2680                    else {
2681                            return users.get(0);
2682                    }
2683            }
2684    
2685            /**
2686             * Returns the user with the UUID.
2687             *
2688             * @param  uuid the user's UUID
2689             * @param  companyId the primary key of the user's company
2690             * @return the user with the UUID
2691             */
2692            @Override
2693            public User getUserByUuidAndCompanyId(String uuid, long companyId)
2694                    throws PortalException {
2695    
2696                    List<User> users = userPersistence.findByUuid_C(uuid, companyId);
2697    
2698                    if (users.isEmpty()) {
2699                            StringBundler sb = new StringBundler(5);
2700    
2701                            sb.append("{uuid=");
2702                            sb.append(uuid);
2703                            sb.append(", companyId=");
2704                            sb.append(companyId);
2705                            sb.append("}");
2706    
2707                            throw new NoSuchUserException(sb.toString());
2708                    }
2709                    else {
2710                            return users.get(0);
2711                    }
2712            }
2713    
2714            /**
2715             * Returns the number of users with the status belonging to the user group.
2716             *
2717             * @param  userGroupId the primary key of the user group
2718             * @param  status the workflow status
2719             * @return the number of users with the status belonging to the user group
2720             */
2721            @Override
2722            public int getUserGroupUsersCount(long userGroupId, int status)
2723                    throws PortalException {
2724    
2725                    UserGroup userGroup = userGroupPersistence.findByPrimaryKey(
2726                            userGroupId);
2727    
2728                    LinkedHashMap<String, Object> params = new LinkedHashMap<>();
2729    
2730                    params.put("usersUserGroups", Long.valueOf(userGroupId));
2731    
2732                    return searchCount(userGroup.getCompanyId(), null, status, params);
2733            }
2734    
2735            /**
2736             * Returns the primary key of the user with the email address.
2737             *
2738             * @param  companyId the primary key of the user's company
2739             * @param  emailAddress the user's email address
2740             * @return the primary key of the user with the email address
2741             */
2742            @Override
2743            public long getUserIdByEmailAddress(long companyId, String emailAddress)
2744                    throws PortalException {
2745    
2746                    emailAddress = StringUtil.toLowerCase(emailAddress.trim());
2747    
2748                    User user = userPersistence.findByC_EA(companyId, emailAddress);
2749    
2750                    return user.getUserId();
2751            }
2752    
2753            /**
2754             * Returns the primary key of the user with the screen name.
2755             *
2756             * @param  companyId the primary key of the user's company
2757             * @param  screenName the user's screen name
2758             * @return the primary key of the user with the screen name
2759             */
2760            @Override
2761            public long getUserIdByScreenName(long companyId, String screenName)
2762                    throws PortalException {
2763    
2764                    screenName = getLogin(screenName);
2765    
2766                    User user = userPersistence.findByC_SN(companyId, screenName);
2767    
2768                    return user.getUserId();
2769            }
2770    
2771            /**
2772             * Returns <code>true</code> if the password policy has been assigned to the
2773             * user.
2774             *
2775             * @param  passwordPolicyId the primary key of the password policy
2776             * @param  userId the primary key of the user
2777             * @return <code>true</code> if the password policy is assigned to the user;
2778             *         <code>false</code> otherwise
2779             */
2780            @Override
2781            public boolean hasPasswordPolicyUser(long passwordPolicyId, long userId) {
2782                    return passwordPolicyRelLocalService.hasPasswordPolicyRel(
2783                            passwordPolicyId, User.class.getName(), userId);
2784            }
2785    
2786            /**
2787             * Returns <code>true</code> if the user has the role with the name,
2788             * optionally through inheritance.
2789             *
2790             * @param  companyId the primary key of the role's company
2791             * @param  name the name of the role (must be a regular role, not an
2792             *         organization, site or provider role)
2793             * @param  userId the primary key of the user
2794             * @param  inherited whether to include roles inherited from organizations,
2795             *         sites, etc.
2796             * @return <code>true</code> if the user has the role; <code>false</code>
2797             *         otherwise
2798             */
2799            @Override
2800            public boolean hasRoleUser(
2801                            long companyId, String name, long userId, boolean inherited)
2802                    throws PortalException {
2803    
2804                    return roleLocalService.hasUserRole(userId, companyId, name, inherited);
2805            }
2806    
2807            /**
2808             * Returns <code>true</code> if the user's password is expired.
2809             *
2810             * @param  user the user
2811             * @return <code>true</code> if the user's password is expired;
2812             *         <code>false</code> otherwise
2813             */
2814            @Override
2815            public boolean isPasswordExpired(User user) throws PortalException {
2816                    PasswordPolicy passwordPolicy = user.getPasswordPolicy();
2817    
2818                    if ((passwordPolicy != null) && passwordPolicy.getExpireable()) {
2819                            Date now = new Date();
2820    
2821                            if (user.getPasswordModifiedDate() == null) {
2822                                    user.setPasswordModifiedDate(now);
2823    
2824                                    userLocalService.updateUser(user);
2825                            }
2826    
2827                            long passwordStartTime = user.getPasswordModifiedDate().getTime();
2828                            long elapsedTime = now.getTime() - passwordStartTime;
2829    
2830                            if (elapsedTime > (passwordPolicy.getMaxAge() * 1000)) {
2831                                    return true;
2832                            }
2833                            else {
2834                                    return false;
2835                            }
2836                    }
2837    
2838                    return false;
2839            }
2840    
2841            /**
2842             * Returns <code>true</code> if the password policy is configured to warn
2843             * the user that his password is expiring and the remaining time until
2844             * expiration is equal or less than the configured warning time.
2845             *
2846             * @param  user the user
2847             * @return <code>true</code> if the user's password is expiring soon;
2848             *         <code>false</code> otherwise
2849             */
2850            @Override
2851            public boolean isPasswordExpiringSoon(User user) throws PortalException {
2852                    PasswordPolicy passwordPolicy = user.getPasswordPolicy();
2853    
2854                    if ((passwordPolicy != null) && passwordPolicy.isExpireable() &&
2855                            (passwordPolicy.getWarningTime() > 0)) {
2856    
2857                            Date now = new Date();
2858    
2859                            if (user.getPasswordModifiedDate() == null) {
2860                                    user.setPasswordModifiedDate(now);
2861    
2862                                    userLocalService.updateUser(user);
2863                            }
2864    
2865                            long timeModified = user.getPasswordModifiedDate().getTime();
2866                            long passwordExpiresOn =
2867                                    (passwordPolicy.getMaxAge() * 1000) + timeModified;
2868    
2869                            long timeStartWarning =
2870                                    passwordExpiresOn - (passwordPolicy.getWarningTime() * 1000);
2871    
2872                            if (now.getTime() > timeStartWarning) {
2873                                    return true;
2874                            }
2875                            else {
2876                                    return false;
2877                            }
2878                    }
2879    
2880                    return false;
2881            }
2882    
2883            /**
2884             * Returns the default user for the company.
2885             *
2886             * @param  companyId the primary key of the company
2887             * @return the default user for the company
2888             */
2889            @Override
2890            public User loadGetDefaultUser(long companyId) throws PortalException {
2891                    return userPersistence.findByC_DU(companyId, true);
2892            }
2893    
2894            /**
2895             * Returns an ordered range of all the users who match the keywords and
2896             * status, without using the indexer. It is preferable to use the indexed
2897             * version {@link #search(long, String, int, LinkedHashMap, int, int, Sort)}
2898             * instead of this method wherever possible for performance reasons.
2899             *
2900             * <p>
2901             * Useful when paginating results. Returns a maximum of <code>end -
2902             * start</code> instances. <code>start</code> and <code>end</code> are not
2903             * primary keys, they are indexes in the result set. Thus, <code>0</code>
2904             * refers to the first result in the set. Setting both <code>start</code>
2905             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
2906             * result set.
2907             * </p>
2908             *
2909             * @param  companyId the primary key of the user's company
2910             * @param  keywords the keywords (space separated), which may occur in the
2911             *         user's first name, middle name, last name, screen name, or email
2912             *         address
2913             * @param  status the workflow status
2914             * @param  params the finder parameters (optionally <code>null</code>). For
2915             *         more information see {@link
2916             *         com.liferay.portal.service.persistence.UserFinder}.
2917             * @param  start the lower bound of the range of users
2918             * @param  end the upper bound of the range of users (not inclusive)
2919             * @param  obc the comparator to order the users by (optionally
2920             *         <code>null</code>)
2921             * @return the matching users
2922             * @see    com.liferay.portal.service.persistence.UserFinder
2923             */
2924            @Override
2925            public List<User> search(
2926                    long companyId, String keywords, int status,
2927                    LinkedHashMap<String, Object> params, int start, int end,
2928                    OrderByComparator<User> obc) {
2929    
2930                    Indexer<?> indexer = IndexerRegistryUtil.nullSafeGetIndexer(User.class);
2931    
2932                    if (!indexer.isIndexerEnabled() ||
2933                            !PropsValues.USERS_SEARCH_WITH_INDEX || isUseCustomSQL(params)) {
2934    
2935                            return userFinder.findByKeywords(
2936                                    companyId, keywords, status, params, start, end, obc);
2937                    }
2938    
2939                    try {
2940                            return UsersAdminUtil.getUsers(
2941                                    search(
2942                                            companyId, keywords, status, params, start, end,
2943                                            getSorts(obc)));
2944                    }
2945                    catch (Exception e) {
2946                            throw new SystemException(e);
2947                    }
2948            }
2949    
2950            /**
2951             * Returns an ordered range of all the users who match the keywords and
2952             * status, using the indexer. It is preferable to use this method instead of
2953             * the non-indexed version whenever possible for performance reasons.
2954             *
2955             * <p>
2956             * Useful when paginating results. Returns a maximum of <code>end -
2957             * start</code> instances. <code>start</code> and <code>end</code> are not
2958             * primary keys, they are indexes in the result set. Thus, <code>0</code>
2959             * refers to the first result in the set. Setting both <code>start</code>
2960             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
2961             * result set.
2962             * </p>
2963             *
2964             * @param  companyId the primary key of the user's company
2965             * @param  keywords the keywords (space separated), which may occur in the
2966             *         user's first name, middle name, last name, screen name, or email
2967             *         address
2968             * @param  status the workflow status
2969             * @param  params the indexer parameters (optionally <code>null</code>). For
2970             *         more information see {@link
2971             *         com.liferay.portlet.usersadmin.util.UserIndexer}.
2972             * @param  start the lower bound of the range of users
2973             * @param  end the upper bound of the range of users (not inclusive)
2974             * @param  sort the field and direction to sort by (optionally
2975             *         <code>null</code>)
2976             * @return the matching users
2977             * @see    com.liferay.portlet.usersadmin.util.UserIndexer
2978             */
2979            @Override
2980            public Hits search(
2981                    long companyId, String keywords, int status,
2982                    LinkedHashMap<String, Object> params, int start, int end, Sort sort) {
2983    
2984                    return search(
2985                            companyId, keywords, status, params, start, end, new Sort[] {sort});
2986            }
2987    
2988            @Override
2989            public Hits search(
2990                    long companyId, String keywords, int status,
2991                    LinkedHashMap<String, Object> params, int start, int end,
2992                    Sort[] sorts) {
2993    
2994                    String firstName = null;
2995                    String middleName = null;
2996                    String lastName = null;
2997                    String fullName = null;
2998                    String screenName = null;
2999                    String emailAddress = null;
3000                    String street = null;
3001                    String city = null;
3002                    String zip = null;
3003                    String region = null;
3004                    String country = null;
3005                    boolean andOperator = false;
3006    
3007                    if (Validator.isNotNull(keywords)) {
3008                            firstName = keywords;
3009                            middleName = keywords;
3010                            lastName = keywords;
3011                            fullName = keywords;
3012                            screenName = keywords;
3013                            emailAddress = keywords;
3014                            street = keywords;
3015                            city = keywords;
3016                            zip = keywords;
3017                            region = keywords;
3018                            country = keywords;
3019                    }
3020                    else {
3021                            andOperator = true;
3022                    }
3023    
3024                    if (params != null) {
3025                            params.put("keywords", keywords);
3026                    }
3027    
3028                    try {
3029                            Indexer<User> indexer = IndexerRegistryUtil.nullSafeGetIndexer(
3030                                    User.class);
3031    
3032                            SearchContext searchContext = buildSearchContext(
3033                                    companyId, firstName, middleName, lastName, fullName,
3034                                    screenName, emailAddress, street, city, zip, region, country,
3035                                    status, params, andOperator, start, end, sorts);
3036    
3037                            return indexer.search(searchContext);
3038                    }
3039                    catch (Exception e) {
3040                            throw new SystemException(e);
3041                    }
3042            }
3043    
3044            /**
3045             * Returns an ordered range of all the users with the status, and whose
3046             * first name, middle name, last name, screen name, and email address match
3047             * the keywords specified for them, without using the indexer. It is
3048             * preferable to use the indexed version {@link #search(long, String,
3049             * String, String, String, String, int, LinkedHashMap, boolean, int, int,
3050             * Sort)} instead of this method wherever possible for performance reasons.
3051             *
3052             * <p>
3053             * Useful when paginating results. Returns a maximum of <code>end -
3054             * start</code> instances. <code>start</code> and <code>end</code> are not
3055             * primary keys, they are indexes in the result set. Thus, <code>0</code>
3056             * refers to the first result in the set. Setting both <code>start</code>
3057             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
3058             * result set.
3059             * </p>
3060             *
3061             * @param  companyId the primary key of the user's company
3062             * @param  firstName the first name keywords (space separated)
3063             * @param  middleName the middle name keywords
3064             * @param  lastName the last name keywords
3065             * @param  screenName the screen name keywords
3066             * @param  emailAddress the email address keywords
3067             * @param  status the workflow status
3068             * @param  params the finder parameters (optionally <code>null</code>). For
3069             *         more information see {@link
3070             *         com.liferay.portal.service.persistence.UserFinder}.
3071             * @param  andSearch whether every field must match its keywords, or just
3072             *         one field. For example, &quot;users with the first name 'bob' and
3073             *         last name 'smith'&quot; vs &quot;users with the first name 'bob'
3074             *         or the last name 'smith'&quot;.
3075             * @param  start the lower bound of the range of users
3076             * @param  end the upper bound of the range of users (not inclusive)
3077             * @param  obc the comparator to order the users by (optionally
3078             *         <code>null</code>)
3079             * @return the matching users
3080             * @see    com.liferay.portal.service.persistence.UserFinder
3081             */
3082            @Override
3083            public List<User> search(
3084                    long companyId, String firstName, String middleName, String lastName,
3085                    String screenName, String emailAddress, int status,
3086                    LinkedHashMap<String, Object> params, boolean andSearch, int start,
3087                    int end, OrderByComparator<User> obc) {
3088    
3089                    Indexer<?> indexer = IndexerRegistryUtil.nullSafeGetIndexer(User.class);
3090    
3091                    if (!indexer.isIndexerEnabled() ||
3092                            !PropsValues.USERS_SEARCH_WITH_INDEX || isUseCustomSQL(params)) {
3093    
3094                            return userFinder.findByC_FN_MN_LN_SN_EA_S(
3095                                    companyId, firstName, middleName, lastName, screenName,
3096                                    emailAddress, status, params, andSearch, start, end, obc);
3097                    }
3098    
3099                    try {
3100                            return UsersAdminUtil.getUsers(
3101                                    search(
3102                                            companyId, firstName, middleName, lastName, screenName,
3103                                            emailAddress, status, params, andSearch, start, end,
3104                                            getSorts(obc)));
3105                    }
3106                    catch (Exception e) {
3107                            throw new SystemException(e);
3108                    }
3109            }
3110    
3111            /**
3112             * Returns an ordered range of all the users with the status, and whose
3113             * first name, middle name, last name, screen name, and email address match
3114             * the keywords specified for them, using the indexer. It is preferable to
3115             * use this method instead of the non-indexed version whenever possible for
3116             * performance reasons.
3117             *
3118             * <p>
3119             * Useful when paginating results. Returns a maximum of <code>end -
3120             * start</code> instances. <code>start</code> and <code>end</code> are not
3121             * primary keys, they are indexes in the result set. Thus, <code>0</code>
3122             * refers to the first result in the set. Setting both <code>start</code>
3123             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
3124             * result set.
3125             * </p>
3126             *
3127             * @param  companyId the primary key of the user's company
3128             * @param  firstName the first name keywords (space separated)
3129             * @param  middleName the middle name keywords
3130             * @param  lastName the last name keywords
3131             * @param  screenName the screen name keywords
3132             * @param  emailAddress the email address keywords
3133             * @param  status the workflow status
3134             * @param  params the indexer parameters (optionally <code>null</code>). For
3135             *         more information see {@link
3136             *         com.liferay.portlet.usersadmin.util.UserIndexer}.
3137             * @param  andSearch whether every field must match its keywords, or just
3138             *         one field. For example, &quot;users with the first name 'bob' and
3139             *         last name 'smith'&quot; vs &quot;users with the first name 'bob'
3140             *         or the last name 'smith'&quot;.
3141             * @param  start the lower bound of the range of users
3142             * @param  end the upper bound of the range of users (not inclusive)
3143             * @param  sort the field and direction to sort by (optionally
3144             *         <code>null</code>)
3145             * @return the matching users
3146             * @see    com.liferay.portlet.usersadmin.util.UserIndexer
3147             */
3148            @Override
3149            public Hits search(
3150                    long companyId, String firstName, String middleName, String lastName,
3151                    String screenName, String emailAddress, int status,
3152                    LinkedHashMap<String, Object> params, boolean andSearch, int start,
3153                    int end, Sort sort) {
3154    
3155                    return search(
3156                            companyId, firstName, middleName, lastName, screenName,
3157                            emailAddress, status, params, andSearch, start, end,
3158                            new Sort[] {sort});
3159            }
3160    
3161            @Override
3162            public Hits search(
3163                    long companyId, String firstName, String middleName, String lastName,
3164                    String screenName, String emailAddress, int status,
3165                    LinkedHashMap<String, Object> params, boolean andSearch, int start,
3166                    int end, Sort[] sorts) {
3167    
3168                    try {
3169                            Indexer<User> indexer = IndexerRegistryUtil.nullSafeGetIndexer(
3170                                    User.class);
3171    
3172                            SearchContext searchContext = buildSearchContext(
3173                                    companyId, firstName, middleName, lastName, null, screenName,
3174                                    emailAddress, null, null, null, null, null, status, params,
3175                                    andSearch, start, end, sorts);
3176    
3177                            return indexer.search(searchContext);
3178                    }
3179                    catch (Exception e) {
3180                            throw new SystemException(e);
3181                    }
3182            }
3183    
3184            /**
3185             * Returns the number of users who match the keywords and status.
3186             *
3187             * @param  companyId the primary key of the user's company
3188             * @param  keywords the keywords (space separated), which may occur in the
3189             *         user's first name, middle name, last name, screen name, or email
3190             *         address
3191             * @param  status the workflow status
3192             * @param  params the finder parameters (optionally <code>null</code>). For
3193             *         more information see {@link
3194             *         com.liferay.portal.service.persistence.UserFinder}.
3195             * @return the number matching users
3196             */
3197            @Override
3198            public int searchCount(
3199                    long companyId, String keywords, int status,
3200                    LinkedHashMap<String, Object> params) {
3201    
3202                    Indexer<?> indexer = IndexerRegistryUtil.nullSafeGetIndexer(User.class);
3203    
3204                    if (!indexer.isIndexerEnabled() ||
3205                            !PropsValues.USERS_SEARCH_WITH_INDEX || isUseCustomSQL(params)) {
3206    
3207                            return userFinder.countByKeywords(
3208                                    companyId, keywords, status, params);
3209                    }
3210    
3211                    try {
3212                            String firstName = null;
3213                            String middleName = null;
3214                            String lastName = null;
3215                            String fullName = null;
3216                            String screenName = null;
3217                            String emailAddress = null;
3218                            String street = null;
3219                            String city = null;
3220                            String zip = null;
3221                            String region = null;
3222                            String country = null;
3223                            boolean andOperator = false;
3224    
3225                            if (Validator.isNotNull(keywords)) {
3226                                    firstName = keywords;
3227                                    middleName = keywords;
3228                                    lastName = keywords;
3229                                    fullName = keywords;
3230                                    screenName = keywords;
3231                                    emailAddress = keywords;
3232                                    street = keywords;
3233                                    city = keywords;
3234                                    zip = keywords;
3235                                    region = keywords;
3236                                    country = keywords;
3237                            }
3238                            else {
3239                                    andOperator = true;
3240                            }
3241    
3242                            if (params != null) {
3243                                    params.put("keywords", keywords);
3244                            }
3245    
3246                            SearchContext searchContext = buildSearchContext(
3247                                    companyId, firstName, middleName, lastName, fullName,
3248                                    screenName, emailAddress, street, city, zip, region, country,
3249                                    status, params, andOperator, QueryUtil.ALL_POS,
3250                                    QueryUtil.ALL_POS, null);
3251    
3252                            return (int)indexer.searchCount(searchContext);
3253                    }
3254                    catch (Exception e) {
3255                            throw new SystemException(e);
3256                    }
3257            }
3258    
3259            /**
3260             * Returns the number of users with the status, and whose first name, middle
3261             * name, last name, screen name, and email address match the keywords
3262             * specified for them.
3263             *
3264             * @param  companyId the primary key of the user's company
3265             * @param  firstName the first name keywords (space separated)
3266             * @param  middleName the middle name keywords
3267             * @param  lastName the last name keywords
3268             * @param  screenName the screen name keywords
3269             * @param  emailAddress the email address keywords
3270             * @param  status the workflow status
3271             * @param  params the finder parameters (optionally <code>null</code>). For
3272             *         more information see {@link
3273             *         com.liferay.portal.service.persistence.UserFinder}.
3274             * @param  andSearch whether every field must match its keywords, or just
3275             *         one field. For example, &quot;users with the first name 'bob' and
3276             *         last name 'smith'&quot; vs &quot;users with the first name 'bob'
3277             *         or the last name 'smith'&quot;.
3278             * @return the number of matching users
3279             */
3280            @Override
3281            public int searchCount(
3282                    long companyId, String firstName, String middleName, String lastName,
3283                    String screenName, String emailAddress, int status,
3284                    LinkedHashMap<String, Object> params, boolean andSearch) {
3285    
3286                    Indexer<?> indexer = IndexerRegistryUtil.nullSafeGetIndexer(User.class);
3287    
3288                    if (!indexer.isIndexerEnabled() ||
3289                            !PropsValues.USERS_SEARCH_WITH_INDEX || isUseCustomSQL(params)) {
3290    
3291                            return userFinder.countByC_FN_MN_LN_SN_EA_S(
3292                                    companyId, firstName, middleName, lastName, screenName,
3293                                    emailAddress, status, params, andSearch);
3294                    }
3295    
3296                    try {
3297                            FullNameGenerator fullNameGenerator =
3298                                    FullNameGeneratorFactory.getInstance();
3299    
3300                            String fullName = fullNameGenerator.getFullName(
3301                                    firstName, middleName, lastName);
3302    
3303                            SearchContext searchContext = buildSearchContext(
3304                                    companyId, firstName, middleName, lastName, fullName,
3305                                    screenName, emailAddress, null, null, null, null, null, status,
3306                                    params, true, QueryUtil.ALL_POS, QueryUtil.ALL_POS, null);
3307    
3308                            return (int)indexer.searchCount(searchContext);
3309                    }
3310                    catch (Exception e) {
3311                            throw new SystemException(e);
3312                    }
3313            }
3314    
3315            @Override
3316            public Map<Long, Integer> searchCounts(
3317                    long companyId, int status, long[] groupIds) {
3318    
3319                    return userFinder.countByGroups(companyId, status, groupIds);
3320            }
3321    
3322            @Override
3323            public List<User> searchSocial(
3324                            long userId, int[] socialRelationTypes, String keywords, int start,
3325                            int end)
3326                    throws PortalException {
3327    
3328                    User user = userPersistence.findByPrimaryKey(userId);
3329    
3330                    LinkedHashMap<String, Object> params = new LinkedHashMap<>();
3331    
3332                    params.put(
3333                            "socialRelationType",
3334                            new Long[][] {
3335                                    new Long[] {userId}, ArrayUtil.toLongArray(socialRelationTypes)
3336                            });
3337                    params.put("wildcardMode", WildcardMode.TRAILING);
3338    
3339                    return userFinder.findByKeywords(
3340                            user.getCompanyId(), keywords, WorkflowConstants.STATUS_APPROVED,
3341                            params, start, end, null);
3342            }
3343    
3344            @Override
3345            public List<User> searchSocial(
3346                    long companyId, long[] groupIds, String keywords, int start, int end) {
3347    
3348                    LinkedHashMap<String, Object> params = new LinkedHashMap<>();
3349    
3350                    params.put("usersGroups", ArrayUtil.toLongArray(groupIds));
3351                    params.put("wildcardMode", WildcardMode.TRAILING);
3352    
3353                    return userFinder.findByKeywords(
3354                            companyId, keywords, WorkflowConstants.STATUS_APPROVED, params,
3355                            start, end, null);
3356            }
3357    
3358            @Override
3359            public List<User> searchSocial(
3360                            long[] groupIds, long userId, int[] socialRelationTypes,
3361                            String keywords, int start, int end)
3362                    throws PortalException {
3363    
3364                    User user = userPersistence.findByPrimaryKey(userId);
3365    
3366                    LinkedHashMap<String, Object> params = new LinkedHashMap<>();
3367    
3368                    params.put(
3369                            "socialRelationType",
3370                            new Long[][] {
3371                                    new Long[] {userId}, ArrayUtil.toLongArray(socialRelationTypes)
3372                            });
3373                    params.put("socialRelationTypeUnionUserGroups", true);
3374                    params.put("usersGroups", ArrayUtil.toLongArray(groupIds));
3375                    params.put("wildcardMode", WildcardMode.TRAILING);
3376    
3377                    return userFinder.findByKeywords(
3378                            user.getCompanyId(), keywords, WorkflowConstants.STATUS_APPROVED,
3379                            params, start, end, null);
3380            }
3381    
3382            @Override
3383            public BaseModelSearchResult<User> searchUsers(
3384                            long companyId, String keywords, int status,
3385                            LinkedHashMap<String, Object> params, int start, int end, Sort sort)
3386                    throws PortalException {
3387    
3388                    return searchUsers(
3389                            companyId, keywords, status, params, start, end, new Sort[] {sort});
3390            }
3391    
3392            @Override
3393            public BaseModelSearchResult<User> searchUsers(
3394                            long companyId, String keywords, int status,
3395                            LinkedHashMap<String, Object> params, int start, int end,
3396                            Sort[] sorts)
3397                    throws PortalException {
3398    
3399                    String firstName = null;
3400                    String middleName = null;
3401                    String lastName = null;
3402                    String fullName = null;
3403                    String screenName = null;
3404                    String emailAddress = null;
3405                    String street = null;
3406                    String city = null;
3407                    String zip = null;
3408                    String region = null;
3409                    String country = null;
3410                    boolean andOperator = false;
3411    
3412                    if (Validator.isNotNull(keywords)) {
3413                            firstName = keywords;
3414                            middleName = keywords;
3415                            lastName = keywords;
3416                            fullName = keywords;
3417                            screenName = keywords;
3418                            emailAddress = keywords;
3419                            street = keywords;
3420                            city = keywords;
3421                            zip = keywords;
3422                            region = keywords;
3423                            country = keywords;
3424                    }
3425                    else {
3426                            andOperator = true;
3427                    }
3428    
3429                    if (params != null) {
3430                            params.put("keywords", keywords);
3431                    }
3432    
3433                    SearchContext searchContext = buildSearchContext(
3434                            companyId, firstName, middleName, lastName, fullName, screenName,
3435                            emailAddress, street, city, zip, region, country, status, params,
3436                            andOperator, start, end, sorts);
3437    
3438                    return searchUsers(searchContext);
3439            }
3440    
3441            @Override
3442            public BaseModelSearchResult<User> searchUsers(
3443                            long companyId, String firstName, String middleName,
3444                            String lastName, String screenName, String emailAddress, int status,
3445                            LinkedHashMap<String, Object> params, boolean andSearch, int start,
3446                            int end, Sort sort)
3447                    throws PortalException {
3448    
3449                    return searchUsers(
3450                            companyId, firstName, middleName, lastName, screenName,
3451                            emailAddress, status, params, andSearch, start, end,
3452                            new Sort[] {sort});
3453            }
3454    
3455            @Override
3456            public BaseModelSearchResult<User> searchUsers(
3457                            long companyId, String firstName, String middleName,
3458                            String lastName, String screenName, String emailAddress, int status,
3459                            LinkedHashMap<String, Object> params, boolean andSearch, int start,
3460                            int end, Sort[] sorts)
3461                    throws PortalException {
3462    
3463                    SearchContext searchContext = buildSearchContext(
3464                            companyId, firstName, middleName, lastName, null, screenName,
3465                            emailAddress, null, null, null, null, null, status, params,
3466                            andSearch, start, end, sorts);
3467    
3468                    return searchUsers(searchContext);
3469            }
3470    
3471            /**
3472             * Sends an email address verification to the user.
3473             *
3474             * @param user the verification email recipient
3475             * @param emailAddress the recipient's email address
3476             * @param serviceContext the service context to be applied. Must set the
3477             *        portal URL, main path, primary key of the layout, remote address,
3478             *        remote host, and agent for the user.
3479             */
3480            @Override
3481            public void sendEmailAddressVerification(
3482                            User user, String emailAddress, ServiceContext serviceContext)
3483                    throws PortalException {
3484    
3485                    if (user.isEmailAddressVerified() &&
3486                            StringUtil.equalsIgnoreCase(emailAddress, user.getEmailAddress())) {
3487    
3488                            return;
3489                    }
3490    
3491                    Ticket ticket = ticketLocalService.addDistinctTicket(
3492                            user.getCompanyId(), User.class.getName(), user.getUserId(),
3493                            TicketConstants.TYPE_EMAIL_ADDRESS, emailAddress, null,
3494                            serviceContext);
3495    
3496                    String verifyEmailAddressURL =
3497                            serviceContext.getPortalURL() + serviceContext.getPathMain() +
3498                                    "/portal/verify_email_address?ticketKey=" + ticket.getKey();
3499    
3500                    long plid = serviceContext.getPlid();
3501    
3502                    if (plid > 0) {
3503                            Layout layout = layoutLocalService.fetchLayout(plid);
3504    
3505                            if (layout != null) {
3506                                    Group group = layout.getGroup();
3507    
3508                                    if (!layout.isPrivateLayout() && !group.isUser()) {
3509                                            verifyEmailAddressURL +=
3510                                                    "&p_l_id=" + serviceContext.getPlid();
3511                                    }
3512                            }
3513                    }
3514    
3515                    String fromName = PrefsPropsUtil.getString(
3516                            user.getCompanyId(), PropsKeys.ADMIN_EMAIL_FROM_NAME);
3517                    String fromAddress = PrefsPropsUtil.getString(
3518                            user.getCompanyId(), PropsKeys.ADMIN_EMAIL_FROM_ADDRESS);
3519    
3520                    String toName = user.getFullName();
3521                    String toAddress = emailAddress;
3522    
3523                    PortletPreferences companyPortletPreferences =
3524                            PrefsPropsUtil.getPreferences(user.getCompanyId(), true);
3525    
3526                    Map<Locale, String> localizedSubjectMap =
3527                            LocalizationUtil.getLocalizationMap(
3528                                    companyPortletPreferences, "adminEmailVerificationSubject",
3529                                    PropsKeys.ADMIN_EMAIL_VERIFICATION_SUBJECT);
3530                    Map<Locale, String> localizedBodyMap =
3531                            LocalizationUtil.getLocalizationMap(
3532                                    companyPortletPreferences, "adminEmailVerificationBody",
3533                                    PropsKeys.ADMIN_EMAIL_VERIFICATION_BODY);
3534    
3535                    SubscriptionSender subscriptionSender = new SubscriptionSender();
3536    
3537                    subscriptionSender.setCompanyId(user.getCompanyId());
3538                    subscriptionSender.setContextAttributes(
3539                            "[$EMAIL_VERIFICATION_CODE$]", ticket.getKey(),
3540                            "[$EMAIL_VERIFICATION_URL$]", verifyEmailAddressURL,
3541                            "[$REMOTE_ADDRESS$]", serviceContext.getRemoteAddr(),
3542                            "[$REMOTE_HOST$]", serviceContext.getRemoteHost(), "[$USER_ID$]",
3543                            user.getUserId(), "[$USER_SCREENNAME$]", user.getScreenName());
3544                    subscriptionSender.setFrom(fromAddress, fromName);
3545                    subscriptionSender.setHtmlFormat(true);
3546                    subscriptionSender.setLocalizedBodyMap(localizedBodyMap);
3547                    subscriptionSender.setLocalizedSubjectMap(localizedSubjectMap);
3548                    subscriptionSender.setMailId("user", user.getUserId());
3549                    subscriptionSender.setServiceContext(serviceContext);
3550    
3551                    subscriptionSender.addRuntimeSubscribers(toAddress, toName);
3552    
3553                    subscriptionSender.flushNotificationsAsync();
3554            }
3555    
3556            /**
3557             * Sends the password email to the user with the email address. The content
3558             * of this email can be specified in <code>portal.properties</code> with the
3559             * <code>admin.email.password</code> keys.
3560             *
3561             * @param companyId the primary key of the user's company
3562             * @param emailAddress the user's email address
3563             * @param fromName the name of the individual that the email should be from
3564             * @param fromAddress the address of the individual that the email should be
3565             *        from
3566             * @param subject the email subject. If <code>null</code>, the subject
3567             *        specified in <code>portal.properties</code> will be used.
3568             * @param body the email body. If <code>null</code>, the body specified in
3569             *        <code>portal.properties</code> will be used.
3570             * @param serviceContext the service context to be applied
3571             */
3572            @Override
3573            public boolean sendPassword(
3574                            long companyId, String emailAddress, String fromName,
3575                            String fromAddress, String subject, String body,
3576                            ServiceContext serviceContext)
3577                    throws PortalException {
3578    
3579                    Company company = companyPersistence.findByPrimaryKey(companyId);
3580    
3581                    if (!company.isSendPassword() && !company.isSendPasswordResetLink()) {
3582                            throw new SendPasswordException.MustBeEnabled(company);
3583                    }
3584    
3585                    emailAddress = StringUtil.toLowerCase(emailAddress.trim());
3586    
3587                    if (Validator.isNull(emailAddress)) {
3588                            throw new UserEmailAddressException.MustNotBeNull();
3589                    }
3590    
3591                    User user = userPersistence.findByC_EA(companyId, emailAddress);
3592    
3593                    PasswordPolicy passwordPolicy = user.getPasswordPolicy();
3594    
3595                    String newPassword = StringPool.BLANK;
3596                    String passwordResetURL = StringPool.BLANK;
3597    
3598                    if (company.isSendPasswordResetLink()) {
3599                            Date expirationDate = null;
3600    
3601                            if ((passwordPolicy != null) &&
3602                                    (passwordPolicy.getResetTicketMaxAge() > 0)) {
3603    
3604                                    expirationDate = new Date(
3605                                            System.currentTimeMillis() +
3606                                                    (passwordPolicy.getResetTicketMaxAge() * 1000));
3607                            }
3608    
3609                            Ticket ticket = ticketLocalService.addDistinctTicket(
3610                                    companyId, User.class.getName(), user.getUserId(),
3611                                    TicketConstants.TYPE_PASSWORD, null, expirationDate,
3612                                    serviceContext);
3613    
3614                            passwordResetURL =
3615                                    serviceContext.getPortalURL() + serviceContext.getPathMain() +
3616                                            "/portal/update_password?p_l_id="+
3617                                                    serviceContext.getPlid() +
3618                                                            "&ticketKey=" + ticket.getKey();
3619                    }
3620                    else {
3621                            if (!Validator.equals(
3622                                            PasswordEncryptorUtil.getDefaultPasswordAlgorithmType(),
3623                                            PasswordEncryptorUtil.TYPE_NONE)) {
3624    
3625                                    if (LDAPSettingsUtil.isPasswordPolicyEnabled(
3626                                                    user.getCompanyId())) {
3627    
3628                                            if (_log.isWarnEnabled()) {
3629                                                    StringBundler sb = new StringBundler(5);
3630    
3631                                                    sb.append("When LDAP password policy is enabled, ");
3632                                                    sb.append("it is possible that portal generated ");
3633                                                    sb.append("passwords will not match the LDAP policy.");
3634                                                    sb.append("Using RegExpToolkit to generate new ");
3635                                                    sb.append("password.");
3636    
3637                                                    _log.warn(sb.toString());
3638                                            }
3639    
3640                                            RegExpToolkit regExpToolkit = new RegExpToolkit();
3641    
3642                                            newPassword = regExpToolkit.generate(null);
3643                                    }
3644                                    else {
3645                                            newPassword = PwdToolkitUtil.generate(passwordPolicy);
3646                                    }
3647    
3648                                    boolean passwordReset = false;
3649    
3650                                    if (passwordPolicy.getChangeable() &&
3651                                            passwordPolicy.getChangeRequired()) {
3652    
3653                                            passwordReset = true;
3654                                    }
3655    
3656                                    user.setPassword(PasswordEncryptorUtil.encrypt(newPassword));
3657                                    user.setPasswordUnencrypted(newPassword);
3658                                    user.setPasswordEncrypted(true);
3659                                    user.setPasswordReset(passwordReset);
3660                                    user.setPasswordModified(true);
3661                                    user.setPasswordModifiedDate(new Date());
3662    
3663                                    userPersistence.update(user);
3664    
3665                                    user.setPasswordModified(false);
3666                            }
3667                            else {
3668                                    newPassword = user.getPassword();
3669                            }
3670                    }
3671    
3672                    sendPasswordNotification(
3673                            user, companyId, newPassword, passwordResetURL, fromName,
3674                            fromAddress, subject, body, serviceContext);
3675    
3676                    return company.isSendPassword();
3677            }
3678    
3679            /**
3680             * Sends a password notification email to the user matching the email
3681             * address. The portal's settings determine whether a password is sent
3682             * explicitly or whether a link for resetting the user's password is sent.
3683             * The method sends the email asynchronously and returns before the email is
3684             * sent.
3685             *
3686             * <p>
3687             * The content of the notification email is specified with the
3688             * <code>admin.email.password</code> portal property keys. They can be
3689             * overridden via a <code>portal-ext.properties</code> file or modified
3690             * through the Portal Settings UI.
3691             * </p>
3692             *
3693             * @param  companyId the primary key of the user's company
3694             * @param  emailAddress the user's email address
3695             * @return <code>true</code> if the notification email includes a new
3696             *         password; <code>false</code> if the notification email only
3697             *         contains a reset link
3698             */
3699            @Override
3700            public boolean sendPasswordByEmailAddress(
3701                            long companyId, String emailAddress)
3702                    throws PortalException {
3703    
3704                    User user = userPersistence.findByC_EA(companyId, emailAddress);
3705    
3706                    return sendPassword(
3707                            user.getCompanyId(), user.getEmailAddress(), null, null, null, null,
3708                            ServiceContextThreadLocal.getServiceContext());
3709            }
3710    
3711            /**
3712             * Sends a password notification email to the user matching the screen name.
3713             * The portal's settings determine whether a password is sent explicitly or
3714             * whether a link for resetting the user's password is sent. The method
3715             * sends the email asynchronously and returns before the email is sent.
3716             *
3717             * <p>
3718             * The content of the notification email is specified with the
3719             * <code>admin.email.password</code> portal property keys. They can be
3720             * overridden via a <code>portal-ext.properties</code> file or modified
3721             * through the Portal Settings UI.
3722             * </p>
3723             *
3724             * @param  companyId the primary key of the user's company
3725             * @param  screenName the user's screen name
3726             * @return <code>true</code> if the notification email includes a new
3727             *         password; <code>false</code> if the notification email only
3728             *         contains a reset link
3729             */
3730            @Override
3731            public boolean sendPasswordByScreenName(long companyId, String screenName)
3732                    throws PortalException {
3733    
3734                    User user = userPersistence.findByC_SN(companyId, screenName);
3735    
3736                    return sendPassword(
3737                            user.getCompanyId(), user.getEmailAddress(), null, null, null, null,
3738                            ServiceContextThreadLocal.getServiceContext());
3739            }
3740    
3741            /**
3742             * Sends a password notification email to the user matching the ID. The
3743             * portal's settings determine whether a password is sent explicitly or
3744             * whether a link for resetting the user's password is sent. The method
3745             * sends the email asynchronously and returns before the email is sent.
3746             *
3747             * <p>
3748             * The content of the notification email is specified with the
3749             * <code>admin.email.password</code> portal property keys. They can be
3750             * overridden via a <code>portal-ext.properties</code> file or modified
3751             * through the Portal Settings UI.
3752             * </p>
3753             *
3754             * @param  userId the user's primary key
3755             * @return <code>true</code> if the notification email includes a new
3756             *         password; <code>false</code> if the notification email only
3757             *         contains a reset link
3758             */
3759            @Override
3760            public boolean sendPasswordByUserId(long userId) throws PortalException {
3761                    User user = userPersistence.findByPrimaryKey(userId);
3762    
3763                    return sendPassword(
3764                            user.getCompanyId(), user.getEmailAddress(), null, null, null, null,
3765                            ServiceContextThreadLocal.getServiceContext());
3766            }
3767    
3768            /**
3769             * Sets the users in the role, removing and adding users to the role as
3770             * necessary.
3771             *
3772             * @param roleId the primary key of the role
3773             * @param userIds the primary keys of the users
3774             */
3775            @Override
3776            public void setRoleUsers(long roleId, long[] userIds)
3777                    throws PortalException {
3778    
3779                    long[] oldUserIds = rolePersistence.getUserPrimaryKeys(roleId);
3780    
3781                    Set<Long> updatedUserIdsSet = SetUtil.symmetricDifference(
3782                            userIds, oldUserIds);
3783    
3784                    long[] updateUserIds = ArrayUtil.toLongArray(updatedUserIdsSet);
3785    
3786                    rolePersistence.setUsers(roleId, userIds);
3787    
3788                    reindex(updateUserIds);
3789    
3790                    PermissionCacheUtil.clearCache(updateUserIds);
3791            }
3792    
3793            /**
3794             * Sets the users in the user group, removing and adding users to the user
3795             * group as necessary.
3796             *
3797             * @param userGroupId the primary key of the user group
3798             * @param userIds the primary keys of the users
3799             */
3800            @Override
3801            @SuppressWarnings("deprecation")
3802            public void setUserGroupUsers(long userGroupId, long[] userIds)
3803                    throws PortalException {
3804    
3805                    if (PropsValues.USER_GROUPS_COPY_LAYOUTS_TO_USER_PERSONAL_SITE) {
3806                            userGroupLocalService.copyUserGroupLayouts(userGroupId, userIds);
3807                    }
3808    
3809                    long[] oldUserIds = userGroupPersistence.getUserPrimaryKeys(
3810                            userGroupId);
3811    
3812                    Set<Long> updatedUserIdsSet = SetUtil.symmetricDifference(
3813                            userIds, oldUserIds);
3814    
3815                    long[] updateUserIds = ArrayUtil.toLongArray(updatedUserIdsSet);
3816    
3817                    userGroupPersistence.setUsers(userGroupId, userIds);
3818    
3819                    reindex(updateUserIds);
3820    
3821                    PermissionCacheUtil.clearCache(updateUserIds);
3822            }
3823    
3824            /**
3825             * Removes the users from the teams of a group.
3826             *
3827             * @param groupId the primary key of the group
3828             * @param userIds the primary keys of the users
3829             */
3830            @Override
3831            public void unsetGroupTeamsUsers(long groupId, long[] userIds)
3832                    throws PortalException {
3833    
3834                    List<Team> teams = teamPersistence.findByGroupId(groupId);
3835    
3836                    for (Team team : teams) {
3837                            unsetTeamUsers(team.getTeamId(), userIds);
3838                    }
3839    
3840                    PermissionCacheUtil.clearCache(userIds);
3841            }
3842    
3843            /**
3844             * Removes the users from the group.
3845             *
3846             * @param groupId the primary key of the group
3847             * @param userIds the primary keys of the users
3848             * @param serviceContext the service context to be applied (optionally
3849             *        <code>null</code>)
3850             */
3851            @Override
3852            public void unsetGroupUsers(
3853                            final long groupId, final long[] userIds,
3854                            ServiceContext serviceContext)
3855                    throws PortalException {
3856    
3857                    userGroupRoleLocalService.deleteUserGroupRoles(
3858                            userIds, groupId, RoleConstants.TYPE_SITE);
3859    
3860                    unsetGroupTeamsUsers(groupId, userIds);
3861    
3862                    groupPersistence.removeUsers(groupId, userIds);
3863    
3864                    reindex(userIds);
3865    
3866                    PermissionCacheUtil.clearCache(userIds);
3867    
3868                    Callable<Void> callable = new Callable<Void>() {
3869    
3870                            @Override
3871                            public Void call() throws Exception {
3872                                    Message message = new Message();
3873    
3874                                    message.put("groupId", groupId);
3875                                    message.put("userIds", userIds);
3876    
3877                                    MessageBusUtil.sendMessage(
3878                                            DestinationNames.SUBSCRIPTION_CLEAN_UP, message);
3879    
3880                                    return null;
3881                            }
3882    
3883                    };
3884    
3885                    TransactionCommitCallbackUtil.registerCallback(callable);
3886            }
3887    
3888            /**
3889             * Removes the users from the organization.
3890             *
3891             * @param organizationId the primary key of the organization
3892             * @param userIds the primary keys of the users
3893             */
3894            @Override
3895            public void unsetOrganizationUsers(
3896                            long organizationId, final long[] userIds)
3897                    throws PortalException {
3898    
3899                    Organization organization = organizationPersistence.findByPrimaryKey(
3900                            organizationId);
3901    
3902                    final Group group = organization.getGroup();
3903    
3904                    userGroupRoleLocalService.deleteUserGroupRoles(
3905                            userIds, group.getGroupId());
3906    
3907                    organizationPersistence.removeUsers(organizationId, userIds);
3908    
3909                    reindex(userIds);
3910    
3911                    PermissionCacheUtil.clearCache(userIds);
3912    
3913                    Callable<Void> callable = new Callable<Void>() {
3914    
3915                            @Override
3916                            public Void call() throws Exception {
3917                                    Message message = new Message();
3918    
3919                                    message.put("groupId", group.getGroupId());
3920                                    message.put("userIds", userIds);
3921    
3922                                    MessageBusUtil.sendMessage(
3923                                            DestinationNames.SUBSCRIPTION_CLEAN_UP, message);
3924    
3925                                    return null;
3926                            }
3927    
3928                    };
3929    
3930                    TransactionCommitCallbackUtil.registerCallback(callable);
3931            }
3932    
3933            /**
3934             * Removes the users from the password policy.
3935             *
3936             * @param passwordPolicyId the primary key of the password policy
3937             * @param userIds the primary keys of the users
3938             */
3939            @Override
3940            public void unsetPasswordPolicyUsers(
3941                    long passwordPolicyId, long[] userIds) {
3942    
3943                    passwordPolicyRelLocalService.deletePasswordPolicyRels(
3944                            passwordPolicyId, User.class.getName(), userIds);
3945            }
3946    
3947            /**
3948             * Removes the users from the role.
3949             *
3950             * @param roleId the primary key of the role
3951             * @param users the users
3952             */
3953            @Override
3954            public void unsetRoleUsers(long roleId, List<User> users)
3955                    throws PortalException {
3956    
3957                    Role role = rolePersistence.findByPrimaryKey(roleId);
3958    
3959                    String roleName = role.getName();
3960    
3961                    if ((roleName.equals(RoleConstants.ADMINISTRATOR) &&
3962                             (getRoleUsersCount(role.getRoleId()) <= 1)) ||
3963                            roleName.equals(RoleConstants.USER)) {
3964    
3965                            return;
3966                    }
3967    
3968                    rolePersistence.removeUsers(roleId, users);
3969    
3970                    Indexer<User> indexer = IndexerRegistryUtil.nullSafeGetIndexer(
3971                            User.class);
3972    
3973                    indexer.reindex(users);
3974    
3975                    long[] userIds = new long[users.size()];
3976    
3977                    for (int i = 0; i < users.size(); i++) {
3978                            User user = users.get(i);
3979    
3980                            userIds[i] = user.getUserId();
3981                    }
3982    
3983                    PermissionCacheUtil.clearCache(userIds);
3984            }
3985    
3986            /**
3987             * Removes the users from the role.
3988             *
3989             * @param roleId the primary key of the role
3990             * @param userIds the primary keys of the users
3991             */
3992            @Override
3993            public void unsetRoleUsers(long roleId, long[] userIds)
3994                    throws PortalException {
3995    
3996                    Role role = rolePersistence.findByPrimaryKey(roleId);
3997    
3998                    String roleName = role.getName();
3999    
4000                    if (roleName.equals(RoleConstants.USER) ||
4001                            (roleName.equals(RoleConstants.ADMINISTRATOR) &&
4002                             getRoleUsersCount(role.getRoleId()) <= 1)) {
4003    
4004                            return;
4005                    }
4006    
4007                    rolePersistence.removeUsers(roleId, userIds);
4008    
4009                    reindex(userIds);
4010    
4011                    PermissionCacheUtil.clearCache(userIds);
4012            }
4013    
4014            /**
4015             * Removes the users from the team.
4016             *
4017             * @param teamId the primary key of the team
4018             * @param userIds the primary keys of the users
4019             */
4020            @Override
4021            public void unsetTeamUsers(long teamId, long[] userIds)
4022                    throws PortalException {
4023    
4024                    teamPersistence.removeUsers(teamId, userIds);
4025    
4026                    reindex(userIds);
4027    
4028                    PermissionCacheUtil.clearCache(userIds);
4029            }
4030    
4031            /**
4032             * Removes the users from the user group.
4033             *
4034             * @param userGroupId the primary key of the user group
4035             * @param userIds the primary keys of the users
4036             */
4037            @Override
4038            public void unsetUserGroupUsers(long userGroupId, long[] userIds)
4039                    throws PortalException {
4040    
4041                    userGroupPersistence.removeUsers(userGroupId, userIds);
4042    
4043                    reindex(userIds);
4044    
4045                    PermissionCacheUtil.clearCache(userIds);
4046            }
4047    
4048            /**
4049             * Updates whether the user has agreed to the terms of use.
4050             *
4051             * @param  userId the primary key of the user
4052             * @param  agreedToTermsOfUse whether the user has agreet to the terms of
4053             *         use
4054             * @return the user
4055             */
4056            @Override
4057            public User updateAgreedToTermsOfUse(
4058                            long userId, boolean agreedToTermsOfUse)
4059                    throws PortalException {
4060    
4061                    User user = userPersistence.findByPrimaryKey(userId);
4062    
4063                    user.setAgreedToTermsOfUse(agreedToTermsOfUse);
4064    
4065                    userPersistence.update(user);
4066    
4067                    return user;
4068            }
4069    
4070            /**
4071             * Updates the user's asset with the new asset categories and tag names,
4072             * removing and adding asset categories and tag names as necessary.
4073             *
4074             * @param userId the primary key of the user
4075             * @param user ID the primary key of the user
4076             * @param assetCategoryIds the primary key's of the new asset categories
4077             * @param assetTagNames the new asset tag names
4078             */
4079            @Override
4080            public void updateAsset(
4081                            long userId, User user, long[] assetCategoryIds,
4082                            String[] assetTagNames)
4083                    throws PortalException {
4084    
4085                    User owner = userPersistence.findByPrimaryKey(userId);
4086    
4087                    Company company = companyPersistence.findByPrimaryKey(
4088                            owner.getCompanyId());
4089    
4090                    Group companyGroup = company.getGroup();
4091    
4092                    assetEntryLocalService.updateEntry(
4093                            userId, companyGroup.getGroupId(), user.getCreateDate(),
4094                            user.getModifiedDate(), User.class.getName(), user.getUserId(),
4095                            user.getUuid(), 0, assetCategoryIds, assetTagNames, false, null,
4096                            null, null, null, user.getFullName(), null, null, null, null, 0, 0,
4097                            null);
4098            }
4099    
4100            /**
4101             * Updates the user's creation date.
4102             *
4103             * @param  userId the primary key of the user
4104             * @param  createDate the new creation date
4105             * @return the user
4106             */
4107            @Override
4108            public User updateCreateDate(long userId, Date createDate)
4109                    throws PortalException {
4110    
4111                    User user = userPersistence.findByPrimaryKey(userId);
4112    
4113                    user.setCreateDate(createDate);
4114    
4115                    userPersistence.update(user);
4116    
4117                    return user;
4118            }
4119    
4120            /**
4121             * Updates the user's email address.
4122             *
4123             * @param  userId the primary key of the user
4124             * @param  password the user's password
4125             * @param  emailAddress1 the user's new email address
4126             * @param  emailAddress2 the user's new email address confirmation
4127             * @return the user
4128             */
4129            @Override
4130            public User updateEmailAddress(
4131                            long userId, String password, String emailAddress1,
4132                            String emailAddress2)
4133                    throws PortalException {
4134    
4135                    emailAddress1 = StringUtil.toLowerCase(emailAddress1.trim());
4136                    emailAddress2 = StringUtil.toLowerCase(emailAddress2.trim());
4137    
4138                    User user = userPersistence.findByPrimaryKey(userId);
4139    
4140                    validateEmailAddress(user, emailAddress1, emailAddress2);
4141    
4142                    setEmailAddress(
4143                            user, password, user.getFirstName(), user.getMiddleName(),
4144                            user.getLastName(), emailAddress1);
4145    
4146                    userPersistence.update(user);
4147    
4148                    Contact contact = user.getContact();
4149    
4150                    contact.setEmailAddress(user.getEmailAddress());
4151    
4152                    contactPersistence.update(contact);
4153    
4154                    return user;
4155            }
4156    
4157            /**
4158             * Updates the user's email address or sends verification email.
4159             *
4160             * @param  userId the primary key of the user
4161             * @param  password the user's password
4162             * @param  emailAddress1 the user's new email address
4163             * @param  emailAddress2 the user's new email address confirmation
4164             * @param  serviceContext the service context to be applied. Must set the
4165             *         portal URL, main path, primary key of the layout, remote address,
4166             *         remote host, and agent for the user.
4167             * @return the user
4168             */
4169            @Override
4170            public User updateEmailAddress(
4171                            long userId, String password, String emailAddress1,
4172                            String emailAddress2, ServiceContext serviceContext)
4173                    throws PortalException {
4174    
4175                    emailAddress1 = StringUtil.toLowerCase(emailAddress1.trim());
4176                    emailAddress2 = StringUtil.toLowerCase(emailAddress2.trim());
4177    
4178                    User user = userPersistence.findByPrimaryKey(userId);
4179    
4180                    validateEmailAddress(user, emailAddress1, emailAddress2);
4181    
4182                    Company company = companyPersistence.findByPrimaryKey(
4183                            user.getCompanyId());
4184    
4185                    if (company.isStrangersVerify() &&
4186                            !StringUtil.equalsIgnoreCase(
4187                                    emailAddress1, user.getEmailAddress())) {
4188    
4189                            sendEmailAddressVerification(user, emailAddress1, serviceContext);
4190                    }
4191                    else {
4192                            setEmailAddress(
4193                                    user, password, user.getFirstName(), user.getMiddleName(),
4194                                    user.getLastName(), emailAddress1);
4195    
4196                            userPersistence.update(user);
4197    
4198                            Contact contact = user.getContact();
4199    
4200                            contact.setEmailAddress(user.getEmailAddress());
4201    
4202                            contactPersistence.update(contact);
4203                    }
4204    
4205                    return user;
4206            }
4207    
4208            /**
4209             * Updates whether the user has verified email address.
4210             *
4211             * @param  userId the primary key of the user
4212             * @param  emailAddressVerified whether the user has verified email address
4213             * @return the user
4214             */
4215            @Override
4216            public User updateEmailAddressVerified(
4217                            long userId, boolean emailAddressVerified)
4218                    throws PortalException {
4219    
4220                    User user = userPersistence.findByPrimaryKey(userId);
4221    
4222                    user.setEmailAddressVerified(emailAddressVerified);
4223    
4224                    userPersistence.update(user);
4225    
4226                    return user;
4227            }
4228    
4229            /**
4230             * Updates the user's Facebook ID.
4231             *
4232             * @param  userId the primary key of the user
4233             * @param  facebookId the user's new Facebook ID
4234             * @return the user
4235             */
4236            @Override
4237            public User updateFacebookId(long userId, long facebookId)
4238                    throws PortalException {
4239    
4240                    User user = userPersistence.findByPrimaryKey(userId);
4241    
4242                    user.setFacebookId(facebookId);
4243    
4244                    userPersistence.update(user);
4245    
4246                    return user;
4247            }
4248    
4249            /**
4250             * Sets the groups the user is in, removing and adding groups as necessary.
4251             *
4252             * @param userId the primary key of the user
4253             * @param newGroupIds the primary keys of the groups
4254             * @param serviceContext the service context to be applied (optionally
4255             *        <code>null</code>)
4256             */
4257            @Override
4258            public void updateGroups(
4259                            long userId, long[] newGroupIds, ServiceContext serviceContext)
4260                    throws PortalException {
4261    
4262                    boolean indexingEnabled = true;
4263    
4264                    if (serviceContext != null) {
4265                            indexingEnabled = serviceContext.isIndexingEnabled();
4266                    }
4267    
4268                    updateGroups(userId, newGroupIds, serviceContext, indexingEnabled);
4269            }
4270    
4271            /**
4272             * Updates a user account that was automatically created when a guest user
4273             * participated in an action (e.g. posting a comment) and only provided his
4274             * name and email address.
4275             *
4276             * @param  creatorUserId the primary key of the creator
4277             * @param  companyId the primary key of the user's company
4278             * @param  autoPassword whether a password should be automatically generated
4279             *         for the user
4280             * @param  password1 the user's password
4281             * @param  password2 the user's password confirmation
4282             * @param  autoScreenName whether a screen name should be automatically
4283             *         generated for the user
4284             * @param  screenName the user's screen name
4285             * @param  emailAddress the user's email address
4286             * @param  facebookId the user's facebook ID
4287             * @param  openId the user's OpenID
4288             * @param  locale the user's locale
4289             * @param  firstName the user's first name
4290             * @param  middleName the user's middle name
4291             * @param  lastName the user's last name
4292             * @param  prefixId the user's name prefix ID
4293             * @param  suffixId the user's name suffix ID
4294             * @param  male whether the user is male
4295             * @param  birthdayMonth the user's birthday month (0-based, meaning 0 for
4296             *         January)
4297             * @param  birthdayDay the user's birthday day
4298             * @param  birthdayYear the user's birthday year
4299             * @param  jobTitle the user's job title
4300             * @param  updateUserInformation whether to update the user's information
4301             * @param  sendEmail whether to send the user an email notification about
4302             *         their new account
4303             * @param  serviceContext the service context to be applied (optionally
4304             *         <code>null</code>). Can set expando bridge attributes for the
4305             *         user.
4306             * @return the user
4307             */
4308            @Override
4309            public User updateIncompleteUser(
4310                            long creatorUserId, long companyId, boolean autoPassword,
4311                            String password1, String password2, boolean autoScreenName,
4312                            String screenName, String emailAddress, long facebookId,
4313                            String openId, Locale locale, String firstName, String middleName,
4314                            String lastName, long prefixId, long suffixId, boolean male,
4315                            int birthdayMonth, int birthdayDay, int birthdayYear,
4316                            String jobTitle, boolean updateUserInformation, boolean sendEmail,
4317                            ServiceContext serviceContext)
4318                    throws PortalException {
4319    
4320                    User user = getUserByEmailAddress(companyId, emailAddress);
4321    
4322                    if (user.getStatus() != WorkflowConstants.STATUS_INCOMPLETE) {
4323                            throw new PortalException("Invalid user status");
4324                    }
4325    
4326                    User defaultUser = getDefaultUser(companyId);
4327    
4328                    if (facebookId > 0) {
4329                            autoPassword = false;
4330    
4331                            if ((password1 == null) || (password2 == null)) {
4332                                    password1 = PwdGenerator.getPassword();
4333                                    password2 = password1;
4334                            }
4335    
4336                            sendEmail = false;
4337                    }
4338    
4339                    if (updateUserInformation) {
4340                            autoScreenName = false;
4341    
4342                            if (PrefsPropsUtil.getBoolean(
4343                                            companyId,
4344                                            PropsKeys.USERS_SCREEN_NAME_ALWAYS_AUTOGENERATE)) {
4345    
4346                                    autoScreenName = true;
4347                            }
4348    
4349                            validate(
4350                                    companyId, user.getUserId(), autoPassword, password1, password2,
4351                                    autoScreenName, screenName, emailAddress, openId, firstName,
4352                                    middleName, lastName, null, locale);
4353    
4354                            if (!autoPassword) {
4355                                    if (Validator.isNull(password1) ||
4356                                            Validator.isNull(password2)) {
4357                                                    throw new UserPasswordException.MustNotBeNull(
4358                                                            user.getUserId());
4359                                    }
4360                            }
4361    
4362                            if (autoScreenName) {
4363                                    ScreenNameGenerator screenNameGenerator =
4364                                            ScreenNameGeneratorFactory.getInstance();
4365    
4366                                    try {
4367                                            screenName = screenNameGenerator.generate(
4368                                                    companyId, user.getUserId(), emailAddress);
4369                                    }
4370                                    catch (Exception e) {
4371                                            throw new SystemException(e);
4372                                    }
4373                            }
4374    
4375                            FullNameGenerator fullNameGenerator =
4376                                    FullNameGeneratorFactory.getInstance();
4377    
4378                            String fullName = fullNameGenerator.getFullName(
4379                                    firstName, middleName, lastName);
4380    
4381                            String greeting = LanguageUtil.format(
4382                                    locale, "welcome-x", fullName, false);
4383    
4384                            if (Validator.isNotNull(password1)) {
4385                                    user.setPassword(PasswordEncryptorUtil.encrypt(password1));
4386                                    user.setPasswordUnencrypted(password1);
4387                            }
4388    
4389                            user.setPasswordEncrypted(true);
4390    
4391                            PasswordPolicy passwordPolicy = defaultUser.getPasswordPolicy();
4392    
4393                            if ((passwordPolicy != null) && passwordPolicy.isChangeable() &&
4394                                    passwordPolicy.isChangeRequired()) {
4395    
4396                                    user.setPasswordReset(true);
4397                            }
4398                            else {
4399                                    user.setPasswordReset(false);
4400                            }
4401    
4402                            user.setScreenName(screenName);
4403                            user.setFacebookId(facebookId);
4404                            user.setOpenId(openId);
4405                            user.setLanguageId(locale.toString());
4406                            user.setTimeZoneId(defaultUser.getTimeZoneId());
4407                            user.setGreeting(greeting);
4408                            user.setFirstName(firstName);
4409                            user.setMiddleName(middleName);
4410                            user.setLastName(lastName);
4411                            user.setJobTitle(jobTitle);
4412                            user.setExpandoBridgeAttributes(serviceContext);
4413    
4414                            Date birthday = getBirthday(
4415                                    birthdayMonth, birthdayDay, birthdayYear);
4416    
4417                            Contact contact = user.getContact();
4418    
4419                            contact.setFirstName(firstName);
4420                            contact.setMiddleName(middleName);
4421                            contact.setLastName(lastName);
4422                            contact.setPrefixId(prefixId);
4423                            contact.setSuffixId(suffixId);
4424                            contact.setMale(male);
4425                            contact.setBirthday(birthday);
4426                            contact.setJobTitle(jobTitle);
4427    
4428                            contactPersistence.update(contact, serviceContext);
4429    
4430                            // Indexer
4431    
4432                            Indexer<User> indexer = IndexerRegistryUtil.nullSafeGetIndexer(
4433                                    User.class);
4434    
4435                            indexer.reindex(user);
4436                    }
4437    
4438                    user.setStatus(WorkflowConstants.STATUS_DRAFT);
4439    
4440                    userPersistence.update(user, serviceContext);
4441    
4442                    // Workflow
4443    
4444                    long workflowUserId = creatorUserId;
4445    
4446                    if (workflowUserId == user.getUserId()) {
4447                            workflowUserId = defaultUser.getUserId();
4448                    }
4449    
4450                    ServiceContext workflowServiceContext = serviceContext;
4451    
4452                    if (workflowServiceContext == null) {
4453                            workflowServiceContext = new ServiceContext();
4454                    }
4455    
4456                    workflowServiceContext.setAttribute("autoPassword", autoPassword);
4457                    workflowServiceContext.setAttribute("passwordUnencrypted", password1);
4458                    workflowServiceContext.setAttribute("sendEmail", sendEmail);
4459    
4460                    WorkflowHandlerRegistryUtil.startWorkflowInstance(
4461                            companyId, workflowUserId, User.class.getName(), user.getUserId(),
4462                            user, workflowServiceContext);
4463    
4464                    return getUserByEmailAddress(companyId, emailAddress);
4465            }
4466    
4467            /**
4468             * Updates the user's job title.
4469             *
4470             * @param  userId the primary key of the user
4471             * @param  jobTitle the user's job title
4472             * @return the user
4473             */
4474            @Override
4475            public User updateJobTitle(long userId, String jobTitle)
4476                    throws PortalException {
4477    
4478                    User user = userPersistence.findByPrimaryKey(userId);
4479    
4480                    user.setJobTitle(jobTitle);
4481    
4482                    userPersistence.update(user);
4483    
4484                    Contact contact = contactPersistence.findByPrimaryKey(
4485                            user.getContactId());
4486    
4487                    contact.setJobTitle(jobTitle);
4488    
4489                    contactPersistence.update(contact);
4490    
4491                    return user;
4492            }
4493    
4494            /**
4495             * Updates the user's last login with the current time and the IP address.
4496             *
4497             * @param  userId the primary key of the user
4498             * @param  loginIP the IP address the user logged in from
4499             * @return the user
4500             */
4501            @Override
4502            public User updateLastLogin(long userId, String loginIP)
4503                    throws PortalException {
4504    
4505                    User user = userPersistence.findByPrimaryKey(userId);
4506    
4507                    Date lastLoginDate = user.getLoginDate();
4508    
4509                    if (lastLoginDate == null) {
4510                            lastLoginDate = new Date();
4511                    }
4512    
4513                    String lastLoginIP = user.getLoginIP();
4514    
4515                    if (lastLoginIP == null) {
4516                            lastLoginIP = loginIP;
4517                    }
4518    
4519                    user.setLoginDate(new Date());
4520                    user.setLoginIP(loginIP);
4521                    user.setLastLoginDate(lastLoginDate);
4522                    user.setLastLoginIP(lastLoginIP);
4523    
4524                    resetFailedLoginAttempts(user, true);
4525    
4526                    return user;
4527            }
4528    
4529            /**
4530             * Updates whether the user is locked out from logging in.
4531             *
4532             * @param  user the user
4533             * @param  lockout whether the user is locked out
4534             * @return the user
4535             */
4536            @Override
4537            public User updateLockout(User user, boolean lockout)
4538                    throws PortalException {
4539    
4540                    PasswordPolicy passwordPolicy = user.getPasswordPolicy();
4541    
4542                    if ((passwordPolicy == null) || !passwordPolicy.isLockout()) {
4543                            return user;
4544                    }
4545    
4546                    Date lockoutDate = null;
4547    
4548                    if (lockout) {
4549                            lockoutDate = new Date();
4550                    }
4551    
4552                    user.setLockout(lockout);
4553                    user.setLockoutDate(lockoutDate);
4554    
4555                    if (!lockout) {
4556                            user.setFailedLoginAttempts(0);
4557                    }
4558    
4559                    userPersistence.update(user);
4560    
4561                    return user;
4562            }
4563    
4564            /**
4565             * Updates whether the user is locked out from logging in.
4566             *
4567             * @param  companyId the primary key of the user's company
4568             * @param  emailAddress the user's email address
4569             * @param  lockout whether the user is locked out
4570             * @return the user
4571             */
4572            @Override
4573            public User updateLockoutByEmailAddress(
4574                            long companyId, String emailAddress, boolean lockout)
4575                    throws PortalException {
4576    
4577                    User user = getUserByEmailAddress(companyId, emailAddress);
4578    
4579                    return updateLockout(user, lockout);
4580            }
4581    
4582            /**
4583             * Updates whether the user is locked out from logging in.
4584             *
4585             * @param  userId the primary key of the user
4586             * @param  lockout whether the user is locked out
4587             * @return the user
4588             */
4589            @Override
4590            public User updateLockoutById(long userId, boolean lockout)
4591                    throws PortalException {
4592    
4593                    User user = userPersistence.findByPrimaryKey(userId);
4594    
4595                    return updateLockout(user, lockout);
4596            }
4597    
4598            /**
4599             * Updates whether the user is locked out from logging in.
4600             *
4601             * @param  companyId the primary key of the user's company
4602             * @param  screenName the user's screen name
4603             * @param  lockout whether the user is locked out
4604             * @return the user
4605             */
4606            @Override
4607            public User updateLockoutByScreenName(
4608                            long companyId, String screenName, boolean lockout)
4609                    throws PortalException {
4610    
4611                    User user = getUserByScreenName(companyId, screenName);
4612    
4613                    return updateLockout(user, lockout);
4614            }
4615    
4616            /**
4617             * Updates the user's modified date.
4618             *
4619             * @param  userId the primary key of the user
4620             * @param  modifiedDate the new modified date
4621             * @return the user
4622             */
4623            @Override
4624            public User updateModifiedDate(long userId, Date modifiedDate)
4625                    throws PortalException {
4626    
4627                    User user = userPersistence.findByPrimaryKey(userId);
4628    
4629                    userPersistence.update(user);
4630    
4631                    return user;
4632            }
4633    
4634            /**
4635             * Updates the user's OpenID.
4636             *
4637             * @param  userId the primary key of the user
4638             * @param  openId the new OpenID
4639             * @return the user
4640             */
4641            @Override
4642            public User updateOpenId(long userId, String openId)
4643                    throws PortalException {
4644    
4645                    openId = openId.trim();
4646    
4647                    User user = userPersistence.findByPrimaryKey(userId);
4648    
4649                    user.setOpenId(openId);
4650    
4651                    userPersistence.update(user);
4652    
4653                    return user;
4654            }
4655    
4656            /**
4657             * Sets the organizations that the user is in, removing and adding
4658             * organizations as necessary.
4659             *
4660             * @param userId the primary key of the user
4661             * @param newOrganizationIds the primary keys of the organizations
4662             * @param serviceContext the service context to be applied. Must set whether
4663             *        user indexing is enabled.
4664             */
4665            @Override
4666            public void updateOrganizations(
4667                            long userId, long[] newOrganizationIds,
4668                            ServiceContext serviceContext)
4669                    throws PortalException {
4670    
4671                    updateOrganizations(
4672                            userId, newOrganizationIds, serviceContext.isIndexingEnabled());
4673            }
4674    
4675            /**
4676             * Updates the user's password without tracking or validation of the change.
4677             *
4678             * @param  userId the primary key of the user
4679             * @param  password1 the user's new password
4680             * @param  password2 the user's new password confirmation
4681             * @param  passwordReset whether the user should be asked to reset their
4682             *         password the next time they log in
4683             * @return the user
4684             */
4685            @Override
4686            public User updatePassword(
4687                            long userId, String password1, String password2,
4688                            boolean passwordReset)
4689                    throws PortalException {
4690    
4691                    return updatePassword(
4692                            userId, password1, password2, passwordReset, false);
4693            }
4694    
4695            /**
4696             * Updates the user's password, optionally with tracking and validation of
4697             * the change.
4698             *
4699             * @param  userId the primary key of the user
4700             * @param  password1 the user's new password
4701             * @param  password2 the user's new password confirmation
4702             * @param  passwordReset whether the user should be asked to reset their
4703             *         password the next time they login
4704             * @param  silentUpdate whether the password should be updated without being
4705             *         tracked, or validated. Primarily used for password imports.
4706             * @return the user
4707             */
4708            @Override
4709            public User updatePassword(
4710                            long userId, String password1, String password2,
4711                            boolean passwordReset, boolean silentUpdate)
4712                    throws PortalException {
4713    
4714                    User user = userPersistence.findByPrimaryKey(userId);
4715    
4716                    if (!silentUpdate) {
4717                            validatePassword(user.getCompanyId(), userId, password1, password2);
4718                    }
4719    
4720                    String oldEncPwd = user.getPassword();
4721    
4722                    if (!user.isPasswordEncrypted()) {
4723                            oldEncPwd = PasswordEncryptorUtil.encrypt(user.getPassword());
4724                    }
4725    
4726                    String newEncPwd = PasswordEncryptorUtil.encrypt(password1);
4727    
4728                    if (user.hasCompanyMx()) {
4729                            mailService.updatePassword(user.getCompanyId(), userId, password1);
4730                    }
4731    
4732                    user.setPassword(newEncPwd);
4733                    user.setPasswordUnencrypted(password1);
4734                    user.setPasswordEncrypted(true);
4735                    user.setPasswordReset(passwordReset);
4736    
4737                    if (!silentUpdate || (user.getPasswordModifiedDate() == null)) {
4738                            user.setPasswordModifiedDate(new Date());
4739                    }
4740    
4741                    user.setDigest(StringPool.BLANK);
4742                    user.setGraceLoginCount(0);
4743    
4744                    if (!silentUpdate) {
4745                            user.setPasswordModified(true);
4746                    }
4747    
4748                    try {
4749                            userPersistence.update(user);
4750                    }
4751                    catch (ModelListenerException mle) {
4752                            String msg = GetterUtil.getString(mle.getCause().getMessage());
4753    
4754                            if (LDAPSettingsUtil.isPasswordPolicyEnabled(user.getCompanyId())) {
4755                                    String errorPasswordHistory =
4756                                            LDAPSettingsUtil.getErrorPasswordHistory(
4757                                                    user.getCompanyId());
4758    
4759                                    if (msg.contains(errorPasswordHistory)) {
4760                                            throw new UserPasswordException.MustNotBeRecentlyUsed(
4761                                                    userId);
4762                                    }
4763                            }
4764    
4765                            throw new UserPasswordException.MustComplyWithModelListeners(
4766                                    userId, mle);
4767                    }
4768    
4769                    if (!silentUpdate) {
4770                            user.setPasswordModified(false);
4771    
4772                            passwordTrackerLocalService.trackPassword(userId, oldEncPwd);
4773                    }
4774    
4775                    if (!silentUpdate && (PrincipalThreadLocal.getUserId() != userId)) {
4776                            sendPasswordNotification(
4777                                    user, user.getCompanyId(), password1, null, null, null, null,
4778                                    null, ServiceContextThreadLocal.getServiceContext());
4779                    }
4780    
4781                    return user;
4782            }
4783    
4784            /**
4785             * Updates the user's password with manually input information. This method
4786             * should only be used when performing maintenance.
4787             *
4788             * @param  userId the primary key of the user
4789             * @param  password the user's new password
4790             * @param  passwordEncrypted the user's new encrypted password
4791             * @param  passwordReset whether the user should be asked to reset their
4792             *         password the next time they login
4793             * @param  passwordModifiedDate the new password modified date
4794             * @return the user
4795             */
4796            @Override
4797            public User updatePasswordManually(
4798                            long userId, String password, boolean passwordEncrypted,
4799                            boolean passwordReset, Date passwordModifiedDate)
4800                    throws PortalException {
4801    
4802                    // This method should only be used to manually massage data
4803    
4804                    User user = userPersistence.findByPrimaryKey(userId);
4805    
4806                    user.setPassword(password);
4807                    user.setPasswordEncrypted(passwordEncrypted);
4808                    user.setPasswordReset(passwordReset);
4809                    user.setPasswordModifiedDate(passwordModifiedDate);
4810                    user.setDigest(StringPool.BLANK);
4811    
4812                    userPersistence.update(user);
4813    
4814                    return user;
4815            }
4816    
4817            /**
4818             * Updates whether the user should be asked to reset their password the next
4819             * time they login.
4820             *
4821             * @param  userId the primary key of the user
4822             * @param  passwordReset whether the user should be asked to reset their
4823             *         password the next time they login
4824             * @return the user
4825             */
4826            @Override
4827            public User updatePasswordReset(long userId, boolean passwordReset)
4828                    throws PortalException {
4829    
4830                    User user = userPersistence.findByPrimaryKey(userId);
4831    
4832                    user.setPasswordReset(passwordReset);
4833    
4834                    userPersistence.update(user);
4835    
4836                    return user;
4837            }
4838    
4839            /**
4840             * Updates the user's portrait image.
4841             *
4842             * @param  userId the primary key of the user
4843             * @param  bytes the new portrait image data
4844             * @return the user
4845             */
4846            @Override
4847            public User updatePortrait(long userId, byte[] bytes)
4848                    throws PortalException {
4849    
4850                    User user = userPersistence.findByPrimaryKey(userId);
4851    
4852                    PortalUtil.updateImageId(
4853                            user, true, bytes, "portraitId",
4854                            PrefsPropsUtil.getLong(PropsKeys.USERS_IMAGE_MAX_SIZE),
4855                            PropsValues.USERS_IMAGE_MAX_HEIGHT,
4856                            PropsValues.USERS_IMAGE_MAX_WIDTH);
4857    
4858                    return userPersistence.update(user);
4859            }
4860    
4861            /**
4862             * Updates the user's password reset question and answer.
4863             *
4864             * @param  userId the primary key of the user
4865             * @param  question the user's new password reset question
4866             * @param  answer the user's new password reset answer
4867             * @return the user
4868             */
4869            @Override
4870            public User updateReminderQuery(long userId, String question, String answer)
4871                    throws PortalException {
4872    
4873                    validateReminderQuery(question, answer);
4874    
4875                    User user = userPersistence.findByPrimaryKey(userId);
4876    
4877                    user.setReminderQueryQuestion(question);
4878                    user.setReminderQueryAnswer(answer);
4879    
4880                    userPersistence.update(user);
4881    
4882                    return user;
4883            }
4884    
4885            /**
4886             * Updates the user's screen name.
4887             *
4888             * @param  userId the primary key of the user
4889             * @param  screenName the user's new screen name
4890             * @return the user
4891             */
4892            @Override
4893            public User updateScreenName(long userId, String screenName)
4894                    throws PortalException {
4895    
4896                    // User
4897    
4898                    User user = userPersistence.findByPrimaryKey(userId);
4899    
4900                    screenName = getLogin(screenName);
4901    
4902                    validateScreenName(user.getCompanyId(), userId, screenName);
4903    
4904                    if (!StringUtil.equalsIgnoreCase(user.getScreenName(), screenName)) {
4905                            user.setDigest(StringPool.BLANK);
4906                    }
4907    
4908                    user.setScreenName(screenName);
4909    
4910                    userPersistence.update(user);
4911    
4912                    // Group
4913    
4914                    Group group = groupLocalService.getUserGroup(
4915                            user.getCompanyId(), userId);
4916    
4917                    group.setFriendlyURL(StringPool.SLASH + screenName);
4918    
4919                    groupPersistence.update(group);
4920    
4921                    return user;
4922            }
4923    
4924            /**
4925             * Updates the user's workflow status.
4926             *
4927             * @param      userId the primary key of the user
4928             * @param      status the user's new workflow status
4929             * @return     the user
4930             * @deprecated As of 7.0.0, replaced by {@link #updateStatus(long, int,
4931             *             ServiceContext)}
4932             */
4933            @Deprecated
4934            @Override
4935            public User updateStatus(long userId, int status) throws PortalException {
4936                    return updateStatus(userId, status, new ServiceContext());
4937            }
4938    
4939            /**
4940             * Updates the user's workflow status.
4941             *
4942             * @param  userId the primary key of the user
4943             * @param  status the user's new workflow status
4944             * @param  serviceContext the service context to be applied. You can specify
4945             *         an unencrypted custom password (used by an LDAP listener) for the
4946             *         user via attribute <code>passwordUnencrypted</code>.
4947             * @return the user
4948             */
4949            @Override
4950            public User updateStatus(
4951                            long userId, int status, ServiceContext serviceContext)
4952                    throws PortalException {
4953    
4954                    User user = userPersistence.findByPrimaryKey(userId);
4955    
4956                    if ((status == WorkflowConstants.STATUS_APPROVED) &&
4957                            (user.getStatus() != WorkflowConstants.STATUS_APPROVED)) {
4958    
4959                            validateCompanyMaxUsers(user.getCompanyId());
4960                    }
4961    
4962                    String passwordUnencrypted = (String)serviceContext.getAttribute(
4963                            "passwordUnencrypted");
4964    
4965                    if (Validator.isNotNull(passwordUnencrypted)) {
4966                            user.setPasswordUnencrypted(passwordUnencrypted);
4967                    }
4968    
4969                    user.setStatus(status);
4970    
4971                    userPersistence.update(user);
4972    
4973                    reindex(user);
4974    
4975                    Group group = user.getGroup();
4976    
4977                    if (status == WorkflowConstants.STATUS_INACTIVE) {
4978                            group.setActive(false);
4979                    }
4980                    else {
4981                            group.setActive(true);
4982                    }
4983    
4984                    groupLocalService.updateGroup(group);
4985    
4986                    return user;
4987            }
4988    
4989            /**
4990             * Updates the user.
4991             *
4992             * @param  userId the primary key of the user
4993             * @param  oldPassword the user's old password
4994             * @param  newPassword1 the user's new password (optionally
4995             *         <code>null</code>)
4996             * @param  newPassword2 the user's new password confirmation (optionally
4997             *         <code>null</code>)
4998             * @param  passwordReset whether the user should be asked to reset their
4999             *         password the next time they login
5000             * @param  reminderQueryQuestion the user's new password reset question
5001             * @param  reminderQueryAnswer the user's new password reset answer
5002             * @param  screenName the user's new screen name
5003             * @param  emailAddress the user's new email address
5004             * @param  facebookId the user's new Facebook ID
5005             * @param  openId the user's new OpenID
5006             * @param  portrait whether to update the user's portrait image
5007             * @param  portraitBytes the new portrait image data
5008             * @param  languageId the user's new language ID
5009             * @param  timeZoneId the user's new time zone ID
5010             * @param  greeting the user's new greeting
5011             * @param  comments the user's new comments
5012             * @param  firstName the user's new first name
5013             * @param  middleName the user's new middle name
5014             * @param  lastName the user's new last name
5015             * @param  prefixId the user's new name prefix ID
5016             * @param  suffixId the user's new name suffix ID
5017             * @param  male whether user is male
5018             * @param  birthdayMonth the user's new birthday month (0-based, meaning 0
5019             *         for January)
5020             * @param  birthdayDay the user's new birthday day
5021             * @param  birthdayYear the user's birthday year
5022             * @param  smsSn the user's new SMS screen name
5023             * @param  facebookSn the user's new Facebook screen name
5024             * @param  jabberSn the user's new Jabber screen name
5025             * @param  skypeSn the user's new Skype screen name
5026             * @param  twitterSn the user's new Twitter screen name
5027             * @param  jobTitle the user's new job title
5028             * @param  groupIds the primary keys of the user's groups
5029             * @param  organizationIds the primary keys of the user's organizations
5030             * @param  roleIds the primary keys of the user's roles
5031             * @param  userGroupRoles the user user's group roles
5032             * @param  userGroupIds the primary keys of the user's user groups
5033             * @param  serviceContext the service context to be applied (optionally
5034             *         <code>null</code>). Can set the UUID (with the <code>uuid</code>
5035             *         attribute), asset category IDs, asset tag names, and expando
5036             *         bridge attributes for the user.
5037             * @return the user
5038             */
5039            @Override
5040            @SuppressWarnings("deprecation")
5041            public User updateUser(
5042                            long userId, String oldPassword, String newPassword1,
5043                            String newPassword2, boolean passwordReset,
5044                            String reminderQueryQuestion, String reminderQueryAnswer,
5045                            String screenName, String emailAddress, long facebookId,
5046                            String openId, boolean portrait, byte[] portraitBytes,
5047                            String languageId, String timeZoneId, String greeting,
5048                            String comments, String firstName, String middleName,
5049                            String lastName, long prefixId, long suffixId, boolean male,
5050                            int birthdayMonth, int birthdayDay, int birthdayYear, String smsSn,
5051                            String facebookSn, String jabberSn, String skypeSn,
5052                            String twitterSn, String jobTitle, long[] groupIds,
5053                            long[] organizationIds, long[] roleIds,
5054                            List<UserGroupRole> userGroupRoles, long[] userGroupIds,
5055                            ServiceContext serviceContext)
5056                    throws PortalException {
5057    
5058                    // User
5059    
5060                    User user = userPersistence.findByPrimaryKey(userId);
5061                    Company company = companyPersistence.findByPrimaryKey(
5062                            user.getCompanyId());
5063                    String password = oldPassword;
5064                    screenName = getLogin(screenName);
5065                    emailAddress = StringUtil.toLowerCase(emailAddress.trim());
5066                    openId = openId.trim();
5067                    String oldFullName = user.getFullName();
5068                    facebookSn = StringUtil.toLowerCase(facebookSn.trim());
5069                    jabberSn = StringUtil.toLowerCase(jabberSn.trim());
5070                    skypeSn = StringUtil.toLowerCase(skypeSn.trim());
5071                    twitterSn = StringUtil.toLowerCase(twitterSn.trim());
5072    
5073                    EmailAddressGenerator emailAddressGenerator =
5074                            EmailAddressGeneratorFactory.getInstance();
5075    
5076                    if (emailAddressGenerator.isGenerated(emailAddress)) {
5077                            emailAddress = StringPool.BLANK;
5078                    }
5079    
5080                    if (!PropsValues.USERS_EMAIL_ADDRESS_REQUIRED &&
5081                            Validator.isNull(emailAddress)) {
5082    
5083                            emailAddress = emailAddressGenerator.generate(
5084                                    user.getCompanyId(), userId);
5085                    }
5086    
5087                    Locale locale = LocaleUtil.fromLanguageId(languageId);
5088    
5089                    validate(
5090                            userId, screenName, emailAddress, openId, firstName, middleName,
5091                            lastName, smsSn, locale);
5092    
5093                    if (Validator.isNotNull(newPassword1) ||
5094                            Validator.isNotNull(newPassword2)) {
5095    
5096                            user = updatePassword(
5097                                    userId, newPassword1, newPassword2, passwordReset);
5098    
5099                            password = newPassword1;
5100    
5101                            user.setDigest(StringPool.BLANK);
5102                    }
5103    
5104                    if (user.getContactId() <= 0) {
5105                            user.setContactId(counterLocalService.increment());
5106                    }
5107    
5108                    user.setPasswordReset(passwordReset);
5109    
5110                    if (Validator.isNotNull(reminderQueryQuestion) &&
5111                            Validator.isNotNull(reminderQueryAnswer)) {
5112    
5113                            user.setReminderQueryQuestion(reminderQueryQuestion);
5114                            user.setReminderQueryAnswer(reminderQueryAnswer);
5115                    }
5116    
5117                    if (!StringUtil.equalsIgnoreCase(user.getScreenName(), screenName)) {
5118                            user.setScreenName(screenName);
5119    
5120                            user.setDigest(StringPool.BLANK);
5121                    }
5122    
5123                    boolean sendEmailAddressVerification = false;
5124    
5125                    if (company.isStrangersVerify() &&
5126                            !StringUtil.equalsIgnoreCase(
5127                                    emailAddress, user.getEmailAddress())) {
5128    
5129                            sendEmailAddressVerification = true;
5130                    }
5131                    else {
5132                            setEmailAddress(
5133                                    user, password, firstName, middleName, lastName, emailAddress);
5134                    }
5135    
5136                    if (serviceContext != null) {
5137                            String uuid = serviceContext.getUuid();
5138    
5139                            if (Validator.isNotNull(uuid)) {
5140                                    user.setUuid(uuid);
5141                            }
5142                    }
5143    
5144                    user.setFacebookId(facebookId);
5145    
5146                    Long ldapServerId = null;
5147    
5148                    if (serviceContext != null) {
5149                            ldapServerId = (Long)serviceContext.getAttribute("ldapServerId");
5150                    }
5151    
5152                    if (ldapServerId != null) {
5153                            user.setLdapServerId(ldapServerId);
5154                    }
5155    
5156                    user.setOpenId(openId);
5157    
5158                    PortalUtil.updateImageId(
5159                            user, portrait, portraitBytes, "portraitId",
5160                            PrefsPropsUtil.getLong(PropsKeys.USERS_IMAGE_MAX_SIZE),
5161                            PropsValues.USERS_IMAGE_MAX_HEIGHT,
5162                            PropsValues.USERS_IMAGE_MAX_WIDTH);
5163    
5164                    user.setLanguageId(languageId);
5165                    user.setTimeZoneId(timeZoneId);
5166                    user.setGreeting(greeting);
5167                    user.setComments(comments);
5168                    user.setFirstName(firstName);
5169                    user.setMiddleName(middleName);
5170                    user.setLastName(lastName);
5171                    user.setJobTitle(jobTitle);
5172                    user.setExpandoBridgeAttributes(serviceContext);
5173    
5174                    userPersistence.update(user, serviceContext);
5175    
5176                    // Contact
5177    
5178                    Date birthday = getBirthday(birthdayMonth, birthdayDay, birthdayYear);
5179    
5180                    long contactId = user.getContactId();
5181    
5182                    Contact contact = contactPersistence.fetchByPrimaryKey(contactId);
5183    
5184                    if (contact == null) {
5185                            contact = contactPersistence.create(contactId);
5186    
5187                            contact.setCompanyId(user.getCompanyId());
5188                            contact.setUserName(StringPool.BLANK);
5189                            contact.setClassName(User.class.getName());
5190                            contact.setClassPK(user.getUserId());
5191                            contact.setAccountId(company.getAccountId());
5192                            contact.setParentContactId(
5193                                    ContactConstants.DEFAULT_PARENT_CONTACT_ID);
5194                    }
5195    
5196                    contact.setEmailAddress(user.getEmailAddress());
5197                    contact.setFirstName(firstName);
5198                    contact.setMiddleName(middleName);
5199                    contact.setLastName(lastName);
5200                    contact.setPrefixId(prefixId);
5201                    contact.setSuffixId(suffixId);
5202                    contact.setMale(male);
5203                    contact.setBirthday(birthday);
5204                    contact.setSmsSn(smsSn);
5205                    contact.setFacebookSn(facebookSn);
5206                    contact.setJabberSn(jabberSn);
5207                    contact.setSkypeSn(skypeSn);
5208                    contact.setTwitterSn(twitterSn);
5209                    contact.setJobTitle(jobTitle);
5210    
5211                    contactPersistence.update(contact, serviceContext);
5212    
5213                    // Group
5214    
5215                    Group group = groupLocalService.getUserGroup(
5216                            user.getCompanyId(), userId);
5217    
5218                    group.setFriendlyURL(StringPool.SLASH + screenName);
5219    
5220                    groupPersistence.update(group);
5221    
5222                    // Groups and organizations
5223    
5224                    // See LPS-33205. Cache the user's list of user group roles because
5225                    // adding or removing groups may add or remove user group roles
5226                    // depending on the site default user associations.
5227    
5228                    List<UserGroupRole> previousUserGroupRoles =
5229                            userGroupRolePersistence.findByUserId(userId);
5230    
5231                    updateGroups(userId, groupIds, serviceContext, false);
5232                    updateOrganizations(userId, organizationIds, false);
5233    
5234                    // Roles
5235    
5236                    if (roleIds != null) {
5237                            roleIds = UsersAdminUtil.addRequiredRoles(user, roleIds);
5238    
5239                            userPersistence.setRoles(userId, roleIds);
5240                    }
5241    
5242                    // User group roles
5243    
5244                    updateUserGroupRoles(
5245                            user, groupIds, organizationIds, userGroupRoles,
5246                            previousUserGroupRoles);
5247    
5248                    // User groups
5249    
5250                    if (userGroupIds != null) {
5251                            if (PropsValues.USER_GROUPS_COPY_LAYOUTS_TO_USER_PERSONAL_SITE) {
5252                                    userGroupLocalService.copyUserGroupLayouts(
5253                                            userGroupIds, userId);
5254                            }
5255    
5256                            userPersistence.setUserGroups(userId, userGroupIds);
5257                    }
5258    
5259                    // Announcements
5260    
5261                    announcementsDeliveryLocalService.getUserDeliveries(user.getUserId());
5262    
5263                    // Asset
5264    
5265                    if (serviceContext != null) {
5266                            updateAsset(
5267                                    userId, user, serviceContext.getAssetCategoryIds(),
5268                                    serviceContext.getAssetTagNames());
5269                    }
5270    
5271                    // Message boards
5272    
5273                    if (GetterUtil.getBoolean(
5274                                    PropsKeys.USERS_UPDATE_USER_NAME + MBMessage.class.getName()) &&
5275                            !oldFullName.equals(user.getFullName())) {
5276    
5277                            mbMessageLocalService.updateUserName(userId, user.getFullName());
5278                    }
5279    
5280                    // Indexer
5281    
5282                    if ((serviceContext == null) || serviceContext.isIndexingEnabled()) {
5283                            Indexer<User> indexer = IndexerRegistryUtil.nullSafeGetIndexer(
5284                                    User.class);
5285    
5286                            indexer.reindex(user);
5287                    }
5288    
5289                    // Email address verification
5290    
5291                    if ((serviceContext != null) && sendEmailAddressVerification) {
5292                            sendEmailAddressVerification(user, emailAddress, serviceContext);
5293                    }
5294    
5295                    // Permission cache
5296    
5297                    PermissionCacheUtil.clearCache(userId);
5298    
5299                    return user;
5300            }
5301    
5302            /**
5303             * Updates the user.
5304             *
5305             * @param      userId the primary key of the user
5306             * @param      oldPassword the user's old password
5307             * @param      newPassword1 the user's new password (optionally
5308             *             <code>null</code>)
5309             * @param      newPassword2 the user's new password confirmation (optionally
5310             *             <code>null</code>)
5311             * @param      passwordReset whether the user should be asked to reset their
5312             *             password the next time they login
5313             * @param      reminderQueryQuestion the user's new password reset question
5314             * @param      reminderQueryAnswer the user's new password reset answer
5315             * @param      screenName the user's new screen name
5316             * @param      emailAddress the user's new email address
5317             * @param      facebookId the user's new Facebook ID
5318             * @param      openId the user's new OpenID
5319             * @param      languageId the user's new language ID
5320             * @param      timeZoneId the user's new time zone ID
5321             * @param      greeting the user's new greeting
5322             * @param      comments the user's new comments
5323             * @param      firstName the user's new first name
5324             * @param      middleName the user's new middle name
5325             * @param      lastName the user's new last name
5326             * @param      prefixId the user's new name prefix ID
5327             * @param      suffixId the user's new name suffix ID
5328             * @param      male whether user is male
5329             * @param      birthdayMonth the user's new birthday month (0-based, meaning
5330             *             0 for January)
5331             * @param      birthdayDay the user's new birthday day
5332             * @param      birthdayYear the user's birthday year
5333             * @param      smsSn the user's new SMS screen name
5334             * @param      facebookSn the user's new Facebook screen name
5335             * @param      jabberSn the user's new Jabber screen name
5336             * @param      skypeSn the user's new Skype screen name
5337             * @param      twitterSn the user's new Twitter screen name
5338             * @param      jobTitle the user's new job title
5339             * @param      groupIds the primary keys of the user's groups
5340             * @param      organizationIds the primary keys of the user's organizations
5341             * @param      roleIds the primary keys of the user's roles
5342             * @param      userGroupRoles the user user's group roles
5343             * @param      userGroupIds the primary keys of the user's user groups
5344             * @param      serviceContext the service context to be applied (optionally
5345             *             <code>null</code>). Can set the UUID (with the
5346             *             <code>uuid</code> attribute), asset category IDs, asset tag
5347             *             names, and expando bridge attributes for the user.
5348             * @return     the user
5349             * @deprecated As of 7.0.0, replaced by {@link #updateUser(long, String,
5350             *             String, String, boolean, String, String, String, String,
5351             *             long, String, boolean, byte[], String, String, String,
5352             *             String, String, String, String, int, int, boolean, int, int,
5353             *             int, String, String, String, String, String, String, String,
5354             *             String, String, String, String, long[], long[], long[], List,
5355             *             long[], ServiceContext)}
5356             */
5357            @Deprecated
5358            @Override
5359            public User updateUser(
5360                            long userId, String oldPassword, String newPassword1,
5361                            String newPassword2, boolean passwordReset,
5362                            String reminderQueryQuestion, String reminderQueryAnswer,
5363                            String screenName, String emailAddress, long facebookId,
5364                            String openId, String languageId, String timeZoneId,
5365                            String greeting, String comments, String firstName,
5366                            String middleName, String lastName, long prefixId, long suffixId,
5367                            boolean male, int birthdayMonth, int birthdayDay, int birthdayYear,
5368                            String smsSn, String facebookSn, String jabberSn, String skypeSn,
5369                            String twitterSn, String jobTitle, long[] groupIds,
5370                            long[] organizationIds, long[] roleIds,
5371                            List<UserGroupRole> userGroupRoles, long[] userGroupIds,
5372                            ServiceContext serviceContext)
5373                    throws PortalException {
5374    
5375                    return updateUser(
5376                            userId, oldPassword, newPassword1, newPassword2, passwordReset,
5377                            reminderQueryQuestion, reminderQueryAnswer, screenName,
5378                            emailAddress, facebookId, openId, true, null, languageId,
5379                            timeZoneId, greeting, comments, firstName, middleName, lastName,
5380                            prefixId, suffixId, male, birthdayMonth, birthdayDay, birthdayYear,
5381                            smsSn, facebookSn, jabberSn, skypeSn, twitterSn, jobTitle, groupIds,
5382                            organizationIds, roleIds, userGroupRoles, userGroupIds,
5383                            serviceContext);
5384            }
5385    
5386            /**
5387             * Verifies the email address of the ticket.
5388             *
5389             * @param ticketKey the ticket key
5390             */
5391            @Override
5392            public void verifyEmailAddress(String ticketKey) throws PortalException {
5393                    Ticket ticket = ticketLocalService.getTicket(ticketKey);
5394    
5395                    if (ticket.isExpired() ||
5396                            (ticket.getType() != TicketConstants.TYPE_EMAIL_ADDRESS)) {
5397    
5398                            throw new NoSuchTicketException("{ticketKey=" + ticketKey + "}");
5399                    }
5400    
5401                    User user = userPersistence.findByPrimaryKey(ticket.getClassPK());
5402    
5403                    String emailAddress = ticket.getExtraInfo();
5404    
5405                    emailAddress = StringUtil.toLowerCase(emailAddress).trim();
5406    
5407                    if (!emailAddress.equals(user.getEmailAddress())) {
5408                            if (userPersistence.fetchByC_EA(
5409                                            user.getCompanyId(), emailAddress) != null) {
5410    
5411                                    throw new UserEmailAddressException.MustNotBeDuplicate(
5412                                            user.getUserId(), emailAddress);
5413                            }
5414    
5415                            setEmailAddress(
5416                                    user, StringPool.BLANK, user.getFirstName(),
5417                                    user.getMiddleName(), user.getLastName(), emailAddress);
5418    
5419                            Contact contact = user.getContact();
5420    
5421                            contact.setEmailAddress(user.getEmailAddress());
5422    
5423                            contactPersistence.update(contact);
5424                    }
5425    
5426                    user.setEmailAddressVerified(true);
5427    
5428                    userPersistence.update(user);
5429    
5430                    ticketLocalService.deleteTicket(ticket);
5431            }
5432    
5433            protected void addDefaultRolesAndTeams(long groupId, long[] userIds)
5434                    throws PortalException {
5435    
5436                    List<Role> defaultSiteRoles = new ArrayList<>();
5437    
5438                    Group group = groupLocalService.getGroup(groupId);
5439    
5440                    UnicodeProperties typeSettingsProperties =
5441                            group.getTypeSettingsProperties();
5442    
5443                    long[] defaultSiteRoleIds = StringUtil.split(
5444                            typeSettingsProperties.getProperty("defaultSiteRoleIds"), 0L);
5445    
5446                    for (long defaultSiteRoleId : defaultSiteRoleIds) {
5447                            Role defaultSiteRole = rolePersistence.fetchByPrimaryKey(
5448                                    defaultSiteRoleId);
5449    
5450                            if (defaultSiteRole == null) {
5451                                    if (_log.isWarnEnabled()) {
5452                                            _log.warn("Unable to find role " + defaultSiteRoleId);
5453                                    }
5454    
5455                                    continue;
5456                            }
5457    
5458                            defaultSiteRoles.add(defaultSiteRole);
5459                    }
5460    
5461                    List<Team> defaultTeams = new ArrayList<>();
5462    
5463                    long[] defaultTeamIds = StringUtil.split(
5464                            typeSettingsProperties.getProperty("defaultTeamIds"), 0L);
5465    
5466                    for (long defaultTeamId : defaultTeamIds) {
5467                            Team defaultTeam = teamPersistence.findByPrimaryKey(defaultTeamId);
5468    
5469                            if (defaultTeam == null) {
5470                                    if (_log.isWarnEnabled()) {
5471                                            _log.warn("Unable to find team " + defaultTeamId);
5472                                    }
5473    
5474                                    continue;
5475                            }
5476    
5477                            defaultTeams.add(defaultTeam);
5478                    }
5479    
5480                    for (long userId : userIds) {
5481                            Set<Long> userRoleIdsSet = new HashSet<>();
5482    
5483                            for (Role role : defaultSiteRoles) {
5484                                    if (!userPersistence.containsRole(userId, role.getRoleId())) {
5485                                            userRoleIdsSet.add(role.getRoleId());
5486                                    }
5487                            }
5488    
5489                            long[] userRoleIds = ArrayUtil.toArray(
5490                                    userRoleIdsSet.toArray(new Long[userRoleIdsSet.size()]));
5491    
5492                            userGroupRoleLocalService.addUserGroupRoles(
5493                                    userId, groupId, userRoleIds);
5494    
5495                            Set<Long> userTeamIdsSet = new HashSet<>();
5496    
5497                            for (Team team : defaultTeams) {
5498                                    if (!userPersistence.containsTeam(userId, team.getTeamId())) {
5499                                            userTeamIdsSet.add(team.getTeamId());
5500                                    }
5501                            }
5502    
5503                            long[] userTeamIds = ArrayUtil.toArray(
5504                                    userTeamIdsSet.toArray(new Long[userTeamIdsSet.size()]));
5505    
5506                            userPersistence.addTeams(userId, userTeamIds);
5507                    }
5508            }
5509    
5510            /**
5511             * Attempts to authenticate the user by their login and password, while
5512             * using the AuthPipeline.
5513             *
5514             * <p>
5515             * Authentication type specifies what <code>login</code> contains.The valid
5516             * values are:
5517             * </p>
5518             *
5519             * <ul>
5520             * <li>
5521             * <code>CompanyConstants.AUTH_TYPE_EA</code> - <code>login</code> is the
5522             * user's email address
5523             * </li>
5524             * <li>
5525             * <code>CompanyConstants.AUTH_TYPE_SN</code> - <code>login</code> is the
5526             * user's screen name
5527             * </li>
5528             * <li>
5529             * <code>CompanyConstants.AUTH_TYPE_ID</code> - <code>login</code> is the
5530             * user's primary key
5531             * </li>
5532             * </ul>
5533             *
5534             * @param  companyId the primary key of the user's company
5535             * @param  login either the user's email address, screen name, or primary
5536             *         key depending on the value of <code>authType</code>
5537             * @param  password the user's password
5538             * @param  authType the type of authentication to perform
5539             * @param  headerMap the header map from the authentication request
5540             * @param  parameterMap the parameter map from the authentication request
5541             * @param  resultsMap the map of authentication results (may be nil). After
5542             *         a successful authentication the user's primary key will be placed
5543             *         under the key <code>userId</code>.
5544             * @return the authentication status. This can be {@link
5545             *         Authenticator#FAILURE} indicating that the user's credentials are
5546             *         invalid, {@link Authenticator#SUCCESS} indicating a successful
5547             *         login, or {@link Authenticator#DNE} indicating that a user with
5548             *         that login does not exist.
5549             * @see    AuthPipeline
5550             */
5551            protected int authenticate(
5552                            long companyId, String login, String password, String authType,
5553                            Map<String, String[]> headerMap, Map<String, String[]> parameterMap,
5554                            Map<String, Object> resultsMap)
5555                    throws PortalException {
5556    
5557                    if (PropsValues.AUTH_LOGIN_DISABLED) {
5558                            return Authenticator.FAILURE;
5559                    }
5560    
5561                    login = StringUtil.toLowerCase(login.trim());
5562    
5563                    long userId = GetterUtil.getLong(login);
5564    
5565                    // User input validation
5566    
5567                    if (authType.equals(CompanyConstants.AUTH_TYPE_EA)) {
5568                            if (Validator.isNull(login)) {
5569                                    throw new UserEmailAddressException.MustNotBeNull();
5570                            }
5571                    }
5572                    else if (authType.equals(CompanyConstants.AUTH_TYPE_SN)) {
5573                            if (Validator.isNull(login)) {
5574                                    throw new UserScreenNameException.MustNotBeNull();
5575                            }
5576                    }
5577                    else if (authType.equals(CompanyConstants.AUTH_TYPE_ID)) {
5578                            if (Validator.isNull(login)) {
5579                                    throw new UserIdException.MustNotBeNull();
5580                            }
5581                    }
5582    
5583                    if (Validator.isNull(password)) {
5584                            throw new UserPasswordException.MustNotBeNull(userId);
5585                    }
5586    
5587                    int authResult = Authenticator.FAILURE;
5588    
5589                    // Pre-authentication pipeline
5590    
5591                    if (authType.equals(CompanyConstants.AUTH_TYPE_EA)) {
5592                            authResult = AuthPipeline.authenticateByEmailAddress(
5593                                    PropsKeys.AUTH_PIPELINE_PRE, companyId, login, password,
5594                                    headerMap, parameterMap);
5595                    }
5596                    else if (authType.equals(CompanyConstants.AUTH_TYPE_SN)) {
5597                            authResult = AuthPipeline.authenticateByScreenName(
5598                                    PropsKeys.AUTH_PIPELINE_PRE, companyId, login, password,
5599                                    headerMap, parameterMap);
5600                    }
5601                    else if (authType.equals(CompanyConstants.AUTH_TYPE_ID)) {
5602                            authResult = AuthPipeline.authenticateByUserId(
5603                                    PropsKeys.AUTH_PIPELINE_PRE, companyId, userId, password,
5604                                    headerMap, parameterMap);
5605                    }
5606    
5607                    // Get user
5608    
5609                    User user = null;
5610    
5611                    if (authType.equals(CompanyConstants.AUTH_TYPE_EA)) {
5612                            user = fetchUserByEmailAddress(companyId, login);
5613                    }
5614                    else if (authType.equals(CompanyConstants.AUTH_TYPE_SN)) {
5615                            user = fetchUserByScreenName(companyId, login);
5616                    }
5617                    else if (authType.equals(CompanyConstants.AUTH_TYPE_ID)) {
5618                            user = userPersistence.fetchByPrimaryKey(GetterUtil.getLong(login));
5619                    }
5620    
5621                    if (user == null) {
5622                            return Authenticator.DNE;
5623                    }
5624    
5625                    if (!isUserAllowedToAuthenticate(user)) {
5626                            return Authenticator.FAILURE;
5627                    }
5628    
5629                    if (!user.isPasswordEncrypted()) {
5630                            user.setPassword(PasswordEncryptorUtil.encrypt(user.getPassword()));
5631                            user.setPasswordEncrypted(true);
5632    
5633                            userPersistence.update(user);
5634                    }
5635    
5636                    // Authenticate against the User_ table
5637    
5638                    boolean skipLiferayCheck = false;
5639    
5640                    if (authResult == Authenticator.SKIP_LIFERAY_CHECK) {
5641                            authResult = Authenticator.SUCCESS;
5642    
5643                            skipLiferayCheck = true;
5644                    }
5645                    else if ((authResult == Authenticator.SUCCESS) &&
5646                                     PropsValues.AUTH_PIPELINE_ENABLE_LIFERAY_CHECK) {
5647    
5648                            boolean authenticated = PwdAuthenticator.authenticate(
5649                                    login, password, user.getPassword());
5650    
5651                            if (authenticated) {
5652                                    authResult = Authenticator.SUCCESS;
5653                            }
5654                            else {
5655                                    authResult = Authenticator.FAILURE;
5656                            }
5657                    }
5658    
5659                    // Post-authentication pipeline
5660    
5661                    if (authResult == Authenticator.SUCCESS) {
5662                            if (authType.equals(CompanyConstants.AUTH_TYPE_EA)) {
5663                                    authResult = AuthPipeline.authenticateByEmailAddress(
5664                                            PropsKeys.AUTH_PIPELINE_POST, companyId, login, password,
5665                                            headerMap, parameterMap);
5666                            }
5667                            else if (authType.equals(CompanyConstants.AUTH_TYPE_SN)) {
5668                                    authResult = AuthPipeline.authenticateByScreenName(
5669                                            PropsKeys.AUTH_PIPELINE_POST, companyId, login, password,
5670                                            headerMap, parameterMap);
5671                            }
5672                            else if (authType.equals(CompanyConstants.AUTH_TYPE_ID)) {
5673                                    authResult = AuthPipeline.authenticateByUserId(
5674                                            PropsKeys.AUTH_PIPELINE_POST, companyId, userId, password,
5675                                            headerMap, parameterMap);
5676                            }
5677                    }
5678    
5679                    if (resultsMap != null) {
5680                            resultsMap.put("userId", user.getUserId());
5681                    }
5682    
5683                    if (authResult == Authenticator.SUCCESS) {
5684    
5685                            // Update digest
5686    
5687                            if (skipLiferayCheck ||
5688                                    !PropsValues.AUTH_PIPELINE_ENABLE_LIFERAY_CHECK ||
5689                                    Validator.isNull(user.getDigest())) {
5690    
5691                                    user = userPersistence.fetchByPrimaryKey(user.getUserId());
5692    
5693                                    String digest = user.getDigest(password);
5694    
5695                                    user.setDigest(digest);
5696    
5697                                    userPersistence.update(user);
5698                            }
5699                    }
5700    
5701                    // Execute code triggered by authentication failure
5702    
5703                    if (authResult == Authenticator.FAILURE) {
5704                            authResult = handleAuthenticationFailure(
5705                                    login, authType, user, headerMap, parameterMap);
5706                    }
5707                    else {
5708                            resetFailedLoginAttempts(user);
5709                    }
5710    
5711                    // PLACEHOLDER 02
5712    
5713                    return authResult;
5714            }
5715    
5716            protected SearchContext buildSearchContext(
5717                    long companyId, String firstName, String middleName, String lastName,
5718                    String fullName, String screenName, String emailAddress, String street,
5719                    String city, String zip, String region, String country, int status,
5720                    LinkedHashMap<String, Object> params, boolean andSearch, int start,
5721                    int end, Sort[] sorts) {
5722    
5723                    SearchContext searchContext = new SearchContext();
5724    
5725                    searchContext.setAndSearch(andSearch);
5726    
5727                    Map<String, Serializable> attributes = new HashMap<>();
5728    
5729                    attributes.put("city", city);
5730                    attributes.put("country", country);
5731                    attributes.put("emailAddress", emailAddress);
5732                    attributes.put("firstName", firstName);
5733                    attributes.put("fullName", fullName);
5734                    attributes.put("lastName", lastName);
5735                    attributes.put("middleName", middleName);
5736                    attributes.put("params", params);
5737                    attributes.put("region", region);
5738                    attributes.put("screenName", screenName);
5739                    attributes.put("street", street);
5740                    attributes.put("status", status);
5741                    attributes.put("zip", zip);
5742    
5743                    searchContext.setAttributes(attributes);
5744    
5745                    searchContext.setCompanyId(companyId);
5746                    searchContext.setEnd(end);
5747    
5748                    if (params != null) {
5749                            String keywords = (String)params.remove("keywords");
5750    
5751                            if (Validator.isNotNull(keywords)) {
5752                                    searchContext.setKeywords(keywords);
5753                            }
5754                    }
5755    
5756                    if (sorts != null) {
5757                            searchContext.setSorts(sorts);
5758                    }
5759    
5760                    searchContext.setStart(start);
5761    
5762                    QueryConfig queryConfig = searchContext.getQueryConfig();
5763    
5764                    queryConfig.setHighlightEnabled(false);
5765                    queryConfig.setScoreEnabled(false);
5766    
5767                    return searchContext;
5768            }
5769    
5770            protected Date getBirthday(
5771                            int birthdayMonth, int birthdayDay, int birthdayYear)
5772                    throws PortalException {
5773    
5774                    Date birthday = PortalUtil.getDate(
5775                            birthdayMonth, birthdayDay, birthdayYear,
5776                            ContactBirthdayException.class);
5777    
5778                    if (birthday.after(new Date())) {
5779                            throw new ContactBirthdayException();
5780                    }
5781    
5782                    return birthday;
5783            }
5784    
5785            protected String getLogin(String login) {
5786                    return StringUtil.lowerCase(StringUtil.trim(login));
5787            }
5788    
5789            protected Sort[] getSorts(OrderByComparator<User> obc) {
5790                    if (obc == null) {
5791                            return new Sort[0];
5792                    }
5793    
5794                    String[] orderByClauses = StringUtil.split(obc.getOrderBy());
5795                    String[] orderByFields = obc.getOrderByFields();
5796    
5797                    Sort[] sorts = new Sort[orderByFields.length];
5798    
5799                    for (int i = 0; i < orderByFields.length; i++) {
5800                            boolean reverse = orderByClauses[i].contains("DESC");
5801    
5802                            sorts[i] = new Sort(orderByFields[i], reverse);
5803                    }
5804    
5805                    return sorts;
5806            }
5807    
5808            protected int handleAuthenticationFailure(
5809                    String login, String authType, User user,
5810                    Map<String, String[]> headerMap, Map<String, String[]> parameterMap) {
5811    
5812                    if (user == null) {
5813                            return Authenticator.DNE;
5814                    }
5815    
5816                    try {
5817                            if (authType.equals(CompanyConstants.AUTH_TYPE_EA)) {
5818                                    AuthPipeline.onFailureByEmailAddress(
5819                                            PropsKeys.AUTH_FAILURE, user.getCompanyId(), login,
5820                                            headerMap, parameterMap);
5821                            }
5822                            else if (authType.equals(CompanyConstants.AUTH_TYPE_SN)) {
5823                                    AuthPipeline.onFailureByScreenName(
5824                                            PropsKeys.AUTH_FAILURE, user.getCompanyId(), login,
5825                                            headerMap, parameterMap);
5826                            }
5827                            else if (authType.equals(CompanyConstants.AUTH_TYPE_ID)) {
5828                                    AuthPipeline.onFailureByUserId(
5829                                            PropsKeys.AUTH_FAILURE, user.getCompanyId(),
5830                                            user.getUserId(), headerMap, parameterMap);
5831                            }
5832    
5833                            user = userPersistence.fetchByPrimaryKey(user.getUserId());
5834    
5835                            if (user == null) {
5836                                    return Authenticator.DNE;
5837                            }
5838    
5839                            // Let LDAP handle max failure event
5840    
5841                            if (!LDAPSettingsUtil.isPasswordPolicyEnabled(
5842                                            user.getCompanyId())) {
5843    
5844                                    PasswordPolicy passwordPolicy = user.getPasswordPolicy();
5845    
5846                                    user = userPersistence.fetchByPrimaryKey(user.getUserId());
5847    
5848                                    int failedLoginAttempts = user.getFailedLoginAttempts();
5849                                    int maxFailures = passwordPolicy.getMaxFailure();
5850    
5851                                    if ((failedLoginAttempts >= maxFailures) &&
5852                                            (maxFailures != 0)) {
5853    
5854                                            if (authType.equals(CompanyConstants.AUTH_TYPE_EA)) {
5855                                                    AuthPipeline.onMaxFailuresByEmailAddress(
5856                                                            PropsKeys.AUTH_MAX_FAILURES, user.getCompanyId(),
5857                                                            login, headerMap, parameterMap);
5858                                            }
5859                                            else if (authType.equals(CompanyConstants.AUTH_TYPE_SN)) {
5860                                                    AuthPipeline.onMaxFailuresByScreenName(
5861                                                            PropsKeys.AUTH_MAX_FAILURES, user.getCompanyId(),
5862                                                            login, headerMap, parameterMap);
5863                                            }
5864                                            else if (authType.equals(CompanyConstants.AUTH_TYPE_ID)) {
5865                                                    AuthPipeline.onMaxFailuresByUserId(
5866                                                            PropsKeys.AUTH_MAX_FAILURES, user.getCompanyId(),
5867                                                            user.getUserId(), headerMap, parameterMap);
5868                                            }
5869                                    }
5870                            }
5871                    }
5872                    catch (Exception e) {
5873                            _log.error(e, e);
5874                    }
5875    
5876                    return Authenticator.FAILURE;
5877            }
5878    
5879            protected boolean isUseCustomSQL(LinkedHashMap<String, Object> params) {
5880                    if (MapUtil.isEmpty(params)) {
5881                            return false;
5882                    }
5883    
5884                    for (String key : params.keySet()) {
5885                            if (!key.equals("inherit") && !key.equals("usersGroups") &&
5886                                    !key.equals("usersOrgs") && !key.equals("usersOrgsCount") &&
5887                                    !key.equals("usersRoles") && !key.equals("usersTeams") &&
5888                                    !key.equals("usersUserGroups")) {
5889    
5890                                    return true;
5891                            }
5892                    }
5893    
5894                    Boolean inherit = (Boolean)params.get("inherit");
5895    
5896                    if ((inherit != null) && inherit) {
5897                            return true;
5898                    }
5899    
5900                    return false;
5901            }
5902    
5903            protected boolean isUserAllowedToAuthenticate(User user)
5904                    throws PortalException {
5905    
5906                    if (user.isDefaultUser()) {
5907                            if (_log.isInfoEnabled()) {
5908                                    _log.info("Authentication is disabled for the default user");
5909                            }
5910    
5911                            return false;
5912                    }
5913                    else if (!user.isActive()) {
5914                            if (_log.isInfoEnabled()) {
5915                                    _log.info(
5916                                            "Authentication is disabled for inactive user " +
5917                                                    user.getUserId());
5918                            }
5919    
5920                            return false;
5921                    }
5922    
5923                    // Check password policy to see if the is account locked out or if the
5924                    // password is expired
5925    
5926                    checkLockout(user);
5927    
5928                    checkPasswordExpired(user);
5929    
5930                    return true;
5931            }
5932    
5933            protected void notifyUser(
5934                    User user, String password, ServiceContext serviceContext) {
5935    
5936                    if (!PrefsPropsUtil.getBoolean(
5937                                    user.getCompanyId(),
5938                                    PropsKeys.ADMIN_EMAIL_USER_ADDED_ENABLED)) {
5939    
5940                            return;
5941                    }
5942    
5943                    String fromName = PrefsPropsUtil.getString(
5944                            user.getCompanyId(), PropsKeys.ADMIN_EMAIL_FROM_NAME);
5945                    String fromAddress = PrefsPropsUtil.getString(
5946                            user.getCompanyId(), PropsKeys.ADMIN_EMAIL_FROM_ADDRESS);
5947    
5948                    String toName = user.getFullName();
5949                    String toAddress = user.getEmailAddress();
5950    
5951                    PortletPreferences companyPortletPreferences =
5952                            PrefsPropsUtil.getPreferences(user.getCompanyId(), true);
5953    
5954                    Map<Locale, String> localizedSubjectMap =
5955                            LocalizationUtil.getLocalizationMap(
5956                                    companyPortletPreferences, "adminEmailUserAddedSubject",
5957                                    PropsKeys.ADMIN_EMAIL_USER_ADDED_SUBJECT);
5958    
5959                    Map<Locale, String> localizedBodyMap = null;
5960    
5961                    if (Validator.isNotNull(password)) {
5962                            localizedBodyMap = LocalizationUtil.getLocalizationMap(
5963                                    companyPortletPreferences, "adminEmailUserAddedBody",
5964                                    PropsKeys.ADMIN_EMAIL_USER_ADDED_BODY);
5965                    }
5966                    else {
5967                            localizedBodyMap = LocalizationUtil.getLocalizationMap(
5968                                    companyPortletPreferences, "adminEmailUserAddedNoPasswordBody",
5969                                    PropsKeys.ADMIN_EMAIL_USER_ADDED_NO_PASSWORD_BODY);
5970                    }
5971    
5972                    SubscriptionSender subscriptionSender = new SubscriptionSender();
5973    
5974                    subscriptionSender.setCompanyId(user.getCompanyId());
5975                    subscriptionSender.setContextAttributes(
5976                            "[$USER_ID$]", user.getUserId(), "[$USER_PASSWORD$]", password,
5977                            "[$USER_SCREENNAME$]", user.getScreenName());
5978                    subscriptionSender.setFrom(fromAddress, fromName);
5979                    subscriptionSender.setHtmlFormat(true);
5980                    subscriptionSender.setLocalizedBodyMap(localizedBodyMap);
5981                    subscriptionSender.setLocalizedSubjectMap(localizedSubjectMap);
5982                    subscriptionSender.setMailId("user", user.getUserId());
5983                    subscriptionSender.setServiceContext(serviceContext);
5984    
5985                    subscriptionSender.addRuntimeSubscribers(toAddress, toName);
5986    
5987                    subscriptionSender.flushNotificationsAsync();
5988            }
5989    
5990            protected void reindex(long userId) throws SearchException {
5991                    Indexer<User> indexer = IndexerRegistryUtil.nullSafeGetIndexer(
5992                            User.class);
5993    
5994                    User user = userLocalService.fetchUser(userId);
5995    
5996                    indexer.reindex(user);
5997            }
5998    
5999            protected void reindex(long[] userIds) throws SearchException {
6000                    Indexer<User> indexer = IndexerRegistryUtil.nullSafeGetIndexer(
6001                            User.class);
6002    
6003                    List<User> users = new ArrayList<>(userIds.length);
6004    
6005                    for (Long userId : userIds) {
6006                            User user = userLocalService.fetchUser(userId);
6007    
6008                            users.add(user);
6009                    }
6010    
6011                    indexer.reindex(users);
6012            }
6013    
6014            protected void reindex(final User user) throws SearchException {
6015                    Indexer<User> indexer = IndexerRegistryUtil.nullSafeGetIndexer(
6016                            User.class);
6017    
6018                    indexer.reindex(user);
6019            }
6020    
6021            protected void resetFailedLoginAttempts(User user) {
6022                    resetFailedLoginAttempts(user, false);
6023            }
6024    
6025            protected void resetFailedLoginAttempts(User user, boolean forceUpdate) {
6026                    if (forceUpdate || (user.getFailedLoginAttempts() > 0)) {
6027                            user.setFailedLoginAttempts(0);
6028    
6029                            userPersistence.update(user);
6030                    }
6031            }
6032    
6033            protected BaseModelSearchResult<User> searchUsers(
6034                            SearchContext searchContext)
6035                    throws PortalException {
6036    
6037                    Indexer<User> indexer = IndexerRegistryUtil.nullSafeGetIndexer(
6038                            User.class);
6039    
6040                    for (int i = 0; i < 10; i++) {
6041                            Hits hits = indexer.search(searchContext);
6042    
6043                            List<User> users = UsersAdminUtil.getUsers(hits);
6044    
6045                            if (users != null) {
6046                                    return new BaseModelSearchResult<>(users, hits.getLength());
6047                            }
6048                    }
6049    
6050                    throw new SearchException(
6051                            "Unable to fix the search index after 10 attempts");
6052            }
6053    
6054            protected void sendPasswordNotification(
6055                    User user, long companyId, String newPassword, String passwordResetURL,
6056                    String fromName, String fromAddress, String subject, String body,
6057                    ServiceContext serviceContext) {
6058    
6059                    if (Validator.isNull(fromName)) {
6060                            fromName = PrefsPropsUtil.getString(
6061                                    companyId, PropsKeys.ADMIN_EMAIL_FROM_NAME);
6062                    }
6063    
6064                    if (Validator.isNull(fromAddress)) {
6065                            fromAddress = PrefsPropsUtil.getString(
6066                                    companyId, PropsKeys.ADMIN_EMAIL_FROM_ADDRESS);
6067                    }
6068    
6069                    String toName = user.getFullName();
6070                    String toAddress = user.getEmailAddress();
6071    
6072                    PortletPreferences companyPortletPreferences =
6073                            PrefsPropsUtil.getPreferences(companyId, true);
6074    
6075                    Map<Locale, String> localizedSubjectMap = null;
6076                    Map<Locale, String> localizedBodyMap = null;
6077    
6078                    String bodyProperty = null;
6079                    String prefix = null;
6080                    String subjectProperty = null;
6081    
6082                    if (Validator.isNotNull(passwordResetURL)) {
6083                            bodyProperty = PropsKeys.ADMIN_EMAIL_PASSWORD_RESET_BODY;
6084                            prefix = "adminEmailPasswordReset";
6085                            subjectProperty = PropsKeys.ADMIN_EMAIL_PASSWORD_RESET_SUBJECT;
6086                    }
6087                    else {
6088                            bodyProperty = PropsKeys.ADMIN_EMAIL_PASSWORD_SENT_BODY;
6089                            prefix = "adminEmailPasswordSent";
6090                            subjectProperty = PropsKeys.ADMIN_EMAIL_PASSWORD_SENT_SUBJECT;
6091                    }
6092    
6093                    if (Validator.isNull(body)) {
6094                            localizedBodyMap = LocalizationUtil.getLocalizationMap(
6095                                    companyPortletPreferences, prefix + "Body", bodyProperty);
6096                    }
6097    
6098                    if (Validator.isNull(subject)) {
6099                            localizedSubjectMap = LocalizationUtil.getLocalizationMap(
6100                                    companyPortletPreferences, prefix + "Subject", subjectProperty);
6101                    }
6102    
6103                    SubscriptionSender subscriptionSender = new SubscriptionSender();
6104    
6105                    subscriptionSender.setCompanyId(companyId);
6106                    subscriptionSender.setContextAttributes(
6107                            "[$PASSWORD_RESET_URL$]", passwordResetURL, "[$REMOTE_ADDRESS$]",
6108                            serviceContext.getRemoteAddr(), "[$REMOTE_HOST$]",
6109                            serviceContext.getRemoteHost(), "[$USER_ID$]", user.getUserId(),
6110                            "[$USER_PASSWORD$]", newPassword, "[$USER_SCREENNAME$]",
6111                            user.getScreenName());
6112                    subscriptionSender.setFrom(fromAddress, fromName);
6113                    subscriptionSender.setHtmlFormat(true);
6114                    subscriptionSender.setLocalizedBodyMap(localizedBodyMap);
6115                    subscriptionSender.setLocalizedSubjectMap(localizedSubjectMap);
6116                    subscriptionSender.setMailId("user", user.getUserId());
6117                    subscriptionSender.setServiceContext(serviceContext);
6118    
6119                    subscriptionSender.addRuntimeSubscribers(toAddress, toName);
6120    
6121                    subscriptionSender.flushNotificationsAsync();
6122            }
6123    
6124            protected void setEmailAddress(
6125                            User user, String password, String firstName, String middleName,
6126                            String lastName, String emailAddress)
6127                    throws PortalException {
6128    
6129                    if (StringUtil.equalsIgnoreCase(emailAddress, user.getEmailAddress())) {
6130                            return;
6131                    }
6132    
6133                    long userId = user.getUserId();
6134    
6135                    // test@test.com -> test@liferay.com
6136    
6137                    if (!user.hasCompanyMx() && user.hasCompanyMx(emailAddress) &&
6138                            Validator.isNotNull(password)) {
6139    
6140                            mailService.addUser(
6141                                    user.getCompanyId(), userId, password, firstName, middleName,
6142                                    lastName, emailAddress);
6143                    }
6144    
6145                    // test@liferay.com -> bob@liferay.com
6146    
6147                    else if (user.hasCompanyMx() && user.hasCompanyMx(emailAddress)) {
6148                            mailService.updateEmailAddress(
6149                                    user.getCompanyId(), userId, emailAddress);
6150                    }
6151    
6152                    // test@liferay.com -> test@test.com
6153    
6154                    else if (user.hasCompanyMx() && !user.hasCompanyMx(emailAddress)) {
6155                            mailService.deleteEmailAddress(user.getCompanyId(), userId);
6156                    }
6157    
6158                    user.setEmailAddress(emailAddress);
6159                    user.setDigest(StringPool.BLANK);
6160            }
6161    
6162            protected void updateGroups(
6163                            long userId, long[] newGroupIds, ServiceContext serviceContext,
6164                            boolean indexingEnabled)
6165                    throws PortalException {
6166    
6167                    if (newGroupIds == null) {
6168                            return;
6169                    }
6170    
6171                    long[] oldGroupIds = getGroupPrimaryKeys(userId);
6172    
6173                    for (long oldGroupId : oldGroupIds) {
6174                            if (!ArrayUtil.contains(newGroupIds, oldGroupId)) {
6175                                    unsetGroupUsers(
6176                                            oldGroupId, new long[] {userId}, serviceContext);
6177                            }
6178                    }
6179    
6180                    for (long newGroupId : newGroupIds) {
6181                            if (!ArrayUtil.contains(oldGroupIds, newGroupId)) {
6182                                    addGroupUsers(newGroupId, new long[] {userId});
6183                            }
6184                    }
6185    
6186                    if (indexingEnabled) {
6187                            reindex(userId);
6188                    }
6189    
6190                    PermissionCacheUtil.clearCache(userId);
6191            }
6192    
6193            protected void updateOrganizations(
6194                            long userId, long[] newOrganizationIds, boolean indexingEnabled)
6195                    throws PortalException {
6196    
6197                    if (newOrganizationIds == null) {
6198                            return;
6199                    }
6200    
6201                    long[] oldOrganizationIds = getOrganizationPrimaryKeys(userId);
6202    
6203                    for (long oldOrganizationId : oldOrganizationIds) {
6204                            if (!ArrayUtil.contains(newOrganizationIds, oldOrganizationId)) {
6205                                    unsetOrganizationUsers(oldOrganizationId, new long[] {userId});
6206                            }
6207                    }
6208    
6209                    for (long newOrganizationId : newOrganizationIds) {
6210                            if (!ArrayUtil.contains(oldOrganizationIds, newOrganizationId)) {
6211                                    addOrganizationUsers(newOrganizationId, new long[] {userId});
6212                            }
6213                    }
6214    
6215                    if (indexingEnabled) {
6216                            reindex(userId);
6217                    }
6218    
6219                    PermissionCacheUtil.clearCache(userId);
6220            }
6221    
6222            protected void updateUserGroupRoles(
6223                            User user, long[] groupIds, long[] organizationIds,
6224                            List<UserGroupRole> userGroupRoles,
6225                            List<UserGroupRole> previousUserGroupRoles)
6226                    throws PortalException {
6227    
6228                    if (userGroupRoles == null) {
6229                            return;
6230                    }
6231    
6232                    userGroupRoles = new ArrayList<>(userGroupRoles);
6233    
6234                    for (UserGroupRole userGroupRole : previousUserGroupRoles) {
6235                            if (userGroupRoles.contains(userGroupRole)) {
6236                                    userGroupRoles.remove(userGroupRole);
6237                            }
6238                            else {
6239                                    userGroupRoleLocalService.deleteUserGroupRole(userGroupRole);
6240                            }
6241                    }
6242    
6243                    if (ListUtil.isEmpty(userGroupRoles)) {
6244                            return;
6245                    }
6246    
6247                    long[] validGroupIds = null;
6248    
6249                    if (groupIds != null) {
6250                            validGroupIds = ArrayUtil.clone(groupIds);
6251                    }
6252                    else {
6253                            validGroupIds = user.getGroupIds();
6254                    }
6255    
6256                    if (organizationIds == null) {
6257                            organizationIds = user.getOrganizationIds();
6258                    }
6259    
6260                    for (long organizationId : organizationIds) {
6261                            Organization organization =
6262                                    organizationPersistence.findByPrimaryKey(organizationId);
6263    
6264                            validGroupIds = ArrayUtil.append(
6265                                    validGroupIds, organization.getGroupId());
6266                    }
6267    
6268                    Arrays.sort(validGroupIds);
6269    
6270                    for (UserGroupRole userGroupRole : userGroupRoles) {
6271                            if (Arrays.binarySearch(
6272                                            validGroupIds, userGroupRole.getGroupId()) >= 0) {
6273    
6274                                    userGroupRoleLocalService.addUserGroupRole(userGroupRole);
6275                            }
6276                    }
6277            }
6278    
6279            protected void validate(
6280                            long companyId, long userId, boolean autoPassword, String password1,
6281                            String password2, boolean autoScreenName, String screenName,
6282                            String emailAddress, String openId, String firstName,
6283                            String middleName, String lastName, long[] organizationIds,
6284                            Locale locale)
6285                    throws PortalException {
6286    
6287                    validateCompanyMaxUsers(companyId);
6288    
6289                    if (!autoScreenName) {
6290                            validateScreenName(companyId, userId, screenName);
6291                    }
6292    
6293                    if (!autoPassword) {
6294                            PasswordPolicy passwordPolicy =
6295                                    passwordPolicyLocalService.getDefaultPasswordPolicy(companyId);
6296    
6297                            PwdToolkitUtil.validate(
6298                                    companyId, 0, password1, password2, passwordPolicy);
6299                    }
6300    
6301                    validateEmailAddress(companyId, emailAddress);
6302    
6303                    if (Validator.isNotNull(emailAddress)) {
6304                            User user = userPersistence.fetchByC_EA(companyId, emailAddress);
6305    
6306                            if ((user != null) && (user.getUserId() != userId)) {
6307                                    throw new UserEmailAddressException.MustNotBeDuplicate(
6308                                            userId, emailAddress);
6309                            }
6310                    }
6311    
6312                    validateOpenId(companyId, userId, openId);
6313    
6314                    validateFullName(companyId, firstName, middleName, lastName, locale);
6315    
6316                    if (organizationIds != null) {
6317                            for (long organizationId : organizationIds) {
6318                                    Organization organization =
6319                                            organizationPersistence.fetchByPrimaryKey(organizationId);
6320    
6321                                    if (organization == null) {
6322                                            throw new NoSuchOrganizationException(
6323                                                    "{organizationId=" + organizationId + "}");
6324                                    }
6325                            }
6326                    }
6327            }
6328    
6329            protected void validate(
6330                            long userId, String screenName, String emailAddress, String openId,
6331                            String firstName, String middleName, String lastName, String smsSn,
6332                            Locale locale)
6333                    throws PortalException {
6334    
6335                    User user = userPersistence.findByPrimaryKey(userId);
6336    
6337                    if (!StringUtil.equalsIgnoreCase(user.getScreenName(), screenName)) {
6338                            validateScreenName(user.getCompanyId(), userId, screenName);
6339                    }
6340    
6341                    validateEmailAddress(user.getCompanyId(), emailAddress);
6342    
6343                    validateOpenId(user.getCompanyId(), userId, openId);
6344    
6345                    if (!user.isDefaultUser()) {
6346                            if (Validator.isNotNull(emailAddress) &&
6347                                    !StringUtil.equalsIgnoreCase(
6348                                            user.getEmailAddress(), emailAddress)) {
6349    
6350                                    if (userPersistence.fetchByC_EA(
6351                                                    user.getCompanyId(), emailAddress) != null) {
6352    
6353                                            throw new UserEmailAddressException.MustNotBeDuplicate(
6354                                                    userId, emailAddress);
6355                                    }
6356                            }
6357    
6358                            validateFullName(
6359                                    user.getCompanyId(), firstName, middleName, lastName, locale);
6360                    }
6361    
6362                    if (Validator.isNotNull(smsSn) && !Validator.isEmailAddress(smsSn)) {
6363                            throw new UserSmsException.MustBeEmailAddress(smsSn);
6364                    }
6365            }
6366    
6367            protected void validateCompanyMaxUsers(long companyId)
6368                    throws PortalException {
6369    
6370                    Company company = companyPersistence.findByPrimaryKey(companyId);
6371    
6372                    if (company.isSystem() || (company.getMaxUsers() == 0)) {
6373                            return;
6374                    }
6375    
6376                    int userCount = searchCount(
6377                            companyId, null, WorkflowConstants.STATUS_APPROVED, null);
6378    
6379                    if (userCount >= company.getMaxUsers()) {
6380                            throw new CompanyMaxUsersException();
6381                    }
6382            }
6383    
6384            protected void validateEmailAddress(long companyId, String emailAddress)
6385                    throws PortalException {
6386    
6387                    if (Validator.isNull(emailAddress) &&
6388                            !PropsValues.USERS_EMAIL_ADDRESS_REQUIRED) {
6389    
6390                            return;
6391                    }
6392    
6393                    EmailAddressValidator emailAddressValidator =
6394                            EmailAddressValidatorFactory.getInstance();
6395    
6396                    if (!emailAddressValidator.validate(companyId, emailAddress)) {
6397                            throw new UserEmailAddressException.MustValidate(
6398                                    emailAddress, emailAddressValidator);
6399                    }
6400    
6401                    String pop3User = PrefsPropsUtil.getString(
6402                            PropsKeys.MAIL_SESSION_MAIL_POP3_USER,
6403                            PropsValues.MAIL_SESSION_MAIL_POP3_USER);
6404    
6405                    if (StringUtil.equalsIgnoreCase(emailAddress, pop3User)) {
6406                            throw new UserEmailAddressException.MustNotBePOP3User(emailAddress);
6407                    }
6408    
6409                    String[] reservedEmailAddresses = PrefsPropsUtil.getStringArray(
6410                            companyId, PropsKeys.ADMIN_RESERVED_EMAIL_ADDRESSES,
6411                            StringPool.NEW_LINE, PropsValues.ADMIN_RESERVED_EMAIL_ADDRESSES);
6412    
6413                    for (String reservedEmailAddress : reservedEmailAddresses) {
6414                            if (StringUtil.equalsIgnoreCase(
6415                                            emailAddress, reservedEmailAddress)) {
6416    
6417                                    throw new UserEmailAddressException.MustNotBeReserved(
6418                                            emailAddress, reservedEmailAddresses);
6419                            }
6420                    }
6421            }
6422    
6423            protected void validateEmailAddress(
6424                            User user, String emailAddress1, String emailAddress2)
6425                    throws PortalException {
6426    
6427                    if (!emailAddress1.equals(emailAddress2)) {
6428                            throw new UserEmailAddressException.MustBeEqual(
6429                                    user, emailAddress1, emailAddress2);
6430                    }
6431    
6432                    validateEmailAddress(user.getCompanyId(), emailAddress1);
6433                    validateEmailAddress(user.getCompanyId(), emailAddress2);
6434    
6435                    if (!StringUtil.equalsIgnoreCase(
6436                                    emailAddress1, user.getEmailAddress())) {
6437    
6438                            if (userPersistence.fetchByC_EA(
6439                                            user.getCompanyId(), emailAddress1) != null) {
6440    
6441                                    throw new UserEmailAddressException.MustNotBeDuplicate(
6442                                            user.getUserId(), emailAddress1);
6443                            }
6444                    }
6445            }
6446    
6447            protected void validateFullName(
6448                            long companyId, String firstName, String middleName,
6449                            String lastName, Locale locale)
6450                    throws PortalException {
6451    
6452                    FullNameDefinition fullNameDefinition =
6453                            FullNameDefinitionFactory.getInstance(locale);
6454    
6455                    if (Validator.isNull(firstName)) {
6456                            throw new ContactNameException.MustHaveFirstName();
6457                    }
6458                    else if (Validator.isNull(middleName) &&
6459                                     fullNameDefinition.isFieldRequired("middle-name")) {
6460    
6461                            throw new ContactNameException.MustHaveMiddleName();
6462                    }
6463                    else if (Validator.isNull(lastName) &&
6464                                     fullNameDefinition.isFieldRequired("last-name")) {
6465    
6466                            throw new ContactNameException.MustHaveLastName();
6467                    }
6468    
6469                    FullNameValidator fullNameValidator =
6470                            FullNameValidatorFactory.getInstance();
6471    
6472                    if (!fullNameValidator.validate(
6473                                    companyId, firstName, middleName, lastName)) {
6474    
6475                            throw new ContactNameException.MustHaveValidFullName(
6476                                    fullNameValidator);
6477                    }
6478            }
6479    
6480            protected void validateOpenId(long companyId, long userId, String openId)
6481                    throws PortalException {
6482    
6483                    if (Validator.isNull(openId)) {
6484                            return;
6485                    }
6486    
6487                    User user = userPersistence.fetchByC_O(companyId, openId);
6488    
6489                    if ((user != null) && (user.getUserId() != userId)) {
6490                            throw new DuplicateOpenIdException("{userId=" + userId + "}");
6491                    }
6492            }
6493    
6494            protected void validatePassword(
6495                            long companyId, long userId, String password1, String password2)
6496                    throws PortalException {
6497    
6498                    if (Validator.isNull(password1) || Validator.isNull(password2)) {
6499                            throw new UserPasswordException.MustNotBeNull(userId);
6500                    }
6501    
6502                    if (!password1.equals(password2)) {
6503                            throw new UserPasswordException.MustMatch(userId);
6504                    }
6505    
6506                    PasswordPolicy passwordPolicy =
6507                            passwordPolicyLocalService.getPasswordPolicyByUserId(userId);
6508    
6509                    PwdToolkitUtil.validate(
6510                            companyId, userId, password1, password2, passwordPolicy);
6511            }
6512    
6513            protected void validateReminderQuery(String question, String answer)
6514                    throws PortalException {
6515    
6516                    if (!PropsValues.USERS_REMINDER_QUERIES_ENABLED) {
6517                            return;
6518                    }
6519    
6520                    if (Validator.isNull(question)) {
6521                            throw new UserReminderQueryException("Question is null");
6522                    }
6523    
6524                    if (Validator.isNull(answer)) {
6525                            throw new UserReminderQueryException("Answer is null");
6526                    }
6527            }
6528    
6529            protected void validateScreenName(
6530                            long companyId, long userId, String screenName)
6531                    throws PortalException {
6532    
6533                    if (Validator.isNull(screenName)) {
6534                            throw new UserScreenNameException.MustNotBeNull(userId);
6535                    }
6536    
6537                    ScreenNameValidator screenNameValidator =
6538                            ScreenNameValidatorFactory.getInstance();
6539    
6540                    if (!screenNameValidator.validate(companyId, screenName)) {
6541                            throw new UserScreenNameException.MustValidate(
6542                                    userId, screenName, screenNameValidator);
6543                    }
6544    
6545                    if (Validator.isNumber(screenName)) {
6546                            if (!PropsValues.USERS_SCREEN_NAME_ALLOW_NUMERIC) {
6547                                    throw new UserScreenNameException.MustNotBeNumeric(
6548                                            userId, screenName);
6549                            }
6550    
6551                            if (!screenName.equals(String.valueOf(userId))) {
6552                                    Group group = groupPersistence.fetchByPrimaryKey(
6553                                            GetterUtil.getLong(screenName));
6554    
6555                                    if (group != null) {
6556                                            throw new UserScreenNameException.MustNotBeUsedByGroup(
6557                                                    userId, screenName, group);
6558                                    }
6559                            }
6560                    }
6561    
6562                    String[] anonymousNames = BaseServiceImpl.ANONYMOUS_NAMES;
6563    
6564                    for (String anonymousName : anonymousNames) {
6565                            if (StringUtil.equalsIgnoreCase(screenName, anonymousName)) {
6566                                    throw new UserScreenNameException.MustNotBeReservedForAnonymous(
6567                                            userId, screenName, anonymousNames);
6568                            }
6569                    }
6570    
6571                    User user = userPersistence.fetchByC_SN(companyId, screenName);
6572    
6573                    if ((user != null) && (user.getUserId() != userId)) {
6574                            throw new UserScreenNameException.MustNotBeDuplicate(
6575                                    user.getUserId(), screenName);
6576                    }
6577    
6578                    String friendlyURL = StringPool.SLASH + screenName;
6579    
6580                    Group group = groupPersistence.fetchByC_F(companyId, friendlyURL);
6581    
6582                    if ((group != null) && (group.getClassPK() != userId)) {
6583                            GroupFriendlyURLException gfurle = new GroupFriendlyURLException(
6584                                    GroupFriendlyURLException.DUPLICATE);
6585    
6586                            gfurle.setDuplicateClassPK(group.getGroupId());
6587                            gfurle.setDuplicateClassName(Group.class.getName());
6588    
6589                            throw gfurle;
6590                    }
6591    
6592                    int exceptionType = LayoutImpl.validateFriendlyURL(friendlyURL);
6593    
6594                    if (exceptionType != -1) {
6595                            throw new UserScreenNameException.MustProduceValidFriendlyURL(
6596                                    userId, screenName, exceptionType);
6597                    }
6598    
6599                    String[] reservedScreenNames = PrefsPropsUtil.getStringArray(
6600                            companyId, PropsKeys.ADMIN_RESERVED_SCREEN_NAMES,
6601                            StringPool.NEW_LINE, PropsValues.ADMIN_RESERVED_SCREEN_NAMES);
6602    
6603                    for (String reservedScreenName : reservedScreenNames) {
6604                            if (StringUtil.equalsIgnoreCase(screenName, reservedScreenName)) {
6605                                    throw new UserScreenNameException.MustNotBeReserved(
6606                                            userId, screenName, reservedScreenNames);
6607                            }
6608                    }
6609            }
6610    
6611            @BeanReference(type = MailService.class)
6612            protected MailService mailService;
6613    
6614            private static final Log _log = LogFactoryUtil.getLog(
6615                    UserLocalServiceImpl.class);
6616    
6617            private final Map<Long, User> _defaultUsers = new ConcurrentHashMap<>();
6618    
6619    }