001/* 002 * Copyright 2017 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.editionfo; 017 018import java.util.Collections; 019import java.util.HashMap; 020import java.util.Map; 021import java.util.Set; 022 023import org.apache.avalon.framework.service.ServiceException; 024import org.apache.avalon.framework.service.ServiceManager; 025import org.apache.avalon.framework.service.Serviceable; 026import org.slf4j.Logger; 027 028import org.ametys.core.group.GroupIdentity; 029import org.ametys.core.right.AccessController; 030import org.ametys.core.right.AccessControllerExtensionPoint; 031import org.ametys.core.user.UserIdentity; 032import org.ametys.plugins.explorer.resources.ResourceCollection; 033import org.ametys.plugins.explorer.rights.ResourceAccessController; 034import org.ametys.plugins.frontedition.AmetysFrontEditionHelper; 035import org.ametys.plugins.workspaces.project.ProjectManager; 036import org.ametys.plugins.workspaces.project.modules.WorkspaceModule; 037import org.ametys.plugins.workspaces.project.modules.WorkspaceModuleExtensionPoint; 038import org.ametys.plugins.workspaces.project.objects.Project; 039import org.ametys.runtime.plugin.component.LogEnabled; 040import org.ametys.web.repository.page.Page; 041import org.ametys.web.repository.page.PagesContainer; 042 043/** 044 * The controller is used for wiki pages edition. 045 * This controller delegates control to the wiki module root. 046 * Beware that this controller works with ResourceAccessController... that should be enabled (and if another AccessController can give rights to resources... that's too bad) 047 */ 048public class EditionFOAccessController implements AccessController, Serviceable, LogEnabled 049{ 050 private ProjectManager _projectManager; 051 private WorkspaceModuleExtensionPoint _workspaceModuleExtensionPoint; 052 private Logger _logger; 053 private AccessControllerExtensionPoint _accessControllerExtensionPoint; 054 private AccessController _accessController; 055 056 public void service(ServiceManager manager) throws ServiceException 057 { 058 _projectManager = (ProjectManager) manager.lookup(ProjectManager.ROLE); 059 _workspaceModuleExtensionPoint = (WorkspaceModuleExtensionPoint) manager.lookup(WorkspaceModuleExtensionPoint.ROLE); 060 _accessControllerExtensionPoint = (AccessControllerExtensionPoint) manager.lookup(AccessControllerExtensionPoint.ROLE); 061 } 062 063 public void setLogger(Logger logger) 064 { 065 _logger = logger; 066 } 067 068 private AccessController _getAccessController() 069 { 070 if (_accessController == null) 071 { 072 _accessController = _accessControllerExtensionPoint.getExtension(ResourceAccessController.class.getName()); 073 } 074 return _accessController; 075 } 076 077 private ResourceCollection _getEditionFOModuleRootFromContext(Object object) 078 { 079 String siteName = _getSiteFromContext(object); 080 for (String projectName : _projectManager.getProjectsForSite(siteName)) 081 { 082 Project project = _projectManager.getProject(projectName); 083 if (project == null) 084 { 085 _logger.warn("Cannot find project '{}' associated to the site '{}'.", projectName, siteName); 086 continue; 087 } 088 089 WorkspaceModule editionFOWorkspaceModule = _workspaceModuleExtensionPoint.getExtension(EditionFOWorkspaceModule.EDITIONFO_MODULE_ID); 090 091 if (!_isPageInProjectWiki(editionFOWorkspaceModule, project, object)) 092 { 093 return null; 094 } 095 096 return editionFOWorkspaceModule.getModuleRoot(project, false); 097 } 098 099 return null; 100 } 101 102 private String _getSiteFromContext(Object context) 103 { 104 if (context instanceof PagesContainer) 105 { 106 return ((PagesContainer) context).getSiteName(); 107 } 108 return null; 109 } 110 111 private boolean _isPageInProjectWiki(WorkspaceModule editionFOWorkspaceModule, Project project, Object object) 112 { 113 if (!(object instanceof PagesContainer)) 114 { 115 return false; 116 } 117 PagesContainer page = (PagesContainer) object; 118 String pagePath = page.getPath(); 119 120 return editionFOWorkspaceModule.getModulePages(project, page.getSitemapName()) 121 .stream() 122 .anyMatch(wikiPage -> pagePath.equals(wikiPage.getPath()) || pagePath.contains(wikiPage.getPath() + "/")); 123 } 124 125 public AccessResult getPermission(UserIdentity user, Set<GroupIdentity> userGroups, String rightId, Object object) 126 { 127 if (AmetysFrontEditionHelper.FRONT_EDITION_RIGHT_ID.equals(rightId) || object instanceof Page) 128 { 129 ResourceCollection moduleRoot = _getEditionFOModuleRootFromContext(object); 130 if (moduleRoot != null) 131 { 132 return _getAccessController().getPermission(user, userGroups, rightId, moduleRoot); 133 } 134 } 135 136 return AccessResult.UNKNOWN; 137 } 138 139 public AccessResult getReadAccessPermission(UserIdentity user, Set<GroupIdentity> userGroups, Object object) 140 { 141 if (object instanceof Page) 142 { 143 ResourceCollection moduleRoot = _getEditionFOModuleRootFromContext(object); 144 if (moduleRoot != null) 145 { 146 return _getAccessController().getReadAccessPermission(user, userGroups, moduleRoot); 147 } 148 } 149 150 return AccessResult.UNKNOWN; 151 } 152 153 public Map<String, AccessResult> getPermissionByRight(UserIdentity user, Set<GroupIdentity> userGroups, Object object) 154 { 155 AccessResult accessResult = getPermission(user, userGroups, AmetysFrontEditionHelper.FRONT_EDITION_RIGHT_ID, object); 156 if (accessResult == AccessResult.UNKNOWN) 157 { 158 return Collections.EMPTY_MAP; 159 } 160 else 161 { 162 Map<String, AccessResult> permissions = new HashMap<>(); 163 permissions.put(AmetysFrontEditionHelper.FRONT_EDITION_RIGHT_ID, accessResult); 164 return permissions; 165 } 166 } 167 168 public AccessResult getPermissionForAnonymous(String rightId, Object object) 169 { 170 if (AmetysFrontEditionHelper.FRONT_EDITION_RIGHT_ID.equals(rightId) || object instanceof Page) 171 { 172 ResourceCollection moduleRoot = _getEditionFOModuleRootFromContext(object); 173 if (moduleRoot != null) 174 { 175 return _getAccessController().getPermissionForAnonymous(rightId, moduleRoot); 176 } 177 } 178 179 return AccessResult.UNKNOWN; 180 } 181 182 public AccessResult getReadAccessPermissionForAnonymous(Object object) 183 { 184 if (object instanceof Page) 185 { 186 ResourceCollection moduleRoot = _getEditionFOModuleRootFromContext(object); 187 if (moduleRoot != null) 188 { 189 return _getAccessController().getReadAccessPermissionForAnonymous(moduleRoot); 190 } 191 } 192 193 return AccessResult.UNKNOWN; 194 } 195 196 public AccessResult getPermissionForAnyConnectedUser(String rightId, Object object) 197 { 198 if (AmetysFrontEditionHelper.FRONT_EDITION_RIGHT_ID.equals(rightId) || object instanceof Page) 199 { 200 ResourceCollection moduleRoot = _getEditionFOModuleRootFromContext(object); 201 if (moduleRoot != null) 202 { 203 return _getAccessController().getPermissionForAnyConnectedUser(rightId, moduleRoot); 204 } 205 } 206 207 return AccessResult.UNKNOWN; 208 } 209 210 public AccessResult getReadAccessPermissionForAnyConnectedUser(Object object) 211 { 212 if (object instanceof Page) 213 { 214 ResourceCollection moduleRoot = _getEditionFOModuleRootFromContext(object); 215 if (moduleRoot != null) 216 { 217 return _getAccessController().getReadAccessPermissionForAnyConnectedUser(moduleRoot); 218 } 219 } 220 221 return AccessResult.UNKNOWN; 222 } 223 224 public Map<UserIdentity, AccessResult> getPermissionByUser(String rightId, Object object) 225 { 226 if (AmetysFrontEditionHelper.FRONT_EDITION_RIGHT_ID.equals(rightId) || object instanceof Page) 227 { 228 ResourceCollection moduleRoot = _getEditionFOModuleRootFromContext(object); 229 if (moduleRoot != null) 230 { 231 return _getAccessController().getPermissionByUser(rightId, moduleRoot); 232 } 233 234 } 235 236 return Collections.EMPTY_MAP; 237 } 238 239 public Map<UserIdentity, AccessResult> getReadAccessPermissionByUser(Object object) 240 { 241 if (object instanceof Page) 242 { 243 ResourceCollection moduleRoot = _getEditionFOModuleRootFromContext(object); 244 if (moduleRoot != null) 245 { 246 return _getAccessController().getReadAccessPermissionByUser(moduleRoot); 247 } 248 } 249 250 return Collections.EMPTY_MAP; 251 } 252 253 public Map<GroupIdentity, AccessResult> getPermissionByGroup(String rightId, Object object) 254 { 255 if (AmetysFrontEditionHelper.FRONT_EDITION_RIGHT_ID.equals(rightId) || object instanceof Page) 256 { 257 ResourceCollection moduleRoot = _getEditionFOModuleRootFromContext(object); 258 if (moduleRoot != null) 259 { 260 return _getAccessController().getPermissionByGroup(rightId, moduleRoot); 261 } 262 } 263 264 return Collections.EMPTY_MAP; 265 } 266 267 public Map<GroupIdentity, AccessResult> getReadAccessPermissionByGroup(Object object) 268 { 269 if (object instanceof Page) 270 { 271 ResourceCollection moduleRoot = _getEditionFOModuleRootFromContext(object); 272 if (moduleRoot != null) 273 { 274 return _getAccessController().getReadAccessPermissionByGroup(moduleRoot); 275 } 276 } 277 278 return Collections.EMPTY_MAP; 279 } 280 281 public boolean hasUserAnyPermissionOnWorkspace(Set<Object> workspacesContexts, UserIdentity user, Set<GroupIdentity> userGroups, String rightId) 282 { 283 // We do not want that this accesscontroller give access to the backoffice (even if #isSupported would not match in this case) 284 return false; 285 } 286 287 public boolean hasUserAnyReadAccessPermissionOnWorkspace(Set<Object> workspacesContexts, UserIdentity user, Set<GroupIdentity> userGroups) 288 { 289 return false; 290 } 291 292 public boolean hasAnonymousAnyPermissionOnWorkspace(Set<Object> workspacesContexts, String rightId) 293 { 294 // We do not want that this accesscontroller give access to the backoffice (even if #isSupported would not match in this case) 295 return false; 296 } 297 298 public boolean hasAnonymousAnyReadAccessPermissionOnWorkspace(Set<Object> workspacesContexts) 299 { 300 return false; 301 } 302 303 public boolean hasAnyConnectedUserAnyPermissionOnWorkspace(Set<Object> workspacesContexts, String rightId) 304 { 305 // We do not want that this accesscontroller give access to the backoffice (even if #isSupported would not match in this case) 306 return false; 307 } 308 309 public boolean hasAnyConnectedUserAnyReadAccessPermissionOnWorkspace(Set<Object> workspacesContexts) 310 { 311 return false; 312 } 313 314 public boolean isSupported(Object object) 315 { 316 return object instanceof PagesContainer; 317 } 318 319}