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.explorer.rights; 017 018import java.util.Collections; 019import java.util.HashSet; 020import java.util.Map; 021import java.util.Set; 022import java.util.regex.Pattern; 023 024import org.apache.avalon.framework.service.ServiceException; 025import org.apache.avalon.framework.service.ServiceManager; 026import org.apache.commons.lang3.StringUtils; 027 028import org.ametys.core.right.AccessController; 029import org.ametys.core.right.RightsException; 030import org.ametys.plugins.core.impl.right.AbstractHierarchicalAccessController; 031import org.ametys.plugins.explorer.ExplorerNode; 032import org.ametys.plugins.explorer.resources.Resource; 033import org.ametys.plugins.explorer.resources.actions.ExplorerResourcesDAO; 034import org.ametys.plugins.repository.AmetysObject; 035import org.ametys.runtime.i18n.I18nizableText; 036import org.ametys.runtime.i18n.I18nizableTextParameter; 037 038/** 039 * {@link AccessController} for a {@link Resource} 040 */ 041public class ResourceAccessController extends AbstractHierarchicalAccessController<AmetysObject> 042{ 043 /** the resource context category */ 044 public static final I18nizableText RESOURCE_CONTEXT_CATEGORY = new I18nizableText("plugin.explorer", "PLUGINS_EXPLORER_RIGHT_ASSIGNMENT_CONTEXT_RESOURCES_LABEL"); 045 /** The explorer resources dao */ 046 protected ExplorerResourcesDAO _resourcesDAO; 047 048 @Override 049 public void service(ServiceManager manager) throws ServiceException 050 { 051 super.service(manager); 052 053 _resourcesDAO = (ExplorerResourcesDAO) manager.lookup(ExplorerResourcesDAO.ROLE); 054 } 055 056 @Override 057 public boolean isSupported(Object object) 058 { 059 if (object instanceof ExplorerNode node) 060 { 061 return _isPartOfResourceExplorer(node.getPath()); 062 } 063 else if (object instanceof Resource resource) 064 { 065 return _isPartOfResourceExplorer(resource.getPath()); 066 } 067 return false; 068 } 069 070 private boolean _isPartOfResourceExplorer(String path) 071 { 072 for (Pattern pattern : _resourcesDAO.getExplorerNodePathPatterns()) 073 { 074 if (pattern.matcher(path).matches()) 075 { 076 return true; 077 } 078 } 079 return false; 080 } 081 082 @Override 083 protected boolean _isSupportedStoredContext(Object storedObject) 084 { 085 // Do not rely on _resourcesDAO.getExplorerNodePathPatterns() but 086 // use the _resourcesDAO.getResourcesRootNodes() to restrict to 087 // resources available in the current context 088 if (storedObject instanceof ExplorerNode || storedObject instanceof Resource) 089 { 090 String path = storedObject instanceof ExplorerNode e ? e.getPath() : ((Resource) storedObject).getPath(); 091 092 for (ExplorerNode roots : _resourcesDAO.getResourcesRootNodes()) 093 { 094 if (StringUtils.startsWith(path, roots.getPath())) 095 { 096 return true; 097 } 098 } 099 } 100 101 return false; 102 } 103 104 @Override 105 protected Set<AmetysObject> _getParents(AmetysObject object) 106 { 107 AmetysObject parent = object.getParent(); 108 if (parent instanceof ExplorerNode) 109 { 110 return Collections.singleton(parent); 111 } 112 else 113 { 114 return null; 115 } 116 } 117 118 @Override 119 protected Set<? extends Object> _convertWorkspaceToRootRightContexts(Set<Object> workspacesContexts) 120 { 121 if (workspacesContexts.contains("/cms")) 122 { 123 Set<Object> resourcesRootContexts = new HashSet<>(); 124 resourcesRootContexts.addAll(_resourcesDAO.getResourcesRootNodes()); 125 return resourcesRootContexts; 126 } 127 return null; 128 } 129 130 @Override 131 protected I18nizableText getObjectLabelForExplanation(Object object) throws RightsException 132 { 133 Map<String, I18nizableTextParameter> params = Map.of("name", getObjectLabel(object)); 134 if (object instanceof Resource) 135 { 136 return new I18nizableText("plugin.explorer", "PLUGINS_EXPLORER_RESOURCE_ACCESS_CONTROLLER_RESOURCE_CONTEXT_LABEL", params); 137 138 } 139 else if (object instanceof ExplorerNode) 140 { 141 return new I18nizableText("plugin.explorer", "PLUGINS_EXPLORER_RESOURCE_ACCESS_CONTROLLER_EXPLORER_NODE_CONTEXT_LABEL", params); 142 } 143 throw new RightsException("Unsupported object " + object.toString()); 144 } 145 146 public I18nizableText getObjectLabel(Object object) throws RightsException 147 { 148 if (object instanceof Resource resource) 149 { 150 return new I18nizableText("plugin.explorer", "PLUGINS_EXPLORER_RESOURCE_ACCESS_CONTROLLER_PATH", 151 Map.of("parent", getObjectLabel(resource.getParent()), 152 "child", new I18nizableText(resource.getName())) 153 ); 154 } 155 else if (object instanceof ExplorerNode node) 156 { 157 if (_resourcesDAO.getResourcesRootNodes().contains(node)) 158 { 159 return _resourcesDAO.getRootNodeLabel(node); 160 } 161 else 162 { 163 return new I18nizableText("plugin.explorer", "PLUGINS_EXPLORER_RESOURCE_ACCESS_CONTROLLER_PATH", 164 Map.of("parent", getObjectLabel(node.getParent()), 165 "child", new I18nizableText(node.getName())) 166 ); 167 } 168 } 169 throw new RightsException("Unsupported object " + object.toString()); 170 } 171 172 public I18nizableText getObjectCategory(Object object) 173 { 174 return RESOURCE_CONTEXT_CATEGORY; 175 } 176}