001/* 002 * Copyright 2020 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.ametys.plugins.workspaces.user; 018 019import java.util.ArrayList; 020import java.util.Arrays; 021import java.util.Collections; 022import java.util.List; 023import java.util.Map; 024import java.util.Set; 025import java.util.stream.Collectors; 026 027import org.apache.avalon.framework.component.Component; 028import org.apache.avalon.framework.service.ServiceException; 029import org.apache.avalon.framework.service.ServiceManager; 030import org.apache.avalon.framework.service.Serviceable; 031 032import org.ametys.cms.fo.ForceDefaultRepositoryWorkspaceCallableDecorator; 033import org.ametys.core.right.RightManager; 034import org.ametys.core.right.RightManager.RightResult; 035import org.ametys.core.ui.Callable; 036import org.ametys.core.user.CurrentUserProvider; 037import org.ametys.core.user.User; 038import org.ametys.core.user.UserManager; 039import org.ametys.core.user.population.UserPopulation; 040import org.ametys.core.user.population.UserPopulationDAO; 041import org.ametys.plugins.core.user.UserDAO; 042import org.ametys.plugins.core.user.UserHelper; 043import org.ametys.plugins.repository.AmetysObjectResolver; 044import org.ametys.plugins.repository.data.holder.ModelAwareDataHolder; 045import org.ametys.plugins.workspaces.project.rights.ProjectRightHelper; 046import org.ametys.runtime.authentication.AccessDeniedException; 047import org.ametys.web.repository.page.SitemapElement; 048import org.ametys.web.repository.page.ZoneItem; 049 050import com.google.common.collect.Sets; 051 052/** 053 * Component to manager user 054 */ 055public class UserComponent implements Component, Serviceable 056{ 057 /** The avalon role */ 058 public static final String ROLE = UserComponent.class.getName(); 059 060 private UserManager _userManager; 061 private UserPopulationDAO _userPopulationDAO; 062 private UserHelper _userHelper; 063 private AmetysObjectResolver _resolver; 064 private ProjectRightHelper _projectRightsHelper; 065 private CurrentUserProvider _currentUserProvider; 066 private RightManager _rightManager; 067 068 public void service(ServiceManager manager) throws ServiceException 069 { 070 _userManager = (UserManager) manager.lookup(UserManager.ROLE); 071 _userPopulationDAO = (UserPopulationDAO) manager.lookup(UserPopulationDAO.ROLE); 072 _userHelper = (UserHelper) manager.lookup(UserHelper.ROLE); 073 _resolver = (AmetysObjectResolver) manager.lookup(AmetysObjectResolver.ROLE); 074 _projectRightsHelper = (ProjectRightHelper) manager.lookup(ProjectRightHelper.ROLE); 075 _currentUserProvider = (CurrentUserProvider) manager.lookup(CurrentUserProvider.ROLE); 076 _rightManager = (RightManager) manager.lookup(RightManager.ROLE); 077 } 078 079 /** 080 * Search users in the given site 081 * @param siteName The site name 082 * @param count Number of results to return 083 * @param offset Offset to start results 084 * @param search Text to filter search 085 * @param zoneItemId the zoneItemId of the catalog service, used to get allowed populations 086 * @return The users as JSON 087 */ 088 @Callable (rights = Callable.CHECKED_BY_IMPLEMENTATION, decorators = ForceDefaultRepositoryWorkspaceCallableDecorator.DECORATOR_ID) 089 public Map<String, Object> getUsers(String siteName, int count, int offset, String search, String zoneItemId) 090 { 091 ZoneItem zoneItem = _resolver.resolveById(zoneItemId); 092 SitemapElement catalogPage = zoneItem.getZone().getSitemapElement(); 093 094 if (!_projectRightsHelper.hasCatalogReadAccess(zoneItem) || _rightManager.currentUserHasRight(UserDAO.RIGHT_LIST_USERS, catalogPage) != RightResult.RIGHT_ALLOW && _rightManager.currentUserHasRight(UserDAO.RIGHT_LIST_USERS, "/${WorkspaceName}") != RightResult.RIGHT_ALLOW) 095 { 096 throw new AccessDeniedException("User '" + _currentUserProvider.getUser() + "' tried to access users' list without convenient right"); 097 } 098 099 ModelAwareDataHolder serviceDataHolder = zoneItem.getServiceParameters(); 100 String[] populationIds = serviceDataHolder.getValue("populationIds") != null ? serviceDataHolder.getValue("populationIds") : new String[0]; 101 102 Map<String, Object> parameters = Collections.singletonMap("pattern", search); 103 104 List<User> usersByContext = new ArrayList<>(); 105 106 if (populationIds.length == 0) 107 { 108 Set<String> contexts = Sets.newHashSet("/sites/" + siteName, "/sites-fo/" + siteName); 109 110 usersByContext = _userManager.getUsersByContext(contexts, count, offset, parameters, true, true); 111 } 112 else 113 { 114 List<UserPopulation> userPopulations = Arrays.stream(populationIds) 115 .map(userPopulationId -> _userPopulationDAO.getUserPopulation(userPopulationId)) 116 .collect(Collectors.toList()); 117 usersByContext = _userManager.getUsers(userPopulations, count, offset, parameters, true); 118 } 119 120 List<Map<String, Object>> usersAsJson = usersByContext.stream() 121 .map(_userHelper::user2json) 122 .collect(Collectors.toList()); 123 124 return Collections.singletonMap("users", usersAsJson); 125 } 126}