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