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