I think the contribution "^org/chenillekit/tapestry/" should be removed from the configuration of the RegexpAuthorizer. App developers using Chenillekit should contribute it.
On Mon, Nov 9, 2009 at 6:23 PM, <[email protected]> wrote: > Author: robertdzeigler > Date: Mon Nov 9 17:23:10 2009 > New Revision: 834151 > > URL: http://svn.apache.org/viewvc?rev=834151&view=rev > Log: > TAP5-815: Asset dispatcher allows any file inside the webapp visible and > downloadable (5.2 branch) > > Added: > > > tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AssetProtectionDispatcher.java > > > tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/RegexAuthorizer.java > > > tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/WhitelistAuthorizer.java > > > tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/AssetPathAuthorizer.java > > > tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/AssetProtectionDispatcherTest.java > > > tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/RegexAuthorizerTest.java > > > tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/WhitelistAuthorizerTest.java > Modified: > tapestry/tapestry5/trunk/src/site/apt/guide/assets.apt > > > tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java > > > tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/AppModule.java > > Modified: tapestry/tapestry5/trunk/src/site/apt/guide/assets.apt > URL: > http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/src/site/apt/guide/assets.apt?rev=834151&r1=834150&r2=834151&view=diff > > ============================================================================== > --- tapestry/tapestry5/trunk/src/site/apt/guide/assets.apt (original) > +++ tapestry/tapestry5/trunk/src/site/apt/guide/assets.apt Mon Nov 9 > 17:23:10 2009 > @@ -138,6 +138,31 @@ > In addition, context assets will use the URL prefix > <<</assets/ctx/>>><app-version><<</>>>. > > > +Securing Assets > + > + Securing assets is an important consideration for any web application. > Many assets, such as hibernate configuration > + files, sit in the classpath and are exposable via the Asset service, > which is not desirable. To protect these and > + other sensitive assets, Tapestry provides the AssetProtectionDispatcher. > This dispatcher sits in front of the > + AssetDispatcher, the service responsible for streaming assets to the > client, and watches for Asset requests. > + When an asset request comes in, the protection dispatcher checks for > authorization to view the file against a > + contributed list of AssetPathAuthorizer implementations. Determination > of whether the client can view the requested > + resource is then made based on whether any of the contributed > AssetPathAuthorizer implementations explicitly allowed > + or denied access to the resource. > + > + Tapestry provides two AssetPathAuthorizer implemenations "out of the > box" to which users may contribute: RegexAuthorizer > + and WhitelistAuthorizer. RegexAuthorizer uses regular expressions to > determine assets which are viewable by the > + client; any assets that match one of its (contributed) regular > expressions are authorized. Anything not matched is > + passed through to the WhitelistAuthorizer. WhitelistAuthorizer uses an > exact-matching whitelist. Anything matching > + exactly one its contributions is allowed; all other asset requests are > denied. The default tapestry configuration > + contributes nothing to WhitelistAuthorizer (access will be denied to all > asset requests passed through to it), and > + explicitly allows access to css, jpg, jpeg, js, png, and gif files > associated with tapestry (tapestry.js, blackbird > + files, date picker files, etc.). The default contribution also enables > access to the css, jpg, jpeg, js, png, and gif > + files provided by the popular chenille-kit 3rd party library. The > default configuration denies access to all other > + assets. To enable access to your application's assets, either > contribute a custom AssetPathAnalyzer, or contribute > + appropriate regular expression or exact path contributions to > RegexAuthorizer or WhitelistAuthorizer, respectively. > + See TapestryModule.contribteRegexAuthorizer for examples. > + > + > Performance Notes > > Assets are expected to be entirely static (not changing while the > application is deployed). When Tapestry generates a URL > @@ -146,4 +171,4 @@ > asset. > > In addition, Tapestry will {{{compress.html}GZIP compress}} the content > of <all> assets (if the asset > - is compressable, and the client supports it). > \ No newline at end of file > + is compressable, and the client supports it). > > Added: > tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AssetProtectionDispatcher.java > URL: > http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AssetProtectionDispatcher.java?rev=834151&view=auto > > ============================================================================== > --- > tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AssetProtectionDispatcher.java > (added) > +++ > tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/AssetProtectionDispatcher.java > Mon Nov 9 17:23:10 2009 > @@ -0,0 +1,92 @@ > +// Copyright 2009 The Apache Software Foundation > +// > +// Licensed under the Apache License, Version 2.0 (the "License"); > +// you may not use this file except in compliance with the License. > +// You may obtain a copy of the License at > +// > +// http://www.apache.org/licenses/LICENSE-2.0 > +// > +// Unless required by applicable law or agreed to in writing, software > +// distributed under the License is distributed on an "AS IS" BASIS, > +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or > implied. > +// See the License for the specific language governing permissions and > +// limitations under the License. > + > +package org.apache.tapestry5.internal.services; > + > +import java.io.IOException; > +import java.util.Collection; > +import java.util.Collections; > +import java.util.List; > + > +import javax.servlet.http.HttpServletResponse; > + > +import org.apache.tapestry5.internal.services.RequestConstants; > +import org.apache.tapestry5.services.*; > +import org.slf4j.Logger; > + > +/** > + * Dispatcher that handles whether to allow or deny access to particular > + * assets. Actual work of authorizing a particular url is handled by > + * implementations of AssetPathAuthorizer. Configuration is an ordered > + * list of AssetPathAuthorizers. Each authorizer specifies an order of > + * operations as a list (see AssetPathAuthorizer.Order). > + * > + */ > +public class AssetProtectionDispatcher implements Dispatcher > +{ > + > + private final Collection<AssetPathAuthorizer> authorizers; > + private final ClasspathAssetAliasManager assetAliasManager; > + private final Logger logger; > + > + public AssetProtectionDispatcher( > + List<AssetPathAuthorizer> auths, > + ClasspathAssetAliasManager manager, > + Logger logger) > + { > + this.authorizers = Collections.unmodifiableList(auths); > + this.assetAliasManager = manager; > + this.logger = logger; > + } > + > + public boolean dispatch(Request request, Response response) > + throws IOException > + { > + String path = request.getPath(); > + //we only protect assets, and don't examine any other url's. > + if (!path.startsWith(RequestConstants.ASSET_PATH_PREFIX)) > + { > + return false; > + } > + String resourcePath = assetAliasManager.toResourcePath(path); > + for(AssetPathAuthorizer auth : authorizers) > + { > + for(AssetPathAuthorizer.Order o : auth.order()) > + { > + if (o == AssetPathAuthorizer.Order.ALLOW) > + { > + if (auth.accessAllowed(resourcePath)) > + { > + logger.debug("Allowing access to " + > resourcePath); > + return false; > + } > + } > + else > + { > + if (auth.accessDenied(resourcePath)) > + { > + logger.debug("Denying access to " + resourcePath); > + > response.sendError(HttpServletResponse.SC_FORBIDDEN,resourcePath); > + return true; > + } > + } > + } > + } > + //if we get here, no Authorizer had anything useful to say about > the resourcePath. > + //so let it fall through. > + logger.debug("Fell through the list of authorizers. Allowing > access to: " + resourcePath); > + return false; > + } > + > +} > > Added: > tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/RegexAuthorizer.java > URL: > http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/RegexAuthorizer.java?rev=834151&view=auto > > ============================================================================== > --- > tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/RegexAuthorizer.java > (added) > +++ > tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/RegexAuthorizer.java > Mon Nov 9 17:23:10 2009 > @@ -0,0 +1,76 @@ > +// Copyright 2009 The Apache Software Foundation > +// > +// Licensed under the Apache License, Version 2.0 (the "License"); > +// you may not use this file except in compliance with the License. > +// You may obtain a copy of the License at > +// > +// http://www.apache.org/licenses/LICENSE-2.0 > +// > +// Unless required by applicable law or agreed to in writing, software > +// distributed under the License is distributed on an "AS IS" BASIS, > +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or > implied. > +// See the License for the specific language governing permissions and > +// limitations under the License. > + > +package org.apache.tapestry5.internal.services; > + > +import org.apache.tapestry5.services.AssetPathAuthorizer; > + > +import java.util.ArrayList; > +import java.util.Arrays; > +import java.util.Collection; > +import java.util.Collections; > +import java.util.List; > +import java.util.regex.Pattern; > + > +/** > + * Provides a regex-based authorization scheme for asset-access > authorization. > + * Note that this implementation doesn't actually deny access to anything. > + * But it's placement within the chain of command of authorizers is just > before > + * the whitelist authorizer, which has an explicit deny policy. > + * Hence, as long as the whitelist authorizer is being used in conjunction > with > + * the regex authorizer, there is no need to worry about accessDenied in > this authorizer. > + * > + */ > +public class RegexAuthorizer implements AssetPathAuthorizer > +{ > + > + private final Collection<Pattern> _regexes; > + > + public RegexAuthorizer(final Collection<String> regex) > + { > + //an alternate way to construct this would be to make sure that > each pattern is grouped > + //and then to regex or the various patterns together into a single > pattern. > + //that might be faster, but probably not enough to make a > difference, and this is cleaner. > + List<Pattern> tmp = new ArrayList<Pattern>(); > + for(String exp : regex) > + { > + tmp.add(Pattern.compile(exp)); > + } > + _regexes = Collections.unmodifiableCollection(tmp); > + > + } > + > + public boolean accessAllowed(String resourcePath) > + { > + for(Pattern regex : _regexes) > + { > + if (regex.matcher(resourcePath).matches()) > + { > + return true; > + } > + } > + return false; > + } > + > + public boolean accessDenied(String resourcePath) > + { > + return false; > + } > + > + public List<Order> order() > + { > + return Arrays.asList(Order.ALLOW); > + } > + > +} > > Added: > tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/WhitelistAuthorizer.java > URL: > http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/WhitelistAuthorizer.java?rev=834151&view=auto > > ============================================================================== > --- > tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/WhitelistAuthorizer.java > (added) > +++ > tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/WhitelistAuthorizer.java > Mon Nov 9 17:23:10 2009 > @@ -0,0 +1,59 @@ > +// Copyright 2009 The Apache Software Foundation > +// > +// Licensed under the Apache License, Version 2.0 (the "License"); > +// you may not use this file except in compliance with the License. > +// You may obtain a copy of the License at > +// > +// http://www.apache.org/licenses/LICENSE-2.0 > +// > +// Unless required by applicable law or agreed to in writing, software > +// distributed under the License is distributed on an "AS IS" BASIS, > +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or > implied. > +// See the License for the specific language governing permissions and > +// limitations under the License. > + > +package org.apache.tapestry5.internal.services; > + > +import org.apache.tapestry5.services.AssetPathAuthorizer; > + > +import java.util.Arrays; > +import java.util.Collection; > +import java.util.List; > +import java.util.Map; > +import java.util.concurrent.ConcurrentHashMap; > + > +/** > + * AssetPathAuthorizer that determines access rights based on exact > matching to a contributed whitelist. > + * Any resource not explicitly specified in the whitelist is denied > access. > + */ > +public class WhitelistAuthorizer implements AssetPathAuthorizer > +{ > + > + public List<Order> order() > + { > + return Arrays.asList(Order.ALLOW, Order.DENY); > + } > + > + //hash the resource paths for fast lookups. > + private final Map<String, Boolean> _paths; > + > + public WhitelistAuthorizer(Collection<String> paths) > + { > + _paths = new ConcurrentHashMap<String, Boolean>(); > + for(String path : paths) > + { > + _paths.put(path, true); > + } > + } > + > + public boolean accessAllowed(String resourcePath) > + { > + return (_paths.containsKey(resourcePath)); > + } > + > + public boolean accessDenied(String resourcePath) > + { > + return !_paths.containsKey(resourcePath); > + } > + > +} > > Added: > tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/AssetPathAuthorizer.java > URL: > http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/AssetPathAuthorizer.java?rev=834151&view=auto > > ============================================================================== > --- > tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/AssetPathAuthorizer.java > (added) > +++ > tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/AssetPathAuthorizer.java > Mon Nov 9 17:23:10 2009 > @@ -0,0 +1,76 @@ > +// Copyright 2009 The Apache Software Foundation > +// > +// Licensed under the Apache License, Version 2.0 (the "License"); > +// you may not use this file except in compliance with the License. > +// You may obtain a copy of the License at > +// > +// http://www.apache.org/licenses/LICENSE-2.0 > +// > +// Unless required by applicable law or agreed to in writing, software > +// distributed under the License is distributed on an "AS IS" BASIS, > +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or > implied. > +// See the License for the specific language governing permissions and > +// limitations under the License. > + > +package org.apache.tapestry5.services; > + > +import java.util.List; > + > +/** > + * Determines whether access to an asset is allowed, denied, or > undetermined. > + * Each contributed authorizer makes up part of a chain of command for > determining access. > + * Access is explicitly allowed if accessAllowed returns true. > + * Access is explicitly denied if accessDenied returns true. > + * Ordering depends on the order specified by the "order" parameter. > + * Hence, an implementation which specifies an order of: > + * ALLOW, DENY, and returns true from both accessAllowed and accessDenied > + * will allow access for all resources. With the same return values for > the > + * access* methods but the order switched to DENY, ALLOW, access to all > resources > + * would be denied. It is possible for an authorizer to have "nothing > + * to say" regarding a particular resource. If accessAllowed returns > false, > + * it does not mean that access is denied, merely that it is not > explicitly allowed. > + * If accessDenied returns false, it does not mean that access is allowed, > merely that > + * it is not explicitly denied. Hence, if both accessAllowed and > accessDenied return false, > + * control will pass to the next authorizer in the chain. > + * > + */ > +public interface AssetPathAuthorizer > +{ > + > + /** > + * Types of orderings, either ALLOW or DENY. > + */ > + enum Order {ALLOW, DENY;} > + > + /** > + * Specify the ordering for this authorizer. > + * @return the operations for this authorizer. > + * Operations will be performed in the order returned by the iterator. > + * It is assumed that the authorizer correctly implements each form of > + * ordering returned. It is acceptable to only return only ALLOW or > DENY. > + */ > + List<Order> order(); > + > + /** > + * Determines whether a request to "resourcePath" is allowed. > + * @param resourcePath > + * @return true if access is explicitly allowed for the path. False > otherwise. > + * For example, a whitelist implementation would return true if the > resource > + * was listed, and false otherwise. A blacklist implementation would > return > + * false regardless of whether the path was in the blacklist. > + * Alternatively, if the blacklist specified an order of DENY, ALLOW, > it could > + * return true from accessAllowed if the resource was not explicitly > listed in its > + * blacklist. > + */ > + boolean accessAllowed(String resourcePath); > + > + /** > + * > + * @param resourcePath > + * @return true if access is explicitly prohibited for the path. False > otherwise. > + * For example, a whitelist implementation would return true if the > resource was > + * not explicitly listed, and false otherwise. A blacklist > implementation would > + * return true if the resource was explicitly denied, and false > otherwise. > + */ > + boolean accessDenied(String resourcePath); > +} > > Modified: > tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java > URL: > http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java?rev=834151&r1=834150&r2=834151&view=diff > > ============================================================================== > --- > tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java > (original) > +++ > tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java > Mon Nov 9 17:23:10 2009 > @@ -305,6 +305,9 @@ > binder.bind(PageRenderLinkSource.class, > PageRenderLinkSourceImpl.class); > binder.bind(ClientInfrastructure.class, > ClientInfrastructureImpl.class); > binder.bind(URLRewriter.class, URLRewriterImpl.class); > + binder.bind(Dispatcher.class, > AssetProtectionDispatcher.class).withId("AssetProtectionDispatcher"); > + binder.bind(AssetPathAuthorizer.class, > WhitelistAuthorizer.class).withId("WhitelistAuthorizer"); > + binder.bind(AssetPathAuthorizer.class, > RegexAuthorizer.class).withId("RegexAuthorizer"); > } > > // > ======================================================================== > @@ -1572,13 +1575,17 @@ > * and forwards onto {...@link PageRenderRequestHandler}</dd> > <dt>ComponentEvent</dt> <dd>Identifies the {...@link > * ComponentEventRequestParameters} and forwards onto the {...@link > ComponentEventRequestHandler}</dd> </dl> > */ > - public static void > contributeMasterDispatcher(OrderedConfiguration<Dispatcher> configuration) > + public static void > contributeMasterDispatcher(OrderedConfiguration<Dispatcher> configuration, > + > @InjectService("AssetProtectionDispatcher") Dispatcher assetProt) > { > // Looks for the root path and renders the start page. This is > maintained for compatibility > // with earlier versions of Tapestry 5, it is recommended that an > Index page be used instead. > > configuration.addInstance("RootPath", RootPathDispatcher.class, > "before:Asset"); > > + //this goes before asset to make sure that only allowed assets are > streamed to the client. > + configuration.add("AssetProtection", assetProt, "before:Asset"); > + > // This goes first because an asset to be streamed may have an file > extension, such as > // ".html", that will confuse the later dispatchers. > > @@ -1591,6 +1598,7 @@ > configuration.addInstance("PageRender", > PageRenderDispatcher.class); > } > > + > /** > * Contributes a default object renderer for type Object, plus > specialized renderers for {...@link > * org.apache.tapestry5.services.Request}, {...@link > org.apache.tapestry5.ioc.Location}, {...@link > @@ -2480,4 +2488,41 @@ > }; > } > > + /** > + * Contributes the default set of AssetPathAuthorizers into the > AssetProtectionDispatcher. > + * @param whitelist authorization based on explicit whitelisting. > + * @param regex authorization based on pattern matching. > + * @param conf > + */ > + public static void contributeAssetProtectionDispatcher( > + @InjectService("WhitelistAuthorizer") AssetPathAuthorizer > whitelist, > + @InjectService("RegexAuthorizer") AssetPathAuthorizer regex, > + OrderedConfiguration<AssetPathAuthorizer> conf) > + { > + //putting whitelist after everything ensures that, in fact, > nothing falls through. > + //also ensures that whitelist gives other authorizers the chance > to act... > + conf.add("regex",regex,"before:whitelist"); > + conf.add("whitelist", whitelist,"after:*"); > + } > + > + public void contributeRegexAuthorizer(Configuration<String> regex, > + @Symbol("tapestry.scriptaculous.path") String scriptPath, > + @Symbol("tapestry.blackbird.path") String blackbirdPath, > + @Symbol("tapestry.datepicker.path") String datepickerPath) > + { > + //allow any js, jpg, jpeg, png, or css under > org/chenillekit/tapstry. The funky bit of ([^/.]+/)* is what allows > + //multiple paths, while not allowing any of those paths to > contains ./ or ../ thereby preventing paths like: > + //org/chenillekit/tapestry/../../../foo.js > + String pathPattern = > "([^/.]+/)*[^/.]+\\.((css)|(js)|(jpg)|(jpeg)|(png)|(gif))$"; > + regex.add("^org/chenillekit/tapestry/" + pathPattern); > + > + regex.add("^org/apache/tapestry5/" + pathPattern); > + > + regex.add(blackbirdPath + "/" + pathPattern); > + regex.add(datepickerPath + "/" + pathPattern); > + regex.add(scriptPath + "/" + pathPattern); > + //allow access to virtual assets. Critical for tapestry-combined > js files. > + regex.add("virtual/" + pathPattern); > + } > + > } > > Modified: > tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/AppModule.java > URL: > http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/AppModule.java?rev=834151&r1=834150&r2=834151&view=diff > > ============================================================================== > --- > tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/AppModule.java > (original) > +++ > tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/AppModule.java > Mon Nov 9 17:23:10 2009 > @@ -257,4 +257,22 @@ > { > configuration.add("ReverseStringsWorker", new > ReverseStringsWorker()); > } > + > + public static void contributeRegexAuthorizer(Configuration<String> > configuration) { > + //use this rather than a blanket regex (^.*.jpg$, etc.); want to > be sure that tests pass from the default > + //configuration setup, (eg: this way, I realized that the > "virtual" assets folder > + //needed to be opened up in the tapestry-provided contributions) > rather than from some blanket configuration in the appmodule > + //opening up all css, js, etc. files. > + //would contribute to whitelist except that the resource path > between ctxt and the rest of the path can change. > + configuration.add("^ctx/[^/]+/css/app\\.css$"); > + configuration.add("^ctx/[^/]+/layout/style\\.css$"); > + configuration.add("^ctx/[^/]+/layout/images/bg\\.gif$"); > + configuration.add("^ctx/[^/]+/layout/images/header\\.gif$"); > + configuration.add("^ctx/[^/]+/layout/images/rightsmall\\.gif$"); > + configuration.add("^ctx/[^/]+/layout/images/rightbig\\.gif$"); > + configuration.add("^ctx/[^/]+/layout/images/bottom\\.gif$"); > + configuration.add("^ctx/[^/]+/layout/images/footer\\.gif$"); > + configuration.add("^ctx/[^/]+/images/tapestry_banner\\.gif$"); > + configuration.add("^ctx/[^/]+/images/asf_logo_wide\\.gif$"); > + } > } > > Added: > tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/AssetProtectionDispatcherTest.java > URL: > http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/AssetProtectionDispatcherTest.java?rev=834151&view=auto > > ============================================================================== > --- > tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/AssetProtectionDispatcherTest.java > (added) > +++ > tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/AssetProtectionDispatcherTest.java > Mon Nov 9 17:23:10 2009 > @@ -0,0 +1,92 @@ > +// Copyright 2009 The Apache Software Foundation > +// > +// Licensed under the Apache License, Version 2.0 (the "License"); > +// you may not use this file except in compliance with the License. > +// You may obtain a copy of the License at > +// > +// http://www.apache.org/licenses/LICENSE-2.0 > +// > +// Unless required by applicable law or agreed to in writing, software > +// distributed under the License is distributed on an "AS IS" BASIS, > +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or > implied. > +// See the License for the specific language governing permissions and > +// limitations under the License. > + > +package org.apache.tapestry5.internal.services; > + > +import static org.easymock.EasyMock.createMock; > +import static org.easymock.EasyMock.expect; > +import static org.easymock.EasyMock.*; > + > +import java.io.IOException; > +import java.util.ArrayList; > +import java.util.Arrays; > +import java.util.Collections; > +import java.util.List; > + > +import javax.servlet.http.HttpServletResponse; > + > +import org.apache.tapestry5.internal.services.RequestConstants; > +import org.apache.tapestry5.internal.services.AssetProtectionDispatcher; > +import org.apache.tapestry5.services.ClasspathAssetAliasManager; > +import org.apache.tapestry5.services.Request; > +import org.apache.tapestry5.services.Response; > +import org.apache.tapestry5.services.AssetPathAuthorizer; > +import org.testng.Assert; > +import org.testng.annotations.Test; > +import org.slf4j.Logger; > + > +public class AssetProtectionDispatcherTest extends Assert > +{ > + > + @Test > + public void ignores_nonassets() throws IOException > + { > + //shouldn't need any configuration here... > + List<AssetPathAuthorizer> auths = Collections.emptyList(); > + Logger logger = createMock(Logger.class); > + AssetProtectionDispatcher disp = new > AssetProtectionDispatcher(auths,null,logger); > + Request request = createMock(Request.class); > + expect(request.getPath()).andReturn("start"); > + Response response = createMock(Response.class); > + replay(request,response,logger); > + assertFalse(disp.dispatch(request, response)); > + verify(request,response,logger); > + } > + > + @Test > + public void checks_authorizers() throws IOException > + { > + Logger logger = createMock(Logger.class); > + List<AssetPathAuthorizer> auths = new > ArrayList<AssetPathAuthorizer>(); > + AssetPathAuthorizer auth = createMock(AssetPathAuthorizer.class); > + > + > expect(auth.order()).andReturn(Arrays.asList(AssetPathAuthorizer.Order.ALLOW, > AssetPathAuthorizer.Order.DENY)).times(2); > + > + expect(auth.accessAllowed("/cayenne.xml")).andReturn(false); > + expect(auth.accessDenied("/cayenne.xml")).andReturn(true); > + > > expect(auth.accessAllowed("/org/apache/tapestry/default.css")).andReturn(true); > + auths.add(auth); > + > + logger.debug("Denying access to /cayenne.xml"); > + logger.debug("Allowing access to > /org/apache/tapestry/default.css"); > + > + Request request = createMock(Request.class); > + Response response = createMock(Response.class); > + > expect(request.getPath()).andReturn(RequestConstants.ASSET_PATH_PREFIX + > "/cayenne.xml"); > + > expect(request.getPath()).andReturn(RequestConstants.ASSET_PATH_PREFIX + > "/org/apache/tapestry/default.css"); > + response.sendError(HttpServletResponse.SC_FORBIDDEN, > "/cayenne.xml"); > + > + ClasspathAssetAliasManager manager = > createMock(ClasspathAssetAliasManager.class); > + expect(manager.toResourcePath(RequestConstants.ASSET_PATH_PREFIX + > "/cayenne.xml")).andReturn("/cayenne.xml"); > + expect(manager.toResourcePath( > + RequestConstants.ASSET_PATH_PREFIX + > "/org/apache/tapestry/default.css")) > + .andReturn("/org/apache/tapestry/default.css"); > + replay(auth,request,response,manager,logger); > + AssetProtectionDispatcher disp = new > AssetProtectionDispatcher(auths,manager,logger); > + > + assertTrue(disp.dispatch(request,response)); > + assertFalse(disp.dispatch(request, response)); > + verify(auth,request,response,logger); > + } > +} > > Added: > tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/RegexAuthorizerTest.java > URL: > http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/RegexAuthorizerTest.java?rev=834151&view=auto > > ============================================================================== > --- > tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/RegexAuthorizerTest.java > (added) > +++ > tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/RegexAuthorizerTest.java > Mon Nov 9 17:23:10 2009 > @@ -0,0 +1,53 @@ > +// Copyright 2009 The Apache Software Foundation > +// > +// Licensed under the Apache License, Version 2.0 (the "License"); > +// you may not use this file except in compliance with the License. > +// You may obtain a copy of the License at > +// > +// http://www.apache.org/licenses/LICENSE-2.0 > +// > +// Unless required by applicable law or agreed to in writing, software > +// distributed under the License is distributed on an "AS IS" BASIS, > +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or > implied. > +// See the License for the specific language governing permissions and > +// limitations under the License. > + > +package org.apache.tapestry5.internal.services; > + > +import java.util.Arrays; > +import java.util.List; > + > +import org.testng.Assert; > +import org.testng.annotations.Test; > +import org.apache.tapestry5.internal.services.RegexAuthorizer; > + > +public class RegexAuthorizerTest extends Assert > +{ > + > + @Test > + public void test_regexes() > + { > + List<String> patterns = > Arrays.asList("^.*\\.png$","^.*\\.jpg","^.*\\.jpeg"); > + RegexAuthorizer auth = new RegexAuthorizer(patterns); > + String pkg = "assets/com/saiwaisolutions/resources/"; > + String png = pkg + "foo.png"; > + String jpg = pkg + "foo.jpg"; > + String jpeg = pkg + "foo.jpeg"; > + String xml = pkg + "foo.xml"; > + test(auth,png,true); > + test(auth,jpg,true); > + test(auth,jpeg,true); > + test(auth,xml,false); > + } > + > + private static void test(RegexAuthorizer auth, String one,boolean > allowed) > + { > + assertEquals(auth.accessAllowed(one),allowed); > + assertEquals( > + auth.accessAllowed( > + "http://localhost:8080" + one), > + allowed); > + assertFalse(auth.accessDenied(one)); > + assertFalse(auth.accessDenied("http://localhost:8080" + one)); > + } > +} > > Added: > tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/WhitelistAuthorizerTest.java > URL: > http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/WhitelistAuthorizerTest.java?rev=834151&view=auto > > ============================================================================== > --- > tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/WhitelistAuthorizerTest.java > (added) > +++ > tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/WhitelistAuthorizerTest.java > Mon Nov 9 17:23:10 2009 > @@ -0,0 +1,45 @@ > +// Copyright 2009 The Apache Software Foundation > +// > +// Licensed under the Apache License, Version 2.0 (the "License"); > +// you may not use this file except in compliance with the License. > +// You may obtain a copy of the License at > +// > +// http://www.apache.org/licenses/LICENSE-2.0 > +// > +// Unless required by applicable law or agreed to in writing, software > +// distributed under the License is distributed on an "AS IS" BASIS, > +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or > implied. > +// See the License for the specific language governing permissions and > +// limitations under the License. > + > +/* > + * Created on Jul 28, 2007 > + * > + * > + */ > +package org.apache.tapestry5.internal.services; > + > +import java.util.Arrays; > + > +import org.testng.Assert; > +import org.testng.annotations.Test; > +import org.apache.tapestry5.internal.services.WhitelistAuthorizer; > +import org.apache.tapestry5.services.AssetPathAuthorizer; > + > +public class WhitelistAuthorizerTest extends Assert { > + > + @Test > + public void run() > + { > + WhitelistAuthorizer auth = new > WhitelistAuthorizer(Arrays.asList("foo")); > + assertEquals(auth.order().get(0), > AssetPathAuthorizer.Order.ALLOW); > + assertEquals(auth.order().get(1), AssetPathAuthorizer.Order.DENY); > + assertEquals(auth.order().size(),2); > + assertTrue(auth.accessAllowed("foo")); > + assertFalse(auth.accessDenied("foo")); > + > + assertFalse(auth.accessAllowed("bar")); > + assertTrue(auth.accessDenied("bar")); > + } > + > +} > > > -- Best regards, Igor Drobiazko
