Good catch, and I agree. On Mon, Nov 23, 2009 at 10:07 AM, Igor Drobiazko <[email protected]> wrote: > 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 >
-- Howard M. Lewis Ship Creator of Apache Tapestry The source for Tapestry training, mentoring and support. Contact me to learn how I can get you up and productive in Tapestry fast! (971) 678-5210 http://howardlewisship.com --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
