001/* 002 * Copyright 2010 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.core.ui; 017 018import java.util.ArrayList; 019import java.util.HashMap; 020import java.util.List; 021import java.util.Map; 022import java.util.Set; 023 024import org.apache.avalon.framework.configuration.Configurable; 025import org.apache.avalon.framework.configuration.Configuration; 026import org.apache.avalon.framework.configuration.ConfigurationException; 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.lang.StringUtils; 031 032import org.ametys.core.right.RightManager; 033import org.ametys.core.right.RightManager.RightResult; 034import org.ametys.core.user.CurrentUserProvider; 035import org.ametys.core.user.UserIdentity; 036import org.ametys.plugins.core.ui.util.ConfigurationHelper; 037import org.ametys.runtime.plugin.component.AbstractLogEnabled; 038import org.ametys.runtime.plugin.component.PluginAware; 039 040 041/** 042 * This implementation creates an element from a static configuration 043 */ 044public class StaticFileImportsClientSideElement extends AbstractLogEnabled implements ClientSideElement, Configurable, PluginAware, Serviceable 045{ 046 /** The current user provider */ 047 protected CurrentUserProvider _currentUserProvider; 048 /** The rights manager */ 049 protected RightManager _rightManager; 050 /** The element id */ 051 protected String _id; 052 /** The script configured */ 053 protected Script _script; 054 /** The right configured. Can be null */ 055 protected Map<String, String> _rights; 056 /** The righs mode to associate rights AND or OR */ 057 protected String _rightsMode; 058 /** The dependencies, as an associ*/ 059 protected Map<String, List<String>> _dependencies; 060 061 /** The name of the plugin that declared the element */ 062 protected String _pluginName; 063 /** The name of the feature that declared the element */ 064 protected String _featureName; 065 066 067 @Override 068 public void service(ServiceManager smanager) throws ServiceException 069 { 070 _currentUserProvider = (CurrentUserProvider) smanager.lookup(CurrentUserProvider.ROLE); 071 _rightManager = (RightManager) smanager.lookup(RightManager.ROLE); 072 } 073 074 @Override 075 public void setPluginInfo(String pluginName, String featureName, String id) 076 { 077 _id = id; 078 _pluginName = pluginName; 079 _featureName = featureName; 080 } 081 082 @Override 083 public void configure(Configuration configuration) throws ConfigurationException 084 { 085 if (getLogger().isDebugEnabled()) 086 { 087 getLogger().debug("Configuring element '" + _id + "'"); 088 } 089 090 _script = _configureScript(configuration); 091 _rights = _configureRights(configuration); 092 _rightsMode = _configureRightsMode(configuration); 093 _dependencies = _configureDependencies(configuration); 094 } 095 096 /** 097 * Configure the script 098 * @param configuration the global configuration 099 * @return The script created 100 * @throws ConfigurationException The configuration is incorrect 101 */ 102 protected Script _configureScript(Configuration configuration) throws ConfigurationException 103 { 104 List<ScriptFile> scriptsImports = _configureImports(configuration.getChild("scripts")); 105 List<ScriptFile> cssImports = _configureImports(configuration.getChild("css")); 106 107 return new Script(this.getId(), "", scriptsImports, cssImports, new HashMap<>()); 108 } 109 110 /** 111 * Configure the import part 112 * @param configuration The imports configuration 113 * @return The set of the complete url of imported file 114 * @throws ConfigurationException If an error occurs 115 */ 116 protected List<ScriptFile> _configureImports(Configuration configuration) throws ConfigurationException 117 { 118 return ConfigurationHelper.parsePluginResourceList(configuration, getPluginName(), getLogger()); 119 } 120 121 /** 122 * Configure the right following the configuration 123 * 124 * @param configuration The root configuration 125 * @return The right name or null. 126 * @throws ConfigurationException if a right element is present but empty 127 */ 128 protected Map<String, String> _configureRights(Configuration configuration) throws ConfigurationException 129 { 130 Map<String, String> rights = new HashMap<>(); 131 132 Configuration[] rightsConf; 133 if (configuration.getChild("rights", false) != null) 134 { 135 rightsConf = configuration.getChild("rights").getChildren("right"); 136 } 137 else 138 { 139 rightsConf = configuration.getChildren("right"); 140 } 141 142 for (Configuration rightConf : rightsConf) 143 { 144 String right = rightConf.getValue(""); 145 if (right.length() != 0) 146 { 147 String prefix = rightConf.getAttribute("context-prefix", null); 148 String[] rightIds = right.split("\\|"); 149 for (String rightId : rightIds) 150 { 151 rights.put(rightId, prefix); 152 } 153 } 154 else 155 { 156 String message = "The optional right element is empty."; 157 getLogger().error(message); 158 throw new ConfigurationException(message, configuration); 159 } 160 } 161 162 return rights; 163 } 164 165 /** 166 * Configure the mode to associate rights AND or OR 167 * @param configuration The configuration of rights mode. 168 * @return AND or OR (default value) 169 * @throws ConfigurationException The configuration is incorrect 170 */ 171 protected String _configureRightsMode(Configuration configuration) throws ConfigurationException 172 { 173 return "AND".equals(configuration.getChild("rights").getAttribute("mode", "OR").toUpperCase()) ? "AND" : "OR"; 174 } 175 176 /** 177 * Configure the dependencies following the configuration 178 * 179 * @param configuration The root configuration 180 * @return The list of dependencies, by extension point. 181 * @throws ConfigurationException if a dependency element is present but empty 182 */ 183 protected Map<String, List<String>> _configureDependencies(Configuration configuration) throws ConfigurationException 184 { 185 Map<String, List<String>> dependencies = new HashMap<>(); 186 187 if (configuration.getChild("depends", false) != null) 188 { 189 for (Configuration dependency : configuration.getChild("depends").getChildren()) 190 { 191 String extensionPointName = dependency.getName(); 192 String dependencyValue = dependency.getValue(); 193 194 if (StringUtils.isEmpty(dependencyValue) || StringUtils.isEmpty(extensionPointName)) 195 { 196 throw new ConfigurationException("Invalid configuration for dependencies", configuration); 197 } 198 199 if (dependencies.containsKey(extensionPointName)) 200 { 201 List<String> extensions = dependencies.get(extensionPointName); 202 extensions.add(dependencyValue); 203 } 204 else 205 { 206 List<String> extensions = new ArrayList<>(); 207 extensions.add(dependencyValue); 208 dependencies.put(extensionPointName, extensions); 209 } 210 } 211 } 212 213 return dependencies; 214 } 215 216 /** 217 * Determine following the right parameter if the user has right to access this feature 218 * 219 * @param rights The rights (name, context) to check. Can be empty. 220 * @return true if the user has the right or if there is not right and false otherwise 221 */ 222 protected boolean hasRight(Map<String, String> rights) 223 { 224 if (rights.isEmpty()) 225 { 226 return true; 227 } 228 else 229 { 230 UserIdentity user = _currentUserProvider.getUser(); 231 Set<String> rightsToCheck = rights.keySet(); 232 for (String rightToCheck : rightsToCheck) 233 { 234 if (StringUtils.isNotEmpty(rightToCheck)) 235 { 236 String rightContext = rights.get(rightToCheck); 237 // Check right on context/* 238 if (_rightManager.hasRight(user, rightToCheck, rightContext) == RightResult.RIGHT_ALLOW) 239 { 240 if ("OR".equals(_rightsMode)) 241 { 242 return true; 243 } 244 } 245 else 246 { 247 if ("AND".equals(_rightsMode)) 248 { 249 return false; 250 } 251 } 252 } 253 } 254 255 return "AND".equals(_rightsMode); 256 } 257 } 258 259 @Override 260 // This method is a shorthand for the getScripts(ignoreRights) and should not be overwritten 261 public final List<Script> getScripts(Map<String, Object> contextParameters) 262 { 263 return getScripts(false, contextParameters); 264 } 265 266 @Override 267 public List<Script> getScripts(boolean ignoreRights, Map<String, Object> contextParameters) 268 { 269 if (ignoreRights) 270 { 271 List<Script> scripts = new ArrayList<>(); 272 scripts.add(_script); 273 return scripts; 274 } 275 276 if (hasRight(getRights(contextParameters))) 277 { 278 List<Script> scripts = new ArrayList<>(); 279 scripts.add(_script); 280 return scripts; 281 } 282 283 return new ArrayList<>(); 284 } 285 286 @Override 287 public Map<String, String> getRights(Map<String, Object> contextParameters) 288 { 289 return _rights; 290 } 291 292 @Override 293 public String getPluginName() 294 { 295 return _pluginName; 296 } 297 298 @Override 299 public String getId() 300 { 301 return _id; 302 } 303 304 @Override 305 public Map<String, List<String>> getDependencies() 306 { 307 return _dependencies; 308 } 309 310 @Override 311 public String toString() 312 { 313 return _id + (_dependencies != null && _dependencies.size() > 0 ? " " + _dependencies : ""); 314 } 315}