001/* 002 * Copyright 2016 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 */ 016package org.ametys.plugins.workspaces.project.rights; 017 018import java.util.Arrays; 019import java.util.HashMap; 020import java.util.List; 021import java.util.Map; 022import java.util.Objects; 023import java.util.stream.Collectors; 024import java.util.stream.Stream; 025 026import org.apache.avalon.framework.component.Component; 027import org.apache.avalon.framework.service.ServiceException; 028import org.apache.avalon.framework.service.ServiceManager; 029import org.apache.avalon.framework.service.Serviceable; 030import org.apache.commons.lang3.StringUtils; 031 032import org.ametys.core.right.Profile; 033import org.ametys.core.right.RightManager; 034import org.ametys.core.right.RightManager.RightResult; 035import org.ametys.core.right.RightProfilesDAO; 036import org.ametys.core.ui.Callable; 037import org.ametys.core.user.CurrentUserProvider; 038import org.ametys.plugins.explorer.ExplorerNode; 039import org.ametys.plugins.explorer.resources.Resource; 040import org.ametys.plugins.repository.AmetysObjectResolver; 041import org.ametys.plugins.repository.UnknownAmetysObjectException; 042import org.ametys.plugins.workspaces.project.ProjectManager; 043import org.ametys.plugins.workspaces.project.modules.WorkspaceModule; 044import org.ametys.plugins.workspaces.project.modules.WorkspaceModuleExtensionPoint; 045import org.ametys.plugins.workspaces.project.objects.Project; 046import org.ametys.runtime.config.Config; 047import org.ametys.runtime.i18n.I18nizableText; 048import org.ametys.runtime.plugin.component.AbstractLogEnabled; 049import org.ametys.runtime.plugin.component.PluginAware; 050 051/** 052 * Helper related to rights management for projects. 053 */ 054public class ProjectRightHelper extends AbstractLogEnabled implements Serviceable, Component, PluginAware 055{ 056 /** Avalon Role */ 057 public static final String ROLE = ProjectRightHelper.class.getName(); 058 059 private static final String __PROJECT_RIGHT_PROFILE = "PROJECT"; 060 061 /** Ametys object resolver */ 062 protected AmetysObjectResolver _resolver; 063 064 /** Project manager */ 065 protected ProjectManager _projectManager; 066 067 /** Right manager */ 068 protected RightManager _rightManager; 069 070 /** Right profiles manager */ 071 protected RightProfilesDAO _rightProfilesDao; 072 073 /** Current user provider */ 074 protected CurrentUserProvider _currentUserProvider; 075 076 /** Module managers EP */ 077 protected WorkspaceModuleExtensionPoint _moduleManagerEP; 078 079 private String _pluginName; 080 081 @Override 082 public void service(ServiceManager manager) throws ServiceException 083 { 084 _resolver = (AmetysObjectResolver) manager.lookup(AmetysObjectResolver.ROLE); 085 _projectManager = (ProjectManager) manager.lookup(ProjectManager.ROLE); 086 _rightManager = (RightManager) manager.lookup(RightManager.ROLE); 087 _rightProfilesDao = (RightProfilesDAO) manager.lookup(RightProfilesDAO.ROLE); 088 _currentUserProvider = (CurrentUserProvider) manager.lookup(CurrentUserProvider.ROLE); 089 _moduleManagerEP = (WorkspaceModuleExtensionPoint) manager.lookup(WorkspaceModuleExtensionPoint.ROLE); 090 } 091 092 public void setPluginInfo(String pluginName, String featureName, String id) 093 { 094 _pluginName = pluginName; 095 } 096 /** 097 * Retrieves all project profile given the "profile list" configuration parameter 098 * Profile order is guaranteed to be the same as in the configuration parameter. 099 * @return the projects 100 */ 101 public List<Profile> getProfileList() 102 { 103 Map<String, Profile> profileMap = _rightProfilesDao.getProfiles().stream().collect(Collectors.toMap(Profile::getId, item -> item)); 104 String rawProjectProfileIds = StringUtils.defaultString(Config.getInstance().getValueAsString("workspaces.profile.list")); 105 106 // Collect project profiles (unexisting entries are filtered out). 107 return Arrays.stream(StringUtils.split(rawProjectProfileIds, ',')) 108 .map(id -> 109 { 110 Profile p = profileMap.get(id); 111 112 // log null entries 113 if (p == null) 114 { 115 getLogger().warn("Could not find profile with id '{}'.", id); 116 } 117 return p; 118 }) 119 .filter(Objects::nonNull) 120 .collect(Collectors.toList()); 121 } 122 123 /** 124 * Get the list of profiles and the list of modules available for rights affectation in the project. 125 * @param projectName The project to check if the modules are activated. Can be null to ignore 126 * @param includeAllModules True to include modules not manager by the WorkspaceModuleManagerExtensionPoint 127 * @return the project rights data 128 */ 129 @Callable 130 public Map<String, Object> getProjectRightsData(String projectName, boolean includeAllModules) 131 { 132 // profiles 133 List<Object> profiles = getProfileList() 134 .stream() 135 .map(this::_getProfileRightData) 136 .collect(Collectors.toList()); 137 138 139 Project project = projectName != null ? _projectManager.getProject(projectName) : null; 140 141 // modules 142 Stream<Map<String, Object>> stream = _moduleManagerEP.getExtensionsIds().stream().map(moduleId -> _moduleManagerEP.getExtension(moduleId)).map(module -> _getModuleRightData(project, module)); 143 if (includeAllModules) 144 { 145 stream = Stream.concat(Stream.of(_getProjectRightData()), stream); 146 } 147 List<Object> modules = stream.filter(Objects::nonNull).collect(Collectors.toList()); 148 149 Map<String, Object> result = new HashMap<>(); 150 result.put("profiles", profiles); 151 result.put("modules", modules); 152 153 return result; 154 } 155 156 private Map<String, Object> _getProfileRightData(Profile profile) 157 { 158 Map<String, Object> data = new HashMap<>(); 159 data.put("id", profile.getId()); 160 data.put("label", profile.getLabel()); 161 return data; 162 } 163 164 private Map<String, Object> _getModuleRightData(Project project, WorkspaceModule module) 165 { 166 if (project != null && !_projectManager.isModuleActivated(project, module.getId())) 167 { 168 return null; 169 } 170 171 Map<String, Object> data = new HashMap<>(); 172 data.put("id", module.getId()); 173 data.put("label", module.getModuleTitle()); 174 return data; 175 } 176 177 private Map<String, Object> _getProjectRightData() 178 { 179 Map<String, Object> data = new HashMap<>(); 180 data.put("id", __PROJECT_RIGHT_PROFILE); 181 data.put("label", new I18nizableText("plugin." + _pluginName, "PLUGINS_WORKSPACES_PROJECT_SERVICE_PROFILE_TO_PROJECT_LABEL")); 182 return data; 183 } 184 185 /** 186 * Test if the current user has the right on the project 187 * @param rightId The right id 188 * @param projectId The project id 189 * @return true if has right 190 */ 191 @Callable 192 public boolean hasRightOnProject(String rightId, String projectId) 193 { 194 try 195 { 196 return hasRight(rightId, _resolver.<Project>resolveById(projectId)); 197 } 198 catch (UnknownAmetysObjectException e) 199 { 200 getLogger().warn("Trying to test right on an unknown project. Requested id : {}", projectId, e); 201 return false; 202 } 203 } 204 205 /** 206 * Test if the current user has the right on the project 207 * @param rightId The right id 208 * @param project The project 209 * @return true if has right 210 */ 211 public boolean hasRight(String rightId, Project project) 212 { 213 return _rightManager.hasRight(_currentUserProvider.getUser(), rightId, project) == RightResult.RIGHT_ALLOW; 214 } 215 216 /** 217 * Test if the current user has a read access on the project 218 * @param projectId The project id 219 * @return true if has read access 220 */ 221 @Callable 222 public boolean hasReadAccessOnProject(String projectId) 223 { 224 try 225 { 226 return hasReadAccess(_resolver.<Project>resolveById(projectId)); 227 } 228 catch (UnknownAmetysObjectException e) 229 { 230 getLogger().warn("Trying to test read access on an unknown project. Requested id : {}", projectId, e); 231 return false; 232 } 233 } 234 235 /** 236 * Test if the current user has a read access on the project 237 * @param project The project 238 * @return true if has read access 239 */ 240 public boolean hasReadAccess(Project project) 241 { 242 return _rightManager.hasReadAccess(_currentUserProvider.getUser(), project); 243 } 244 245 /** 246 * Test if the current user has the right on an explorer node 247 * @param rightId The right id 248 * @param explorerNodeId The explorer node id 249 * @return true if has right 250 */ 251 @Callable 252 public boolean hasRightOnExplorerNode(String rightId, String explorerNodeId) 253 { 254 try 255 { 256 return hasRight(rightId, _resolver.<ExplorerNode>resolveById(explorerNodeId)); 257 } 258 catch (UnknownAmetysObjectException e) 259 { 260 getLogger().warn("Trying to test right on an unknown explorer node. Requested id : {}", explorerNodeId, e); 261 return false; 262 } 263 } 264 265 /** 266 * Test if the current user has the right on an explorer node 267 * @param rightId The right id 268 * @param explorerNode The explorer node 269 * @return true if has right 270 */ 271 public boolean hasRight(String rightId, ExplorerNode explorerNode) 272 { 273 return _rightManager.hasRight(_currentUserProvider.getUser(), rightId, explorerNode) == RightResult.RIGHT_ALLOW; 274 } 275 276 /** 277 * Test if the current user has a read access on an explorer node 278 * @param explorerNodeId The explorer node id 279 * @return true if has read access 280 */ 281 @Callable 282 public boolean hasReadAccessOnExplorerNode(String explorerNodeId) 283 { 284 try 285 { 286 return hasReadAccess(_resolver.<ExplorerNode>resolveById(explorerNodeId)); 287 } 288 catch (UnknownAmetysObjectException e) 289 { 290 getLogger().warn("Trying to test read access on an unknown explorer node. Requested id : {}", explorerNodeId, e); 291 return false; 292 } 293 } 294 295 /** 296 * Test if the current user has a read access on an explorer node 297 * @param explorerNode The explorer node 298 * @return true if has read access 299 */ 300 public boolean hasReadAccess(ExplorerNode explorerNode) 301 { 302 return _rightManager.currentUserHasReadAccess(explorerNode); 303 } 304 305 /** 306 * Test if the current user has a read access on a resource 307 * @param resource The resource 308 * @return true if has read access 309 */ 310 public boolean hasReadAccess(Resource resource) 311 { 312 return _rightManager.currentUserHasReadAccess(resource); 313 } 314}