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