View Javadoc

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 }