svn commit: r666713 - in /lenya/trunk/src: java/org/apache/lenya/cms/cocoon/source/ modules-core/usecase/java/src/org/apache/lenya/cms/ac/usecase/impl/

[email protected]
Newsgroups gmane.comp.cms.lenya.cvs
Message-ID <[email protected]>
Author: andreas
Date: Wed Jun 11 08:41:31 2008
New Revision: 666713

URL: http://svn.apache.org/viewvc?rev=666713&view=rev
Log:
Unify handling of fallback URIs, use URIs containing publication IDs for usecase policy file resolving (fixes bug 44604).

Added:
    lenya/trunk/src/java/org/apache/lenya/cms/cocoon/source/FallbackUri.java
Modified:
    lenya/trunk/src/java/org/apache/lenya/cms/cocoon/source/AggregatingFallbackSourceFactory.java
    lenya/trunk/src/java/org/apache/lenya/cms/cocoon/source/FallbackSourceFactory.java
    lenya/trunk/src/modules-core/usecase/java/src/org/apache/lenya/cms/ac/usecase/impl/UsecaseAuthorizerImpl.java

Modified: lenya/trunk/src/java/org/apache/lenya/cms/cocoon/source/AggregatingFallbackSourceFactory.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/java/org/apache/lenya/cms/cocoon/source/AggregatingFallbackSourceFactory.java?rev=666713&r1=666712&r2=666713&view=diff
==============================================================================
--- lenya/trunk/src/java/org/apache/lenya/cms/cocoon/source/AggregatingFallbackSourceFactory.java (original)
+++ lenya/trunk/src/java/org/apache/lenya/cms/cocoon/source/AggregatingFallbackSourceFactory.java Wed Jun 11 08:41:31 2008
@@ -91,34 +91,10 @@
 
     protected String[] findUris(final String location, Map parameters) throws IOException,
             MalformedURLException {
-
-        // Remove the protocol and the first '//'
-        int pos = location.indexOf("://");
-
-        if (pos == -1) {
-            throw new RuntimeException("The location [" + location
-                    + "] does not contain the string '://'");
-        }
-
-        String path = location.substring(pos + 3);
-        String publicationId = null;
-
-        // allow for template-fallback://{pubid}//{path} for the sake of the
-        // cocoon use-store
-        if (path.indexOf("//") > 1) {
-            pos = path.indexOf("//");
-            publicationId = path.substring(0, pos);
-            path = path.substring(pos + 2, path.length());
-        }
-
-        if (path.length() == 0) {
-            throw new RuntimeException("The path after the protocol must not be empty!");
-        }
-
-        if (getLogger().isDebugEnabled()) {
-            getLogger().debug("Location:     [" + location + "]");
-            getLogger().debug("Path:         [" + path + "]");
-        }
+        
+        FallbackUri uri = new FallbackUri(location);
+        String pubId = uri.getPubId();
+        String path = uri.getPath();
 
         PublicationTemplateManager templateManager = null;
         try {
@@ -127,18 +103,18 @@
 
             Request request = ContextHelper.getRequest(this.context);
 
-            if (publicationId == null) {
+            if (pubId == null) {
                 String webappUrl = ServletHelper.getWebappURI(request);
                 URLInformation info = new URLInformation(webappUrl);
-                publicationId = info.getPublicationId();
+                pubId = info.getPublicationId();
             }
 
             DocumentFactory factory = DocumentUtil.getDocumentFactory(this.manager, request);
 
             String[] uris;
 
-            if (factory.existsPublication(publicationId)) {
-                Publication pub = factory.getPublication(publicationId);
+            if (factory.existsPublication(pubId)) {
+                Publication pub = factory.getPublication(pubId);
                 AllExistingSourceResolver resolver = new AllExistingSourceResolver();
                 templateManager.visit(pub, path, resolver);
                 uris = resolver.getUris();

Modified: lenya/trunk/src/java/org/apache/lenya/cms/cocoon/source/FallbackSourceFactory.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/java/org/apache/lenya/cms/cocoon/source/FallbackSourceFactory.java?rev=666713&r1=666712&r2=666713&view=diff
==============================================================================
--- lenya/trunk/src/java/org/apache/lenya/cms/cocoon/source/FallbackSourceFactory.java (original)
+++ lenya/trunk/src/java/org/apache/lenya/cms/cocoon/source/FallbackSourceFactory.java Wed Jun 11 08:41:31 2008
@@ -20,7 +20,6 @@
 import java.io.IOException;
 import java.net.MalformedURLException;
 import java.util.Map;
-import java.util.StringTokenizer;
 
 import org.apache.avalon.framework.context.ContextException;
 import org.apache.avalon.framework.context.Contextualizable;
@@ -160,44 +159,14 @@
         }
         return pubId;
     }
-
+    
     protected Source findSource(final String location, Map parameters) throws IOException,
             MalformedURLException {
+        
+        FallbackUri uri = new FallbackUri(location);
 
-        // Remove the protocol and the first '//'
-        int pos = location.indexOf("://");
-
-        if (pos == -1) {
-            throw new RuntimeException("The location [" + location
-                    + "] does not contain the string '://'");
-        }
-
-        String path = location.substring(pos + 3);
-
-        String publicationId = null;
-
-        // extract publication ID
-        String prefix = location.substring(0, pos);
-        StringTokenizer tokens = new StringTokenizer(prefix, ":");
-        if (tokens.countTokens() > 1) {
-            tokens.nextToken();
-            publicationId = tokens.nextToken();
-        }
-
-        // remove query string
-        int questionMarkIndex = path.indexOf("?");
-        if (questionMarkIndex > -1) {
-            path = path.substring(0, questionMarkIndex);
-        }
-
-        if (path.length() == 0) {
-            throw new RuntimeException("The path after the protocol must not be empty!");
-        }
-
-        if (getLogger().isDebugEnabled()) {
-            getLogger().debug("Location:     [" + location + "]");
-            getLogger().debug("Path:         [" + path + "]");
-        }
+        String pubId = uri.getPubId();
+        String path = uri.getPath();
 
         PublicationTemplateManager templateManager = null;
         SourceResolver sourceResolver = null;
@@ -210,17 +179,17 @@
 
             Request request = ContextHelper.getRequest(this.context);
 
-            if (publicationId == null) {
+            if (pubId == null) {
                 String webappUrl = request.getRequestURI().substring(
                         request.getContextPath().length());
 
                 URLInformation info = new URLInformation(webappUrl);
-                publicationId = info.getPublicationId();
+                pubId = info.getPublicationId();
             }
 
             DocumentFactory factory = DocumentUtil.getDocumentFactory(this.manager, request);
-            if (factory.existsPublication(publicationId)) {
-                Publication pub = factory.getPublication(publicationId);
+            if (factory.existsPublication(pubId)) {
+                Publication pub = factory.getPublication(pubId);
                 VisitingSourceResolver resolver = getSourceVisitor();
                 templateManager.visit(pub, path, resolver);
                 source = resolver.getSource();

Added: lenya/trunk/src/java/org/apache/lenya/cms/cocoon/source/FallbackUri.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/java/org/apache/lenya/cms/cocoon/source/FallbackUri.java?rev=666713&view=auto
==============================================================================
--- lenya/trunk/src/java/org/apache/lenya/cms/cocoon/source/FallbackUri.java (added)
+++ lenya/trunk/src/java/org/apache/lenya/cms/cocoon/source/FallbackUri.java Wed Jun 11 08:41:31 2008
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You 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.lenya.cms.cocoon.source;
+
+import java.net.MalformedURLException;
+import java.util.StringTokenizer;
+
+public class FallbackUri {
+    
+    private String uri;
+    private String pubId;
+    private String path;
+    private String queryString;
+    
+    public FallbackUri(String uri) throws MalformedURLException {
+        
+        this.uri = uri;
+        
+        // Remove the protocol and the first '//'
+        int pos = uri.indexOf("://");
+
+        if (pos == -1) {
+            throw new MalformedURLException("The URI [" + uri
+                    + "] does not contain the string '://'");
+        }
+
+        String path = uri.substring(pos + 3);
+
+        // extract publication ID
+        String prefix = uri.substring(0, pos);
+        StringTokenizer tokens = new StringTokenizer(prefix, ":");
+        if (tokens.countTokens() > 1) {
+            tokens.nextToken();
+            this.pubId = tokens.nextToken();
+        }
+
+        // remove query string
+        int questionMarkIndex = path.indexOf("?");
+        if (questionMarkIndex > -1) {
+            this.queryString = path.substring(questionMarkIndex);
+            path = path.substring(0, questionMarkIndex);
+        }
+
+        if (path.length() == 0) {
+            throw new MalformedURLException("The path after the protocol must not be empty!");
+        }
+        
+        this.path = path;
+    }
+    
+    public String getPubId() {
+        return this.pubId;
+    }
+    
+    public String getPath() {
+        return this.path;
+    }
+    
+    public String getQeryString() {
+        return this.queryString;
+    }
+    
+    public String getUri() {
+        return this.uri;
+    }
+}

Modified: lenya/trunk/src/modules-core/usecase/java/src/org/apache/lenya/cms/ac/usecase/impl/UsecaseAuthorizerImpl.java
URL: http://svn.apache.org/viewvc/lenya/trunk/src/modules-core/usecase/java/src/org/apache/lenya/cms/ac/usecase/impl/UsecaseAuthorizerImpl.java?rev=666713&r1=666712&r2=666713&view=diff
==============================================================================
--- lenya/trunk/src/modules-core/usecase/java/src/org/apache/lenya/cms/ac/usecase/impl/UsecaseAuthorizerImpl.java (original)
+++ lenya/trunk/src/modules-core/usecase/java/src/org/apache/lenya/cms/ac/usecase/impl/UsecaseAuthorizerImpl.java Wed Jun 11 08:41:31 2008
@@ -18,15 +18,10 @@
 
 package org.apache.lenya.cms.ac.usecase.impl;
 
-import java.io.File;
 import java.util.Arrays;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 
 import org.apache.avalon.framework.activity.Disposable;
-import org.apache.avalon.framework.configuration.Configuration;
-import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
 import org.apache.avalon.framework.logger.AbstractLogEnabled;
 import org.apache.avalon.framework.parameters.ParameterException;
 import org.apache.avalon.framework.parameters.Parameterizable;
@@ -43,8 +38,8 @@
 import org.apache.lenya.cms.ac.PolicyUtil;
 import org.apache.lenya.cms.ac.usecase.UsecaseAuthorizer;
 import org.apache.lenya.cms.publication.Publication;
-import org.apache.lenya.cms.publication.PublicationException;
-import org.apache.lenya.cms.publication.PublicationUtil;
+import org.apache.lenya.cms.publication.URLInformation;
+import org.apache.lenya.util.ServletHelper;
 
 /**
  * Authorizer for usecases.
@@ -66,10 +61,7 @@
     public static final String VISIT_USECASE = "ac.visit";
 
     protected static final String PARAMETER_CONFIGURATION = "configuration";
-    protected static final String TYPE = "usecase";
     protected static final String USECASE_PARAMETER = "lenya.usecase";
-    private static final String AC_CONFIGURATION_FILE = "config/access-control/access-control.xml"
-            .replace('/', File.separatorChar);
 
     private SourceCache cache;
     /**
@@ -79,22 +71,13 @@
     private ServiceManager manager;
 
     /**
-     * Maps publication IDs to their configuration URIs. This is a persistent
-     * map to avoid unnecessary publication lookups. Whenever an authorization
-     * request for a new publication is dealt with, the publication's
-     * configuration URI is stored, to be re-used on later occasions (for the
-     * lifetime of the component).
-     */
-    private Map pubId2configUri = new HashMap();
-
-    /**
      * @see org.apache.lenya.cms.ac.usecase.UsecaseAuthorizer#authorizeUsecase(java.lang.String,
      *      org.apache.lenya.ac.Role[],
      *      org.apache.lenya.cms.publication.Publication)
      */
-    public boolean authorizeUsecase(String usecase, Role[] roles, Publication publication)
+    public boolean authorizeUsecase(String usecase, Role[] roles, Publication pub)
             throws AccessControlException {
-        return authorizeUsecase(usecase, roles, getConfigurationURI(publication));
+        return authorizeUsecase(usecase, roles, getConfigurationUri(pub.getId()));
     }
 
     private boolean authorizeUsecase(String usecase, Role[] roles, String _configurationUri)
@@ -136,7 +119,7 @@
      */
     public boolean isPermitted(String usecase, Publication publication, Role role)
             throws AccessControlException {
-        String configUri = getConfigurationURI(publication);
+        String configUri = getConfigurationUri(publication.getId());
         UsecaseRoles usecaseRoles = getUsecaseRoles(configUri);
         String[] roles = usecaseRoles.getRoles(usecase);
         return Arrays.asList(roles).contains(role.getId());
@@ -149,7 +132,7 @@
      */
     public void setPermission(String usecase, Publication publication, Role role, boolean granted)
             throws AccessControlException {
-        String configUri = getConfigurationURI(publication);
+        String configUri = getConfigurationUri(publication.getId());
         if (configUri.startsWith("aggregate-")) {
             configUri = configUri.substring("aggregate-".length());
         }
@@ -185,28 +168,17 @@
             usecase = VISIT_USECASE;
         }
 
-        boolean authorized = false;
-
-        try {
-            String _configurationUri;
-            // Check if the service has been parameterized with a
-            // configuration URI. This can be used for testing purposes etc.
-            if (getConfigurationURI() != null) {
-                _configurationUri = getConfigurationURI();
-            } else {
-                Publication publication = PublicationUtil.getPublication(this.manager, request);
-                _configurationUri = getConfigurationURI(publication);
-            }
-
-            Role[] roles = PolicyUtil.getRoles(request);
-            authorized = authorizeUsecase(usecase, roles, _configurationUri);
-        } catch (final PublicationException e) {
-            throw new AccessControlException(e);
-        } catch (final AccessControlException e) {
-            throw new AccessControlException(e);
+        String configurationUri = getConfigurationURI();
+        // Check if the service has been parameterized with a
+        // configuration URI. This can be used for testing purposes etc.
+        if (configurationUri == null) {
+            String webappUrl = ServletHelper.getWebappURI(request);
+            URLInformation info = new URLInformation(webappUrl);
+            configurationUri = getConfigurationUri(info.getPublicationId());
         }
 
-        return authorized;
+        Role[] roles = PolicyUtil.getRoles(request);
+        return authorizeUsecase(usecase, roles, configurationUri);
     }
 
     /**
@@ -224,25 +196,8 @@
      * @param publication The publication.
      * @return A string representing a URI.
      */
-    protected String getConfigurationURI(Publication publication) {
-
-        String configURI = (String) this.pubId2configUri.get(publication.getId());
-        if (configURI == null) {
-            try {
-                Configuration config = getConfiguration(publication);
-                Configuration[] authorizerConfigs = config.getChildren("authorizer");
-                for (int i = 0; i < authorizerConfigs.length; i++) {
-                    if (authorizerConfigs[i].getAttribute("type").equals("usecase")) {
-                        Configuration paraConfig = authorizerConfigs[i].getChild("parameter");
-                        configURI = paraConfig.getAttribute("value");
-                        this.pubId2configUri.put(publication.getId(), configURI);
-                    }
-                }
-            } catch (Exception e) {
-                getLogger().error(e.getMessage(), e);
-            }
-        }
-        return configURI;
+    protected String getConfigurationUri(String pubId) {
+        return "aggregate-fallback:" + pubId + "://config/access-control/usecase-policies.xml";
     }
 
     protected UsecaseRoles getUsecaseRoles(String _configurationUri) throws AccessControlException {
@@ -276,7 +231,7 @@
 
     public void parameterize(Parameters parameters) throws ParameterException {
         if (parameters.isParameter(PARAMETER_CONFIGURATION)) {
-            this.configurationUri = parameters.getParameter(PARAMETER_CONFIGURATION);
+            getLogger().warn("Configuring the location of the usecase policies file is not supported anymore.");
         }
     }
 
@@ -284,26 +239,4 @@
         return this.configurationUri;
     }
 
-    /**
-     * Retrieves access control configuration of a specific publication.
-     * @param publication The publication.
-     * @return Configuration
-     * @throws AccessControlException when something went wrong.
-     */
-    private Configuration getConfiguration(Publication publication) throws AccessControlException {
-        File configurationFile = new File(publication.getDirectory(), AC_CONFIGURATION_FILE);
-
-        if (configurationFile.isFile()) {
-            try {
-                Configuration configuration = new DefaultConfigurationBuilder()
-                        .buildFromFile(configurationFile);
-                return configuration;
-            } catch (Exception e) {
-                throw new AccessControlException(e);
-            }
-        } else {
-            throw new AccessControlException("No such file or directory: " + configurationFile);
-        }
-    }
-
 }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.