/** * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. */ package com.liferay.portal.service.impl; import com.liferay.admin.kernel.util.PortalMyAccountApplicationType; import com.liferay.exportimport.kernel.lar.ExportImportThreadLocal; import com.liferay.portal.kernel.cache.thread.local.Lifecycle; import com.liferay.portal.kernel.cache.thread.local.ThreadLocalCachable; import com.liferay.portal.kernel.cache.thread.local.ThreadLocalCache; import com.liferay.portal.kernel.cache.thread.local.ThreadLocalCacheManager; import com.liferay.portal.kernel.dao.orm.DynamicQuery; import com.liferay.portal.kernel.dao.orm.ProjectionFactoryUtil; import com.liferay.portal.kernel.dao.orm.Property; import com.liferay.portal.kernel.dao.orm.PropertyFactoryUtil; import com.liferay.portal.kernel.exception.DuplicateRoleException; import com.liferay.portal.kernel.exception.NoSuchRoleException; import com.liferay.portal.kernel.exception.PortalException; import com.liferay.portal.kernel.exception.RequiredRoleException; import com.liferay.portal.kernel.exception.RoleNameException; import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.kernel.model.Company; import com.liferay.portal.kernel.model.Group; import com.liferay.portal.kernel.model.Layout; import com.liferay.portal.kernel.model.ResourceAction; import com.liferay.portal.kernel.model.ResourceBlockPermission; import com.liferay.portal.kernel.model.ResourceConstants; import com.liferay.portal.kernel.model.ResourcePermission; import com.liferay.portal.kernel.model.ResourceTypePermission; import com.liferay.portal.kernel.model.Role; import com.liferay.portal.kernel.model.RoleConstants; import com.liferay.portal.kernel.model.SystemEventConstants; import com.liferay.portal.kernel.model.Team; import com.liferay.portal.kernel.model.User; import com.liferay.portal.kernel.portlet.PortletProvider; import com.liferay.portal.kernel.portlet.PortletProviderUtil; import com.liferay.portal.kernel.search.Indexer; import com.liferay.portal.kernel.search.IndexerRegistryUtil; import com.liferay.portal.kernel.search.SearchException; import com.liferay.portal.kernel.security.auth.CompanyThreadLocal; import com.liferay.portal.kernel.security.permission.ActionKeys; import com.liferay.portal.kernel.security.permission.PermissionThreadLocal; import com.liferay.portal.kernel.service.ServiceContext; import com.liferay.portal.kernel.spring.aop.Skip; import com.liferay.portal.kernel.systemevent.SystemEvent; import com.liferay.portal.kernel.transaction.Propagation; import com.liferay.portal.kernel.transaction.Transactional; import com.liferay.portal.kernel.util.ArrayUtil; import com.liferay.portal.kernel.util.CharPool; import com.liferay.portal.kernel.util.GetterUtil; import com.liferay.portal.kernel.util.ListUtil; import com.liferay.portal.kernel.util.LocaleUtil; import com.liferay.portal.kernel.util.OrderByComparator; import com.liferay.portal.kernel.util.PortalUtil; import com.liferay.portal.kernel.util.PortletKeys; import com.liferay.portal.kernel.util.SetUtil; import com.liferay.portal.kernel.util.StringUtil; import com.liferay.portal.kernel.util.Validator; import com.liferay.portal.security.permission.PermissionCacheUtil; import com.liferay.portal.service.base.RoleLocalServiceBaseImpl; import com.liferay.portal.util.PropsUtil; import com.liferay.portal.util.PropsValues; import com.liferay.users.admin.kernel.util.UsersAdminUtil; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; /** * Provides the local service for accessing, adding, checking, deleting, and * updating roles. * * @author Brian Wing Shun Chan * @author Marcellus Tavares */ public class RoleLocalServiceImpl extends RoleLocalServiceBaseImpl { /** * Adds a role with additional parameters. The user is reindexed after role * is added. * * @param userId the primary key of the user * @param className the name of the class for which the role is created * (optionally <code>null</code>) * @param classPK the primary key of the class for which the role is * created (optionally <code>0</code>) * @param name the role's name * @param titleMap the role's localized titles (optionally * <code>null</code>) * @param descriptionMap the role's localized descriptions (optionally * <code>null</code>) * @param type the role's type (optionally <code>0</code>) * @param subtype the role's subtype (optionally <code>null</code>) * @param serviceContext the service context to be applied (optionally * <code>null</code>). Can set expando bridge attributes for the * role. * @return the role */ @Override public Role addRole( long userId, String className, long classPK, String name, Map<Locale, String> titleMap, Map<Locale, String> descriptionMap, int type, String subtype, ServiceContext serviceContext) throws PortalException { // Role User user = userPersistence.findByPrimaryKey(userId); className = GetterUtil.getString(className); long classNameId = classNameLocalService.getClassNameId(className); long roleId = counterLocalService.increment(); if ((classNameId <= 0) || className.equals(Role.class.getName())) { classNameId = classNameLocalService.getClassNameId(Role.class); classPK = roleId; } validate(0, user.getCompanyId(), classNameId, name); Role role = rolePersistence.create(roleId); if (serviceContext != null) { role.setUuid(serviceContext.getUuid()); } role.setCompanyId(user.getCompanyId()); role.setUserId(user.getUserId()); role.setUserName(user.getFullName()); role.setClassNameId(classNameId); role.setClassPK(classPK); role.setName(name); role.setTitleMap(titleMap); role.setDescriptionMap(descriptionMap); role.setType(type); role.setSubtype(subtype); role.setExpandoBridgeAttributes(serviceContext); rolePersistence.update(role); // Resources long ownerId = userId; if (user.isDefaultUser()) { ownerId = 0; } resourceLocalService.addResources( user.getCompanyId(), 0, ownerId, Role.class.getName(), role.getRoleId(), false, false, false); if (!user.isDefaultUser()) { resourceLocalService.addResources( user.getCompanyId(), 0, userId, Role.class.getName(), role.getRoleId(), false, false, false); if (!ExportImportThreadLocal.isImportInProcess()) { reindex(userId); } } return role; } /** * Adds the role to the user. The user is reindexed after the role is added. * * @param userId the primary key of the user * @param roleId the primary key of the role * @see com.liferay.portal.kernel.service.persistence.UserPersistence#addRole( * long, long) */ @Override public void addUserRole(long userId, long roleId) throws PortalException { userPersistence.addRole(userId, roleId); reindex(userId); } /** * Adds the role to the user. The user is reindexed after the role is added. * * @param userId the primary key of the user * @param role the role * @see com.liferay.portal.kernel.service.persistence.UserPersistence#addRole( * long, Role) */ @Override public void addUserRole(long userId, Role role) throws PortalException { userPersistence.addRole(userId, role); reindex(userId); } /** * Adds the roles to the user. The user is reindexed after the roles are * added. * * @param userId the primary key of the user * @param roles the roles * @see com.liferay.portal.kernel.service.persistence.UserPersistence#addRoles( * long, List) */ @Override public void addUserRoles(long userId, List<Role> roles) throws PortalException { userPersistence.addRoles(userId, roles); reindex(userId); } /** * Adds the roles to the user. The user is reindexed after the roles are * added. * * @param userId the primary key of the user * @param roleIds the primary keys of the roles * @see com.liferay.portal.kernel.service.persistence.UserPersistence#addRoles( * long, long[]) */ @Override public void addUserRoles(long userId, long[] roleIds) throws PortalException { userPersistence.addRoles(userId, roleIds); reindex(userId); } /** * Checks to ensure that the system roles map has appropriate default roles * in each company. */ @Override public void checkSystemRoles() throws PortalException { List<Company> companies = companyLocalService.getCompanies(); for (Company company : companies) { checkSystemRoles(company.getCompanyId()); } } /** * Checks to ensure that the system roles map has appropriate default roles * in the company. * * @param companyId the primary key of the company */ @Override @Transactional(propagation = Propagation.SUPPORTS, readOnly = true) public void checkSystemRoles(long companyId) throws PortalException { String companyIdHexString = StringUtil.toHexString(companyId); List<Role> roles = null; try { roles = roleFinder.findBySystem(companyId); } catch (Exception e) { // LPS-34324 runSQL("alter table Role_ add uuid_ VARCHAR(75) null"); runSQL("alter table Role_ add userId LONG"); runSQL("alter table Role_ add userName VARCHAR(75) null"); runSQL("alter table Role_ add createDate DATE null"); runSQL("alter table Role_ add modifiedDate DATE null"); roles = roleFinder.findBySystem(companyId); } for (Role role : roles) { _systemRolesMap.put( companyIdHexString.concat(role.getName()), role); } // Regular roles String[] systemRoles = PortalUtil.getSystemRoles(); for (String name : systemRoles) { String key = "system.role." + StringUtil.replace(name, CharPool.SPACE, CharPool.PERIOD) + ".description"; Map<Locale, String> descriptionMap = new HashMap<>(); descriptionMap.put(LocaleUtil.getDefault(), PropsUtil.get(key)); int type = RoleConstants.TYPE_REGULAR; checkSystemRole(companyId, name, descriptionMap, type); } // Organization roles String[] systemOrganizationRoles = PortalUtil.getSystemOrganizationRoles(); for (String name : systemOrganizationRoles) { String key = "system.organization.role." + StringUtil.replace(name, CharPool.SPACE, CharPool.PERIOD) + ".description"; Map<Locale, String> descriptionMap = new HashMap<>(); descriptionMap.put(LocaleUtil.getDefault(), PropsUtil.get(key)); int type = RoleConstants.TYPE_ORGANIZATION; checkSystemRole(companyId, name, descriptionMap, type); } // Site roles String[] systemSiteRoles = PortalUtil.getSystemSiteRoles(); for (String name : systemSiteRoles) { String key = "system.site.role." + StringUtil.replace(name, CharPool.SPACE, CharPool.PERIOD) + ".description"; Map<Locale, String> descriptionMap = new HashMap<>(); descriptionMap.put(LocaleUtil.getDefault(), PropsUtil.get(key)); int type = RoleConstants.TYPE_SITE; checkSystemRole(companyId, name, descriptionMap, type); } String[] allSystemRoles = ArrayUtil.append( systemRoles, systemOrganizationRoles, systemSiteRoles); for (String roleName : allSystemRoles) { Role role = getRole(companyId, roleName); resourceLocalService.addResources( companyId, 0, 0, Role.class.getName(), role.getRoleId(), false, false, false); } // All users should be able to view all system roles Role userRole = getRole(companyId, RoleConstants.USER); for (String roleName : allSystemRoles) { Role role = getRole(companyId, roleName); resourcePermissionLocalService.setResourcePermissions( companyId, Role.class.getName(), ResourceConstants.SCOPE_INDIVIDUAL, String.valueOf(role.getRoleId()), userRole.getRoleId(), new String[] {ActionKeys.VIEW}); } } /** * Removes every role from the user. The user is reindexed after the roles * are removed. * * @param userId the primary key of the user * @see com.liferay.portal.kernel.service.persistence.UserPersistence#clearRoles( * long) */ @Override public void clearUserRoles(long userId) throws PortalException { userPersistence.clearRoles(userId); reindex(userId); } /** * Deletes the role with the primary key and its associated permissions. * * @param roleId the primary key of the role * @return the deleted role */ @Override public Role deleteRole(long roleId) throws PortalException { Role role = rolePersistence.findByPrimaryKey(roleId); return roleLocalService.deleteRole(role); } /** * Deletes the role and its associated permissions. * * @param role the role * @return the deleted role */ @Override @SystemEvent( action = SystemEventConstants.ACTION_SKIP, type = SystemEventConstants.TYPE_DELETE ) public Role deleteRole(Role role) throws PortalException { if (role.isSystem() && !CompanyThreadLocal.isDeleteInProcess()) { throw new RequiredRoleException(); } // Resources List<ResourceBlockPermission> resourceBlockPermissions = resourceBlockPermissionPersistence.findByRoleId(role.getRoleId()); for (ResourceBlockPermission resourceBlockPermission : resourceBlockPermissions) { resourceBlockPermissionLocalService.deleteResourceBlockPermission( resourceBlockPermission); } List<ResourcePermission> resourcePermissions = resourcePermissionPersistence.findByRoleId(role.getRoleId()); for (ResourcePermission resourcePermission : resourcePermissions) { resourcePermissionLocalService.deleteResourcePermission( resourcePermission); } List<ResourceTypePermission> resourceTypePermissions = resourceTypePermissionPersistence.findByRoleId(role.getRoleId()); for (ResourceTypePermission resourceTypePermission : resourceTypePermissions) { resourceTypePermissionLocalService.deleteResourceTypePermission( resourceTypePermission); } String className = role.getClassName(); long classNameId = role.getClassNameId(); if ((classNameId <= 0) || className.equals(Role.class.getName())) { resourceLocalService.deleteResource( role.getCompanyId(), Role.class.getName(), ResourceConstants.SCOPE_INDIVIDUAL, role.getRoleId()); } if ((role.getType() == RoleConstants.TYPE_ORGANIZATION) || (role.getType() == RoleConstants.TYPE_SITE)) { userGroupRoleLocalService.deleteUserGroupRolesByRoleId( role.getRoleId()); userGroupGroupRoleLocalService.deleteUserGroupGroupRolesByRoleId( role.getRoleId()); } // Role rolePersistence.remove(role); // Expando expandoRowLocalService.deleteRows(role.getRoleId()); return role; } /** * Removes the role from the user. The user is reindexed after the role is * removed. * * @param userId the primary key of the user * @param roleId the primary key of the role * @see com.liferay.portal.kernel.service.persistence.UserPersistence#removeRole( * long, long) */ @Override public void deleteUserRole(long userId, long roleId) throws PortalException { userPersistence.removeRole(userId, roleId); reindex(userId); } /** * Removes the role from the user. The user is reindexed after the role is * removed. * * @param userId the primary key of the user * @param role the role * @see com.liferay.portal.kernel.service.persistence.UserPersistence#removeRole( * long, Role) */ @Override public void deleteUserRole(long userId, Role role) throws PortalException { userPersistence.removeRole(userId, role); reindex(userId); } /** * Removes the roles from the user. The user is reindexed after the roles * are removed. * * @param userId the primary key of the user * @param roles the roles * @see com.liferay.portal.kernel.service.persistence.UserPersistence#removeRoles( * long, List) */ @Override public void deleteUserRoles(long userId, List<Role> roles) throws PortalException { userPersistence.removeRoles(userId, roles); reindex(userId); } /** * Removes the roles from the user. The user is reindexed after the roles * are removed. * * @param userId the primary key of the user * @param roleIds the primary keys of the roles * @see com.liferay.portal.kernel.service.persistence.UserPersistence#removeRoles( * long, long[]) */ @Override public void deleteUserRoles(long userId, long[] roleIds) throws PortalException { userPersistence.removeRoles(userId, roleIds); reindex(userId); } /** * Returns the role with the name in the company. * * <p> * The method searches the system roles map first for default roles. If a * role with the name is not found, then the method will query the database. * </p> * * @param companyId the primary key of the company * @param name the role's name * @return Returns the role with the name or <code>null</code> if a role * with the name could not be found in the company */ @Override @Skip public Role fetchRole(long companyId, String name) { String companyIdHexString = StringUtil.toHexString(companyId); Role role = _systemRolesMap.get(companyIdHexString.concat(name)); if (role != null) { return role; } return roleLocalService.loadFetchRole(companyId, name); } @Override public int getAssigneesTotal(long roleId) throws PortalException { int assigneesTotal = 0; Role role = getRole(roleId); int type = role.getType(); if (type == RoleConstants.TYPE_REGULAR) { assigneesTotal += groupLocalService.getRoleGroupsCount(roleId); assigneesTotal += userLocalService.getRoleUsersCount(roleId); } if (type == RoleConstants.TYPE_SITE) { DynamicQuery userGroupGroupRoleDynamicQuery = userGroupGroupRoleLocalService.dynamicQuery(); Property property = PropertyFactoryUtil.forName( "primaryKey.roleId"); userGroupGroupRoleDynamicQuery.add(property.eq(roleId)); userGroupGroupRoleDynamicQuery.setProjection( ProjectionFactoryUtil.countDistinct("primaryKey.userGroupId")); List<?> list = userGroupRoleLocalService.dynamicQuery( userGroupGroupRoleDynamicQuery); Long count = (Long)list.get(0); assigneesTotal += count.intValue(); } if ((type == RoleConstants.TYPE_SITE) || (type == RoleConstants.TYPE_ORGANIZATION)) { DynamicQuery userGroupRoleDynamicQuery = userGroupRoleLocalService.dynamicQuery(); Property property = PropertyFactoryUtil.forName( "primaryKey.roleId"); userGroupRoleDynamicQuery.add(property.eq(roleId)); userGroupRoleDynamicQuery.setProjection( ProjectionFactoryUtil.countDistinct("primaryKey.userId")); List<?> list = userGroupRoleLocalService.dynamicQuery( userGroupRoleDynamicQuery); Long count = (Long)list.get(0); assigneesTotal += count.intValue(); } return assigneesTotal; } /** * Returns the default role for the group with the primary key. * * <p> * If the group is a site, then the default role is {@link * RoleConstants#SITE_MEMBER}. If the group is an organization, then the * default role is {@link RoleConstants#ORGANIZATION_USER}. If the group is * a user or user group, then the default role is {@link * RoleConstants#POWER_USER}. For all other group types, the default role is * {@link RoleConstants#USER}. * </p> * * @param groupId the primary key of the group * @return the default role for the group with the primary key */ @Override public Role getDefaultGroupRole(long groupId) throws PortalException { Group group = groupPersistence.findByPrimaryKey(groupId); if (group.isLayout()) { Layout layout = layoutLocalService.getLayout(group.getClassPK()); group = layout.getGroup(); } if (group.isStagingGroup()) { group = group.getLiveGroup(); } Role role = null; if (group.isCompany()) { role = getRole(group.getCompanyId(), RoleConstants.USER); } else if (group.isLayoutPrototype() || group.isLayoutSetPrototype() || group.isRegularSite() || group.isSite()) { role = getRole(group.getCompanyId(), RoleConstants.SITE_MEMBER); } else if (group.isOrganization()) { role = getRole( group.getCompanyId(), RoleConstants.ORGANIZATION_USER); } else { role = getRole(group.getCompanyId(), RoleConstants.USER); } return role; } @Override public List<Role> getGroupRelatedRoles(long groupId) throws PortalException { List<Role> roles = new ArrayList<>(); Group group = groupLocalService.getGroup(groupId); if (group.isStagingGroup()) { group = group.getLiveGroup(); } int[] types = RoleConstants.TYPES_REGULAR; if (group.isOrganization()) { if (group.isSite()) { types = RoleConstants.TYPES_ORGANIZATION_AND_REGULAR_AND_SITE; } else { types = RoleConstants.TYPES_ORGANIZATION_AND_REGULAR; } } else if (group.isLayout() || group.isLayoutSetPrototype() || group.isSite() || group.isUser()) { types = RoleConstants.TYPES_REGULAR_AND_SITE; } roles.addAll(getRoles(group.getCompanyId(), types)); roles.addAll(getTeamRoles(groupId)); return roles; } @Override public List<Role> getGroupRolesAndTeamRoles( long companyId, String keywords, List<String> excludedNames, int[] types, long excludedTeamRoleId, long teamGroupId, int start, int end) { return roleFinder.findByGroupRoleAndTeamRole( companyId, keywords, excludedNames, types, excludedTeamRoleId, teamGroupId, start, end); } @Override public int getGroupRolesAndTeamRolesCount( long companyId, String keywords, List<String> excludedNames, int[] types, long excludedTeamRoleId, long teamGroupId) { return roleFinder.countByGroupRoleAndTeamRole( companyId, keywords, excludedNames, types, excludedTeamRoleId, teamGroupId); } @Override public List<Role> getResourceBlockRoles( long resourceBlockId, String className, String actionId) { return roleFinder.findByR_N_A(resourceBlockId, className, actionId); } /** * Returns a map of role names to associated action IDs for the named * resource in the company within the permission scope. * * @param companyId the primary key of the company * @param name the resource name * @param scope the permission scope * @param primKey the primary key of the resource's class * @return the role names and action IDs * @see com.liferay.portal.kernel.service.persistence.RoleFinder#findByC_N_S_P( * long, String, int, String) */ @Override public Map<String, List<String>> getResourceRoles( long companyId, String name, int scope, String primKey) { return roleFinder.findByC_N_S_P(companyId, name, scope, primKey); } /** * Returns all the roles associated with the action ID in the company within * the permission scope. * * @param companyId the primary key of the company * @param name the resource name * @param scope the permission scope * @param primKey the primary key of the resource's class * @param actionId the name of the resource action * @return the roles * @see com.liferay.portal.kernel.service.persistence.RoleFinder#findByC_N_S_P_A( * long, String, int, String, String) */ @Override public List<Role> getResourceRoles( long companyId, String name, int scope, String primKey, String actionId) { return roleFinder.findByC_N_S_P_A( companyId, name, scope, primKey, actionId); } /** * Returns the role with the name in the company. * * <p> * The method searches the system roles map first for default roles. If a * role with the name is not found, then the method will query the database. * </p> * * @param companyId the primary key of the company * @param name the role's name * @return the role with the name */ @Override @Skip public Role getRole(long companyId, String name) throws PortalException { String companyIdHexString = StringUtil.toHexString(companyId); Role role = _systemRolesMap.get(companyIdHexString.concat(name)); if (role != null) { return role; } return roleLocalService.loadGetRole(companyId, name); } /** * Returns all the roles of the type and subtype. * * @param type the role's type (optionally <code>0</code>) * @param subtype the role's subtype (optionally <code>null</code>) * @return the roles of the type and subtype */ @Override public List<Role> getRoles(int type, String subtype) { return rolePersistence.findByT_S(type, subtype); } /** * Returns all the roles in the company. * * @param companyId the primary key of the company * @return the roles in the company */ @Override public List<Role> getRoles(long companyId) { return rolePersistence.findByCompanyId(companyId); } /** * Returns all the roles with the types. * * @param companyId the primary key of the company * @param types the role types (optionally <code>null</code>) * @return the roles with the types */ @Override public List<Role> getRoles(long companyId, int[] types) { return rolePersistence.findByC_T(companyId, types); } /** * Returns all the roles with the primary keys. * * @param roleIds the primary keys of the roles * @return the roles with the primary keys */ @Override public List<Role> getRoles(long[] roleIds) throws PortalException { List<Role> roles = new ArrayList<>(roleIds.length); for (long roleId : roleIds) { Role role = getRole(roleId); roles.add(role); } return roles; } /** * Returns all the roles of the subtype. * * @param subtype the role's subtype (optionally <code>null</code>) * @return the roles of the subtype */ @Override public List<Role> getSubtypeRoles(String subtype) { return rolePersistence.findBySubtype(subtype); } /** * Returns the number of roles of the subtype. * * @param subtype the role's subtype (optionally <code>null</code>) * @return the number of roles of the subtype */ @Override public int getSubtypeRolesCount(String subtype) { return rolePersistence.countBySubtype(subtype); } /** * Returns the team role in the company. * * @param companyId the primary key of the company * @param teamId the primary key of the team * @return the team role in the company */ @Override public Role getTeamRole(long companyId, long teamId) throws PortalException { long classNameId = classNameLocalService.getClassNameId(Team.class); return rolePersistence.findByC_C_C(companyId, classNameId, teamId); } /** * Returns the team role map for the group. * * @param groupId the primary key of the group * @return the team role map for the group */ @Override public Map<Team, Role> getTeamRoleMap(long groupId) throws PortalException { return getTeamRoleMap(groupId, null); } /** * Returns the team roles in the group. * * @param groupId the primary key of the group * @return the team roles in the group */ @Override public List<Role> getTeamRoles(long groupId) throws PortalException { return getTeamRoles(groupId, null); } /** * Returns the team roles in the group, excluding the specified role IDs. * * @param groupId the primary key of the group * @param excludedRoleIds the primary keys of the roles to exclude * (optionally <code>null</code>) * @return the team roles in the group, excluding the specified role IDs */ @Override public List<Role> getTeamRoles(long groupId, long[] excludedRoleIds) throws PortalException { Map<Team, Role> teamRoleMap = getTeamRoleMap(groupId, excludedRoleIds); Collection<Role> roles = teamRoleMap.values(); return ListUtil.fromCollection(roles); } /** * Returns the team roles in the company. * * @param companyId the primary key of the company * @param teamIds the primary keys of the teams * @return the team roles in the company */ @Override public List<Role> getTeamsRoles(long companyId, long[] teamIds) throws PortalException { long classNameId = classNameLocalService.getClassNameId(Team.class); return rolePersistence.findByC_C_C(companyId, classNameId, teamIds); } /** * Returns all the roles of the type. * * @param type the role's type (optionally <code>0</code>) * @return the range of the roles of the type */ @Override public List<Role> getTypeRoles(int type) { return rolePersistence.findByType(type); } /** * Returns a range of all the roles of the type. * * @param type the role's type (optionally <code>0</code>) * @param start the lower bound of the range of roles to return * @param end the upper bound of the range of roles to return (not * inclusive) * @return the range of the roles of the type */ @Override public List<Role> getTypeRoles(int type, int start, int end) { return rolePersistence.findByType(type, start, end); } /** * Returns the number of roles of the type. * * @param type the role's type (optionally <code>0</code>) * @return the number of roles of the type */ @Override public int getTypeRolesCount(int type) { return rolePersistence.countByType(type); } /** * Returns all the user's roles within the user group. * * @param userId the primary key of the user * @param groupId the primary key of the group * @return the user's roles within the user group * @see com.liferay.portal.kernel.service.persistence.RoleFinder#findByUserGroupGroupRole( * long, long) */ @Override public List<Role> getUserGroupGroupRoles(long userId, long groupId) { return roleFinder.findByUserGroupGroupRole(userId, groupId); } @Override public List<Role> getUserGroupGroupRoles( long userId, long groupId, int start, int end) { return roleFinder.findByUserGroupGroupRole(userId, groupId, start, end); } @Override public int getUserGroupGroupRolesCount(long userId, long groupId) { return roleFinder.countByUserGroupGroupRole(userId, groupId); } /** * Returns all the user's roles within the user group. * * @param userId the primary key of the user * @param groupId the primary key of the group * @return the user's roles within the user group * @see com.liferay.portal.kernel.service.persistence.RoleFinder#findByUserGroupRole( * long, long) */ @Override public List<Role> getUserGroupRoles(long userId, long groupId) { return roleFinder.findByUserGroupRole(userId, groupId); } /** * Returns the union of all the user's roles within the groups. * * @param userId the primary key of the user * @param groups the groups (optionally <code>null</code>) * @return the union of all the user's roles within the groups * @see com.liferay.portal.kernel.service.persistence.RoleFinder#findByU_G( * long, List) */ @Override public List<Role> getUserRelatedRoles(long userId, List<Group> groups) { if ((groups == null) || groups.isEmpty()) { return Collections.emptyList(); } return roleFinder.findByU_G(userId, groups); } /** * Returns all the user's roles within the group. * * @param userId the primary key of the user * @param groupId the primary key of the group * @return the user's roles within the group * @see com.liferay.portal.kernel.service.persistence.RoleFinder#findByU_G( * long, long) */ @Override public List<Role> getUserRelatedRoles(long userId, long groupId) { return roleFinder.findByU_G(userId, groupId); } /** * Returns the union of all the user's roles within the groups. * * @param userId the primary key of the user * @param groupIds the primary keys of the groups * @return the union of all the user's roles within the groups * @see com.liferay.portal.kernel.service.persistence.RoleFinder#findByU_G( * long, long[]) */ @Override public List<Role> getUserRelatedRoles(long userId, long[] groupIds) { return roleFinder.findByU_G(userId, groupIds); } @Override public List<Role> getUserTeamRoles(long userId, long groupId) { return roleFinder.findByTeamsUser(userId, groupId); } /** * Returns <code>true</code> if the user is associated with the named * regular role. * * @param userId the primary key of the user * @param companyId the primary key of the company * @param name the name of the role * @param inherited whether to include the user's inherited roles in the * search * @return <code>true</code> if the user is associated with the regular * role; <code>false</code> otherwise */ @Override @ThreadLocalCachable public boolean hasUserRole( long userId, long companyId, String name, boolean inherited) throws PortalException { Role role = rolePersistence.fetchByC_N(companyId, name); if (role == null) { return false; } if (role.getType() != RoleConstants.TYPE_REGULAR) { throw new IllegalArgumentException(name + " is not a regular role"); } long defaultUserId = userLocalService.getDefaultUserId(companyId); if (userId == defaultUserId) { if (name.equals(RoleConstants.GUEST)) { return true; } else { return false; } } if (inherited) { if (userPersistence.containsRole(userId, role.getRoleId())) { return true; } ThreadLocalCache<Boolean> threadLocalCache = ThreadLocalCacheManager.getThreadLocalCache( Lifecycle.REQUEST, RoleLocalServiceImpl.class.getName()); String key = String.valueOf(role.getRoleId()).concat( String.valueOf(userId)); Boolean value = threadLocalCache.get(key); if (value != null) { return value; } value = PermissionCacheUtil.getUserRole(userId, role); if (value == null) { int count = roleFinder.countByR_U(role.getRoleId(), userId); if (count > 0) { value = true; } else { value = false; } PermissionCacheUtil.putUserRole(userId, role, value); } threadLocalCache.put(key, value); return value; } else { return userPersistence.containsRole(userId, role.getRoleId()); } } /** * Returns <code>true</code> if the user has any one of the named regular * roles. * * @param userId the primary key of the user * @param companyId the primary key of the company * @param names the names of the roles * @param inherited whether to include the user's inherited roles in the * search * @return <code>true</code> if the user has any one of the regular roles; * <code>false</code> otherwise */ @Override public boolean hasUserRoles( long userId, long companyId, String[] names, boolean inherited) throws PortalException { for (String name : names) { if (hasUserRole(userId, companyId, name, inherited)) { return true; } } return false; } /** * Returns a role with the name in the company. * * @param companyId the primary key of the company * @param name the role's name (optionally <code>null</code>) * @return the role with the name, or <code>null</code> if a role with the * name could not be found in the company */ @Override public Role loadFetchRole(long companyId, String name) { return rolePersistence.fetchByC_N(companyId, name); } /** * Returns a role with the name in the company. * * @param companyId the primary key of the company * @param name the role's name * @return the role with the name in the company */ @Override public Role loadGetRole(long companyId, String name) throws PortalException { return rolePersistence.findByC_N(companyId, name); } /** * Returns an ordered range of all the roles that match the keywords and * types. * * <p> * Useful when paginating results. Returns a maximum of <code>end - * start</code> instances. <code>start</code> and <code>end</code> are not * primary keys, they are indexes in the result set. Thus, <code>0</code> * refers to the first result in the set. Setting both <code>start</code> * and <code>end</code> to {@link * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full * result set. * </p> * * @param companyId the primary key of the company * @param keywords the keywords (space separated), which may occur in the * role's name or description (optionally <code>null</code>) * @param types the role types (optionally <code>null</code>) * @param start the lower bound of the range of roles to return * @param end the upper bound of the range of roles to return (not * inclusive) * @param obc the comparator to order the roles (optionally * <code>null</code>) * @return the ordered range of the matching roles, ordered by * <code>obc</code> * @see com.liferay.portal.kernel.service.persistence.RoleFinder */ @Override public List<Role> search( long companyId, String keywords, Integer[] types, int start, int end, OrderByComparator<Role> obc) { return search( companyId, keywords, types, new LinkedHashMap<String, Object>(), start, end, obc); } /** * Returns an ordered range of all the roles that match the keywords, types, * and params. * * <p> * Useful when paginating results. Returns a maximum of <code>end - * start</code> instances. <code>start</code> and <code>end</code> are not * primary keys, they are indexes in the result set. Thus, <code>0</code> * refers to the first result in the set. Setting both <code>start</code> * and <code>end</code> to {@link * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full * result set. * </p> * * @param companyId the primary key of the company * @param keywords the keywords (space separated), which may occur in the * role's name or description (optionally <code>null</code>) * @param types the role types (optionally <code>null</code>) * @param params the finder parameters. Can specify values for the * "usersRoles" key. For more information, see {@link * com.liferay.portal.kernel.service.persistence.RoleFinder} * @param start the lower bound of the range of roles to return * @param end the upper bound of the range of roles to return (not * inclusive) * @param obc the comparator to order the roles (optionally * <code>null</code>) * @return the ordered range of the matching roles, ordered by * <code>obc</code> * @see com.liferay.portal.kernel.service.persistence.RoleFinder */ @Override public List<Role> search( long companyId, String keywords, Integer[] types, LinkedHashMap<String, Object> params, int start, int end, OrderByComparator<Role> obc) { return roleFinder.findByKeywords( companyId, keywords, types, params, start, end, obc); } /** * Returns an ordered range of all the roles that match the name, * description, and types. * * <p> * Useful when paginating results. Returns a maximum of <code>end - * start</code> instances. <code>start</code> and <code>end</code> are not * primary keys, they are indexes in the result set. Thus, <code>0</code> * refers to the first result in the set. Setting both <code>start</code> * and <code>end</code> to {@link * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full * result set. * </p> * * @param companyId the primary key of the company * @param name the role's name (optionally <code>null</code>) * @param description the role's description (optionally <code>null</code>) * @param types the role types (optionally <code>null</code>) * @param start the lower bound of the range of the roles to return * @param end the upper bound of the range of the roles to return (not * inclusive) * @param obc the comparator to order the roles (optionally * <code>null</code>) * @return the ordered range of the matching roles, ordered by * <code>obc</code> * @see com.liferay.portal.kernel.service.persistence.RoleFinder */ @Override public List<Role> search( long companyId, String name, String description, Integer[] types, int start, int end, OrderByComparator<Role> obc) { return search( companyId, name, description, types, new LinkedHashMap<String, Object>(), start, end, obc); } /** * Returns an ordered range of all the roles that match the name, * description, types, and params. * * <p> * Useful when paginating results. Returns a maximum of <code>end - * start</code> instances. <code>start</code> and <code>end</code> are not * primary keys, they are indexes in the result set. Thus, <code>0</code> * refers to the first result in the set. Setting both <code>start</code> * and <code>end</code> to {@link * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full * result set. * </p> * * @param companyId the primary key of the company * @param name the role's name (optionally <code>null</code>) * @param description the role's description (optionally <code>null</code>) * @param types the role types (optionally <code>null</code>) * @param params the finder's parameters. Can specify values for the * "usersRoles" key. For more information, see {@link * com.liferay.portal.kernel.service.persistence.RoleFinder} * @param start the lower bound of the range of the roles to return * @param end the upper bound of the range of the roles to return (not * inclusive) * @param obc the comparator to order the roles (optionally * <code>null</code>) * @return the ordered range of the matching roles, ordered by * <code>obc</code> * @see com.liferay.portal.kernel.service.persistence.RoleFinder */ @Override public List<Role> search( long companyId, String name, String description, Integer[] types, LinkedHashMap<String, Object> params, int start, int end, OrderByComparator<Role> obc) { return roleFinder.findByC_N_D_T( companyId, name, description, types, params, true, start, end, obc); } /** * Returns the number of roles that match the keywords and types. * * @param companyId the primary key of the company * @param keywords the keywords (space separated), which may occur in the * role's name or description (optionally <code>null</code>) * @param types the role types (optionally <code>null</code>) * @return the number of matching roles */ @Override public int searchCount(long companyId, String keywords, Integer[] types) { return searchCount( companyId, keywords, types, new LinkedHashMap<String, Object>()); } /** * Returns the number of roles that match the keywords, types and params. * * @param companyId the primary key of the company * @param keywords the keywords (space separated), which may occur in the * role's name or description (optionally <code>null</code>) * @param types the role types (optionally <code>null</code>) * @param params the finder parameters. For more information, see {@link * com.liferay.portal.kernel.service.persistence.RoleFinder} * @return the number of matching roles */ @Override public int searchCount( long companyId, String keywords, Integer[] types, LinkedHashMap<String, Object> params) { return roleFinder.countByKeywords(companyId, keywords, types, params); } /** * Returns the number of roles that match the name, description, and types. * * @param companyId the primary key of the company * @param name the role's name (optionally <code>null</code>) * @param description the role's description (optionally <code>null</code>) * @param types the role types (optionally <code>null</code>) * @return the number of matching roles */ @Override public int searchCount( long companyId, String name, String description, Integer[] types) { return searchCount( companyId, name, description, types, new LinkedHashMap<String, Object>()); } /** * Returns the number of roles that match the name, description, types, and * params. * * @param companyId the primary key of the company * @param name the role's name (optionally <code>null</code>) * @param description the role's description (optionally <code>null</code>) * @param types the role types (optionally <code>null</code>) * @param params the finder parameters. Can specify values for the * "usersRoles" key. For more information, see {@link * com.liferay.portal.kernel.service.persistence.RoleFinder} * @return the number of matching roles */ @Override public int searchCount( long companyId, String name, String description, Integer[] types, LinkedHashMap<String, Object> params) { return roleFinder.countByC_N_D_T( companyId, name, description, types, params, true); } /** * Sets the roles associated with the user, replacing the user's existing * roles. The user is reindexed after the roles are set. * * @param userId the primary key of the user * @param roleIds the primary keys of the roles */ @Override public void setUserRoles(long userId, long[] roleIds) throws PortalException { roleIds = UsersAdminUtil.addRequiredRoles(userId, roleIds); userPersistence.setRoles(userId, roleIds); reindex(userId); } /** * Removes the matching roles associated with the user. The user is * reindexed after the roles are removed. * * @param userId the primary key of the user * @param roleIds the primary keys of the roles */ @Override public void unsetUserRoles(long userId, long[] roleIds) throws PortalException { roleIds = UsersAdminUtil.removeRequiredRoles(userId, roleIds); userPersistence.removeRoles(userId, roleIds); reindex(userId); } /** * Updates the role with the primary key. * * @param roleId the primary key of the role * @param name the role's new name * @param titleMap the new localized titles (optionally <code>null</code>) * to replace those existing for the role * @param descriptionMap the new localized descriptions (optionally * <code>null</code>) to replace those existing for the role * @param subtype the role's new subtype (optionally <code>null</code>) * @param serviceContext the service context to be applied (optionally * <code>null</code>). Can set expando bridge attributes for the * role. * @return the role with the primary key */ @Override public Role updateRole( long roleId, String name, Map<Locale, String> titleMap, Map<Locale, String> descriptionMap, String subtype, ServiceContext serviceContext) throws PortalException { Role role = rolePersistence.findByPrimaryKey(roleId); validate(roleId, role.getCompanyId(), role.getClassNameId(), name); if (role.isSystem()) { name = role.getName(); subtype = null; } role.setName(name); role.setTitleMap(titleMap); role.setDescriptionMap(descriptionMap); role.setSubtype(subtype); role.setExpandoBridgeAttributes(serviceContext); rolePersistence.update(role); return role; } protected void checkSystemRole( long companyId, String name, Map<Locale, String> descriptionMap, int type) throws PortalException { String companyIdHexString = StringUtil.toHexString(companyId); String key = companyIdHexString.concat(name); Role role = _systemRolesMap.get(key); try { if (role == null) { role = rolePersistence.findByC_N(companyId, name); } if (!descriptionMap.equals(role.getDescriptionMap())) { role.setDescriptionMap(descriptionMap); roleLocalService.updateRole(role); } } catch (NoSuchRoleException nsre) { // LPS-52675 if (_log.isDebugEnabled()) { _log.debug(nsre, nsre); } User user = userLocalService.getDefaultUser(companyId); PermissionThreadLocal.setAddResource(false); try { role = roleLocalService.addRole( user.getUserId(), null, 0, name, null, descriptionMap, type, null, null); } finally { PermissionThreadLocal.setAddResource(true); } if (name.equals(RoleConstants.USER)) { initPersonalControlPanelPortletsPermissions(role); } } _systemRolesMap.put(key, role); } protected String[] getDefaultControlPanelPortlets() { String myAccountPortletId = PortletProviderUtil.getPortletId( PortalMyAccountApplicationType.MyAccount.CLASS_NAME, PortletProvider.Action.VIEW); return new String[] { myAccountPortletId, PortletKeys.MY_PAGES, PortletKeys.MY_WORKFLOW_INSTANCE, PortletKeys.MY_WORKFLOW_TASK }; } protected Map<Team, Role> getTeamRoleMap( long groupId, long[] excludedRoleIds) throws PortalException { Group group = groupPersistence.findByPrimaryKey(groupId); if (group.isLayout()) { group = group.getParentGroup(); } List<Team> teams = teamPersistence.findByGroupId(group.getGroupId()); if (teams.isEmpty()) { return Collections.emptyMap(); } Set<Long> roleIds = SetUtil.fromArray(excludedRoleIds); Map<Team, Role> teamRoleMap = new LinkedHashMap<>(); for (Team team : teams) { Role role = getTeamRole(team.getCompanyId(), team.getTeamId()); if (roleIds.contains(role.getRoleId())) { continue; } teamRoleMap.put(team, role); } return teamRoleMap; } protected void initPersonalControlPanelPortletsPermissions(Role role) throws PortalException { for (String portletId : getDefaultControlPanelPortlets()) { int count = resourcePermissionPersistence.countByC_N_S_P_R( role.getCompanyId(), portletId, ResourceConstants.SCOPE_COMPANY, String.valueOf(role.getCompanyId()), role.getRoleId()); if (count > 0) { continue; } ResourceAction resourceAction = resourceActionLocalService.fetchResourceAction( portletId, ActionKeys.ACCESS_IN_CONTROL_PANEL); if (resourceAction == null) { continue; } setRolePermissions( role, portletId, new String[] {ActionKeys.ACCESS_IN_CONTROL_PANEL}); } } protected void reindex(long userId) throws SearchException { Indexer<User> indexer = IndexerRegistryUtil.nullSafeGetIndexer( User.class); User user = userLocalService.fetchUser(userId); indexer.reindex(user); } protected void setRolePermissions( Role role, String name, String[] actionIds) throws PortalException { if (resourceBlockLocalService.isSupported(name)) { resourceBlockLocalService.setCompanyScopePermissions( role.getCompanyId(), name, role.getRoleId(), Arrays.asList(actionIds)); } else { resourcePermissionLocalService.setResourcePermissions( role.getCompanyId(), name, ResourceConstants.SCOPE_COMPANY, String.valueOf(role.getCompanyId()), role.getRoleId(), actionIds); } } protected void validate( long roleId, long companyId, long classNameId, String name) throws PortalException { if (classNameId == classNameLocalService.getClassNameId(Role.class)) { if (Validator.isNull(name) || (name.indexOf(CharPool.COMMA) != -1) || (name.indexOf(CharPool.STAR) != -1)) { throw new RoleNameException(); } if (Validator.isNumber(name) && !PropsValues.ROLES_NAME_ALLOW_NUMERIC) { throw new RoleNameException(); } } try { Role role = roleFinder.findByC_N(companyId, name); if (role.getRoleId() != roleId) { throw new DuplicateRoleException("{roleId=" + roleId + "}"); } } catch (NoSuchRoleException nsre) { // LPS-52675 if (_log.isDebugEnabled()) { _log.debug(nsre, nsre); } } if (name.equals(RoleConstants.PLACEHOLDER_DEFAULT_GROUP_ROLE)) { throw new RoleNameException( RoleConstants.PLACEHOLDER_DEFAULT_GROUP_ROLE + " is a temporary placeholder that must not be persisted"); } } private static final Log _log = LogFactoryUtil.getLog( RoleLocalServiceImpl.class); private final Map<String, Role> _systemRolesMap = new HashMap<>(); }