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