1 package org.apache.velocity.tools.generic; 2 3 /* 4 * Licensed to the Apache Software Foundation (ASF) under one 5 * or more contributor license agreements. See the NOTICE file 6 * distributed with this work for additional information 7 * regarding copyright ownership. The ASF licenses this file 8 * to you under the Apache License, Version 2.0 (the 9 * "License"); you may not use this file except in compliance 10 * with the License. You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, 15 * software distributed under the License is distributed on an 16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 * KIND, either express or implied. See the License for the 18 * specific language governing permissions and limitations 19 * under the License. 20 */ 21 22 import java.util.Map; 23 24 /** 25 * <p>Implements common logic and constants for tools which automatically 26 * locks down the {@code public void configure(Map params)} method after 27 * it is called once. 28 * This keeps application or session scoped tools thread-safe in templates, 29 * which generally have access to the tool after configuration has happened. 30 * </p><p> 31 * It also provides for a separate "safe mode" setting which tells 32 * tools to block any functions that may pose a security threat. This, 33 * of course, is set to {@code true} by default. 34 * </p><p> 35 * Once "locked down", the {@link #configure(Map)} may still be called, 36 * however it will do nothing (unless some subclass is foolish enough to 37 * override it and not check if {@link #isConfigLocked} before changing 38 * configurations. The proper method for subclasses to override is 39 * {@link #configure(ValueParser)} which will only be called by 40 * {@link #configure(Map)} when the {@link #isConfigLocked} is false 41 * (i.e. the first time only). 42 * </p> 43 * 44 * @author Nathan Bubna 45 * @since VelocityTools 2.0 46 */ 47 public class SafeConfig 48 { 49 /** 50 * The key used for specifying whether or not to prevent templates 51 * from reconfiguring this tool. The default is true. 52 */ 53 public static final String LOCK_CONFIG_KEY = "lockConfig"; 54 @Deprecated 55 public static final String OLD_LOCK_CONFIG_KEY = "lock-config"; 56 57 /** 58 * Many tools interested in locking configure() also have other 59 * things they wish to secure. This key controls that property. 60 * The default value is true, of course. 61 */ 62 public static final String SAFE_MODE_KEY = "safeMode"; 63 64 private boolean configLocked = false; 65 private boolean safeMode = false; 66 67 /** 68 * Only allow subclass access to this. 69 */ 70 protected void setLockConfig(boolean lock) 71 { 72 this.configLocked = lock; 73 } 74 75 protected void setSafeMode(boolean safe) 76 { 77 this.safeMode = safe; 78 } 79 80 /** 81 * Returns {@code true} if the {@link #configure(Map)} method 82 * has been locked. 83 */ 84 public boolean isConfigLocked() 85 { 86 return this.configLocked; 87 } 88 89 /** 90 * Returns {@code true} if this tool is in "safe mode". 91 */ 92 public boolean isSafeMode() 93 { 94 return this.safeMode; 95 } 96 97 /** 98 * If {@link #isConfigLocked} returns {@code true}, then this method 99 * does nothing; otherwise, if {@code false}, this will create a new 100 * {@link ValueParser} from the specified Map of params and call 101 * {@link #configure(ValueParser)} with it. Then this will check 102 * the parameters itself to find out whether or not the configuration 103 * for this tool should be put into safe mode or have its config locked. 104 * The safe mode value should be a boolean under the key 105 * {@link #SAFE_MODE_KEY} and the lock value should be a boolean 106 * under the key {@link #LOCK_CONFIG_KEY}. 107 */ 108 public void configure(Map params) 109 { 110 if (!isConfigLocked()) 111 { 112 ValueParser values = new ValueParser(params); 113 configure(values); 114 115 setSafeMode(values.getBoolean(SAFE_MODE_KEY, true)); 116 117 // check under the new key 118 Boolean lock = values.getBoolean(LOCK_CONFIG_KEY); 119 if (lock == null) 120 { 121 // now check the old key (for now) 122 // by default, lock down this method after use 123 // to prevent templates from re-configuring this instance 124 lock = values.getBoolean(OLD_LOCK_CONFIG_KEY, Boolean.TRUE); 125 } 126 setLockConfig(lock.booleanValue()); 127 } 128 } 129 130 /** 131 * Does the actual configuration. This is protected, so 132 * subclasses may share the same ValueParser and call configure 133 * at any time, while preventing templates from doing so when 134 * configure(Map) is locked. 135 */ 136 protected void configure(ValueParser values) 137 { 138 // base implementation does nothing 139 } 140 141 }