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 (!ArrayUtil.isEmpty(groupIds)) {
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                    // Recent layouts
1858    
1859                    recentLayoutBranchLocalService.deleteUserRecentLayoutBranches(
1860                            user.getUserId());
1861                    recentLayoutRevisionLocalService.deleteUserRecentLayoutRevisions(
1862                            user.getUserId());
1863                    recentLayoutSetBranchLocalService.deleteUserRecentLayoutSetBranches(
1864                            user.getUserId());
1865    
1866                    // Resources
1867    
1868                    resourceLocalService.deleteResource(
1869                            user.getCompanyId(), User.class.getName(),
1870                            ResourceConstants.SCOPE_INDIVIDUAL, user.getUserId());
1871    
1872                    // User
1873    
1874                    userPersistence.remove(user);
1875    
1876                    // Permission cache
1877    
1878                    PermissionCacheUtil.clearCache(user.getUserId());
1879    
1880                    // Workflow
1881    
1882                    workflowInstanceLinkLocalService.deleteWorkflowInstanceLinks(
1883                            user.getCompanyId(), 0, User.class.getName(), user.getUserId());
1884    
1885                    return user;
1886            }
1887    
1888            /**
1889             * Removes the user from the user group.
1890             *
1891             * @param userGroupId the primary key of the user group
1892             * @param userId the primary key of the user
1893             */
1894            @Override
1895            public void deleteUserGroupUser(long userGroupId, long userId)
1896                    throws PortalException {
1897    
1898                    userGroupPersistence.removeUser(userGroupId, userId);
1899    
1900                    reindex(userId);
1901    
1902                    PermissionCacheUtil.clearCache(userId);
1903            }
1904    
1905            /**
1906             * Encrypts the primary key of the user. Used when encrypting the user's
1907             * credentials for storage in an automatic login cookie.
1908             *
1909             * @param  name the primary key of the user
1910             * @return the user's encrypted primary key
1911             */
1912            @Override
1913            @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
1914            public String encryptUserId(String name) throws PortalException {
1915                    long userId = GetterUtil.getLong(name);
1916    
1917                    User user = userPersistence.findByPrimaryKey(userId);
1918    
1919                    Company company = companyPersistence.findByPrimaryKey(
1920                            user.getCompanyId());
1921    
1922                    try {
1923                            return Encryptor.encrypt(company.getKeyObj(), name);
1924                    }
1925                    catch (EncryptorException ee) {
1926                            throw new SystemException(ee);
1927                    }
1928            }
1929    
1930            /**
1931             * Returns the user with the contact ID.
1932             *
1933             * @param  contactId the user's contact ID
1934             * @return the user with the contact ID, or <code>null</code> if a user with
1935             *         the contact ID could not be found
1936             */
1937            @Override
1938            public User fetchUserByContactId(long contactId) {
1939                    return userPersistence.fetchByContactId(contactId);
1940            }
1941    
1942            /**
1943             * Returns the user with the email address.
1944             *
1945             * @param  companyId the primary key of the user's company
1946             * @param  emailAddress the user's email address
1947             * @return the user with the email address, or <code>null</code> if a user
1948             *         with the email address could not be found
1949             */
1950            @Override
1951            public User fetchUserByEmailAddress(long companyId, String emailAddress) {
1952                    emailAddress = getLogin(emailAddress);
1953    
1954                    return userPersistence.fetchByC_EA(companyId, emailAddress);
1955            }
1956    
1957            /**
1958             * Returns the user with the Facebook ID.
1959             *
1960             * @param  companyId the primary key of the user's company
1961             * @param  facebookId the user's Facebook ID
1962             * @return the user with the Facebook ID, or <code>null</code> if a user
1963             *         with the Facebook ID could not be found
1964             */
1965            @Override
1966            public User fetchUserByFacebookId(long companyId, long facebookId) {
1967                    return userPersistence.fetchByC_FID(companyId, facebookId);
1968            }
1969    
1970            /**
1971             * Returns the user with the primary key.
1972             *
1973             * @param  userId the primary key of the user
1974             * @return the user with the primary key, or <code>null</code> if a user
1975             *         with the primary key could not be found
1976             */
1977            @Override
1978            public User fetchUserById(long userId) {
1979                    return userPersistence.fetchByPrimaryKey(userId);
1980            }
1981    
1982            /**
1983             * Returns the user with the OpenID.
1984             *
1985             * @param  companyId the primary key of the user's company
1986             * @param  openId the user's OpenID
1987             * @return the user with the OpenID, or <code>null</code> if a user with the
1988             *         OpenID could not be found
1989             */
1990            @Override
1991            public User fetchUserByOpenId(long companyId, String openId) {
1992                    return userPersistence.fetchByC_O(companyId, openId);
1993            }
1994    
1995            /**
1996             * Returns the user with the portrait ID.
1997             *
1998             * @param  portraitId the user's portrait ID
1999             * @return the user with the portrait ID, or <code>null</code> if a user
2000             *         with the portrait ID could not be found
2001             */
2002            @Override
2003            public User fetchUserByPortraitId(long portraitId) {
2004                    return userPersistence.fetchByPortraitId(portraitId);
2005            }
2006    
2007            /**
2008             * Returns the user with the screen name.
2009             *
2010             * @param  companyId the primary key of the user's company
2011             * @param  screenName the user's screen name
2012             * @return the user with the screen name, or <code>null</code> if a user
2013             *         with the screen name could not be found
2014             */
2015            @Override
2016            public User fetchUserByScreenName(long companyId, String screenName) {
2017                    screenName = getLogin(screenName);
2018    
2019                    return userPersistence.fetchByC_SN(companyId, screenName);
2020            }
2021    
2022            /**
2023             * Returns a range of all the users belonging to the company.
2024             *
2025             * <p>
2026             * Useful when paginating results. Returns a maximum of <code>end -
2027             * start</code> instances. <code>start</code> and <code>end</code> are not
2028             * primary keys, they are indexes in the result set. Thus, <code>0</code>
2029             * refers to the first result in the set. Setting both <code>start</code>
2030             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
2031             * result set.
2032             * </p>
2033             *
2034             * @param  companyId the primary key of the company
2035             * @param  start the lower bound of the range of users
2036             * @param  end the upper bound of the range of users (not inclusive)
2037             * @return the range of users belonging to the company
2038             */
2039            @Override
2040            public List<User> getCompanyUsers(long companyId, int start, int end) {
2041                    return userPersistence.findByCompanyId(companyId, start, end);
2042            }
2043    
2044            /**
2045             * Returns the number of users belonging to the company.
2046             *
2047             * @param  companyId the primary key of the company
2048             * @return the number of users belonging to the company
2049             */
2050            @Override
2051            public int getCompanyUsersCount(long companyId) {
2052                    return userPersistence.countByCompanyId(companyId);
2053            }
2054    
2055            /**
2056             * Returns the default user for the company.
2057             *
2058             * @param  companyId the primary key of the company
2059             * @return the default user for the company
2060             */
2061            @Override
2062            @Skip
2063            public User getDefaultUser(long companyId) throws PortalException {
2064                    User userModel = _defaultUsers.get(companyId);
2065    
2066                    if (userModel == null) {
2067                            userModel = userLocalService.loadGetDefaultUser(companyId);
2068    
2069                            _defaultUsers.put(companyId, userModel);
2070                    }
2071    
2072                    return userModel;
2073            }
2074    
2075            /**
2076             * Returns the primary key of the default user for the company.
2077             *
2078             * @param  companyId the primary key of the company
2079             * @return the primary key of the default user for the company
2080             */
2081            @Override
2082            @Skip
2083            public long getDefaultUserId(long companyId) throws PortalException {
2084                    User user = getDefaultUser(companyId);
2085    
2086                    return user.getUserId();
2087            }
2088    
2089            /**
2090             * Returns the primary keys of all the users belonging to the group.
2091             *
2092             * @param  groupId the primary key of the group
2093             * @return the primary keys of the users belonging to the group
2094             */
2095            @Override
2096            public long[] getGroupUserIds(long groupId) {
2097                    return groupPersistence.getUserPrimaryKeys(groupId);
2098            }
2099    
2100            /**
2101             * Returns the number of users with the status belonging to the group.
2102             *
2103             * @param  groupId the primary key of the group
2104             * @param  status the workflow status
2105             * @return the number of users with the status belonging to the group
2106             */
2107            @Override
2108            public int getGroupUsersCount(long groupId, int status)
2109                    throws PortalException {
2110    
2111                    Group group = groupPersistence.findByPrimaryKey(groupId);
2112    
2113                    LinkedHashMap<String, Object> params = new LinkedHashMap<>();
2114    
2115                    params.put("usersGroups", Long.valueOf(groupId));
2116    
2117                    return searchCount(group.getCompanyId(), null, status, params);
2118            }
2119    
2120            @Override
2121            public List<User> getInheritedRoleUsers(
2122                            long roleId, int start, int end, OrderByComparator<User> obc)
2123                    throws PortalException {
2124    
2125                    Role role = rolePersistence.findByPrimaryKey(roleId);
2126    
2127                    LinkedHashMap<String, Object> params = new LinkedHashMap<>();
2128    
2129                    params.put("inherit", Boolean.TRUE);
2130                    params.put("usersRoles", roleId);
2131    
2132                    return search(
2133                            role.getCompanyId(), null, WorkflowConstants.STATUS_APPROVED,
2134                            params, start, end, obc);
2135            }
2136    
2137            /**
2138             * Returns all the users who have not had any announcements of the type
2139             * delivered, excluding the default user.
2140             *
2141             * @param  type the type of announcement
2142             * @return the users who have not had any annoucements of the type delivered
2143             */
2144            @Override
2145            public List<User> getNoAnnouncementsDeliveries(String type) {
2146                    return userFinder.findByNoAnnouncementsDeliveries(type);
2147            }
2148    
2149            /**
2150             * Returns all the users who do not have any contacts.
2151             *
2152             * @return the users who do not have any contacts
2153             */
2154            @Override
2155            public List<User> getNoContacts() {
2156                    return userFinder.findByNoContacts();
2157            }
2158    
2159            /**
2160             * Returns all the users who do not belong to any groups, excluding the
2161             * default user.
2162             *
2163             * @return the users who do not belong to any groups
2164             */
2165            @Override
2166            public List<User> getNoGroups() {
2167                    return userFinder.findByNoGroups();
2168            }
2169    
2170            /**
2171             * Returns the primary keys of all the users belonging to the organization.
2172             *
2173             * @param  organizationId the primary key of the organization
2174             * @return the primary keys of the users belonging to the organization
2175             */
2176            @Override
2177            public long[] getOrganizationUserIds(long organizationId) {
2178                    return organizationPersistence.getUserPrimaryKeys(organizationId);
2179            }
2180    
2181            /**
2182             * Returns the number of users with the status belonging to the
2183             * organization.
2184             *
2185             * @param  organizationId the primary key of the organization
2186             * @param  status the workflow status
2187             * @return the number of users with the status belonging to the organization
2188             */
2189            @Override
2190            public int getOrganizationUsersCount(long organizationId, int status)
2191                    throws PortalException {
2192    
2193                    Organization organization = organizationPersistence.findByPrimaryKey(
2194                            organizationId);
2195    
2196                    LinkedHashMap<String, Object> params = new LinkedHashMap<>();
2197    
2198                    params.put("usersOrgs", Long.valueOf(organizationId));
2199    
2200                    return searchCount(organization.getCompanyId(), null, status, params);
2201            }
2202    
2203            /**
2204             * Returns the primary keys of all the users belonging to the role.
2205             *
2206             * @param  roleId the primary key of the role
2207             * @return the primary keys of the users belonging to the role
2208             */
2209            @Override
2210            public long[] getRoleUserIds(long roleId) {
2211                    return rolePersistence.getUserPrimaryKeys(roleId);
2212            }
2213    
2214            /**
2215             * Returns the number of users with the status belonging to the role.
2216             *
2217             * @param  roleId the primary key of the role
2218             * @param  status the workflow status
2219             * @return the number of users with the status belonging to the role
2220             */
2221            @Override
2222            public int getRoleUsersCount(long roleId, int status)
2223                    throws PortalException {
2224    
2225                    Role role = rolePersistence.findByPrimaryKey(roleId);
2226    
2227                    LinkedHashMap<String, Object> params = new LinkedHashMap<>();
2228    
2229                    params.put("usersRoles", Long.valueOf(roleId));
2230    
2231                    return searchCount(role.getCompanyId(), null, status, params);
2232            }
2233    
2234            /**
2235             * Returns an ordered range of all the users with a social relation of the
2236             * type with the user.
2237             *
2238             * <p>
2239             * Useful when paginating results. Returns a maximum of <code>end -
2240             * start</code> instances. <code>start</code> and <code>end</code> are not
2241             * primary keys, they are indexes in the result set. Thus, <code>0</code>
2242             * refers to the first result in the set. Setting both <code>start</code>
2243             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
2244             * result set.
2245             * </p>
2246             *
2247             * @param      userId the primary key of the user
2248             * @param      socialRelationType the type of social relation. The possible
2249             *             types can be found in {@link SocialRelationConstants}.
2250             * @param      start the lower bound of the range of users
2251             * @param      end the upper bound of the range of users (not inclusive)
2252             * @param      obc the comparator to order the users by (optionally
2253             *             <code>null</code>)
2254             * @return     the ordered range of users with a social relation of the type
2255             *             with the user
2256             * @deprecated As of 7.0.0, replaced by {@link #getSocialUsers(long, int,
2257             *             String, int, int, OrderByComparator)}
2258             */
2259            @Deprecated
2260            @Override
2261            public List<User> getSocialUsers(
2262                            long userId, int socialRelationType, int start, int end,
2263                            OrderByComparator<User> obc)
2264                    throws PortalException {
2265    
2266                    return getSocialUsers(
2267                            userId, socialRelationType, StringPool.EQUAL, start, end, obc);
2268            }
2269    
2270            /**
2271             * Returns an ordered range of all the users with a social relation with the
2272             * user.
2273             *
2274             * <p>
2275             * Useful when paginating results. Returns a maximum of <code>end -
2276             * start</code> instances. <code>start</code> and <code>end</code> are not
2277             * primary keys, they are indexes in the result set. Thus, <code>0</code>
2278             * refers to the first result in the set. Setting both <code>start</code>
2279             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
2280             * result set.
2281             * </p>
2282             *
2283             * @param      userId the primary key of the user
2284             * @param      start the lower bound of the range of users
2285             * @param      end the upper bound of the range of users (not inclusive)
2286             * @param      obc the comparator to order the users by (optionally
2287             *             <code>null</code>)
2288             * @return     the ordered range of users with a social relation with the
2289             *             user
2290             * @deprecated As of 7.0.0, replaced by {@link #getSocialUsers(long, int,
2291             *             String, int, int, OrderByComparator)}
2292             */
2293            @Deprecated
2294            @Override
2295            public List<User> getSocialUsers(
2296                            long userId, int start, int end, OrderByComparator<User> obc)
2297                    throws PortalException {
2298    
2299                    return getSocialUsers(
2300                            userId, SocialRelationConstants.TYPE_UNI_ENEMY,
2301                            StringPool.NOT_EQUAL, start, end, obc);
2302            }
2303    
2304            @Override
2305            public List<User> getSocialUsers(
2306                            long userId, int socialRelationType,
2307                            String socialRelationTypeComparator, int start, int end,
2308                            OrderByComparator<User> obc)
2309                    throws PortalException {
2310    
2311                    if (!socialRelationTypeComparator.equals(StringPool.EQUAL) &&
2312                            !socialRelationTypeComparator.equals(StringPool.NOT_EQUAL)) {
2313    
2314                            throw new IllegalArgumentException(
2315                                    "Invalid social relation type comparator " +
2316                                            socialRelationTypeComparator);
2317                    }
2318    
2319                    if ((start == QueryUtil.ALL_POS) && (end == QueryUtil.ALL_POS)) {
2320                            List<SocialRelation> socialRelations =
2321                                    socialRelationPersistence.findByU1_T(
2322                                            userId, socialRelationType);
2323    
2324                            if (socialRelationTypeComparator.equals(StringPool.NOT_EQUAL)) {
2325                                    socialRelations = ListUtil.remove(
2326                                            socialRelationPersistence.findByUserId1(userId),
2327                                            socialRelations);
2328                            }
2329    
2330                            List<User> users = new ArrayList<>();
2331    
2332                            for (SocialRelation socialRelation : socialRelations) {
2333                                    User user = userPersistence.findByPrimaryKey(
2334                                            socialRelation.getUserId2());
2335    
2336                                    if (user.isDefaultUser() ||
2337                                            (user.getStatus() != WorkflowConstants.STATUS_APPROVED)) {
2338    
2339                                            continue;
2340                                    }
2341    
2342                                    if (!users.contains(user)) {
2343                                            users.add(user);
2344                                    }
2345                            }
2346    
2347                            if (obc != null) {
2348                                    users = ListUtil.sort(users, obc);
2349                            }
2350    
2351                            return users;
2352                    }
2353    
2354                    User user = userPersistence.findByPrimaryKey(userId);
2355    
2356                    return userFinder.findBySocialUsers(
2357                            user.getCompanyId(), userId, socialRelationType,
2358                            socialRelationTypeComparator, WorkflowConstants.STATUS_APPROVED,
2359                            start, end, obc);
2360            }
2361    
2362            /**
2363             * Returns an ordered range of all the users with a mutual social relation
2364             * of the type with both of the given users.
2365             *
2366             * <p>
2367             * Useful when paginating results. Returns a maximum of <code>end -
2368             * start</code> instances. <code>start</code> and <code>end</code> are not
2369             * primary keys, they are indexes in the result set. Thus, <code>0</code>
2370             * refers to the first result in the set. Setting both <code>start</code>
2371             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
2372             * result set.
2373             * </p>
2374             *
2375             * @param  userId1 the primary key of the first user
2376             * @param  userId2 the primary key of the second user
2377             * @param  socialRelationType the type of social relation. The possible
2378             *         types can be found in {@link SocialRelationConstants}.
2379             * @param  start the lower bound of the range of users
2380             * @param  end the upper bound of the range of users (not inclusive)
2381             * @param  obc the comparator to order the users by (optionally
2382             *         <code>null</code>)
2383             * @return the ordered range of users with a mutual social relation of the
2384             *         type with the user
2385             */
2386            @Override
2387            public List<User> getSocialUsers(
2388                            long userId1, long userId2, int socialRelationType, int start,
2389                            int end, OrderByComparator<User> obc)
2390                    throws PortalException {
2391    
2392                    User user1 = userPersistence.findByPrimaryKey(userId1);
2393    
2394                    LinkedHashMap<String, Object> params = new LinkedHashMap<>();
2395    
2396                    params.put(
2397                            "socialMutualRelationType",
2398                            new Long[] {
2399                                    userId1, Long.valueOf(socialRelationType), userId2,
2400                                    Long.valueOf(socialRelationType)
2401                            });
2402    
2403                    return search(
2404                            user1.getCompanyId(), null, WorkflowConstants.STATUS_APPROVED,
2405                            params, start, end, obc);
2406            }
2407    
2408            /**
2409             * Returns an ordered range of all the users with a mutual social relation
2410             * with both of the given users.
2411             *
2412             * <p>
2413             * Useful when paginating results. Returns a maximum of <code>end -
2414             * start</code> instances. <code>start</code> and <code>end</code> are not
2415             * primary keys, they are indexes in the result set. Thus, <code>0</code>
2416             * refers to the first result in the set. Setting both <code>start</code>
2417             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
2418             * result set.
2419             * </p>
2420             *
2421             * @param  userId1 the primary key of the first user
2422             * @param  userId2 the primary key of the second user
2423             * @param  start the lower bound of the range of users
2424             * @param  end the upper bound of the range of users (not inclusive)
2425             * @param  obc the comparator to order the users by (optionally
2426             *         <code>null</code>)
2427             * @return the ordered range of users with a mutual social relation with the
2428             *         user
2429             */
2430            @Override
2431            public List<User> getSocialUsers(
2432                            long userId1, long userId2, int start, int end,
2433                            OrderByComparator<User> obc)
2434                    throws PortalException {
2435    
2436                    User user1 = userPersistence.findByPrimaryKey(userId1);
2437    
2438                    LinkedHashMap<String, Object> params = new LinkedHashMap<>();
2439    
2440                    params.put("socialMutualRelation", new Long[] {userId1, userId2});
2441    
2442                    return search(
2443                            user1.getCompanyId(), null, WorkflowConstants.STATUS_APPROVED,
2444                            params, start, end, obc);
2445            }
2446    
2447            /**
2448             * Returns the number of users with a social relation with the user.
2449             *
2450             * @param      userId the primary key of the user
2451             * @return     the number of users with a social relation with the user
2452             * @deprecated As of 7.0.0, replaced by {@link #getSocialUsersCount(long,
2453             *             int, String)}
2454             */
2455            @Deprecated
2456            @Override
2457            public int getSocialUsersCount(long userId) throws PortalException {
2458                    return getSocialUsersCount(
2459                            userId, SocialRelationConstants.TYPE_UNI_ENEMY,
2460                            StringPool.NOT_EQUAL);
2461            }
2462    
2463            /**
2464             * Returns the number of users with a social relation of the type with the
2465             * user.
2466             *
2467             * @param      userId the primary key of the user
2468             * @param      socialRelationType the type of social relation. The possible
2469             *             types can be found in {@link SocialRelationConstants}.
2470             * @return     the number of users with a social relation of the type with
2471             *             the user
2472             * @deprecated As of 7.0.0, replaced by {@link #getSocialUsersCount(long,
2473             *             int, String)}
2474             */
2475            @Deprecated
2476            @Override
2477            public int getSocialUsersCount(long userId, int socialRelationType)
2478                    throws PortalException {
2479    
2480                    return getSocialUsersCount(
2481                            userId, socialRelationType, StringPool.EQUAL);
2482            }
2483    
2484            /**
2485             * Returns the number of users with a social relation with the user.
2486             *
2487             * @param  userId the primary key of the user
2488             * @param  socialRelationType the type of social relation. The possible
2489             *         types can be found in {@link SocialRelationConstants}.
2490             * @return the number of users with a social relation with the user
2491             */
2492            @Override
2493            public int getSocialUsersCount(
2494                            long userId, int socialRelationType,
2495                            String socialRelationTypeComparator)
2496                    throws PortalException {
2497    
2498                    User user = userPersistence.findByPrimaryKey(userId);
2499    
2500                    if (!socialRelationTypeComparator.equals(StringPool.EQUAL) &&
2501                            !socialRelationTypeComparator.equals(StringPool.NOT_EQUAL)) {
2502    
2503                            throw new IllegalArgumentException(
2504                                    "Invalid social relation type comparator " +
2505                                            socialRelationTypeComparator);
2506                    }
2507    
2508                    return userFinder.countBySocialUsers(
2509                            user.getCompanyId(), user.getUserId(), socialRelationType,
2510                            socialRelationTypeComparator, WorkflowConstants.STATUS_APPROVED);
2511            }
2512    
2513            /**
2514             * Returns the number of users with a mutual social relation with both of
2515             * the given users.
2516             *
2517             * @param  userId1 the primary key of the first user
2518             * @param  userId2 the primary key of the second user
2519             * @return the number of users with a mutual social relation with the user
2520             */
2521            @Override
2522            public int getSocialUsersCount(long userId1, long userId2)
2523                    throws PortalException {
2524    
2525                    User user1 = userPersistence.findByPrimaryKey(userId1);
2526    
2527                    LinkedHashMap<String, Object> params = new LinkedHashMap<>();
2528    
2529                    params.put("socialMutualRelation", new Long[] {userId1, userId2});
2530    
2531                    return searchCount(
2532                            user1.getCompanyId(), null, WorkflowConstants.STATUS_APPROVED,
2533                            params);
2534            }
2535    
2536            /**
2537             * Returns the number of users with a mutual social relation of the type
2538             * with both of the given users.
2539             *
2540             * @param  userId1 the primary key of the first user
2541             * @param  userId2 the primary key of the second user
2542             * @param  socialRelationType the type of social relation. The possible
2543             *         types can be found in {@link SocialRelationConstants}.
2544             * @return the number of users with a mutual social relation of the type
2545             *         with the user
2546             */
2547            @Override
2548            public int getSocialUsersCount(
2549                            long userId1, long userId2, int socialRelationType)
2550                    throws PortalException {
2551    
2552                    User user1 = userPersistence.findByPrimaryKey(userId1);
2553    
2554                    LinkedHashMap<String, Object> params = new LinkedHashMap<>();
2555    
2556                    params.put(
2557                            "socialMutualRelationType",
2558                            new Long[] {
2559                                    userId1, Long.valueOf(socialRelationType), userId2,
2560                                    Long.valueOf(socialRelationType)
2561                            });
2562    
2563                    return searchCount(
2564                            user1.getCompanyId(), null, WorkflowConstants.STATUS_APPROVED,
2565                            params);
2566            }
2567    
2568            /**
2569             * Returns the user with the contact ID.
2570             *
2571             * @param  contactId the user's contact ID
2572             * @return the user with the contact ID
2573             */
2574            @Override
2575            public User getUserByContactId(long contactId) throws PortalException {
2576                    return userPersistence.findByContactId(contactId);
2577            }
2578    
2579            /**
2580             * Returns the user with the email address.
2581             *
2582             * @param  companyId the primary key of the user's company
2583             * @param  emailAddress the user's email address
2584             * @return the user with the email address
2585             */
2586            @Override
2587            public User getUserByEmailAddress(long companyId, String emailAddress)
2588                    throws PortalException {
2589    
2590                    emailAddress = getLogin(emailAddress);
2591    
2592                    return userPersistence.findByC_EA(companyId, emailAddress);
2593            }
2594    
2595            /**
2596             * Returns the user with the Facebook ID.
2597             *
2598             * @param  companyId the primary key of the user's company
2599             * @param  facebookId the user's Facebook ID
2600             * @return the user with the Facebook ID
2601             */
2602            @Override
2603            public User getUserByFacebookId(long companyId, long facebookId)
2604                    throws PortalException {
2605    
2606                    return userPersistence.findByC_FID(companyId, facebookId);
2607            }
2608    
2609            /**
2610             * Returns the user with the primary key.
2611             *
2612             * @param  userId the primary key of the user
2613             * @return the user with the primary key
2614             */
2615            @Override
2616            public User getUserById(long userId) throws PortalException {
2617                    return userPersistence.findByPrimaryKey(userId);
2618            }
2619    
2620            /**
2621             * Returns the user with the primary key from the company.
2622             *
2623             * @param  companyId the primary key of the user's company
2624             * @param  userId the primary key of the user
2625             * @return the user with the primary key
2626             */
2627            @Override
2628            public User getUserById(long companyId, long userId)
2629                    throws PortalException {
2630    
2631                    return userPersistence.findByC_U(companyId, userId);
2632            }
2633    
2634            /**
2635             * Returns the user with the OpenID.
2636             *
2637             * @param  companyId the primary key of the user's company
2638             * @param  openId the user's OpenID
2639             * @return the user with the OpenID
2640             */
2641            @Override
2642            public User getUserByOpenId(long companyId, String openId)
2643                    throws PortalException {
2644    
2645                    return userPersistence.findByC_O(companyId, openId);
2646            }
2647    
2648            /**
2649             * Returns the user with the portrait ID.
2650             *
2651             * @param  portraitId the user's portrait ID
2652             * @return the user with the portrait ID
2653             */
2654            @Override
2655            public User getUserByPortraitId(long portraitId) throws PortalException {
2656                    return userPersistence.findByPortraitId(portraitId);
2657            }
2658    
2659            /**
2660             * Returns the user with the screen name.
2661             *
2662             * @param  companyId the primary key of the user's company
2663             * @param  screenName the user's screen name
2664             * @return the user with the screen name
2665             */
2666            @Override
2667            public User getUserByScreenName(long companyId, String screenName)
2668                    throws PortalException {
2669    
2670                    screenName = getLogin(screenName);
2671    
2672                    return userPersistence.findByC_SN(companyId, screenName);
2673            }
2674    
2675            /**
2676             * Returns the user with the UUID.
2677             *
2678             * @param      uuid the user's UUID
2679             * @return     the user with the UUID
2680             * @deprecated As of 6.2.0, replaced by {@link
2681             *             #getUserByUuidAndCompanyId(String, long)}
2682             */
2683            @Deprecated
2684            @Override
2685            public User getUserByUuid(String uuid) throws PortalException {
2686                    List<User> users = userPersistence.findByUuid(uuid);
2687    
2688                    if (users.isEmpty()) {
2689                            throw new NoSuchUserException("{uuid=" + uuid + "}");
2690                    }
2691                    else {
2692                            return users.get(0);
2693                    }
2694            }
2695    
2696            /**
2697             * Returns the user with the UUID.
2698             *
2699             * @param  uuid the user's UUID
2700             * @param  companyId the primary key of the user's company
2701             * @return the user with the UUID
2702             */
2703            @Override
2704            public User getUserByUuidAndCompanyId(String uuid, long companyId)
2705                    throws PortalException {
2706    
2707                    List<User> users = userPersistence.findByUuid_C(uuid, companyId);
2708    
2709                    if (users.isEmpty()) {
2710                            StringBundler sb = new StringBundler(5);
2711    
2712                            sb.append("{uuid=");
2713                            sb.append(uuid);
2714                            sb.append(", companyId=");
2715                            sb.append(companyId);
2716                            sb.append("}");
2717    
2718                            throw new NoSuchUserException(sb.toString());
2719                    }
2720                    else {
2721                            return users.get(0);
2722                    }
2723            }
2724    
2725            /**
2726             * Returns the number of users with the status belonging to the user group.
2727             *
2728             * @param  userGroupId the primary key of the user group
2729             * @param  status the workflow status
2730             * @return the number of users with the status belonging to the user group
2731             */
2732            @Override
2733            public int getUserGroupUsersCount(long userGroupId, int status)
2734                    throws PortalException {
2735    
2736                    UserGroup userGroup = userGroupPersistence.findByPrimaryKey(
2737                            userGroupId);
2738    
2739                    LinkedHashMap<String, Object> params = new LinkedHashMap<>();
2740    
2741                    params.put("usersUserGroups", Long.valueOf(userGroupId));
2742    
2743                    return searchCount(userGroup.getCompanyId(), null, status, params);
2744            }
2745    
2746            /**
2747             * Returns the primary key of the user with the email address.
2748             *
2749             * @param  companyId the primary key of the user's company
2750             * @param  emailAddress the user's email address
2751             * @return the primary key of the user with the email address
2752             */
2753            @Override
2754            public long getUserIdByEmailAddress(long companyId, String emailAddress)
2755                    throws PortalException {
2756    
2757                    emailAddress = StringUtil.toLowerCase(emailAddress.trim());
2758    
2759                    User user = userPersistence.findByC_EA(companyId, emailAddress);
2760    
2761                    return user.getUserId();
2762            }
2763    
2764            /**
2765             * Returns the primary key of the user with the screen name.
2766             *
2767             * @param  companyId the primary key of the user's company
2768             * @param  screenName the user's screen name
2769             * @return the primary key of the user with the screen name
2770             */
2771            @Override
2772            public long getUserIdByScreenName(long companyId, String screenName)
2773                    throws PortalException {
2774    
2775                    screenName = getLogin(screenName);
2776    
2777                    User user = userPersistence.findByC_SN(companyId, screenName);
2778    
2779                    return user.getUserId();
2780            }
2781    
2782            /**
2783             * Returns <code>true</code> if the password policy has been assigned to the
2784             * user.
2785             *
2786             * @param  passwordPolicyId the primary key of the password policy
2787             * @param  userId the primary key of the user
2788             * @return <code>true</code> if the password policy is assigned to the user;
2789             *         <code>false</code> otherwise
2790             */
2791            @Override
2792            public boolean hasPasswordPolicyUser(long passwordPolicyId, long userId) {
2793                    return passwordPolicyRelLocalService.hasPasswordPolicyRel(
2794                            passwordPolicyId, User.class.getName(), userId);
2795            }
2796    
2797            /**
2798             * Returns <code>true</code> if the user has the role with the name,
2799             * optionally through inheritance.
2800             *
2801             * @param  companyId the primary key of the role's company
2802             * @param  name the name of the role (must be a regular role, not an
2803             *         organization, site or provider role)
2804             * @param  userId the primary key of the user
2805             * @param  inherited whether to include roles inherited from organizations,
2806             *         sites, etc.
2807             * @return <code>true</code> if the user has the role; <code>false</code>
2808             *         otherwise
2809             */
2810            @Override
2811            public boolean hasRoleUser(
2812                            long companyId, String name, long userId, boolean inherited)
2813                    throws PortalException {
2814    
2815                    return roleLocalService.hasUserRole(userId, companyId, name, inherited);
2816            }
2817    
2818            /**
2819             * Returns <code>true</code> if the user's password is expired.
2820             *
2821             * @param  user the user
2822             * @return <code>true</code> if the user's password is expired;
2823             *         <code>false</code> otherwise
2824             */
2825            @Override
2826            public boolean isPasswordExpired(User user) throws PortalException {
2827                    PasswordPolicy passwordPolicy = user.getPasswordPolicy();
2828    
2829                    if ((passwordPolicy != null) && passwordPolicy.getExpireable()) {
2830                            Date now = new Date();
2831    
2832                            if (user.getPasswordModifiedDate() == null) {
2833                                    user.setPasswordModifiedDate(now);
2834    
2835                                    userLocalService.updateUser(user);
2836                            }
2837    
2838                            long passwordStartTime = user.getPasswordModifiedDate().getTime();
2839                            long elapsedTime = now.getTime() - passwordStartTime;
2840    
2841                            if (elapsedTime > (passwordPolicy.getMaxAge() * 1000)) {
2842                                    return true;
2843                            }
2844                            else {
2845                                    return false;
2846                            }
2847                    }
2848    
2849                    return false;
2850            }
2851    
2852            /**
2853             * Returns <code>true</code> if the password policy is configured to warn
2854             * the user that his password is expiring and the remaining time until
2855             * expiration is equal or less than the configured warning time.
2856             *
2857             * @param  user the user
2858             * @return <code>true</code> if the user's password is expiring soon;
2859             *         <code>false</code> otherwise
2860             */
2861            @Override
2862            public boolean isPasswordExpiringSoon(User user) throws PortalException {
2863                    PasswordPolicy passwordPolicy = user.getPasswordPolicy();
2864    
2865                    if ((passwordPolicy != null) && passwordPolicy.isExpireable() &&
2866                            (passwordPolicy.getWarningTime() > 0)) {
2867    
2868                            Date now = new Date();
2869    
2870                            if (user.getPasswordModifiedDate() == null) {
2871                                    user.setPasswordModifiedDate(now);
2872    
2873                                    userLocalService.updateUser(user);
2874                            }
2875    
2876                            long timeModified = user.getPasswordModifiedDate().getTime();
2877                            long passwordExpiresOn =
2878                                    (passwordPolicy.getMaxAge() * 1000) + timeModified;
2879    
2880                            long timeStartWarning =
2881                                    passwordExpiresOn - (passwordPolicy.getWarningTime() * 1000);
2882    
2883                            if (now.getTime() > timeStartWarning) {
2884                                    return true;
2885                            }
2886                            else {
2887                                    return false;
2888                            }
2889                    }
2890    
2891                    return false;
2892            }
2893    
2894            /**
2895             * Returns the default user for the company.
2896             *
2897             * @param  companyId the primary key of the company
2898             * @return the default user for the company
2899             */
2900            @Override
2901            public User loadGetDefaultUser(long companyId) throws PortalException {
2902                    return userPersistence.findByC_DU(companyId, true);
2903            }
2904    
2905            /**
2906             * Returns an ordered range of all the users who match the keywords and
2907             * status, without using the indexer. It is preferable to use the indexed
2908             * version {@link #search(long, String, int, LinkedHashMap, int, int, Sort)}
2909             * instead of this method wherever possible for performance reasons.
2910             *
2911             * <p>
2912             * Useful when paginating results. Returns a maximum of <code>end -
2913             * start</code> instances. <code>start</code> and <code>end</code> are not
2914             * primary keys, they are indexes in the result set. Thus, <code>0</code>
2915             * refers to the first result in the set. Setting both <code>start</code>
2916             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
2917             * result set.
2918             * </p>
2919             *
2920             * @param  companyId the primary key of the user's company
2921             * @param  keywords the keywords (space separated), which may occur in the
2922             *         user's first name, middle name, last name, screen name, or email
2923             *         address
2924             * @param  status the workflow status
2925             * @param  params the finder parameters (optionally <code>null</code>). For
2926             *         more information see {@link
2927             *         com.liferay.portal.service.persistence.UserFinder}.
2928             * @param  start the lower bound of the range of users
2929             * @param  end the upper bound of the range of users (not inclusive)
2930             * @param  obc the comparator to order the users by (optionally
2931             *         <code>null</code>)
2932             * @return the matching users
2933             * @see    com.liferay.portal.service.persistence.UserFinder
2934             */
2935            @Override
2936            public List<User> search(
2937                    long companyId, String keywords, int status,
2938                    LinkedHashMap<String, Object> params, int start, int end,
2939                    OrderByComparator<User> obc) {
2940    
2941                    Indexer<?> indexer = IndexerRegistryUtil.nullSafeGetIndexer(User.class);
2942    
2943                    if (!indexer.isIndexerEnabled() ||
2944                            !PropsValues.USERS_SEARCH_WITH_INDEX || isUseCustomSQL(params)) {
2945    
2946                            return userFinder.findByKeywords(
2947                                    companyId, keywords, status, params, start, end, obc);
2948                    }
2949    
2950                    try {
2951                            return UsersAdminUtil.getUsers(
2952                                    search(
2953                                            companyId, keywords, status, params, start, end,
2954                                            getSorts(obc)));
2955                    }
2956                    catch (Exception e) {
2957                            throw new SystemException(e);
2958                    }
2959            }
2960    
2961            /**
2962             * Returns an ordered range of all the users who match the keywords and
2963             * status, using the indexer. It is preferable to use this method instead of
2964             * the non-indexed version whenever possible for performance reasons.
2965             *
2966             * <p>
2967             * Useful when paginating results. Returns a maximum of <code>end -
2968             * start</code> instances. <code>start</code> and <code>end</code> are not
2969             * primary keys, they are indexes in the result set. Thus, <code>0</code>
2970             * refers to the first result in the set. Setting both <code>start</code>
2971             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
2972             * result set.
2973             * </p>
2974             *
2975             * @param  companyId the primary key of the user's company
2976             * @param  keywords the keywords (space separated), which may occur in the
2977             *         user's first name, middle name, last name, screen name, or email
2978             *         address
2979             * @param  status the workflow status
2980             * @param  params the indexer parameters (optionally <code>null</code>). For
2981             *         more information see {@link
2982             *         com.liferay.portlet.usersadmin.util.UserIndexer}.
2983             * @param  start the lower bound of the range of users
2984             * @param  end the upper bound of the range of users (not inclusive)
2985             * @param  sort the field and direction to sort by (optionally
2986             *         <code>null</code>)
2987             * @return the matching users
2988             * @see    com.liferay.portlet.usersadmin.util.UserIndexer
2989             */
2990            @Override
2991            public Hits search(
2992                    long companyId, String keywords, int status,
2993                    LinkedHashMap<String, Object> params, int start, int end, Sort sort) {
2994    
2995                    return search(
2996                            companyId, keywords, status, params, start, end, new Sort[] {sort});
2997            }
2998    
2999            @Override
3000            public Hits search(
3001                    long companyId, String keywords, int status,
3002                    LinkedHashMap<String, Object> params, int start, int end,
3003                    Sort[] sorts) {
3004    
3005                    String firstName = null;
3006                    String middleName = null;
3007                    String lastName = null;
3008                    String fullName = null;
3009                    String screenName = null;
3010                    String emailAddress = null;
3011                    String street = null;
3012                    String city = null;
3013                    String zip = null;
3014                    String region = null;
3015                    String country = null;
3016                    boolean andOperator = false;
3017    
3018                    if (Validator.isNotNull(keywords)) {
3019                            firstName = keywords;
3020                            middleName = keywords;
3021                            lastName = keywords;
3022                            fullName = keywords;
3023                            screenName = keywords;
3024                            emailAddress = keywords;
3025                            street = keywords;
3026                            city = keywords;
3027                            zip = keywords;
3028                            region = keywords;
3029                            country = keywords;
3030                    }
3031                    else {
3032                            andOperator = true;
3033                    }
3034    
3035                    if (params != null) {
3036                            params.put("keywords", keywords);
3037                    }
3038    
3039                    try {
3040                            Indexer<User> indexer = IndexerRegistryUtil.nullSafeGetIndexer(
3041                                    User.class);
3042    
3043                            SearchContext searchContext = buildSearchContext(
3044                                    companyId, firstName, middleName, lastName, fullName,
3045                                    screenName, emailAddress, street, city, zip, region, country,
3046                                    status, params, andOperator, start, end, sorts);
3047    
3048                            return indexer.search(searchContext);
3049                    }
3050                    catch (Exception e) {
3051                            throw new SystemException(e);
3052                    }
3053            }
3054    
3055            /**
3056             * Returns an ordered range of all the users with the status, and whose
3057             * first name, middle name, last name, screen name, and email address match
3058             * the keywords specified for them, without using the indexer. It is
3059             * preferable to use the indexed version {@link #search(long, String,
3060             * String, String, String, String, int, LinkedHashMap, boolean, int, int,
3061             * Sort)} instead of this method wherever possible for performance reasons.
3062             *
3063             * <p>
3064             * Useful when paginating results. Returns a maximum of <code>end -
3065             * start</code> instances. <code>start</code> and <code>end</code> are not
3066             * primary keys, they are indexes in the result set. Thus, <code>0</code>
3067             * refers to the first result in the set. Setting both <code>start</code>
3068             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
3069             * result set.
3070             * </p>
3071             *
3072             * @param  companyId the primary key of the user's company
3073             * @param  firstName the first name keywords (space separated)
3074             * @param  middleName the middle name keywords
3075             * @param  lastName the last name keywords
3076             * @param  screenName the screen name keywords
3077             * @param  emailAddress the email address keywords
3078             * @param  status the workflow status
3079             * @param  params the finder parameters (optionally <code>null</code>). For
3080             *         more information see {@link
3081             *         com.liferay.portal.service.persistence.UserFinder}.
3082             * @param  andSearch whether every field must match its keywords, or just
3083             *         one field. For example, &quot;users with the first name 'bob' and
3084             *         last name 'smith'&quot; vs &quot;users with the first name 'bob'
3085             *         or the last name 'smith'&quot;.
3086             * @param  start the lower bound of the range of users
3087             * @param  end the upper bound of the range of users (not inclusive)
3088             * @param  obc the comparator to order the users by (optionally
3089             *         <code>null</code>)
3090             * @return the matching users
3091             * @see    com.liferay.portal.service.persistence.UserFinder
3092             */
3093            @Override
3094            public List<User> search(
3095                    long companyId, String firstName, String middleName, String lastName,
3096                    String screenName, String emailAddress, int status,
3097                    LinkedHashMap<String, Object> params, boolean andSearch, int start,
3098                    int end, OrderByComparator<User> obc) {
3099    
3100                    Indexer<?> indexer = IndexerRegistryUtil.nullSafeGetIndexer(User.class);
3101    
3102                    if (!indexer.isIndexerEnabled() ||
3103                            !PropsValues.USERS_SEARCH_WITH_INDEX || isUseCustomSQL(params)) {
3104    
3105                            return userFinder.findByC_FN_MN_LN_SN_EA_S(
3106                                    companyId, firstName, middleName, lastName, screenName,
3107                                    emailAddress, status, params, andSearch, start, end, obc);
3108                    }
3109    
3110                    try {
3111                            return UsersAdminUtil.getUsers(
3112                                    search(
3113                                            companyId, firstName, middleName, lastName, screenName,
3114                                            emailAddress, status, params, andSearch, start, end,
3115                                            getSorts(obc)));
3116                    }
3117                    catch (Exception e) {
3118                            throw new SystemException(e);
3119                    }
3120            }
3121    
3122            /**
3123             * Returns an ordered range of all the users with the status, and whose
3124             * first name, middle name, last name, screen name, and email address match
3125             * the keywords specified for them, using the indexer. It is preferable to
3126             * use this method instead of the non-indexed version whenever possible for
3127             * performance reasons.
3128             *
3129             * <p>
3130             * Useful when paginating results. Returns a maximum of <code>end -
3131             * start</code> instances. <code>start</code> and <code>end</code> are not
3132             * primary keys, they are indexes in the result set. Thus, <code>0</code>
3133             * refers to the first result in the set. Setting both <code>start</code>
3134             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
3135             * result set.
3136             * </p>
3137             *
3138             * @param  companyId the primary key of the user's company
3139             * @param  firstName the first name keywords (space separated)
3140             * @param  middleName the middle name keywords
3141             * @param  lastName the last name keywords
3142             * @param  screenName the screen name keywords
3143             * @param  emailAddress the email address keywords
3144             * @param  status the workflow status
3145             * @param  params the indexer parameters (optionally <code>null</code>). For
3146             *         more information see {@link
3147             *         com.liferay.portlet.usersadmin.util.UserIndexer}.
3148             * @param  andSearch whether every field must match its keywords, or just
3149             *         one field. For example, &quot;users with the first name 'bob' and
3150             *         last name 'smith'&quot; vs &quot;users with the first name 'bob'
3151             *         or the last name 'smith'&quot;.
3152             * @param  start the lower bound of the range of users
3153             * @param  end the upper bound of the range of users (not inclusive)
3154             * @param  sort the field and direction to sort by (optionally
3155             *         <code>null</code>)
3156             * @return the matching users
3157             * @see    com.liferay.portlet.usersadmin.util.UserIndexer
3158             */
3159            @Override
3160            public Hits search(
3161                    long companyId, String firstName, String middleName, String lastName,
3162                    String screenName, String emailAddress, int status,
3163                    LinkedHashMap<String, Object> params, boolean andSearch, int start,
3164                    int end, Sort sort) {
3165    
3166                    return search(
3167                            companyId, firstName, middleName, lastName, screenName,
3168                            emailAddress, status, params, andSearch, start, end,
3169                            new Sort[] {sort});
3170            }
3171    
3172            @Override
3173            public Hits search(
3174                    long companyId, String firstName, String middleName, String lastName,
3175                    String screenName, String emailAddress, int status,
3176                    LinkedHashMap<String, Object> params, boolean andSearch, int start,
3177                    int end, Sort[] sorts) {
3178    
3179                    try {
3180                            Indexer<User> indexer = IndexerRegistryUtil.nullSafeGetIndexer(
3181                                    User.class);
3182    
3183                            SearchContext searchContext = buildSearchContext(
3184                                    companyId, firstName, middleName, lastName, null, screenName,
3185                                    emailAddress, null, null, null, null, null, status, params,
3186                                    andSearch, start, end, sorts);
3187    
3188                            return indexer.search(searchContext);
3189                    }
3190                    catch (Exception e) {
3191                            throw new SystemException(e);
3192                    }
3193            }
3194    
3195            /**
3196             * Returns the number of users who match the keywords and status.
3197             *
3198             * @param  companyId the primary key of the user's company
3199             * @param  keywords the keywords (space separated), which may occur in the
3200             *         user's first name, middle name, last name, screen name, or email
3201             *         address
3202             * @param  status the workflow status
3203             * @param  params the finder parameters (optionally <code>null</code>). For
3204             *         more information see {@link
3205             *         com.liferay.portal.service.persistence.UserFinder}.
3206             * @return the number matching users
3207             */
3208            @Override
3209            public int searchCount(
3210                    long companyId, String keywords, int status,
3211                    LinkedHashMap<String, Object> params) {
3212    
3213                    Indexer<?> indexer = IndexerRegistryUtil.nullSafeGetIndexer(User.class);
3214    
3215                    if (!indexer.isIndexerEnabled() ||
3216                            !PropsValues.USERS_SEARCH_WITH_INDEX || isUseCustomSQL(params)) {
3217    
3218                            return userFinder.countByKeywords(
3219                                    companyId, keywords, status, params);
3220                    }
3221    
3222                    try {
3223                            String firstName = null;
3224                            String middleName = null;
3225                            String lastName = null;
3226                            String fullName = null;
3227                            String screenName = null;
3228                            String emailAddress = null;
3229                            String street = null;
3230                            String city = null;
3231                            String zip = null;
3232                            String region = null;
3233                            String country = null;
3234                            boolean andOperator = false;
3235    
3236                            if (Validator.isNotNull(keywords)) {
3237                                    firstName = keywords;
3238                                    middleName = keywords;
3239                                    lastName = keywords;
3240                                    fullName = keywords;
3241                                    screenName = keywords;
3242                                    emailAddress = keywords;
3243                                    street = keywords;
3244                                    city = keywords;
3245                                    zip = keywords;
3246                                    region = keywords;
3247                                    country = keywords;
3248                            }
3249                            else {
3250                                    andOperator = true;
3251                            }
3252    
3253                            if (params != null) {
3254                                    params.put("keywords", keywords);
3255                            }
3256    
3257                            SearchContext searchContext = buildSearchContext(
3258                                    companyId, firstName, middleName, lastName, fullName,
3259                                    screenName, emailAddress, street, city, zip, region, country,
3260                                    status, params, andOperator, QueryUtil.ALL_POS,
3261                                    QueryUtil.ALL_POS, null);
3262    
3263                            return (int)indexer.searchCount(searchContext);
3264                    }
3265                    catch (Exception e) {
3266                            throw new SystemException(e);
3267                    }
3268            }
3269    
3270            /**
3271             * Returns the number of users with the status, and whose first name, middle
3272             * name, last name, screen name, and email address match the keywords
3273             * specified for them.
3274             *
3275             * @param  companyId the primary key of the user's company
3276             * @param  firstName the first name keywords (space separated)
3277             * @param  middleName the middle name keywords
3278             * @param  lastName the last name keywords
3279             * @param  screenName the screen name keywords
3280             * @param  emailAddress the email address keywords
3281             * @param  status the workflow status
3282             * @param  params the finder parameters (optionally <code>null</code>). For
3283             *         more information see {@link
3284             *         com.liferay.portal.service.persistence.UserFinder}.
3285             * @param  andSearch whether every field must match its keywords, or just
3286             *         one field. For example, &quot;users with the first name 'bob' and
3287             *         last name 'smith'&quot; vs &quot;users with the first name 'bob'
3288             *         or the last name 'smith'&quot;.
3289             * @return the number of matching users
3290             */
3291            @Override
3292            public int searchCount(
3293                    long companyId, String firstName, String middleName, String lastName,
3294                    String screenName, String emailAddress, int status,
3295                    LinkedHashMap<String, Object> params, boolean andSearch) {
3296    
3297                    Indexer<?> indexer = IndexerRegistryUtil.nullSafeGetIndexer(User.class);
3298    
3299                    if (!indexer.isIndexerEnabled() ||
3300                            !PropsValues.USERS_SEARCH_WITH_INDEX || isUseCustomSQL(params)) {
3301    
3302                            return userFinder.countByC_FN_MN_LN_SN_EA_S(
3303                                    companyId, firstName, middleName, lastName, screenName,
3304                                    emailAddress, status, params, andSearch);
3305                    }
3306    
3307                    try {
3308                            FullNameGenerator fullNameGenerator =
3309                                    FullNameGeneratorFactory.getInstance();
3310    
3311                            String fullName = fullNameGenerator.getFullName(
3312                                    firstName, middleName, lastName);
3313    
3314                            SearchContext searchContext = buildSearchContext(
3315                                    companyId, firstName, middleName, lastName, fullName,
3316                                    screenName, emailAddress, null, null, null, null, null, status,
3317                                    params, true, QueryUtil.ALL_POS, QueryUtil.ALL_POS, null);
3318    
3319                            return (int)indexer.searchCount(searchContext);
3320                    }
3321                    catch (Exception e) {
3322                            throw new SystemException(e);
3323                    }
3324            }
3325    
3326            @Override
3327            public Map<Long, Integer> searchCounts(
3328                    long companyId, int status, long[] groupIds) {
3329    
3330                    return userFinder.countByGroups(companyId, status, groupIds);
3331            }
3332    
3333            @Override
3334            public List<User> searchSocial(
3335                            long userId, int[] socialRelationTypes, String keywords, int start,
3336                            int end)
3337                    throws PortalException {
3338    
3339                    User user = userPersistence.findByPrimaryKey(userId);
3340    
3341                    LinkedHashMap<String, Object> params = new LinkedHashMap<>();
3342    
3343                    params.put(
3344                            "socialRelationType",
3345                            new Long[][] {
3346                                    new Long[] {userId}, ArrayUtil.toLongArray(socialRelationTypes)
3347                            });
3348                    params.put("wildcardMode", WildcardMode.TRAILING);
3349    
3350                    return userFinder.findByKeywords(
3351                            user.getCompanyId(), keywords, WorkflowConstants.STATUS_APPROVED,
3352                            params, start, end, null);
3353            }
3354    
3355            @Override
3356            public List<User> searchSocial(
3357                    long companyId, long[] groupIds, String keywords, int start, int end) {
3358    
3359                    LinkedHashMap<String, Object> params = new LinkedHashMap<>();
3360    
3361                    params.put("usersGroups", ArrayUtil.toLongArray(groupIds));
3362                    params.put("wildcardMode", WildcardMode.TRAILING);
3363    
3364                    return userFinder.findByKeywords(
3365                            companyId, keywords, WorkflowConstants.STATUS_APPROVED, params,
3366                            start, end, null);
3367            }
3368    
3369            @Override
3370            public List<User> searchSocial(
3371                            long[] groupIds, long userId, int[] socialRelationTypes,
3372                            String keywords, int start, int end)
3373                    throws PortalException {
3374    
3375                    User user = userPersistence.findByPrimaryKey(userId);
3376    
3377                    LinkedHashMap<String, Object> params = new LinkedHashMap<>();
3378    
3379                    params.put(
3380                            "socialRelationType",
3381                            new Long[][] {
3382                                    new Long[] {userId}, ArrayUtil.toLongArray(socialRelationTypes)
3383                            });
3384                    params.put("socialRelationTypeUnionUserGroups", true);
3385                    params.put("usersGroups", ArrayUtil.toLongArray(groupIds));
3386                    params.put("wildcardMode", WildcardMode.TRAILING);
3387    
3388                    return userFinder.findByKeywords(
3389                            user.getCompanyId(), keywords, WorkflowConstants.STATUS_APPROVED,
3390                            params, start, end, null);
3391            }
3392    
3393            @Override
3394            public BaseModelSearchResult<User> searchUsers(
3395                            long companyId, String keywords, int status,
3396                            LinkedHashMap<String, Object> params, int start, int end, Sort sort)
3397                    throws PortalException {
3398    
3399                    return searchUsers(
3400                            companyId, keywords, status, params, start, end, new Sort[] {sort});
3401            }
3402    
3403            @Override
3404            public BaseModelSearchResult<User> searchUsers(
3405                            long companyId, String keywords, int status,
3406                            LinkedHashMap<String, Object> params, int start, int end,
3407                            Sort[] sorts)
3408                    throws PortalException {
3409    
3410                    String firstName = null;
3411                    String middleName = null;
3412                    String lastName = null;
3413                    String fullName = null;
3414                    String screenName = null;
3415                    String emailAddress = null;
3416                    String street = null;
3417                    String city = null;
3418                    String zip = null;
3419                    String region = null;
3420                    String country = null;
3421                    boolean andOperator = false;
3422    
3423                    if (Validator.isNotNull(keywords)) {
3424                            firstName = keywords;
3425                            middleName = keywords;
3426                            lastName = keywords;
3427                            fullName = keywords;
3428                            screenName = keywords;
3429                            emailAddress = keywords;
3430                            street = keywords;
3431                            city = keywords;
3432                            zip = keywords;
3433                            region = keywords;
3434                            country = keywords;
3435                    }
3436                    else {
3437                            andOperator = true;
3438                    }
3439    
3440                    if (params != null) {
3441                            params.put("keywords", keywords);
3442                    }
3443    
3444                    SearchContext searchContext = buildSearchContext(
3445                            companyId, firstName, middleName, lastName, fullName, screenName,
3446                            emailAddress, street, city, zip, region, country, status, params,
3447                            andOperator, start, end, sorts);
3448    
3449                    return searchUsers(searchContext);
3450            }
3451    
3452            @Override
3453            public BaseModelSearchResult<User> searchUsers(
3454                            long companyId, String firstName, String middleName,
3455                            String lastName, String screenName, String emailAddress, int status,
3456                            LinkedHashMap<String, Object> params, boolean andSearch, int start,
3457                            int end, Sort sort)
3458                    throws PortalException {
3459    
3460                    return searchUsers(
3461                            companyId, firstName, middleName, lastName, screenName,
3462                            emailAddress, status, params, andSearch, start, end,
3463                            new Sort[] {sort});
3464            }
3465    
3466            @Override
3467            public BaseModelSearchResult<User> searchUsers(
3468                            long companyId, String firstName, String middleName,
3469                            String lastName, String screenName, String emailAddress, int status,
3470                            LinkedHashMap<String, Object> params, boolean andSearch, int start,
3471                            int end, Sort[] sorts)
3472                    throws PortalException {
3473    
3474                    SearchContext searchContext = buildSearchContext(
3475                            companyId, firstName, middleName, lastName, null, screenName,
3476                            emailAddress, null, null, null, null, null, status, params,
3477                            andSearch, start, end, sorts);
3478    
3479                    return searchUsers(searchContext);
3480            }
3481    
3482            /**
3483             * Sends an email address verification to the user.
3484             *
3485             * @param user the verification email recipient
3486             * @param emailAddress the recipient's email address
3487             * @param serviceContext the service context to be applied. Must set the
3488             *        portal URL, main path, primary key of the layout, remote address,
3489             *        remote host, and agent for the user.
3490             */
3491            @Override
3492            public void sendEmailAddressVerification(
3493                            User user, String emailAddress, ServiceContext serviceContext)
3494                    throws PortalException {
3495    
3496                    if (user.isEmailAddressVerified() &&
3497                            StringUtil.equalsIgnoreCase(emailAddress, user.getEmailAddress())) {
3498    
3499                            return;
3500                    }
3501    
3502                    Ticket ticket = ticketLocalService.addDistinctTicket(
3503                            user.getCompanyId(), User.class.getName(), user.getUserId(),
3504                            TicketConstants.TYPE_EMAIL_ADDRESS, emailAddress, null,
3505                            serviceContext);
3506    
3507                    String verifyEmailAddressURL =
3508                            serviceContext.getPortalURL() + serviceContext.getPathMain() +
3509                                    "/portal/verify_email_address?ticketKey=" + ticket.getKey();
3510    
3511                    long plid = serviceContext.getPlid();
3512    
3513                    if (plid > 0) {
3514                            Layout layout = layoutLocalService.fetchLayout(plid);
3515    
3516                            if (layout != null) {
3517                                    Group group = layout.getGroup();
3518    
3519                                    if (!layout.isPrivateLayout() && !group.isUser()) {
3520                                            verifyEmailAddressURL +=
3521                                                    "&p_l_id=" + serviceContext.getPlid();
3522                                    }
3523                            }
3524                    }
3525    
3526                    String fromName = PrefsPropsUtil.getString(
3527                            user.getCompanyId(), PropsKeys.ADMIN_EMAIL_FROM_NAME);
3528                    String fromAddress = PrefsPropsUtil.getString(
3529                            user.getCompanyId(), PropsKeys.ADMIN_EMAIL_FROM_ADDRESS);
3530    
3531                    String toName = user.getFullName();
3532                    String toAddress = emailAddress;
3533    
3534                    PortletPreferences companyPortletPreferences =
3535                            PrefsPropsUtil.getPreferences(user.getCompanyId(), true);
3536    
3537                    Map<Locale, String> localizedSubjectMap =
3538                            LocalizationUtil.getLocalizationMap(
3539                                    companyPortletPreferences, "adminEmailVerificationSubject",
3540                                    PropsKeys.ADMIN_EMAIL_VERIFICATION_SUBJECT);
3541                    Map<Locale, String> localizedBodyMap =
3542                            LocalizationUtil.getLocalizationMap(
3543                                    companyPortletPreferences, "adminEmailVerificationBody",
3544                                    PropsKeys.ADMIN_EMAIL_VERIFICATION_BODY);
3545    
3546                    SubscriptionSender subscriptionSender = new SubscriptionSender();
3547    
3548                    subscriptionSender.setCompanyId(user.getCompanyId());
3549                    subscriptionSender.setContextAttributes(
3550                            "[$EMAIL_VERIFICATION_CODE$]", ticket.getKey(),
3551                            "[$EMAIL_VERIFICATION_URL$]", verifyEmailAddressURL,
3552                            "[$REMOTE_ADDRESS$]", serviceContext.getRemoteAddr(),
3553                            "[$REMOTE_HOST$]", serviceContext.getRemoteHost(), "[$USER_ID$]",
3554                            user.getUserId(), "[$USER_SCREENNAME$]", user.getScreenName());
3555                    subscriptionSender.setFrom(fromAddress, fromName);
3556                    subscriptionSender.setHtmlFormat(true);
3557                    subscriptionSender.setLocalizedBodyMap(localizedBodyMap);
3558                    subscriptionSender.setLocalizedSubjectMap(localizedSubjectMap);
3559                    subscriptionSender.setMailId("user", user.getUserId());
3560                    subscriptionSender.setServiceContext(serviceContext);
3561    
3562                    subscriptionSender.addRuntimeSubscribers(toAddress, toName);
3563    
3564                    subscriptionSender.flushNotificationsAsync();
3565            }
3566    
3567            /**
3568             * Sends the password email to the user with the email address. The content
3569             * of this email can be specified in <code>portal.properties</code> with the
3570             * <code>admin.email.password</code> keys.
3571             *
3572             * @param companyId the primary key of the user's company
3573             * @param emailAddress the user's email address
3574             * @param fromName the name of the individual that the email should be from
3575             * @param fromAddress the address of the individual that the email should be
3576             *        from
3577             * @param subject the email subject. If <code>null</code>, the subject
3578             *        specified in <code>portal.properties</code> will be used.
3579             * @param body the email body. If <code>null</code>, the body specified in
3580             *        <code>portal.properties</code> will be used.
3581             * @param serviceContext the service context to be applied
3582             */
3583            @Override
3584            public boolean sendPassword(
3585                            long companyId, String emailAddress, String fromName,
3586                            String fromAddress, String subject, String body,
3587                            ServiceContext serviceContext)
3588                    throws PortalException {
3589    
3590                    Company company = companyPersistence.findByPrimaryKey(companyId);
3591    
3592                    if (!company.isSendPassword() && !company.isSendPasswordResetLink()) {
3593                            throw new SendPasswordException.MustBeEnabled(company);
3594                    }
3595    
3596                    emailAddress = StringUtil.toLowerCase(emailAddress.trim());
3597    
3598                    if (Validator.isNull(emailAddress)) {
3599                            throw new UserEmailAddressException.MustNotBeNull();
3600                    }
3601    
3602                    User user = userPersistence.findByC_EA(companyId, emailAddress);
3603    
3604                    PasswordPolicy passwordPolicy = user.getPasswordPolicy();
3605    
3606                    String newPassword = StringPool.BLANK;
3607                    String passwordResetURL = StringPool.BLANK;
3608    
3609                    if (company.isSendPasswordResetLink()) {
3610                            Date expirationDate = null;
3611    
3612                            if ((passwordPolicy != null) &&
3613                                    (passwordPolicy.getResetTicketMaxAge() > 0)) {
3614    
3615                                    expirationDate = new Date(
3616                                            System.currentTimeMillis() +
3617                                                    (passwordPolicy.getResetTicketMaxAge() * 1000));
3618                            }
3619    
3620                            Ticket ticket = ticketLocalService.addDistinctTicket(
3621                                    companyId, User.class.getName(), user.getUserId(),
3622                                    TicketConstants.TYPE_PASSWORD, null, expirationDate,
3623                                    serviceContext);
3624    
3625                            passwordResetURL =
3626                                    serviceContext.getPortalURL() + serviceContext.getPathMain() +
3627                                            "/portal/update_password?p_l_id="+
3628                                                    serviceContext.getPlid() +
3629                                                            "&ticketKey=" + ticket.getKey();
3630                    }
3631                    else {
3632                            if (!Validator.equals(
3633                                            PasswordEncryptorUtil.getDefaultPasswordAlgorithmType(),
3634                                            PasswordEncryptorUtil.TYPE_NONE)) {
3635    
3636                                    if (LDAPSettingsUtil.isPasswordPolicyEnabled(
3637                                                    user.getCompanyId())) {
3638    
3639                                            if (_log.isWarnEnabled()) {
3640                                                    StringBundler sb = new StringBundler(5);
3641    
3642                                                    sb.append("When LDAP password policy is enabled, ");
3643                                                    sb.append("it is possible that portal generated ");
3644                                                    sb.append("passwords will not match the LDAP policy.");
3645                                                    sb.append("Using RegExpToolkit to generate new ");
3646                                                    sb.append("password.");
3647    
3648                                                    _log.warn(sb.toString());
3649                                            }
3650    
3651                                            RegExpToolkit regExpToolkit = new RegExpToolkit();
3652    
3653                                            newPassword = regExpToolkit.generate(null);
3654                                    }
3655                                    else {
3656                                            newPassword = PwdToolkitUtil.generate(passwordPolicy);
3657                                    }
3658    
3659                                    boolean passwordReset = false;
3660    
3661                                    if (passwordPolicy.getChangeable() &&
3662                                            passwordPolicy.getChangeRequired()) {
3663    
3664                                            passwordReset = true;
3665                                    }
3666    
3667                                    user.setPassword(PasswordEncryptorUtil.encrypt(newPassword));
3668                                    user.setPasswordUnencrypted(newPassword);
3669                                    user.setPasswordEncrypted(true);
3670                                    user.setPasswordReset(passwordReset);
3671                                    user.setPasswordModified(true);
3672                                    user.setPasswordModifiedDate(new Date());
3673    
3674                                    userPersistence.update(user);
3675    
3676                                    user.setPasswordModified(false);
3677                            }
3678                            else {
3679                                    newPassword = user.getPassword();
3680                            }
3681                    }
3682    
3683                    sendPasswordNotification(
3684                            user, companyId, newPassword, passwordResetURL, fromName,
3685                            fromAddress, subject, body, serviceContext);
3686    
3687                    return company.isSendPassword();
3688            }
3689    
3690            /**
3691             * Sends a password notification email to the user matching the email
3692             * address. The portal's settings determine whether a password is sent
3693             * explicitly or whether a link for resetting the user's password is sent.
3694             * The method sends the email asynchronously and returns before the email is
3695             * sent.
3696             *
3697             * <p>
3698             * The content of the notification email is specified with the
3699             * <code>admin.email.password</code> portal property keys. They can be
3700             * overridden via a <code>portal-ext.properties</code> file or modified
3701             * through the Portal Settings UI.
3702             * </p>
3703             *
3704             * @param  companyId the primary key of the user's company
3705             * @param  emailAddress the user's email address
3706             * @return <code>true</code> if the notification email includes a new
3707             *         password; <code>false</code> if the notification email only
3708             *         contains a reset link
3709             */
3710            @Override
3711            public boolean sendPasswordByEmailAddress(
3712                            long companyId, String emailAddress)
3713                    throws PortalException {
3714    
3715                    User user = userPersistence.findByC_EA(companyId, emailAddress);
3716    
3717                    return sendPassword(
3718                            user.getCompanyId(), user.getEmailAddress(), null, null, null, null,
3719                            ServiceContextThreadLocal.getServiceContext());
3720            }
3721    
3722            /**
3723             * Sends a password notification email to the user matching the screen name.
3724             * The portal's settings determine whether a password is sent explicitly or
3725             * whether a link for resetting the user's password is sent. The method
3726             * sends the email asynchronously and returns before the email is sent.
3727             *
3728             * <p>
3729             * The content of the notification email is specified with the
3730             * <code>admin.email.password</code> portal property keys. They can be
3731             * overridden via a <code>portal-ext.properties</code> file or modified
3732             * through the Portal Settings UI.
3733             * </p>
3734             *
3735             * @param  companyId the primary key of the user's company
3736             * @param  screenName the user's screen name
3737             * @return <code>true</code> if the notification email includes a new
3738             *         password; <code>false</code> if the notification email only
3739             *         contains a reset link
3740             */
3741            @Override
3742            public boolean sendPasswordByScreenName(long companyId, String screenName)
3743                    throws PortalException {
3744    
3745                    User user = userPersistence.findByC_SN(companyId, screenName);
3746    
3747                    return sendPassword(
3748                            user.getCompanyId(), user.getEmailAddress(), null, null, null, null,
3749                            ServiceContextThreadLocal.getServiceContext());
3750            }
3751    
3752            /**
3753             * Sends a password notification email to the user matching the ID. The
3754             * portal's settings determine whether a password is sent explicitly or
3755             * whether a link for resetting the user's password is sent. The method
3756             * sends the email asynchronously and returns before the email is sent.
3757             *
3758             * <p>
3759             * The content of the notification email is specified with the
3760             * <code>admin.email.password</code> portal property keys. They can be
3761             * overridden via a <code>portal-ext.properties</code> file or modified
3762             * through the Portal Settings UI.
3763             * </p>
3764             *
3765             * @param  userId the user's primary key
3766             * @return <code>true</code> if the notification email includes a new
3767             *         password; <code>false</code> if the notification email only
3768             *         contains a reset link
3769             */
3770            @Override
3771            public boolean sendPasswordByUserId(long userId) throws PortalException {
3772                    User user = userPersistence.findByPrimaryKey(userId);
3773    
3774                    return sendPassword(
3775                            user.getCompanyId(), user.getEmailAddress(), null, null, null, null,
3776                            ServiceContextThreadLocal.getServiceContext());
3777            }
3778    
3779            /**
3780             * Sets the users in the role, removing and adding users to the role as
3781             * necessary.
3782             *
3783             * @param roleId the primary key of the role
3784             * @param userIds the primary keys of the users
3785             */
3786            @Override
3787            public void setRoleUsers(long roleId, long[] userIds)
3788                    throws PortalException {
3789    
3790                    long[] oldUserIds = rolePersistence.getUserPrimaryKeys(roleId);
3791    
3792                    Set<Long> updatedUserIdsSet = SetUtil.symmetricDifference(
3793                            userIds, oldUserIds);
3794    
3795                    long[] updateUserIds = ArrayUtil.toLongArray(updatedUserIdsSet);
3796    
3797                    rolePersistence.setUsers(roleId, userIds);
3798    
3799                    reindex(updateUserIds);
3800    
3801                    PermissionCacheUtil.clearCache(updateUserIds);
3802            }
3803    
3804            /**
3805             * Sets the users in the user group, removing and adding users to the user
3806             * group as necessary.
3807             *
3808             * @param userGroupId the primary key of the user group
3809             * @param userIds the primary keys of the users
3810             */
3811            @Override
3812            @SuppressWarnings("deprecation")
3813            public void setUserGroupUsers(long userGroupId, long[] userIds)
3814                    throws PortalException {
3815    
3816                    if (PropsValues.USER_GROUPS_COPY_LAYOUTS_TO_USER_PERSONAL_SITE) {
3817                            userGroupLocalService.copyUserGroupLayouts(userGroupId, userIds);
3818                    }
3819    
3820                    long[] oldUserIds = userGroupPersistence.getUserPrimaryKeys(
3821                            userGroupId);
3822    
3823                    Set<Long> updatedUserIdsSet = SetUtil.symmetricDifference(
3824                            userIds, oldUserIds);
3825    
3826                    long[] updateUserIds = ArrayUtil.toLongArray(updatedUserIdsSet);
3827    
3828                    userGroupPersistence.setUsers(userGroupId, userIds);
3829    
3830                    reindex(updateUserIds);
3831    
3832                    PermissionCacheUtil.clearCache(updateUserIds);
3833            }
3834    
3835            /**
3836             * Removes the users from the teams of a group.
3837             *
3838             * @param groupId the primary key of the group
3839             * @param userIds the primary keys of the users
3840             */
3841            @Override
3842            public void unsetGroupTeamsUsers(long groupId, long[] userIds)
3843                    throws PortalException {
3844    
3845                    List<Team> teams = teamPersistence.findByGroupId(groupId);
3846    
3847                    for (Team team : teams) {
3848                            unsetTeamUsers(team.getTeamId(), userIds);
3849                    }
3850    
3851                    PermissionCacheUtil.clearCache(userIds);
3852            }
3853    
3854            /**
3855             * Removes the users from the group.
3856             *
3857             * @param groupId the primary key of the group
3858             * @param userIds the primary keys of the users
3859             * @param serviceContext the service context to be applied (optionally
3860             *        <code>null</code>)
3861             */
3862            @Override
3863            public void unsetGroupUsers(
3864                            final long groupId, final long[] userIds,
3865                            ServiceContext serviceContext)
3866                    throws PortalException {
3867    
3868                    userGroupRoleLocalService.deleteUserGroupRoles(
3869                            userIds, groupId, RoleConstants.TYPE_SITE);
3870    
3871                    unsetGroupTeamsUsers(groupId, userIds);
3872    
3873                    groupPersistence.removeUsers(groupId, userIds);
3874    
3875                    reindex(userIds);
3876    
3877                    PermissionCacheUtil.clearCache(userIds);
3878    
3879                    Callable<Void> callable = new Callable<Void>() {
3880    
3881                            @Override
3882                            public Void call() throws Exception {
3883                                    Message message = new Message();
3884    
3885                                    message.put("groupId", groupId);
3886                                    message.put("userIds", userIds);
3887    
3888                                    MessageBusUtil.sendMessage(
3889                                            DestinationNames.SUBSCRIPTION_CLEAN_UP, message);
3890    
3891                                    return null;
3892                            }
3893    
3894                    };
3895    
3896                    TransactionCommitCallbackUtil.registerCallback(callable);
3897            }
3898    
3899            /**
3900             * Removes the users from the organization.
3901             *
3902             * @param organizationId the primary key of the organization
3903             * @param userIds the primary keys of the users
3904             */
3905            @Override
3906            public void unsetOrganizationUsers(
3907                            long organizationId, final long[] userIds)
3908                    throws PortalException {
3909    
3910                    Organization organization = organizationPersistence.findByPrimaryKey(
3911                            organizationId);
3912    
3913                    final Group group = organization.getGroup();
3914    
3915                    userGroupRoleLocalService.deleteUserGroupRoles(
3916                            userIds, group.getGroupId());
3917    
3918                    organizationPersistence.removeUsers(organizationId, userIds);
3919    
3920                    reindex(userIds);
3921    
3922                    PermissionCacheUtil.clearCache(userIds);
3923    
3924                    Callable<Void> callable = new Callable<Void>() {
3925    
3926                            @Override
3927                            public Void call() throws Exception {
3928                                    Message message = new Message();
3929    
3930                                    message.put("groupId", group.getGroupId());
3931                                    message.put("userIds", userIds);
3932    
3933                                    MessageBusUtil.sendMessage(
3934                                            DestinationNames.SUBSCRIPTION_CLEAN_UP, message);
3935    
3936                                    return null;
3937                            }
3938    
3939                    };
3940    
3941                    TransactionCommitCallbackUtil.registerCallback(callable);
3942            }
3943    
3944            /**
3945             * Removes the users from the password policy.
3946             *
3947             * @param passwordPolicyId the primary key of the password policy
3948             * @param userIds the primary keys of the users
3949             */
3950            @Override
3951            public void unsetPasswordPolicyUsers(
3952                    long passwordPolicyId, long[] userIds) {
3953    
3954                    passwordPolicyRelLocalService.deletePasswordPolicyRels(
3955                            passwordPolicyId, User.class.getName(), userIds);
3956            }
3957    
3958            /**
3959             * Removes the users from the role.
3960             *
3961             * @param roleId the primary key of the role
3962             * @param users the users
3963             */
3964            @Override
3965            public void unsetRoleUsers(long roleId, List<User> users)
3966                    throws PortalException {
3967    
3968                    Role role = rolePersistence.findByPrimaryKey(roleId);
3969    
3970                    String roleName = role.getName();
3971    
3972                    if ((roleName.equals(RoleConstants.ADMINISTRATOR) &&
3973                             (getRoleUsersCount(role.getRoleId()) <= 1)) ||
3974                            roleName.equals(RoleConstants.USER)) {
3975    
3976                            return;
3977                    }
3978    
3979                    rolePersistence.removeUsers(roleId, users);
3980    
3981                    Indexer<User> indexer = IndexerRegistryUtil.nullSafeGetIndexer(
3982                            User.class);
3983    
3984                    indexer.reindex(users);
3985    
3986                    long[] userIds = new long[users.size()];
3987    
3988                    for (int i = 0; i < users.size(); i++) {
3989                            User user = users.get(i);
3990    
3991                            userIds[i] = user.getUserId();
3992                    }
3993    
3994                    PermissionCacheUtil.clearCache(userIds);
3995            }
3996    
3997            /**
3998             * Removes the users from the role.
3999             *
4000             * @param roleId the primary key of the role
4001             * @param userIds the primary keys of the users
4002             */
4003            @Override
4004            public void unsetRoleUsers(long roleId, long[] userIds)
4005                    throws PortalException {
4006    
4007                    Role role = rolePersistence.findByPrimaryKey(roleId);
4008    
4009                    String roleName = role.getName();
4010    
4011                    if (roleName.equals(RoleConstants.USER) ||
4012                            (roleName.equals(RoleConstants.ADMINISTRATOR) &&
4013                             getRoleUsersCount(role.getRoleId()) <= 1)) {
4014    
4015                            return;
4016                    }
4017    
4018                    rolePersistence.removeUsers(roleId, userIds);
4019    
4020                    reindex(userIds);
4021    
4022                    PermissionCacheUtil.clearCache(userIds);
4023            }
4024    
4025            /**
4026             * Removes the users from the team.
4027             *
4028             * @param teamId the primary key of the team
4029             * @param userIds the primary keys of the users
4030             */
4031            @Override
4032            public void unsetTeamUsers(long teamId, long[] userIds)
4033                    throws PortalException {
4034    
4035                    teamPersistence.removeUsers(teamId, userIds);
4036    
4037                    reindex(userIds);
4038    
4039                    PermissionCacheUtil.clearCache(userIds);
4040            }
4041    
4042            /**
4043             * Removes the users from the user group.
4044             *
4045             * @param userGroupId the primary key of the user group
4046             * @param userIds the primary keys of the users
4047             */
4048            @Override
4049            public void unsetUserGroupUsers(long userGroupId, long[] userIds)
4050                    throws PortalException {
4051    
4052                    userGroupPersistence.removeUsers(userGroupId, userIds);
4053    
4054                    reindex(userIds);
4055    
4056                    PermissionCacheUtil.clearCache(userIds);
4057            }
4058    
4059            /**
4060             * Updates whether the user has agreed to the terms of use.
4061             *
4062             * @param  userId the primary key of the user
4063             * @param  agreedToTermsOfUse whether the user has agreet to the terms of
4064             *         use
4065             * @return the user
4066             */
4067            @Override
4068            public User updateAgreedToTermsOfUse(
4069                            long userId, boolean agreedToTermsOfUse)
4070                    throws PortalException {
4071    
4072                    User user = userPersistence.findByPrimaryKey(userId);
4073    
4074                    user.setAgreedToTermsOfUse(agreedToTermsOfUse);
4075    
4076                    userPersistence.update(user);
4077    
4078                    return user;
4079            }
4080    
4081            /**
4082             * Updates the user's asset with the new asset categories and tag names,
4083             * removing and adding asset categories and tag names as necessary.
4084             *
4085             * @param userId the primary key of the user
4086             * @param user ID the primary key of the user
4087             * @param assetCategoryIds the primary key's of the new asset categories
4088             * @param assetTagNames the new asset tag names
4089             */
4090            @Override
4091            public void updateAsset(
4092                            long userId, User user, long[] assetCategoryIds,
4093                            String[] assetTagNames)
4094                    throws PortalException {
4095    
4096                    User owner = userPersistence.findByPrimaryKey(userId);
4097    
4098                    Company company = companyPersistence.findByPrimaryKey(
4099                            owner.getCompanyId());
4100    
4101                    Group companyGroup = company.getGroup();
4102    
4103                    assetEntryLocalService.updateEntry(
4104                            userId, companyGroup.getGroupId(), user.getCreateDate(),
4105                            user.getModifiedDate(), User.class.getName(), user.getUserId(),
4106                            user.getUuid(), 0, assetCategoryIds, assetTagNames, false, null,
4107                            null, null, null, user.getFullName(), null, null, null, null, 0, 0,
4108                            null);
4109            }
4110    
4111            /**
4112             * Updates the user's creation date.
4113             *
4114             * @param  userId the primary key of the user
4115             * @param  createDate the new creation date
4116             * @return the user
4117             */
4118            @Override
4119            public User updateCreateDate(long userId, Date createDate)
4120                    throws PortalException {
4121    
4122                    User user = userPersistence.findByPrimaryKey(userId);
4123    
4124                    user.setCreateDate(createDate);
4125    
4126                    userPersistence.update(user);
4127    
4128                    return user;
4129            }
4130    
4131            /**
4132             * Updates the user's email address.
4133             *
4134             * @param  userId the primary key of the user
4135             * @param  password the user's password
4136             * @param  emailAddress1 the user's new email address
4137             * @param  emailAddress2 the user's new email address confirmation
4138             * @return the user
4139             */
4140            @Override
4141            public User updateEmailAddress(
4142                            long userId, String password, String emailAddress1,
4143                            String emailAddress2)
4144                    throws PortalException {
4145    
4146                    emailAddress1 = StringUtil.toLowerCase(emailAddress1.trim());
4147                    emailAddress2 = StringUtil.toLowerCase(emailAddress2.trim());
4148    
4149                    User user = userPersistence.findByPrimaryKey(userId);
4150    
4151                    validateEmailAddress(user, emailAddress1, emailAddress2);
4152    
4153                    setEmailAddress(
4154                            user, password, user.getFirstName(), user.getMiddleName(),
4155                            user.getLastName(), emailAddress1);
4156    
4157                    userPersistence.update(user);
4158    
4159                    Contact contact = user.getContact();
4160    
4161                    contact.setEmailAddress(user.getEmailAddress());
4162    
4163                    contactPersistence.update(contact);
4164    
4165                    return user;
4166            }
4167    
4168            /**
4169             * Updates the user's email address or sends verification email.
4170             *
4171             * @param  userId the primary key of the user
4172             * @param  password the user's password
4173             * @param  emailAddress1 the user's new email address
4174             * @param  emailAddress2 the user's new email address confirmation
4175             * @param  serviceContext the service context to be applied. Must set the
4176             *         portal URL, main path, primary key of the layout, remote address,
4177             *         remote host, and agent for the user.
4178             * @return the user
4179             */
4180            @Override
4181            public User updateEmailAddress(
4182                            long userId, String password, String emailAddress1,
4183                            String emailAddress2, ServiceContext serviceContext)
4184                    throws PortalException {
4185    
4186                    emailAddress1 = StringUtil.toLowerCase(emailAddress1.trim());
4187                    emailAddress2 = StringUtil.toLowerCase(emailAddress2.trim());
4188    
4189                    User user = userPersistence.findByPrimaryKey(userId);
4190    
4191                    validateEmailAddress(user, emailAddress1, emailAddress2);
4192    
4193                    Company company = companyPersistence.findByPrimaryKey(
4194                            user.getCompanyId());
4195    
4196                    if (company.isStrangersVerify() &&
4197                            !StringUtil.equalsIgnoreCase(
4198                                    emailAddress1, user.getEmailAddress())) {
4199    
4200                            sendEmailAddressVerification(user, emailAddress1, serviceContext);
4201                    }
4202                    else {
4203                            setEmailAddress(
4204                                    user, password, user.getFirstName(), user.getMiddleName(),
4205                                    user.getLastName(), emailAddress1);
4206    
4207                            userPersistence.update(user);
4208    
4209                            Contact contact = user.getContact();
4210    
4211                            contact.setEmailAddress(user.getEmailAddress());
4212    
4213                            contactPersistence.update(contact);
4214                    }
4215    
4216                    return user;
4217            }
4218    
4219            /**
4220             * Updates whether the user has verified email address.
4221             *
4222             * @param  userId the primary key of the user
4223             * @param  emailAddressVerified whether the user has verified email address
4224             * @return the user
4225             */
4226            @Override
4227            public User updateEmailAddressVerified(
4228                            long userId, boolean emailAddressVerified)
4229                    throws PortalException {
4230    
4231                    User user = userPersistence.findByPrimaryKey(userId);
4232    
4233                    user.setEmailAddressVerified(emailAddressVerified);
4234    
4235                    userPersistence.update(user);
4236    
4237                    return user;
4238            }
4239    
4240            /**
4241             * Updates the user's Facebook ID.
4242             *
4243             * @param  userId the primary key of the user
4244             * @param  facebookId the user's new Facebook ID
4245             * @return the user
4246             */
4247            @Override
4248            public User updateFacebookId(long userId, long facebookId)
4249                    throws PortalException {
4250    
4251                    User user = userPersistence.findByPrimaryKey(userId);
4252    
4253                    user.setFacebookId(facebookId);
4254    
4255                    userPersistence.update(user);
4256    
4257                    return user;
4258            }
4259    
4260            /**
4261             * Sets the groups the user is in, removing and adding groups as necessary.
4262             *
4263             * @param userId the primary key of the user
4264             * @param newGroupIds the primary keys of the groups
4265             * @param serviceContext the service context to be applied (optionally
4266             *        <code>null</code>)
4267             */
4268            @Override
4269            public void updateGroups(
4270                            long userId, long[] newGroupIds, ServiceContext serviceContext)
4271                    throws PortalException {
4272    
4273                    boolean indexingEnabled = true;
4274    
4275                    if (serviceContext != null) {
4276                            indexingEnabled = serviceContext.isIndexingEnabled();
4277                    }
4278    
4279                    updateGroups(userId, newGroupIds, serviceContext, indexingEnabled);
4280            }
4281    
4282            /**
4283             * Updates a user account that was automatically created when a guest user
4284             * participated in an action (e.g. posting a comment) and only provided his
4285             * name and email address.
4286             *
4287             * @param  creatorUserId the primary key of the creator
4288             * @param  companyId the primary key of the user's company
4289             * @param  autoPassword whether a password should be automatically generated
4290             *         for the user
4291             * @param  password1 the user's password
4292             * @param  password2 the user's password confirmation
4293             * @param  autoScreenName whether a screen name should be automatically
4294             *         generated for the user
4295             * @param  screenName the user's screen name
4296             * @param  emailAddress the user's email address
4297             * @param  facebookId the user's facebook ID
4298             * @param  openId the user's OpenID
4299             * @param  locale the user's locale
4300             * @param  firstName the user's first name
4301             * @param  middleName the user's middle name
4302             * @param  lastName the user's last name
4303             * @param  prefixId the user's name prefix ID
4304             * @param  suffixId the user's name suffix ID
4305             * @param  male whether the user is male
4306             * @param  birthdayMonth the user's birthday month (0-based, meaning 0 for
4307             *         January)
4308             * @param  birthdayDay the user's birthday day
4309             * @param  birthdayYear the user's birthday year
4310             * @param  jobTitle the user's job title
4311             * @param  updateUserInformation whether to update the user's information
4312             * @param  sendEmail whether to send the user an email notification about
4313             *         their new account
4314             * @param  serviceContext the service context to be applied (optionally
4315             *         <code>null</code>). Can set expando bridge attributes for the
4316             *         user.
4317             * @return the user
4318             */
4319            @Override
4320            public User updateIncompleteUser(
4321                            long creatorUserId, long companyId, boolean autoPassword,
4322                            String password1, String password2, boolean autoScreenName,
4323                            String screenName, String emailAddress, long facebookId,
4324                            String openId, Locale locale, String firstName, String middleName,
4325                            String lastName, long prefixId, long suffixId, boolean male,
4326                            int birthdayMonth, int birthdayDay, int birthdayYear,
4327                            String jobTitle, boolean updateUserInformation, boolean sendEmail,
4328                            ServiceContext serviceContext)
4329                    throws PortalException {
4330    
4331                    User user = getUserByEmailAddress(companyId, emailAddress);
4332    
4333                    if (user.getStatus() != WorkflowConstants.STATUS_INCOMPLETE) {
4334                            throw new PortalException("Invalid user status");
4335                    }
4336    
4337                    User defaultUser = getDefaultUser(companyId);
4338    
4339                    if (facebookId > 0) {
4340                            autoPassword = false;
4341    
4342                            if ((password1 == null) || (password2 == null)) {
4343                                    password1 = PwdGenerator.getPassword();
4344                                    password2 = password1;
4345                            }
4346    
4347                            sendEmail = false;
4348                    }
4349    
4350                    if (updateUserInformation) {
4351                            autoScreenName = false;
4352    
4353                            if (PrefsPropsUtil.getBoolean(
4354                                            companyId,
4355                                            PropsKeys.USERS_SCREEN_NAME_ALWAYS_AUTOGENERATE)) {
4356    
4357                                    autoScreenName = true;
4358                            }
4359    
4360                            validate(
4361                                    companyId, user.getUserId(), autoPassword, password1, password2,
4362                                    autoScreenName, screenName, emailAddress, openId, firstName,
4363                                    middleName, lastName, null, locale);
4364    
4365                            if (!autoPassword) {
4366                                    if (Validator.isNull(password1) ||
4367                                            Validator.isNull(password2)) {
4368                                                    throw new UserPasswordException.MustNotBeNull(
4369                                                            user.getUserId());
4370                                    }
4371                            }
4372    
4373                            if (autoScreenName) {
4374                                    ScreenNameGenerator screenNameGenerator =
4375                                            ScreenNameGeneratorFactory.getInstance();
4376    
4377                                    try {
4378                                            screenName = screenNameGenerator.generate(
4379                                                    companyId, user.getUserId(), emailAddress);
4380                                    }
4381                                    catch (Exception e) {
4382                                            throw new SystemException(e);
4383                                    }
4384                            }
4385    
4386                            FullNameGenerator fullNameGenerator =
4387                                    FullNameGeneratorFactory.getInstance();
4388    
4389                            String fullName = fullNameGenerator.getFullName(
4390                                    firstName, middleName, lastName);
4391    
4392                            String greeting = LanguageUtil.format(
4393                                    locale, "welcome-x", fullName, false);
4394    
4395                            if (Validator.isNotNull(password1)) {
4396                                    user.setPassword(PasswordEncryptorUtil.encrypt(password1));
4397                                    user.setPasswordUnencrypted(password1);
4398                            }
4399    
4400                            user.setPasswordEncrypted(true);
4401    
4402                            PasswordPolicy passwordPolicy = defaultUser.getPasswordPolicy();
4403    
4404                            if ((passwordPolicy != null) && passwordPolicy.isChangeable() &&
4405                                    passwordPolicy.isChangeRequired()) {
4406    
4407                                    user.setPasswordReset(true);
4408                            }
4409                            else {
4410                                    user.setPasswordReset(false);
4411                            }
4412    
4413                            user.setScreenName(screenName);
4414                            user.setFacebookId(facebookId);
4415                            user.setOpenId(openId);
4416                            user.setLanguageId(locale.toString());
4417                            user.setTimeZoneId(defaultUser.getTimeZoneId());
4418                            user.setGreeting(greeting);
4419                            user.setFirstName(firstName);
4420                            user.setMiddleName(middleName);
4421                            user.setLastName(lastName);
4422                            user.setJobTitle(jobTitle);
4423                            user.setExpandoBridgeAttributes(serviceContext);
4424    
4425                            Date birthday = getBirthday(
4426                                    birthdayMonth, birthdayDay, birthdayYear);
4427    
4428                            Contact contact = user.getContact();
4429    
4430                            contact.setFirstName(firstName);
4431                            contact.setMiddleName(middleName);
4432                            contact.setLastName(lastName);
4433                            contact.setPrefixId(prefixId);
4434                            contact.setSuffixId(suffixId);
4435                            contact.setMale(male);
4436                            contact.setBirthday(birthday);
4437                            contact.setJobTitle(jobTitle);
4438    
4439                            contactPersistence.update(contact, serviceContext);
4440    
4441                            // Indexer
4442    
4443                            Indexer<User> indexer = IndexerRegistryUtil.nullSafeGetIndexer(
4444                                    User.class);
4445    
4446                            indexer.reindex(user);
4447                    }
4448    
4449                    user.setStatus(WorkflowConstants.STATUS_DRAFT);
4450    
4451                    userPersistence.update(user, serviceContext);
4452    
4453                    // Workflow
4454    
4455                    long workflowUserId = creatorUserId;
4456    
4457                    if (workflowUserId == user.getUserId()) {
4458                            workflowUserId = defaultUser.getUserId();
4459                    }
4460    
4461                    ServiceContext workflowServiceContext = serviceContext;
4462    
4463                    if (workflowServiceContext == null) {
4464                            workflowServiceContext = new ServiceContext();
4465                    }
4466    
4467                    workflowServiceContext.setAttribute("autoPassword", autoPassword);
4468                    workflowServiceContext.setAttribute("passwordUnencrypted", password1);
4469                    workflowServiceContext.setAttribute("sendEmail", sendEmail);
4470    
4471                    WorkflowHandlerRegistryUtil.startWorkflowInstance(
4472                            companyId, workflowUserId, User.class.getName(), user.getUserId(),
4473                            user, workflowServiceContext);
4474    
4475                    return getUserByEmailAddress(companyId, emailAddress);
4476            }
4477    
4478            /**
4479             * Updates the user's job title.
4480             *
4481             * @param  userId the primary key of the user
4482             * @param  jobTitle the user's job title
4483             * @return the user
4484             */
4485            @Override
4486            public User updateJobTitle(long userId, String jobTitle)
4487                    throws PortalException {
4488    
4489                    User user = userPersistence.findByPrimaryKey(userId);
4490    
4491                    user.setJobTitle(jobTitle);
4492    
4493                    userPersistence.update(user);
4494    
4495                    Contact contact = contactPersistence.findByPrimaryKey(
4496                            user.getContactId());
4497    
4498                    contact.setJobTitle(jobTitle);
4499    
4500                    contactPersistence.update(contact);
4501    
4502                    return user;
4503            }
4504    
4505            /**
4506             * Updates the user's last login with the current time and the IP address.
4507             *
4508             * @param  userId the primary key of the user
4509             * @param  loginIP the IP address the user logged in from
4510             * @return the user
4511             */
4512            @Override
4513            public User updateLastLogin(long userId, String loginIP)
4514                    throws PortalException {
4515    
4516                    User user = userPersistence.findByPrimaryKey(userId);
4517    
4518                    Date lastLoginDate = user.getLoginDate();
4519    
4520                    if (lastLoginDate == null) {
4521                            lastLoginDate = new Date();
4522                    }
4523    
4524                    String lastLoginIP = user.getLoginIP();
4525    
4526                    if (lastLoginIP == null) {
4527                            lastLoginIP = loginIP;
4528                    }
4529    
4530                    user.setLoginDate(new Date());
4531                    user.setLoginIP(loginIP);
4532                    user.setLastLoginDate(lastLoginDate);
4533                    user.setLastLoginIP(lastLoginIP);
4534    
4535                    resetFailedLoginAttempts(user, true);
4536    
4537                    return user;
4538            }
4539    
4540            /**
4541             * Updates whether the user is locked out from logging in.
4542             *
4543             * @param  user the user
4544             * @param  lockout whether the user is locked out
4545             * @return the user
4546             */
4547            @Override
4548            public User updateLockout(User user, boolean lockout)
4549                    throws PortalException {
4550    
4551                    PasswordPolicy passwordPolicy = user.getPasswordPolicy();
4552    
4553                    if ((passwordPolicy == null) || !passwordPolicy.isLockout()) {
4554                            return user;
4555                    }
4556    
4557                    Date lockoutDate = null;
4558    
4559                    if (lockout) {
4560                            lockoutDate = new Date();
4561                    }
4562    
4563                    user.setLockout(lockout);
4564                    user.setLockoutDate(lockoutDate);
4565    
4566                    if (!lockout) {
4567                            user.setFailedLoginAttempts(0);
4568                    }
4569    
4570                    userPersistence.update(user);
4571    
4572                    return user;
4573            }
4574    
4575            /**
4576             * Updates whether the user is locked out from logging in.
4577             *
4578             * @param  companyId the primary key of the user's company
4579             * @param  emailAddress the user's email address
4580             * @param  lockout whether the user is locked out
4581             * @return the user
4582             */
4583            @Override
4584            public User updateLockoutByEmailAddress(
4585                            long companyId, String emailAddress, boolean lockout)
4586                    throws PortalException {
4587    
4588                    User user = getUserByEmailAddress(companyId, emailAddress);
4589    
4590                    return updateLockout(user, lockout);
4591            }
4592    
4593            /**
4594             * Updates whether the user is locked out from logging in.
4595             *
4596             * @param  userId the primary key of the user
4597             * @param  lockout whether the user is locked out
4598             * @return the user
4599             */
4600            @Override
4601            public User updateLockoutById(long userId, boolean lockout)
4602                    throws PortalException {
4603    
4604                    User user = userPersistence.findByPrimaryKey(userId);
4605    
4606                    return updateLockout(user, lockout);
4607            }
4608    
4609            /**
4610             * Updates whether the user is locked out from logging in.
4611             *
4612             * @param  companyId the primary key of the user's company
4613             * @param  screenName the user's screen name
4614             * @param  lockout whether the user is locked out
4615             * @return the user
4616             */
4617            @Override
4618            public User updateLockoutByScreenName(
4619                            long companyId, String screenName, boolean lockout)
4620                    throws PortalException {
4621    
4622                    User user = getUserByScreenName(companyId, screenName);
4623    
4624                    return updateLockout(user, lockout);
4625            }
4626    
4627            /**
4628             * Updates the user's modified date.
4629             *
4630             * @param  userId the primary key of the user
4631             * @param  modifiedDate the new modified date
4632             * @return the user
4633             */
4634            @Override
4635            public User updateModifiedDate(long userId, Date modifiedDate)
4636                    throws PortalException {
4637    
4638                    User user = userPersistence.findByPrimaryKey(userId);
4639    
4640                    userPersistence.update(user);
4641    
4642                    return user;
4643            }
4644    
4645            /**
4646             * Updates the user's OpenID.
4647             *
4648             * @param  userId the primary key of the user
4649             * @param  openId the new OpenID
4650             * @return the user
4651             */
4652            @Override
4653            public User updateOpenId(long userId, String openId)
4654                    throws PortalException {
4655    
4656                    openId = openId.trim();
4657    
4658                    User user = userPersistence.findByPrimaryKey(userId);
4659    
4660                    user.setOpenId(openId);
4661    
4662                    userPersistence.update(user);
4663    
4664                    return user;
4665            }
4666    
4667            /**
4668             * Sets the organizations that the user is in, removing and adding
4669             * organizations as necessary.
4670             *
4671             * @param userId the primary key of the user
4672             * @param newOrganizationIds the primary keys of the organizations
4673             * @param serviceContext the service context to be applied. Must set whether
4674             *        user indexing is enabled.
4675             */
4676            @Override
4677            public void updateOrganizations(
4678                            long userId, long[] newOrganizationIds,
4679                            ServiceContext serviceContext)
4680                    throws PortalException {
4681    
4682                    updateOrganizations(
4683                            userId, newOrganizationIds, serviceContext.isIndexingEnabled());
4684            }
4685    
4686            /**
4687             * Updates the user's password without tracking or validation of the change.
4688             *
4689             * @param  userId the primary key of the user
4690             * @param  password1 the user's new password
4691             * @param  password2 the user's new password confirmation
4692             * @param  passwordReset whether the user should be asked to reset their
4693             *         password the next time they log in
4694             * @return the user
4695             */
4696            @Override
4697            public User updatePassword(
4698                            long userId, String password1, String password2,
4699                            boolean passwordReset)
4700                    throws PortalException {
4701    
4702                    return updatePassword(
4703                            userId, password1, password2, passwordReset, false);
4704            }
4705    
4706            /**
4707             * Updates the user's password, optionally with tracking and validation of
4708             * the change.
4709             *
4710             * @param  userId the primary key of the user
4711             * @param  password1 the user's new password
4712             * @param  password2 the user's new password confirmation
4713             * @param  passwordReset whether the user should be asked to reset their
4714             *         password the next time they login
4715             * @param  silentUpdate whether the password should be updated without being
4716             *         tracked, or validated. Primarily used for password imports.
4717             * @return the user
4718             */
4719            @Override
4720            public User updatePassword(
4721                            long userId, String password1, String password2,
4722                            boolean passwordReset, boolean silentUpdate)
4723                    throws PortalException {
4724    
4725                    User user = userPersistence.findByPrimaryKey(userId);
4726    
4727                    if (!silentUpdate) {
4728                            validatePassword(user.getCompanyId(), userId, password1, password2);
4729                    }
4730    
4731                    String oldEncPwd = user.getPassword();
4732    
4733                    if (!user.isPasswordEncrypted()) {
4734                            oldEncPwd = PasswordEncryptorUtil.encrypt(user.getPassword());
4735                    }
4736    
4737                    String newEncPwd = PasswordEncryptorUtil.encrypt(password1);
4738    
4739                    if (user.hasCompanyMx()) {
4740                            mailService.updatePassword(user.getCompanyId(), userId, password1);
4741                    }
4742    
4743                    user.setPassword(newEncPwd);
4744                    user.setPasswordUnencrypted(password1);
4745                    user.setPasswordEncrypted(true);
4746                    user.setPasswordReset(passwordReset);
4747    
4748                    if (!silentUpdate || (user.getPasswordModifiedDate() == null)) {
4749                            user.setPasswordModifiedDate(new Date());
4750                    }
4751    
4752                    user.setDigest(StringPool.BLANK);
4753                    user.setGraceLoginCount(0);
4754    
4755                    if (!silentUpdate) {
4756                            user.setPasswordModified(true);
4757                    }
4758    
4759                    try {
4760                            userPersistence.update(user);
4761                    }
4762                    catch (ModelListenerException mle) {
4763                            String msg = GetterUtil.getString(mle.getCause().getMessage());
4764    
4765                            if (LDAPSettingsUtil.isPasswordPolicyEnabled(user.getCompanyId())) {
4766                                    String errorPasswordHistory =
4767                                            LDAPSettingsUtil.getErrorPasswordHistory(
4768                                                    user.getCompanyId());
4769    
4770                                    if (msg.contains(errorPasswordHistory)) {
4771                                            throw new UserPasswordException.MustNotBeRecentlyUsed(
4772                                                    userId);
4773                                    }
4774                            }
4775    
4776                            throw new UserPasswordException.MustComplyWithModelListeners(
4777                                    userId, mle);
4778                    }
4779    
4780                    if (!silentUpdate) {
4781                            user.setPasswordModified(false);
4782    
4783                            passwordTrackerLocalService.trackPassword(userId, oldEncPwd);
4784                    }
4785    
4786                    if (!silentUpdate && (PrincipalThreadLocal.getUserId() != userId)) {
4787                            sendPasswordNotification(
4788                                    user, user.getCompanyId(), password1, null, null, null, null,
4789                                    null, ServiceContextThreadLocal.getServiceContext());
4790                    }
4791    
4792                    return user;
4793            }
4794    
4795            /**
4796             * Updates the user's password with manually input information. This method
4797             * should only be used when performing maintenance.
4798             *
4799             * @param  userId the primary key of the user
4800             * @param  password the user's new password
4801             * @param  passwordEncrypted the user's new encrypted password
4802             * @param  passwordReset whether the user should be asked to reset their
4803             *         password the next time they login
4804             * @param  passwordModifiedDate the new password modified date
4805             * @return the user
4806             */
4807            @Override
4808            public User updatePasswordManually(
4809                            long userId, String password, boolean passwordEncrypted,
4810                            boolean passwordReset, Date passwordModifiedDate)
4811                    throws PortalException {
4812    
4813                    // This method should only be used to manually massage data
4814    
4815                    User user = userPersistence.findByPrimaryKey(userId);
4816    
4817                    user.setPassword(password);
4818                    user.setPasswordEncrypted(passwordEncrypted);
4819                    user.setPasswordReset(passwordReset);
4820                    user.setPasswordModifiedDate(passwordModifiedDate);
4821                    user.setDigest(StringPool.BLANK);
4822    
4823                    userPersistence.update(user);
4824    
4825                    return user;
4826            }
4827    
4828            /**
4829             * Updates whether the user should be asked to reset their password the next
4830             * time they login.
4831             *
4832             * @param  userId the primary key of the user
4833             * @param  passwordReset whether the user should be asked to reset their
4834             *         password the next time they login
4835             * @return the user
4836             */
4837            @Override
4838            public User updatePasswordReset(long userId, boolean passwordReset)
4839                    throws PortalException {
4840    
4841                    User user = userPersistence.findByPrimaryKey(userId);
4842    
4843                    user.setPasswordReset(passwordReset);
4844    
4845                    userPersistence.update(user);
4846    
4847                    return user;
4848            }
4849    
4850            /**
4851             * Updates the user's portrait image.
4852             *
4853             * @param  userId the primary key of the user
4854             * @param  bytes the new portrait image data
4855             * @return the user
4856             */
4857            @Override
4858            public User updatePortrait(long userId, byte[] bytes)
4859                    throws PortalException {
4860    
4861                    User user = userPersistence.findByPrimaryKey(userId);
4862    
4863                    PortalUtil.updateImageId(
4864                            user, true, bytes, "portraitId",
4865                            PrefsPropsUtil.getLong(PropsKeys.USERS_IMAGE_MAX_SIZE),
4866                            PropsValues.USERS_IMAGE_MAX_HEIGHT,
4867                            PropsValues.USERS_IMAGE_MAX_WIDTH);
4868    
4869                    return userPersistence.update(user);
4870            }
4871    
4872            /**
4873             * Updates the user's password reset question and answer.
4874             *
4875             * @param  userId the primary key of the user
4876             * @param  question the user's new password reset question
4877             * @param  answer the user's new password reset answer
4878             * @return the user
4879             */
4880            @Override
4881            public User updateReminderQuery(long userId, String question, String answer)
4882                    throws PortalException {
4883    
4884                    validateReminderQuery(question, answer);
4885    
4886                    User user = userPersistence.findByPrimaryKey(userId);
4887    
4888                    user.setReminderQueryQuestion(question);
4889                    user.setReminderQueryAnswer(answer);
4890    
4891                    userPersistence.update(user);
4892    
4893                    return user;
4894            }
4895    
4896            /**
4897             * Updates the user's screen name.
4898             *
4899             * @param  userId the primary key of the user
4900             * @param  screenName the user's new screen name
4901             * @return the user
4902             */
4903            @Override
4904            public User updateScreenName(long userId, String screenName)
4905                    throws PortalException {
4906    
4907                    // User
4908    
4909                    User user = userPersistence.findByPrimaryKey(userId);
4910    
4911                    screenName = getLogin(screenName);
4912    
4913                    validateScreenName(user.getCompanyId(), userId, screenName);
4914    
4915                    if (!StringUtil.equalsIgnoreCase(user.getScreenName(), screenName)) {
4916                            user.setDigest(StringPool.BLANK);
4917                    }
4918    
4919                    user.setScreenName(screenName);
4920    
4921                    userPersistence.update(user);
4922    
4923                    // Group
4924    
4925                    Group group = groupLocalService.getUserGroup(
4926                            user.getCompanyId(), userId);
4927    
4928                    group.setFriendlyURL(StringPool.SLASH + screenName);
4929    
4930                    groupPersistence.update(group);
4931    
4932                    return user;
4933            }
4934    
4935            /**
4936             * Updates the user's workflow status.
4937             *
4938             * @param      userId the primary key of the user
4939             * @param      status the user's new workflow status
4940             * @return     the user
4941             * @deprecated As of 7.0.0, replaced by {@link #updateStatus(long, int,
4942             *             ServiceContext)}
4943             */
4944            @Deprecated
4945            @Override
4946            public User updateStatus(long userId, int status) throws PortalException {
4947                    return updateStatus(userId, status, new ServiceContext());
4948            }
4949    
4950            /**
4951             * Updates the user's workflow status.
4952             *
4953             * @param  userId the primary key of the user
4954             * @param  status the user's new workflow status
4955             * @param  serviceContext the service context to be applied. You can specify
4956             *         an unencrypted custom password (used by an LDAP listener) for the
4957             *         user via attribute <code>passwordUnencrypted</code>.
4958             * @return the user
4959             */
4960            @Override
4961            public User updateStatus(
4962                            long userId, int status, ServiceContext serviceContext)
4963                    throws PortalException {
4964    
4965                    User user = userPersistence.findByPrimaryKey(userId);
4966    
4967                    if ((status == WorkflowConstants.STATUS_APPROVED) &&
4968                            (user.getStatus() != WorkflowConstants.STATUS_APPROVED)) {
4969    
4970                            validateCompanyMaxUsers(user.getCompanyId());
4971                    }
4972    
4973                    String passwordUnencrypted = (String)serviceContext.getAttribute(
4974                            "passwordUnencrypted");
4975    
4976                    if (Validator.isNotNull(passwordUnencrypted)) {
4977                            user.setPasswordUnencrypted(passwordUnencrypted);
4978                    }
4979    
4980                    user.setStatus(status);
4981    
4982                    userPersistence.update(user);
4983    
4984                    reindex(user);
4985    
4986                    Group group = user.getGroup();
4987    
4988                    if (status == WorkflowConstants.STATUS_INACTIVE) {
4989                            group.setActive(false);
4990                    }
4991                    else {
4992                            group.setActive(true);
4993                    }
4994    
4995                    groupLocalService.updateGroup(group);
4996    
4997                    return user;
4998            }
4999    
5000            /**
5001             * Updates the user.
5002             *
5003             * @param  userId the primary key of the user
5004             * @param  oldPassword the user's old password
5005             * @param  newPassword1 the user's new password (optionally
5006             *         <code>null</code>)
5007             * @param  newPassword2 the user's new password confirmation (optionally
5008             *         <code>null</code>)
5009             * @param  passwordReset whether the user should be asked to reset their
5010             *         password the next time they login
5011             * @param  reminderQueryQuestion the user's new password reset question
5012             * @param  reminderQueryAnswer the user's new password reset answer
5013             * @param  screenName the user's new screen name
5014             * @param  emailAddress the user's new email address
5015             * @param  facebookId the user's new Facebook ID
5016             * @param  openId the user's new OpenID
5017             * @param  portrait whether to update the user's portrait image
5018             * @param  portraitBytes the new portrait image data
5019             * @param  languageId the user's new language ID
5020             * @param  timeZoneId the user's new time zone ID
5021             * @param  greeting the user's new greeting
5022             * @param  comments the user's new comments
5023             * @param  firstName the user's new first name
5024             * @param  middleName the user's new middle name
5025             * @param  lastName the user's new last name
5026             * @param  prefixId the user's new name prefix ID
5027             * @param  suffixId the user's new name suffix ID
5028             * @param  male whether user is male
5029             * @param  birthdayMonth the user's new birthday month (0-based, meaning 0
5030             *         for January)
5031             * @param  birthdayDay the user's new birthday day
5032             * @param  birthdayYear the user's birthday year
5033             * @param  smsSn the user's new SMS screen name
5034             * @param  facebookSn the user's new Facebook screen name
5035             * @param  jabberSn the user's new Jabber screen name
5036             * @param  skypeSn the user's new Skype screen name
5037             * @param  twitterSn the user's new Twitter screen name
5038             * @param  jobTitle the user's new job title
5039             * @param  groupIds the primary keys of the user's groups
5040             * @param  organizationIds the primary keys of the user's organizations
5041             * @param  roleIds the primary keys of the user's roles
5042             * @param  userGroupRoles the user user's group roles
5043             * @param  userGroupIds the primary keys of the user's user groups
5044             * @param  serviceContext the service context to be applied (optionally
5045             *         <code>null</code>). Can set the UUID (with the <code>uuid</code>
5046             *         attribute), asset category IDs, asset tag names, and expando
5047             *         bridge attributes for the user.
5048             * @return the user
5049             */
5050            @Override
5051            @SuppressWarnings("deprecation")
5052            public User updateUser(
5053                            long userId, String oldPassword, String newPassword1,
5054                            String newPassword2, boolean passwordReset,
5055                            String reminderQueryQuestion, String reminderQueryAnswer,
5056                            String screenName, String emailAddress, long facebookId,
5057                            String openId, boolean portrait, byte[] portraitBytes,
5058                            String languageId, String timeZoneId, String greeting,
5059                            String comments, String firstName, String middleName,
5060                            String lastName, long prefixId, long suffixId, boolean male,
5061                            int birthdayMonth, int birthdayDay, int birthdayYear, String smsSn,
5062                            String facebookSn, String jabberSn, String skypeSn,
5063                            String twitterSn, String jobTitle, long[] groupIds,
5064                            long[] organizationIds, long[] roleIds,
5065                            List<UserGroupRole> userGroupRoles, long[] userGroupIds,
5066                            ServiceContext serviceContext)
5067                    throws PortalException {
5068    
5069                    // User
5070    
5071                    User user = userPersistence.findByPrimaryKey(userId);
5072                    Company company = companyPersistence.findByPrimaryKey(
5073                            user.getCompanyId());
5074                    String password = oldPassword;
5075                    screenName = getLogin(screenName);
5076                    emailAddress = StringUtil.toLowerCase(emailAddress.trim());
5077                    openId = openId.trim();
5078                    String oldFullName = user.getFullName();
5079                    facebookSn = StringUtil.toLowerCase(facebookSn.trim());
5080                    jabberSn = StringUtil.toLowerCase(jabberSn.trim());
5081                    skypeSn = StringUtil.toLowerCase(skypeSn.trim());
5082                    twitterSn = StringUtil.toLowerCase(twitterSn.trim());
5083    
5084                    EmailAddressGenerator emailAddressGenerator =
5085                            EmailAddressGeneratorFactory.getInstance();
5086    
5087                    if (emailAddressGenerator.isGenerated(emailAddress)) {
5088                            emailAddress = StringPool.BLANK;
5089                    }
5090    
5091                    if (!PropsValues.USERS_EMAIL_ADDRESS_REQUIRED &&
5092                            Validator.isNull(emailAddress)) {
5093    
5094                            emailAddress = emailAddressGenerator.generate(
5095                                    user.getCompanyId(), userId);
5096                    }
5097    
5098                    Locale locale = LocaleUtil.fromLanguageId(languageId);
5099    
5100                    validate(
5101                            userId, screenName, emailAddress, openId, firstName, middleName,
5102                            lastName, smsSn, locale);
5103    
5104                    if (Validator.isNotNull(newPassword1) ||
5105                            Validator.isNotNull(newPassword2)) {
5106    
5107                            user = updatePassword(
5108                                    userId, newPassword1, newPassword2, passwordReset);
5109    
5110                            password = newPassword1;
5111    
5112                            user.setDigest(StringPool.BLANK);
5113                    }
5114    
5115                    if (user.getContactId() <= 0) {
5116                            user.setContactId(counterLocalService.increment());
5117                    }
5118    
5119                    user.setPasswordReset(passwordReset);
5120    
5121                    if (Validator.isNotNull(reminderQueryQuestion) &&
5122                            Validator.isNotNull(reminderQueryAnswer)) {
5123    
5124                            user.setReminderQueryQuestion(reminderQueryQuestion);
5125                            user.setReminderQueryAnswer(reminderQueryAnswer);
5126                    }
5127    
5128                    if (!StringUtil.equalsIgnoreCase(user.getScreenName(), screenName)) {
5129                            user.setScreenName(screenName);
5130    
5131                            user.setDigest(StringPool.BLANK);
5132                    }
5133    
5134                    boolean sendEmailAddressVerification = false;
5135    
5136                    if (company.isStrangersVerify() &&
5137                            !StringUtil.equalsIgnoreCase(
5138                                    emailAddress, user.getEmailAddress())) {
5139    
5140                            sendEmailAddressVerification = true;
5141                    }
5142                    else {
5143                            setEmailAddress(
5144                                    user, password, firstName, middleName, lastName, emailAddress);
5145                    }
5146    
5147                    if (serviceContext != null) {
5148                            String uuid = serviceContext.getUuid();
5149    
5150                            if (Validator.isNotNull(uuid)) {
5151                                    user.setUuid(uuid);
5152                            }
5153                    }
5154    
5155                    user.setFacebookId(facebookId);
5156    
5157                    Long ldapServerId = null;
5158    
5159                    if (serviceContext != null) {
5160                            ldapServerId = (Long)serviceContext.getAttribute("ldapServerId");
5161                    }
5162    
5163                    if (ldapServerId != null) {
5164                            user.setLdapServerId(ldapServerId);
5165                    }
5166    
5167                    user.setOpenId(openId);
5168    
5169                    PortalUtil.updateImageId(
5170                            user, portrait, portraitBytes, "portraitId",
5171                            PrefsPropsUtil.getLong(PropsKeys.USERS_IMAGE_MAX_SIZE),
5172                            PropsValues.USERS_IMAGE_MAX_HEIGHT,
5173                            PropsValues.USERS_IMAGE_MAX_WIDTH);
5174    
5175                    user.setLanguageId(languageId);
5176                    user.setTimeZoneId(timeZoneId);
5177                    user.setGreeting(greeting);
5178                    user.setComments(comments);
5179                    user.setFirstName(firstName);
5180                    user.setMiddleName(middleName);
5181                    user.setLastName(lastName);
5182                    user.setJobTitle(jobTitle);
5183                    user.setExpandoBridgeAttributes(serviceContext);
5184    
5185                    userPersistence.update(user, serviceContext);
5186    
5187                    // Contact
5188    
5189                    Date birthday = getBirthday(birthdayMonth, birthdayDay, birthdayYear);
5190    
5191                    long contactId = user.getContactId();
5192    
5193                    Contact contact = contactPersistence.fetchByPrimaryKey(contactId);
5194    
5195                    if (contact == null) {
5196                            contact = contactPersistence.create(contactId);
5197    
5198                            contact.setCompanyId(user.getCompanyId());
5199                            contact.setUserName(StringPool.BLANK);
5200                            contact.setClassName(User.class.getName());
5201                            contact.setClassPK(user.getUserId());
5202                            contact.setAccountId(company.getAccountId());
5203                            contact.setParentContactId(
5204                                    ContactConstants.DEFAULT_PARENT_CONTACT_ID);
5205                    }
5206    
5207                    contact.setEmailAddress(user.getEmailAddress());
5208                    contact.setFirstName(firstName);
5209                    contact.setMiddleName(middleName);
5210                    contact.setLastName(lastName);
5211                    contact.setPrefixId(prefixId);
5212                    contact.setSuffixId(suffixId);
5213                    contact.setMale(male);
5214                    contact.setBirthday(birthday);
5215                    contact.setSmsSn(smsSn);
5216                    contact.setFacebookSn(facebookSn);
5217                    contact.setJabberSn(jabberSn);
5218                    contact.setSkypeSn(skypeSn);
5219                    contact.setTwitterSn(twitterSn);
5220                    contact.setJobTitle(jobTitle);
5221    
5222                    contactPersistence.update(contact, serviceContext);
5223    
5224                    // Group
5225    
5226                    Group group = groupLocalService.getUserGroup(
5227                            user.getCompanyId(), userId);
5228    
5229                    group.setFriendlyURL(StringPool.SLASH + screenName);
5230    
5231                    groupPersistence.update(group);
5232    
5233                    // Groups and organizations
5234    
5235                    // See LPS-33205. Cache the user's list of user group roles because
5236                    // adding or removing groups may add or remove user group roles
5237                    // depending on the site default user associations.
5238    
5239                    List<UserGroupRole> previousUserGroupRoles =
5240                            userGroupRolePersistence.findByUserId(userId);
5241    
5242                    updateGroups(userId, groupIds, serviceContext, false);
5243                    updateOrganizations(userId, organizationIds, false);
5244    
5245                    // Roles
5246    
5247                    if (roleIds != null) {
5248                            roleIds = UsersAdminUtil.addRequiredRoles(user, roleIds);
5249    
5250                            userPersistence.setRoles(userId, roleIds);
5251                    }
5252    
5253                    // User group roles
5254    
5255                    updateUserGroupRoles(
5256                            user, groupIds, organizationIds, userGroupRoles,
5257                            previousUserGroupRoles);
5258    
5259                    // User groups
5260    
5261                    if (userGroupIds != null) {
5262                            if (PropsValues.USER_GROUPS_COPY_LAYOUTS_TO_USER_PERSONAL_SITE) {
5263                                    userGroupLocalService.copyUserGroupLayouts(
5264                                            userGroupIds, userId);
5265                            }
5266    
5267                            userPersistence.setUserGroups(userId, userGroupIds);
5268                    }
5269    
5270                    // Announcements
5271    
5272                    announcementsDeliveryLocalService.getUserDeliveries(user.getUserId());
5273    
5274                    // Asset
5275    
5276                    if (serviceContext != null) {
5277                            updateAsset(
5278                                    userId, user, serviceContext.getAssetCategoryIds(),
5279                                    serviceContext.getAssetTagNames());
5280                    }
5281    
5282                    // Message boards
5283    
5284                    if (GetterUtil.getBoolean(
5285                                    PropsKeys.USERS_UPDATE_USER_NAME + MBMessage.class.getName()) &&
5286                            !oldFullName.equals(user.getFullName())) {
5287    
5288                            mbMessageLocalService.updateUserName(userId, user.getFullName());
5289                    }
5290    
5291                    // Indexer
5292    
5293                    if ((serviceContext == null) || serviceContext.isIndexingEnabled()) {
5294                            Indexer<User> indexer = IndexerRegistryUtil.nullSafeGetIndexer(
5295                                    User.class);
5296    
5297                            indexer.reindex(user);
5298                    }
5299    
5300                    // Email address verification
5301    
5302                    if ((serviceContext != null) && sendEmailAddressVerification) {
5303                            sendEmailAddressVerification(user, emailAddress, serviceContext);
5304                    }
5305    
5306                    // Permission cache
5307    
5308                    PermissionCacheUtil.clearCache(userId);
5309    
5310                    return user;
5311            }
5312    
5313            /**
5314             * Updates the user.
5315             *
5316             * @param      userId the primary key of the user
5317             * @param      oldPassword the user's old password
5318             * @param      newPassword1 the user's new password (optionally
5319             *             <code>null</code>)
5320             * @param      newPassword2 the user's new password confirmation (optionally
5321             *             <code>null</code>)
5322             * @param      passwordReset whether the user should be asked to reset their
5323             *             password the next time they login
5324             * @param      reminderQueryQuestion the user's new password reset question
5325             * @param      reminderQueryAnswer the user's new password reset answer
5326             * @param      screenName the user's new screen name
5327             * @param      emailAddress the user's new email address
5328             * @param      facebookId the user's new Facebook ID
5329             * @param      openId the user's new OpenID
5330             * @param      languageId the user's new language ID
5331             * @param      timeZoneId the user's new time zone ID
5332             * @param      greeting the user's new greeting
5333             * @param      comments the user's new comments
5334             * @param      firstName the user's new first name
5335             * @param      middleName the user's new middle name
5336             * @param      lastName the user's new last name
5337             * @param      prefixId the user's new name prefix ID
5338             * @param      suffixId the user's new name suffix ID
5339             * @param      male whether user is male
5340             * @param      birthdayMonth the user's new birthday month (0-based, meaning
5341             *             0 for January)
5342             * @param      birthdayDay the user's new birthday day
5343             * @param      birthdayYear the user's birthday year
5344             * @param      smsSn the user's new SMS screen name
5345             * @param      facebookSn the user's new Facebook screen name
5346             * @param      jabberSn the user's new Jabber screen name
5347             * @param      skypeSn the user's new Skype screen name
5348             * @param      twitterSn the user's new Twitter screen name
5349             * @param      jobTitle the user's new job title
5350             * @param      groupIds the primary keys of the user's groups
5351             * @param      organizationIds the primary keys of the user's organizations
5352             * @param      roleIds the primary keys of the user's roles
5353             * @param      userGroupRoles the user user's group roles
5354             * @param      userGroupIds the primary keys of the user's user groups
5355             * @param      serviceContext the service context to be applied (optionally
5356             *             <code>null</code>). Can set the UUID (with the
5357             *             <code>uuid</code> attribute), asset category IDs, asset tag
5358             *             names, and expando bridge attributes for the user.
5359             * @return     the user
5360             * @deprecated As of 7.0.0, replaced by {@link #updateUser(long, String,
5361             *             String, String, boolean, String, String, String, String,
5362             *             long, String, boolean, byte[], String, String, String,
5363             *             String, String, String, String, int, int, boolean, int, int,
5364             *             int, String, String, String, String, String, String, String,
5365             *             String, String, String, String, long[], long[], long[], List,
5366             *             long[], ServiceContext)}
5367             */
5368            @Deprecated
5369            @Override
5370            public User updateUser(
5371                            long userId, String oldPassword, String newPassword1,
5372                            String newPassword2, boolean passwordReset,
5373                            String reminderQueryQuestion, String reminderQueryAnswer,
5374                            String screenName, String emailAddress, long facebookId,
5375                            String openId, String languageId, String timeZoneId,
5376                            String greeting, String comments, String firstName,
5377                            String middleName, String lastName, long prefixId, long suffixId,
5378                            boolean male, int birthdayMonth, int birthdayDay, int birthdayYear,
5379                            String smsSn, String facebookSn, String jabberSn, String skypeSn,
5380                            String twitterSn, String jobTitle, long[] groupIds,
5381                            long[] organizationIds, long[] roleIds,
5382                            List<UserGroupRole> userGroupRoles, long[] userGroupIds,
5383                            ServiceContext serviceContext)
5384                    throws PortalException {
5385    
5386                    return updateUser(
5387                            userId, oldPassword, newPassword1, newPassword2, passwordReset,
5388                            reminderQueryQuestion, reminderQueryAnswer, screenName,
5389                            emailAddress, facebookId, openId, true, null, languageId,
5390                            timeZoneId, greeting, comments, firstName, middleName, lastName,
5391                            prefixId, suffixId, male, birthdayMonth, birthdayDay, birthdayYear,
5392                            smsSn, facebookSn, jabberSn, skypeSn, twitterSn, jobTitle, groupIds,
5393                            organizationIds, roleIds, userGroupRoles, userGroupIds,
5394                            serviceContext);
5395            }
5396    
5397            /**
5398             * Verifies the email address of the ticket.
5399             *
5400             * @param ticketKey the ticket key
5401             */
5402            @Override
5403            public void verifyEmailAddress(String ticketKey) throws PortalException {
5404                    Ticket ticket = ticketLocalService.getTicket(ticketKey);
5405    
5406                    if (ticket.isExpired() ||
5407                            (ticket.getType() != TicketConstants.TYPE_EMAIL_ADDRESS)) {
5408    
5409                            throw new NoSuchTicketException("{ticketKey=" + ticketKey + "}");
5410                    }
5411    
5412                    User user = userPersistence.findByPrimaryKey(ticket.getClassPK());
5413    
5414                    String emailAddress = ticket.getExtraInfo();
5415    
5416                    emailAddress = StringUtil.toLowerCase(emailAddress).trim();
5417    
5418                    if (!emailAddress.equals(user.getEmailAddress())) {
5419                            if (userPersistence.fetchByC_EA(
5420                                            user.getCompanyId(), emailAddress) != null) {
5421    
5422                                    throw new UserEmailAddressException.MustNotBeDuplicate(
5423                                            user.getUserId(), emailAddress);
5424                            }
5425    
5426                            setEmailAddress(
5427                                    user, StringPool.BLANK, user.getFirstName(),
5428                                    user.getMiddleName(), user.getLastName(), emailAddress);
5429    
5430                            Contact contact = user.getContact();
5431    
5432                            contact.setEmailAddress(user.getEmailAddress());
5433    
5434                            contactPersistence.update(contact);
5435                    }
5436    
5437                    user.setEmailAddressVerified(true);
5438    
5439                    userPersistence.update(user);
5440    
5441                    ticketLocalService.deleteTicket(ticket);
5442            }
5443    
5444            protected void addDefaultRolesAndTeams(long groupId, long[] userIds)
5445                    throws PortalException {
5446    
5447                    List<Role> defaultSiteRoles = new ArrayList<>();
5448    
5449                    Group group = groupLocalService.getGroup(groupId);
5450    
5451                    UnicodeProperties typeSettingsProperties =
5452                            group.getTypeSettingsProperties();
5453    
5454                    long[] defaultSiteRoleIds = StringUtil.split(
5455                            typeSettingsProperties.getProperty("defaultSiteRoleIds"), 0L);
5456    
5457                    for (long defaultSiteRoleId : defaultSiteRoleIds) {
5458                            Role defaultSiteRole = rolePersistence.fetchByPrimaryKey(
5459                                    defaultSiteRoleId);
5460    
5461                            if (defaultSiteRole == null) {
5462                                    if (_log.isWarnEnabled()) {
5463                                            _log.warn("Unable to find role " + defaultSiteRoleId);
5464                                    }
5465    
5466                                    continue;
5467                            }
5468    
5469                            defaultSiteRoles.add(defaultSiteRole);
5470                    }
5471    
5472                    List<Team> defaultTeams = new ArrayList<>();
5473    
5474                    long[] defaultTeamIds = StringUtil.split(
5475                            typeSettingsProperties.getProperty("defaultTeamIds"), 0L);
5476    
5477                    for (long defaultTeamId : defaultTeamIds) {
5478                            Team defaultTeam = teamPersistence.findByPrimaryKey(defaultTeamId);
5479    
5480                            if (defaultTeam == null) {
5481                                    if (_log.isWarnEnabled()) {
5482                                            _log.warn("Unable to find team " + defaultTeamId);
5483                                    }
5484    
5485                                    continue;
5486                            }
5487    
5488                            defaultTeams.add(defaultTeam);
5489                    }
5490    
5491                    for (long userId : userIds) {
5492                            Set<Long> userRoleIdsSet = new HashSet<>();
5493    
5494                            for (Role role : defaultSiteRoles) {
5495                                    if (!userPersistence.containsRole(userId, role.getRoleId())) {
5496                                            userRoleIdsSet.add(role.getRoleId());
5497                                    }
5498                            }
5499    
5500                            long[] userRoleIds = ArrayUtil.toArray(
5501                                    userRoleIdsSet.toArray(new Long[userRoleIdsSet.size()]));
5502    
5503                            userGroupRoleLocalService.addUserGroupRoles(
5504                                    userId, groupId, userRoleIds);
5505    
5506                            Set<Long> userTeamIdsSet = new HashSet<>();
5507    
5508                            for (Team team : defaultTeams) {
5509                                    if (!userPersistence.containsTeam(userId, team.getTeamId())) {
5510                                            userTeamIdsSet.add(team.getTeamId());
5511                                    }
5512                            }
5513    
5514                            long[] userTeamIds = ArrayUtil.toArray(
5515                                    userTeamIdsSet.toArray(new Long[userTeamIdsSet.size()]));
5516    
5517                            userPersistence.addTeams(userId, userTeamIds);
5518                    }
5519            }
5520    
5521            /**
5522             * Attempts to authenticate the user by their login and password, while
5523             * using the AuthPipeline.
5524             *
5525             * <p>
5526             * Authentication type specifies what <code>login</code> contains.The valid
5527             * values are:
5528             * </p>
5529             *
5530             * <ul>
5531             * <li>
5532             * <code>CompanyConstants.AUTH_TYPE_EA</code> - <code>login</code> is the
5533             * user's email address
5534             * </li>
5535             * <li>
5536             * <code>CompanyConstants.AUTH_TYPE_SN</code> - <code>login</code> is the
5537             * user's screen name
5538             * </li>
5539             * <li>
5540             * <code>CompanyConstants.AUTH_TYPE_ID</code> - <code>login</code> is the
5541             * user's primary key
5542             * </li>
5543             * </ul>
5544             *
5545             * @param  companyId the primary key of the user's company
5546             * @param  login either the user's email address, screen name, or primary
5547             *         key depending on the value of <code>authType</code>
5548             * @param  password the user's password
5549             * @param  authType the type of authentication to perform
5550             * @param  headerMap the header map from the authentication request
5551             * @param  parameterMap the parameter map from the authentication request
5552             * @param  resultsMap the map of authentication results (may be nil). After
5553             *         a successful authentication the user's primary key will be placed
5554             *         under the key <code>userId</code>.
5555             * @return the authentication status. This can be {@link
5556             *         Authenticator#FAILURE} indicating that the user's credentials are
5557             *         invalid, {@link Authenticator#SUCCESS} indicating a successful
5558             *         login, or {@link Authenticator#DNE} indicating that a user with
5559             *         that login does not exist.
5560             * @see    AuthPipeline
5561             */
5562            protected int authenticate(
5563                            long companyId, String login, String password, String authType,
5564                            Map<String, String[]> headerMap, Map<String, String[]> parameterMap,
5565                            Map<String, Object> resultsMap)
5566                    throws PortalException {
5567    
5568                    if (PropsValues.AUTH_LOGIN_DISABLED) {
5569                            return Authenticator.FAILURE;
5570                    }
5571    
5572                    login = StringUtil.toLowerCase(login.trim());
5573    
5574                    long userId = GetterUtil.getLong(login);
5575    
5576                    // User input validation
5577    
5578                    if (authType.equals(CompanyConstants.AUTH_TYPE_EA)) {
5579                            if (Validator.isNull(login)) {
5580                                    throw new UserEmailAddressException.MustNotBeNull();
5581                            }
5582                    }
5583                    else if (authType.equals(CompanyConstants.AUTH_TYPE_SN)) {
5584                            if (Validator.isNull(login)) {
5585                                    throw new UserScreenNameException.MustNotBeNull();
5586                            }
5587                    }
5588                    else if (authType.equals(CompanyConstants.AUTH_TYPE_ID)) {
5589                            if (Validator.isNull(login)) {
5590                                    throw new UserIdException.MustNotBeNull();
5591                            }
5592                    }
5593    
5594                    if (Validator.isNull(password)) {
5595                            throw new UserPasswordException.MustNotBeNull(userId);
5596                    }
5597    
5598                    int authResult = Authenticator.FAILURE;
5599    
5600                    // Pre-authentication pipeline
5601    
5602                    if (authType.equals(CompanyConstants.AUTH_TYPE_EA)) {
5603                            authResult = AuthPipeline.authenticateByEmailAddress(
5604                                    PropsKeys.AUTH_PIPELINE_PRE, companyId, login, password,
5605                                    headerMap, parameterMap);
5606                    }
5607                    else if (authType.equals(CompanyConstants.AUTH_TYPE_SN)) {
5608                            authResult = AuthPipeline.authenticateByScreenName(
5609                                    PropsKeys.AUTH_PIPELINE_PRE, companyId, login, password,
5610                                    headerMap, parameterMap);
5611                    }
5612                    else if (authType.equals(CompanyConstants.AUTH_TYPE_ID)) {
5613                            authResult = AuthPipeline.authenticateByUserId(
5614                                    PropsKeys.AUTH_PIPELINE_PRE, companyId, userId, password,
5615                                    headerMap, parameterMap);
5616                    }
5617    
5618                    // Get user
5619    
5620                    User user = null;
5621    
5622                    if (authType.equals(CompanyConstants.AUTH_TYPE_EA)) {
5623                            user = fetchUserByEmailAddress(companyId, login);
5624                    }
5625                    else if (authType.equals(CompanyConstants.AUTH_TYPE_SN)) {
5626                            user = fetchUserByScreenName(companyId, login);
5627                    }
5628                    else if (authType.equals(CompanyConstants.AUTH_TYPE_ID)) {
5629                            user = userPersistence.fetchByPrimaryKey(GetterUtil.getLong(login));
5630                    }
5631    
5632                    if (user == null) {
5633                            return Authenticator.DNE;
5634                    }
5635    
5636                    if (!isUserAllowedToAuthenticate(user)) {
5637                            return Authenticator.FAILURE;
5638                    }
5639    
5640                    if (!user.isPasswordEncrypted()) {
5641                            user.setPassword(PasswordEncryptorUtil.encrypt(user.getPassword()));
5642                            user.setPasswordEncrypted(true);
5643    
5644                            userPersistence.update(user);
5645                    }
5646    
5647                    // Authenticate against the User_ table
5648    
5649                    boolean skipLiferayCheck = false;
5650    
5651                    if (authResult == Authenticator.SKIP_LIFERAY_CHECK) {
5652                            authResult = Authenticator.SUCCESS;
5653    
5654                            skipLiferayCheck = true;
5655                    }
5656                    else if ((authResult == Authenticator.SUCCESS) &&
5657                                     PropsValues.AUTH_PIPELINE_ENABLE_LIFERAY_CHECK) {
5658    
5659                            boolean authenticated = PwdAuthenticator.authenticate(
5660                                    login, password, user.getPassword());
5661    
5662                            if (authenticated) {
5663                                    authResult = Authenticator.SUCCESS;
5664                            }
5665                            else {
5666                                    authResult = Authenticator.FAILURE;
5667                            }
5668                    }
5669    
5670                    // Post-authentication pipeline
5671    
5672                    if (authResult == Authenticator.SUCCESS) {
5673                            if (authType.equals(CompanyConstants.AUTH_TYPE_EA)) {
5674                                    authResult = AuthPipeline.authenticateByEmailAddress(
5675                                            PropsKeys.AUTH_PIPELINE_POST, companyId, login, password,
5676                                            headerMap, parameterMap);
5677                            }
5678                            else if (authType.equals(CompanyConstants.AUTH_TYPE_SN)) {
5679                                    authResult = AuthPipeline.authenticateByScreenName(
5680                                            PropsKeys.AUTH_PIPELINE_POST, companyId, login, password,
5681                                            headerMap, parameterMap);
5682                            }
5683                            else if (authType.equals(CompanyConstants.AUTH_TYPE_ID)) {
5684                                    authResult = AuthPipeline.authenticateByUserId(
5685                                            PropsKeys.AUTH_PIPELINE_POST, companyId, userId, password,
5686                                            headerMap, parameterMap);
5687                            }
5688                    }
5689    
5690                    if (resultsMap != null) {
5691                            resultsMap.put("userId", user.getUserId());
5692                    }
5693    
5694                    if (authResult == Authenticator.SUCCESS) {
5695    
5696                            // Update digest
5697    
5698                            if (skipLiferayCheck ||
5699                                    !PropsValues.AUTH_PIPELINE_ENABLE_LIFERAY_CHECK ||
5700                                    Validator.isNull(user.getDigest())) {
5701    
5702                                    user = userPersistence.fetchByPrimaryKey(user.getUserId());
5703    
5704                                    String digest = user.getDigest(password);
5705    
5706                                    user.setDigest(digest);
5707    
5708                                    userPersistence.update(user);
5709                            }
5710                    }
5711    
5712                    // Execute code triggered by authentication failure
5713    
5714                    if (authResult == Authenticator.FAILURE) {
5715                            authResult = handleAuthenticationFailure(
5716                                    login, authType, user, headerMap, parameterMap);
5717                    }
5718                    else {
5719                            resetFailedLoginAttempts(user);
5720                    }
5721    
5722                    // PLACEHOLDER 02
5723    
5724                    return authResult;
5725            }
5726    
5727            protected SearchContext buildSearchContext(
5728                    long companyId, String firstName, String middleName, String lastName,
5729                    String fullName, String screenName, String emailAddress, String street,
5730                    String city, String zip, String region, String country, int status,
5731                    LinkedHashMap<String, Object> params, boolean andSearch, int start,
5732                    int end, Sort[] sorts) {
5733    
5734                    SearchContext searchContext = new SearchContext();
5735    
5736                    searchContext.setAndSearch(andSearch);
5737    
5738                    Map<String, Serializable> attributes = new HashMap<>();
5739    
5740                    attributes.put("city", city);
5741                    attributes.put("country", country);
5742                    attributes.put("emailAddress", emailAddress);
5743                    attributes.put("firstName", firstName);
5744                    attributes.put("fullName", fullName);
5745                    attributes.put("lastName", lastName);
5746                    attributes.put("middleName", middleName);
5747                    attributes.put("params", params);
5748                    attributes.put("region", region);
5749                    attributes.put("screenName", screenName);
5750                    attributes.put("street", street);
5751                    attributes.put("status", status);
5752                    attributes.put("zip", zip);
5753    
5754                    searchContext.setAttributes(attributes);
5755    
5756                    searchContext.setCompanyId(companyId);
5757                    searchContext.setEnd(end);
5758    
5759                    if (params != null) {
5760                            String keywords = (String)params.remove("keywords");
5761    
5762                            if (Validator.isNotNull(keywords)) {
5763                                    searchContext.setKeywords(keywords);
5764                            }
5765                    }
5766    
5767                    if (sorts != null) {
5768                            searchContext.setSorts(sorts);
5769                    }
5770    
5771                    searchContext.setStart(start);
5772    
5773                    QueryConfig queryConfig = searchContext.getQueryConfig();
5774    
5775                    queryConfig.setHighlightEnabled(false);
5776                    queryConfig.setScoreEnabled(false);
5777    
5778                    return searchContext;
5779            }
5780    
5781            protected Date getBirthday(
5782                            int birthdayMonth, int birthdayDay, int birthdayYear)
5783                    throws PortalException {
5784    
5785                    Date birthday = PortalUtil.getDate(
5786                            birthdayMonth, birthdayDay, birthdayYear,
5787                            ContactBirthdayException.class);
5788    
5789                    if (birthday.after(new Date())) {
5790                            throw new ContactBirthdayException();
5791                    }
5792    
5793                    return birthday;
5794            }
5795    
5796            protected String getLogin(String login) {
5797                    return StringUtil.lowerCase(StringUtil.trim(login));
5798            }
5799    
5800            protected Sort[] getSorts(OrderByComparator<User> obc) {
5801                    if (obc == null) {
5802                            return new Sort[0];
5803                    }
5804    
5805                    String[] orderByClauses = StringUtil.split(obc.getOrderBy());
5806                    String[] orderByFields = obc.getOrderByFields();
5807    
5808                    Sort[] sorts = new Sort[orderByFields.length];
5809    
5810                    for (int i = 0; i < orderByFields.length; i++) {
5811                            boolean reverse = orderByClauses[i].contains("DESC");
5812    
5813                            sorts[i] = new Sort(orderByFields[i], reverse);
5814                    }
5815    
5816                    return sorts;
5817            }
5818    
5819            protected int handleAuthenticationFailure(
5820                    String login, String authType, User user,
5821                    Map<String, String[]> headerMap, Map<String, String[]> parameterMap) {
5822    
5823                    if (user == null) {
5824                            return Authenticator.DNE;
5825                    }
5826    
5827                    try {
5828                            if (authType.equals(CompanyConstants.AUTH_TYPE_EA)) {
5829                                    AuthPipeline.onFailureByEmailAddress(
5830                                            PropsKeys.AUTH_FAILURE, user.getCompanyId(), login,
5831                                            headerMap, parameterMap);
5832                            }
5833                            else if (authType.equals(CompanyConstants.AUTH_TYPE_SN)) {
5834                                    AuthPipeline.onFailureByScreenName(
5835                                            PropsKeys.AUTH_FAILURE, user.getCompanyId(), login,
5836                                            headerMap, parameterMap);
5837                            }
5838                            else if (authType.equals(CompanyConstants.AUTH_TYPE_ID)) {
5839                                    AuthPipeline.onFailureByUserId(
5840                                            PropsKeys.AUTH_FAILURE, user.getCompanyId(),
5841                                            user.getUserId(), headerMap, parameterMap);
5842                            }
5843    
5844                            user = userPersistence.fetchByPrimaryKey(user.getUserId());
5845    
5846                            if (user == null) {
5847                                    return Authenticator.DNE;
5848                            }
5849    
5850                            // Let LDAP handle max failure event
5851    
5852                            if (!LDAPSettingsUtil.isPasswordPolicyEnabled(
5853                                            user.getCompanyId())) {
5854    
5855                                    PasswordPolicy passwordPolicy = user.getPasswordPolicy();
5856    
5857                                    user = userPersistence.fetchByPrimaryKey(user.getUserId());
5858    
5859                                    int failedLoginAttempts = user.getFailedLoginAttempts();
5860                                    int maxFailures = passwordPolicy.getMaxFailure();
5861    
5862                                    if ((failedLoginAttempts >= maxFailures) &&
5863                                            (maxFailures != 0)) {
5864    
5865                                            if (authType.equals(CompanyConstants.AUTH_TYPE_EA)) {
5866                                                    AuthPipeline.onMaxFailuresByEmailAddress(
5867                                                            PropsKeys.AUTH_MAX_FAILURES, user.getCompanyId(),
5868                                                            login, headerMap, parameterMap);
5869                                            }
5870                                            else if (authType.equals(CompanyConstants.AUTH_TYPE_SN)) {
5871                                                    AuthPipeline.onMaxFailuresByScreenName(
5872                                                            PropsKeys.AUTH_MAX_FAILURES, user.getCompanyId(),
5873                                                            login, headerMap, parameterMap);
5874                                            }
5875                                            else if (authType.equals(CompanyConstants.AUTH_TYPE_ID)) {
5876                                                    AuthPipeline.onMaxFailuresByUserId(
5877                                                            PropsKeys.AUTH_MAX_FAILURES, user.getCompanyId(),
5878                                                            user.getUserId(), headerMap, parameterMap);
5879                                            }
5880                                    }
5881                            }
5882                    }
5883                    catch (Exception e) {
5884                            _log.error(e, e);
5885                    }
5886    
5887                    return Authenticator.FAILURE;
5888            }
5889    
5890            protected boolean isUseCustomSQL(LinkedHashMap<String, Object> params) {
5891                    if (MapUtil.isEmpty(params)) {
5892                            return false;
5893                    }
5894    
5895                    for (String key : params.keySet()) {
5896                            if (!key.equals("inherit") && !key.equals("usersGroups") &&
5897                                    !key.equals("usersOrgs") && !key.equals("usersOrgsCount") &&
5898                                    !key.equals("usersRoles") && !key.equals("usersTeams") &&
5899                                    !key.equals("usersUserGroups")) {
5900    
5901                                    return true;
5902                            }
5903                    }
5904    
5905                    Boolean inherit = (Boolean)params.get("inherit");
5906    
5907                    if ((inherit != null) && inherit) {
5908                            return true;
5909                    }
5910    
5911                    return false;
5912            }
5913    
5914            protected boolean isUserAllowedToAuthenticate(User user)
5915                    throws PortalException {
5916    
5917                    if (user.isDefaultUser()) {
5918                            if (_log.isInfoEnabled()) {
5919                                    _log.info("Authentication is disabled for the default user");
5920                            }
5921    
5922                            return false;
5923                    }
5924                    else if (!user.isActive()) {
5925                            if (_log.isInfoEnabled()) {
5926                                    _log.info(
5927                                            "Authentication is disabled for inactive user " +
5928                                                    user.getUserId());
5929                            }
5930    
5931                            return false;
5932                    }
5933    
5934                    // Check password policy to see if the is account locked out or if the
5935                    // password is expired
5936    
5937                    checkLockout(user);
5938    
5939                    checkPasswordExpired(user);
5940    
5941                    return true;
5942            }
5943    
5944            protected void notifyUser(
5945                    User user, String password, ServiceContext serviceContext) {
5946    
5947                    if (!PrefsPropsUtil.getBoolean(
5948                                    user.getCompanyId(),
5949                                    PropsKeys.ADMIN_EMAIL_USER_ADDED_ENABLED)) {
5950    
5951                            return;
5952                    }
5953    
5954                    String fromName = PrefsPropsUtil.getString(
5955                            user.getCompanyId(), PropsKeys.ADMIN_EMAIL_FROM_NAME);
5956                    String fromAddress = PrefsPropsUtil.getString(
5957                            user.getCompanyId(), PropsKeys.ADMIN_EMAIL_FROM_ADDRESS);
5958    
5959                    String toName = user.getFullName();
5960                    String toAddress = user.getEmailAddress();
5961    
5962                    PortletPreferences companyPortletPreferences =
5963                            PrefsPropsUtil.getPreferences(user.getCompanyId(), true);
5964    
5965                    Map<Locale, String> localizedSubjectMap =
5966                            LocalizationUtil.getLocalizationMap(
5967                                    companyPortletPreferences, "adminEmailUserAddedSubject",
5968                                    PropsKeys.ADMIN_EMAIL_USER_ADDED_SUBJECT);
5969    
5970                    Map<Locale, String> localizedBodyMap = null;
5971    
5972                    if (Validator.isNotNull(password)) {
5973                            localizedBodyMap = LocalizationUtil.getLocalizationMap(
5974                                    companyPortletPreferences, "adminEmailUserAddedBody",
5975                                    PropsKeys.ADMIN_EMAIL_USER_ADDED_BODY);
5976                    }
5977                    else {
5978                            localizedBodyMap = LocalizationUtil.getLocalizationMap(
5979                                    companyPortletPreferences, "adminEmailUserAddedNoPasswordBody",
5980                                    PropsKeys.ADMIN_EMAIL_USER_ADDED_NO_PASSWORD_BODY);
5981                    }
5982    
5983                    SubscriptionSender subscriptionSender = new SubscriptionSender();
5984    
5985                    subscriptionSender.setCompanyId(user.getCompanyId());
5986                    subscriptionSender.setContextAttributes(
5987                            "[$USER_ID$]", user.getUserId(), "[$USER_PASSWORD$]", password,
5988                            "[$USER_SCREENNAME$]", user.getScreenName());
5989                    subscriptionSender.setFrom(fromAddress, fromName);
5990                    subscriptionSender.setHtmlFormat(true);
5991                    subscriptionSender.setLocalizedBodyMap(localizedBodyMap);
5992                    subscriptionSender.setLocalizedSubjectMap(localizedSubjectMap);
5993                    subscriptionSender.setMailId("user", user.getUserId());
5994                    subscriptionSender.setServiceContext(serviceContext);
5995    
5996                    subscriptionSender.addRuntimeSubscribers(toAddress, toName);
5997    
5998                    subscriptionSender.flushNotificationsAsync();
5999            }
6000    
6001            protected void reindex(long userId) throws SearchException {
6002                    Indexer<User> indexer = IndexerRegistryUtil.nullSafeGetIndexer(
6003                            User.class);
6004    
6005                    User user = userLocalService.fetchUser(userId);
6006    
6007                    indexer.reindex(user);
6008            }
6009    
6010            protected void reindex(long[] userIds) throws SearchException {
6011                    Indexer<User> indexer = IndexerRegistryUtil.nullSafeGetIndexer(
6012                            User.class);
6013    
6014                    List<User> users = new ArrayList<>(userIds.length);
6015    
6016                    for (Long userId : userIds) {
6017                            User user = userLocalService.fetchUser(userId);
6018    
6019                            users.add(user);
6020                    }
6021    
6022                    indexer.reindex(users);
6023            }
6024    
6025            protected void reindex(final User user) throws SearchException {
6026                    Indexer<User> indexer = IndexerRegistryUtil.nullSafeGetIndexer(
6027                            User.class);
6028    
6029                    indexer.reindex(user);
6030            }
6031    
6032            protected void resetFailedLoginAttempts(User user) {
6033                    resetFailedLoginAttempts(user, false);
6034            }
6035    
6036            protected void resetFailedLoginAttempts(User user, boolean forceUpdate) {
6037                    if (forceUpdate || (user.getFailedLoginAttempts() > 0)) {
6038                            user.setFailedLoginAttempts(0);
6039    
6040                            userPersistence.update(user);
6041                    }
6042            }
6043    
6044            protected BaseModelSearchResult<User> searchUsers(
6045                            SearchContext searchContext)
6046                    throws PortalException {
6047    
6048                    Indexer<User> indexer = IndexerRegistryUtil.nullSafeGetIndexer(
6049                            User.class);
6050    
6051                    for (int i = 0; i < 10; i++) {
6052                            Hits hits = indexer.search(searchContext);
6053    
6054                            List<User> users = UsersAdminUtil.getUsers(hits);
6055    
6056                            if (users != null) {
6057                                    return new BaseModelSearchResult<>(users, hits.getLength());
6058                            }
6059                    }
6060    
6061                    throw new SearchException(
6062                            "Unable to fix the search index after 10 attempts");
6063            }
6064    
6065            protected void sendPasswordNotification(
6066                    User user, long companyId, String newPassword, String passwordResetURL,
6067                    String fromName, String fromAddress, String subject, String body,
6068                    ServiceContext serviceContext) {
6069    
6070                    if (Validator.isNull(fromName)) {
6071                            fromName = PrefsPropsUtil.getString(
6072                                    companyId, PropsKeys.ADMIN_EMAIL_FROM_NAME);
6073                    }
6074    
6075                    if (Validator.isNull(fromAddress)) {
6076                            fromAddress = PrefsPropsUtil.getString(
6077                                    companyId, PropsKeys.ADMIN_EMAIL_FROM_ADDRESS);
6078                    }
6079    
6080                    String toName = user.getFullName();
6081                    String toAddress = user.getEmailAddress();
6082    
6083                    PortletPreferences companyPortletPreferences =
6084                            PrefsPropsUtil.getPreferences(companyId, true);
6085    
6086                    Map<Locale, String> localizedSubjectMap = null;
6087                    Map<Locale, String> localizedBodyMap = null;
6088    
6089                    String bodyProperty = null;
6090                    String prefix = null;
6091                    String subjectProperty = null;
6092    
6093                    if (Validator.isNotNull(passwordResetURL)) {
6094                            bodyProperty = PropsKeys.ADMIN_EMAIL_PASSWORD_RESET_BODY;
6095                            prefix = "adminEmailPasswordReset";
6096                            subjectProperty = PropsKeys.ADMIN_EMAIL_PASSWORD_RESET_SUBJECT;
6097                    }
6098                    else {
6099                            bodyProperty = PropsKeys.ADMIN_EMAIL_PASSWORD_SENT_BODY;
6100                            prefix = "adminEmailPasswordSent";
6101                            subjectProperty = PropsKeys.ADMIN_EMAIL_PASSWORD_SENT_SUBJECT;
6102                    }
6103    
6104                    if (Validator.isNull(body)) {
6105                            localizedBodyMap = LocalizationUtil.getLocalizationMap(
6106                                    companyPortletPreferences, prefix + "Body", bodyProperty);
6107                    }
6108    
6109                    if (Validator.isNull(subject)) {
6110                            localizedSubjectMap = LocalizationUtil.getLocalizationMap(
6111                                    companyPortletPreferences, prefix + "Subject", subjectProperty);
6112                    }
6113    
6114                    SubscriptionSender subscriptionSender = new SubscriptionSender();
6115    
6116                    subscriptionSender.setCompanyId(companyId);
6117                    subscriptionSender.setContextAttributes(
6118                            "[$PASSWORD_RESET_URL$]", passwordResetURL, "[$REMOTE_ADDRESS$]",
6119                            serviceContext.getRemoteAddr(), "[$REMOTE_HOST$]",
6120                            serviceContext.getRemoteHost(), "[$USER_ID$]", user.getUserId(),
6121                            "[$USER_PASSWORD$]", newPassword, "[$USER_SCREENNAME$]",
6122                            user.getScreenName());
6123                    subscriptionSender.setFrom(fromAddress, fromName);
6124                    subscriptionSender.setHtmlFormat(true);
6125                    subscriptionSender.setLocalizedBodyMap(localizedBodyMap);
6126                    subscriptionSender.setLocalizedSubjectMap(localizedSubjectMap);
6127                    subscriptionSender.setMailId("user", user.getUserId());
6128                    subscriptionSender.setServiceContext(serviceContext);
6129    
6130                    subscriptionSender.addRuntimeSubscribers(toAddress, toName);
6131    
6132                    subscriptionSender.flushNotificationsAsync();
6133            }
6134    
6135            protected void setEmailAddress(
6136                            User user, String password, String firstName, String middleName,
6137                            String lastName, String emailAddress)
6138                    throws PortalException {
6139    
6140                    if (StringUtil.equalsIgnoreCase(emailAddress, user.getEmailAddress())) {
6141                            return;
6142                    }
6143    
6144                    long userId = user.getUserId();
6145    
6146                    // test@test.com -> test@liferay.com
6147    
6148                    if (!user.hasCompanyMx() && user.hasCompanyMx(emailAddress) &&
6149                            Validator.isNotNull(password)) {
6150    
6151                            mailService.addUser(
6152                                    user.getCompanyId(), userId, password, firstName, middleName,
6153                                    lastName, emailAddress);
6154                    }
6155    
6156                    // test@liferay.com -> bob@liferay.com
6157    
6158                    else if (user.hasCompanyMx() && user.hasCompanyMx(emailAddress)) {
6159                            mailService.updateEmailAddress(
6160                                    user.getCompanyId(), userId, emailAddress);
6161                    }
6162    
6163                    // test@liferay.com -> test@test.com
6164    
6165                    else if (user.hasCompanyMx() && !user.hasCompanyMx(emailAddress)) {
6166                            mailService.deleteEmailAddress(user.getCompanyId(), userId);
6167                    }
6168    
6169                    user.setEmailAddress(emailAddress);
6170                    user.setDigest(StringPool.BLANK);
6171            }
6172    
6173            protected void updateGroups(
6174                            long userId, long[] newGroupIds, ServiceContext serviceContext,
6175                            boolean indexingEnabled)
6176                    throws PortalException {
6177    
6178                    if (newGroupIds == null) {
6179                            return;
6180                    }
6181    
6182                    long[] oldGroupIds = getGroupPrimaryKeys(userId);
6183    
6184                    for (long oldGroupId : oldGroupIds) {
6185                            if (!ArrayUtil.contains(newGroupIds, oldGroupId)) {
6186                                    unsetGroupUsers(
6187                                            oldGroupId, new long[] {userId}, serviceContext);
6188                            }
6189                    }
6190    
6191                    for (long newGroupId : newGroupIds) {
6192                            if (!ArrayUtil.contains(oldGroupIds, newGroupId)) {
6193                                    addGroupUsers(newGroupId, new long[] {userId});
6194                            }
6195                    }
6196    
6197                    if (indexingEnabled) {
6198                            reindex(userId);
6199                    }
6200    
6201                    PermissionCacheUtil.clearCache(userId);
6202            }
6203    
6204            protected void updateOrganizations(
6205                            long userId, long[] newOrganizationIds, boolean indexingEnabled)
6206                    throws PortalException {
6207    
6208                    if (newOrganizationIds == null) {
6209                            return;
6210                    }
6211    
6212                    long[] oldOrganizationIds = getOrganizationPrimaryKeys(userId);
6213    
6214                    for (long oldOrganizationId : oldOrganizationIds) {
6215                            if (!ArrayUtil.contains(newOrganizationIds, oldOrganizationId)) {
6216                                    unsetOrganizationUsers(oldOrganizationId, new long[] {userId});
6217                            }
6218                    }
6219    
6220                    for (long newOrganizationId : newOrganizationIds) {
6221                            if (!ArrayUtil.contains(oldOrganizationIds, newOrganizationId)) {
6222                                    addOrganizationUsers(newOrganizationId, new long[] {userId});
6223                            }
6224                    }
6225    
6226                    if (indexingEnabled) {
6227                            reindex(userId);
6228                    }
6229    
6230                    PermissionCacheUtil.clearCache(userId);
6231            }
6232    
6233            protected void updateUserGroupRoles(
6234                            User user, long[] groupIds, long[] organizationIds,
6235                            List<UserGroupRole> userGroupRoles,
6236                            List<UserGroupRole> previousUserGroupRoles)
6237                    throws PortalException {
6238    
6239                    if (userGroupRoles == null) {
6240                            return;
6241                    }
6242    
6243                    userGroupRoles = new ArrayList<>(userGroupRoles);
6244    
6245                    for (UserGroupRole userGroupRole : previousUserGroupRoles) {
6246                            if (userGroupRoles.contains(userGroupRole)) {
6247                                    userGroupRoles.remove(userGroupRole);
6248                            }
6249                            else {
6250                                    userGroupRoleLocalService.deleteUserGroupRole(userGroupRole);
6251                            }
6252                    }
6253    
6254                    if (ListUtil.isEmpty(userGroupRoles)) {
6255                            return;
6256                    }
6257    
6258                    long[] validGroupIds = null;
6259    
6260                    if (groupIds != null) {
6261                            validGroupIds = ArrayUtil.clone(groupIds);
6262                    }
6263                    else {
6264                            validGroupIds = user.getGroupIds();
6265                    }
6266    
6267                    if (organizationIds == null) {
6268                            organizationIds = user.getOrganizationIds();
6269                    }
6270    
6271                    for (long organizationId : organizationIds) {
6272                            Organization organization =
6273                                    organizationPersistence.findByPrimaryKey(organizationId);
6274    
6275                            validGroupIds = ArrayUtil.append(
6276                                    validGroupIds, organization.getGroupId());
6277                    }
6278    
6279                    Arrays.sort(validGroupIds);
6280    
6281                    for (UserGroupRole userGroupRole : userGroupRoles) {
6282                            if (Arrays.binarySearch(
6283                                            validGroupIds, userGroupRole.getGroupId()) >= 0) {
6284    
6285                                    userGroupRoleLocalService.addUserGroupRole(userGroupRole);
6286                            }
6287                    }
6288            }
6289    
6290            protected void validate(
6291                            long companyId, long userId, boolean autoPassword, String password1,
6292                            String password2, boolean autoScreenName, String screenName,
6293                            String emailAddress, String openId, String firstName,
6294                            String middleName, String lastName, long[] organizationIds,
6295                            Locale locale)
6296                    throws PortalException {
6297    
6298                    validateCompanyMaxUsers(companyId);
6299    
6300                    if (!autoScreenName) {
6301                            validateScreenName(companyId, userId, screenName);
6302                    }
6303    
6304                    if (!autoPassword) {
6305                            PasswordPolicy passwordPolicy =
6306                                    passwordPolicyLocalService.getDefaultPasswordPolicy(companyId);
6307    
6308                            PwdToolkitUtil.validate(
6309                                    companyId, 0, password1, password2, passwordPolicy);
6310                    }
6311    
6312                    validateEmailAddress(companyId, emailAddress);
6313    
6314                    if (Validator.isNotNull(emailAddress)) {
6315                            User user = userPersistence.fetchByC_EA(companyId, emailAddress);
6316    
6317                            if ((user != null) && (user.getUserId() != userId)) {
6318                                    throw new UserEmailAddressException.MustNotBeDuplicate(
6319                                            userId, emailAddress);
6320                            }
6321                    }
6322    
6323                    validateOpenId(companyId, userId, openId);
6324    
6325                    validateFullName(companyId, firstName, middleName, lastName, locale);
6326    
6327                    if (organizationIds != null) {
6328                            for (long organizationId : organizationIds) {
6329                                    Organization organization =
6330                                            organizationPersistence.fetchByPrimaryKey(organizationId);
6331    
6332                                    if (organization == null) {
6333                                            throw new NoSuchOrganizationException(
6334                                                    "{organizationId=" + organizationId + "}");
6335                                    }
6336                            }
6337                    }
6338            }
6339    
6340            protected void validate(
6341                            long userId, String screenName, String emailAddress, String openId,
6342                            String firstName, String middleName, String lastName, String smsSn,
6343                            Locale locale)
6344                    throws PortalException {
6345    
6346                    User user = userPersistence.findByPrimaryKey(userId);
6347    
6348                    if (!StringUtil.equalsIgnoreCase(user.getScreenName(), screenName)) {
6349                            validateScreenName(user.getCompanyId(), userId, screenName);
6350                    }
6351    
6352                    validateEmailAddress(user.getCompanyId(), emailAddress);
6353    
6354                    validateOpenId(user.getCompanyId(), userId, openId);
6355    
6356                    if (!user.isDefaultUser()) {
6357                            if (Validator.isNotNull(emailAddress) &&
6358                                    !StringUtil.equalsIgnoreCase(
6359                                            user.getEmailAddress(), emailAddress)) {
6360    
6361                                    if (userPersistence.fetchByC_EA(
6362                                                    user.getCompanyId(), emailAddress) != null) {
6363    
6364                                            throw new UserEmailAddressException.MustNotBeDuplicate(
6365                                                    userId, emailAddress);
6366                                    }
6367                            }
6368    
6369                            validateFullName(
6370                                    user.getCompanyId(), firstName, middleName, lastName, locale);
6371                    }
6372    
6373                    if (Validator.isNotNull(smsSn) && !Validator.isEmailAddress(smsSn)) {
6374                            throw new UserSmsException.MustBeEmailAddress(smsSn);
6375                    }
6376            }
6377    
6378            protected void validateCompanyMaxUsers(long companyId)
6379                    throws PortalException {
6380    
6381                    Company company = companyPersistence.findByPrimaryKey(companyId);
6382    
6383                    if (company.isSystem() || (company.getMaxUsers() == 0)) {
6384                            return;
6385                    }
6386    
6387                    int userCount = searchCount(
6388                            companyId, null, WorkflowConstants.STATUS_APPROVED, null);
6389    
6390                    if (userCount >= company.getMaxUsers()) {
6391                            throw new CompanyMaxUsersException();
6392                    }
6393            }
6394    
6395            protected void validateEmailAddress(long companyId, String emailAddress)
6396                    throws PortalException {
6397    
6398                    if (Validator.isNull(emailAddress) &&
6399                            !PropsValues.USERS_EMAIL_ADDRESS_REQUIRED) {
6400    
6401                            return;
6402                    }
6403    
6404                    EmailAddressValidator emailAddressValidator =
6405                            EmailAddressValidatorFactory.getInstance();
6406    
6407                    if (!emailAddressValidator.validate(companyId, emailAddress)) {
6408                            throw new UserEmailAddressException.MustValidate(
6409                                    emailAddress, emailAddressValidator);
6410                    }
6411    
6412                    String pop3User = PrefsPropsUtil.getString(
6413                            PropsKeys.MAIL_SESSION_MAIL_POP3_USER,
6414                            PropsValues.MAIL_SESSION_MAIL_POP3_USER);
6415    
6416                    if (StringUtil.equalsIgnoreCase(emailAddress, pop3User)) {
6417                            throw new UserEmailAddressException.MustNotBePOP3User(emailAddress);
6418                    }
6419    
6420                    String[] reservedEmailAddresses = PrefsPropsUtil.getStringArray(
6421                            companyId, PropsKeys.ADMIN_RESERVED_EMAIL_ADDRESSES,
6422                            StringPool.NEW_LINE, PropsValues.ADMIN_RESERVED_EMAIL_ADDRESSES);
6423    
6424                    for (String reservedEmailAddress : reservedEmailAddresses) {
6425                            if (StringUtil.equalsIgnoreCase(
6426                                            emailAddress, reservedEmailAddress)) {
6427    
6428                                    throw new UserEmailAddressException.MustNotBeReserved(
6429                                            emailAddress, reservedEmailAddresses);
6430                            }
6431                    }
6432            }
6433    
6434            protected void validateEmailAddress(
6435                            User user, String emailAddress1, String emailAddress2)
6436                    throws PortalException {
6437    
6438                    if (!emailAddress1.equals(emailAddress2)) {
6439                            throw new UserEmailAddressException.MustBeEqual(
6440                                    user, emailAddress1, emailAddress2);
6441                    }
6442    
6443                    validateEmailAddress(user.getCompanyId(), emailAddress1);
6444                    validateEmailAddress(user.getCompanyId(), emailAddress2);
6445    
6446                    if (!StringUtil.equalsIgnoreCase(
6447                                    emailAddress1, user.getEmailAddress())) {
6448    
6449                            if (userPersistence.fetchByC_EA(
6450                                            user.getCompanyId(), emailAddress1) != null) {
6451    
6452                                    throw new UserEmailAddressException.MustNotBeDuplicate(
6453                                            user.getUserId(), emailAddress1);
6454                            }
6455                    }
6456            }
6457    
6458            protected void validateFullName(
6459                            long companyId, String firstName, String middleName,
6460                            String lastName, Locale locale)
6461                    throws PortalException {
6462    
6463                    FullNameDefinition fullNameDefinition =
6464                            FullNameDefinitionFactory.getInstance(locale);
6465    
6466                    if (Validator.isNull(firstName)) {
6467                            throw new ContactNameException.MustHaveFirstName();
6468                    }
6469                    else if (Validator.isNull(middleName) &&
6470                                     fullNameDefinition.isFieldRequired("middle-name")) {
6471    
6472                            throw new ContactNameException.MustHaveMiddleName();
6473                    }
6474                    else if (Validator.isNull(lastName) &&
6475                                     fullNameDefinition.isFieldRequired("last-name")) {
6476    
6477                            throw new ContactNameException.MustHaveLastName();
6478                    }
6479    
6480                    FullNameValidator fullNameValidator =
6481                            FullNameValidatorFactory.getInstance();
6482    
6483                    if (!fullNameValidator.validate(
6484                                    companyId, firstName, middleName, lastName)) {
6485    
6486                            throw new ContactNameException.MustHaveValidFullName(
6487                                    fullNameValidator);
6488                    }
6489            }
6490    
6491            protected void validateOpenId(long companyId, long userId, String openId)
6492                    throws PortalException {
6493    
6494                    if (Validator.isNull(openId)) {
6495                            return;
6496                    }
6497    
6498                    User user = userPersistence.fetchByC_O(companyId, openId);
6499    
6500                    if ((user != null) && (user.getUserId() != userId)) {
6501                            throw new DuplicateOpenIdException("{userId=" + userId + "}");
6502                    }
6503            }
6504    
6505            protected void validatePassword(
6506                            long companyId, long userId, String password1, String password2)
6507                    throws PortalException {
6508    
6509                    if (Validator.isNull(password1) || Validator.isNull(password2)) {
6510                            throw new UserPasswordException.MustNotBeNull(userId);
6511                    }
6512    
6513                    if (!password1.equals(password2)) {
6514                            throw new UserPasswordException.MustMatch(userId);
6515                    }
6516    
6517                    PasswordPolicy passwordPolicy =
6518                            passwordPolicyLocalService.getPasswordPolicyByUserId(userId);
6519    
6520                    PwdToolkitUtil.validate(
6521                            companyId, userId, password1, password2, passwordPolicy);
6522            }
6523    
6524            protected void validateReminderQuery(String question, String answer)
6525                    throws PortalException {
6526    
6527                    if (!PropsValues.USERS_REMINDER_QUERIES_ENABLED) {
6528                            return;
6529                    }
6530    
6531                    if (Validator.isNull(question)) {
6532                            throw new UserReminderQueryException("Question is null");
6533                    }
6534    
6535                    if (Validator.isNull(answer)) {
6536                            throw new UserReminderQueryException("Answer is null");
6537                    }
6538            }
6539    
6540            protected void validateScreenName(
6541                            long companyId, long userId, String screenName)
6542                    throws PortalException {
6543    
6544                    if (Validator.isNull(screenName)) {
6545                            throw new UserScreenNameException.MustNotBeNull(userId);
6546                    }
6547    
6548                    ScreenNameValidator screenNameValidator =
6549                            ScreenNameValidatorFactory.getInstance();
6550    
6551                    if (!screenNameValidator.validate(companyId, screenName)) {
6552                            throw new UserScreenNameException.MustValidate(
6553                                    userId, screenName, screenNameValidator);
6554                    }
6555    
6556                    if (Validator.isNumber(screenName)) {
6557                            if (!PropsValues.USERS_SCREEN_NAME_ALLOW_NUMERIC) {
6558                                    throw new UserScreenNameException.MustNotBeNumeric(
6559                                            userId, screenName);
6560                            }
6561    
6562                            if (!screenName.equals(String.valueOf(userId))) {
6563                                    Group group = groupPersistence.fetchByPrimaryKey(
6564                                            GetterUtil.getLong(screenName));
6565    
6566                                    if (group != null) {
6567                                            throw new UserScreenNameException.MustNotBeUsedByGroup(
6568                                                    userId, screenName, group);
6569                                    }
6570                            }
6571                    }
6572    
6573                    String[] anonymousNames = BaseServiceImpl.ANONYMOUS_NAMES;
6574    
6575                    for (String anonymousName : anonymousNames) {
6576                            if (StringUtil.equalsIgnoreCase(screenName, anonymousName)) {
6577                                    throw new UserScreenNameException.MustNotBeReservedForAnonymous(
6578                                            userId, screenName, anonymousNames);
6579                            }
6580                    }
6581    
6582                    User user = userPersistence.fetchByC_SN(companyId, screenName);
6583    
6584                    if ((user != null) && (user.getUserId() != userId)) {
6585                            throw new UserScreenNameException.MustNotBeDuplicate(
6586                                    user.getUserId(), screenName);
6587                    }
6588    
6589                    String friendlyURL = StringPool.SLASH + screenName;
6590    
6591                    Group group = groupPersistence.fetchByC_F(companyId, friendlyURL);
6592    
6593                    if ((group != null) && (group.getClassPK() != userId)) {
6594                            GroupFriendlyURLException gfurle = new GroupFriendlyURLException(
6595                                    GroupFriendlyURLException.DUPLICATE);
6596    
6597                            gfurle.setDuplicateClassPK(group.getGroupId());
6598                            gfurle.setDuplicateClassName(Group.class.getName());
6599    
6600                            throw gfurle;
6601                    }
6602    
6603                    int exceptionType = LayoutImpl.validateFriendlyURL(friendlyURL);
6604    
6605                    if (exceptionType != -1) {
6606                            throw new UserScreenNameException.MustProduceValidFriendlyURL(
6607                                    userId, screenName, exceptionType);
6608                    }
6609    
6610                    String[] reservedScreenNames = PrefsPropsUtil.getStringArray(
6611                            companyId, PropsKeys.ADMIN_RESERVED_SCREEN_NAMES,
6612                            StringPool.NEW_LINE, PropsValues.ADMIN_RESERVED_SCREEN_NAMES);
6613    
6614                    for (String reservedScreenName : reservedScreenNames) {
6615                            if (StringUtil.equalsIgnoreCase(screenName, reservedScreenName)) {
6616                                    throw new UserScreenNameException.MustNotBeReserved(
6617                                            userId, screenName, reservedScreenNames);
6618                            }
6619                    }
6620            }
6621    
6622            @BeanReference(type = MailService.class)
6623            protected MailService mailService;
6624    
6625            private static final Log _log = LogFactoryUtil.getLog(
6626                    UserLocalServiceImpl.class);
6627    
6628            private final Map<Long, User> _defaultUsers = new ConcurrentHashMap<>();
6629    
6630    }