Release notes + maven site.

On Mon, Nov 23, 2009 at 8:53 PM, Ulrich Stärk <[email protected]> wrote:

> This will break all applications using chenillekit until the chenillekit
> devs update their code and should be visibly documented somewhere.
>
> Uli
>
> Howard Lewis Ship schrieb:
>
>  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
>>>
>>>
>>
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]
>
>


-- 
Best regards,

Igor Drobiazko

Reply via email to