You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jetspeed-dev@portals.apache.org by dl...@apache.org on 2005/09/24 14:29:43 UTC

svn commit: r291290 [1/2] - in /portals/jetspeed-2/trunk: components/security/ components/security/src/java/org/apache/jetspeed/security/ components/security/src/java/org/apache/jetspeed/security/impl/ components/security/src/java/org/apache/jetspeed/s...

Author: dlestrat
Date: Sat Sep 24 05:29:23 2005
New Revision: 291290

URL: http://svn.apache.org/viewcvs?rev=291290&view=rev
Log:
http://issues.apache.org/jira/browse/JS2-205

Added:
    portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/PolicyWrapper.java
    portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/SecurityPolicies.java
    portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/impl/PermissionManagerImpl.java
    portals/jetspeed-2/trunk/components/security/xdocs/config.xml
Modified:
    portals/jetspeed-2/trunk/components/security/maven.xml
    portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/AuthorizationProvider.java
    portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/SecurityHelper.java
    portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/impl/AuthorizationProviderImpl.java
    portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/impl/BasePrincipalImpl.java
    portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/impl/RdbmsPolicy.java
    portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/util/test/AbstractSecurityTestcase.java
    portals/jetspeed-2/trunk/components/security/src/test/org/apache/jetspeed/security/TestRdbmsPolicy.java
    portals/jetspeed-2/trunk/components/security/xdocs/atz-jaas.xml
    portals/jetspeed-2/trunk/components/security/xdocs/images/arch-overview.gif
    portals/jetspeed-2/trunk/design-docs/src/security/securityArchOverview.vsd
    portals/jetspeed-2/trunk/src/webapp/WEB-INF/assembly/security-providers.xml
    portals/jetspeed-2/trunk/src/webapp/WEB-INF/assembly/userinfo.xml

Modified: portals/jetspeed-2/trunk/components/security/maven.xml
URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/trunk/components/security/maven.xml?rev=291290&r1=291289&r2=291290&view=diff
==============================================================================
--- portals/jetspeed-2/trunk/components/security/maven.xml (original)
+++ portals/jetspeed-2/trunk/components/security/maven.xml Sat Sep 24 05:29:23 2005
@@ -17,6 +17,6 @@
 <project default="java:jar" xmlns:j="jelly:core" xmlns:define="jelly:define" xmlns:maven="jelly:maven">
 
     <!-- Target of maven test:single test -->
-    <property name='testcase' value='org.apache.jetspeed.security.TestAuthenticationProviderProxy' />
+    <property name="testcase" value="org.apache.jetspeed.security.TestRdbmsPolicy" />
     
 </project>

Modified: portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/AuthorizationProvider.java
URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/AuthorizationProvider.java?rev=291290&r1=291289&r2=291290&view=diff
==============================================================================
--- portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/AuthorizationProvider.java (original)
+++ portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/AuthorizationProvider.java Sat Sep 24 05:29:23 2005
@@ -18,7 +18,9 @@
 
 /**
  * <p>
- * Configures the policies.
+ * Configures the policies.  Instantiates the <code>SecurityPolicies</code> with the security policies
+ * that need to be enforced.  It will add the default policy already configured as well as the engine policies
+ * used to enforce permission checks.
  * </p>
  * 
  * @author <a href="mailto:dlestrat@apache.org">David Le Strat </a>
@@ -34,4 +36,13 @@
      */
     List getPolicies();
     
+    
+    /**
+     * <p>
+     * Whether to use the default policy or not in addition to the Policies configured for the AuthorizationProvider.
+     * </p>
+     * 
+     * @param whetherToUseDefaultPolicy Boolean false: does not use the default policy, true: does.
+     */
+    void useDefaultPolicy(boolean whetherToUseDefaultPolicy);
 }

Added: portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/PolicyWrapper.java
URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/PolicyWrapper.java?rev=291290&view=auto
==============================================================================
--- portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/PolicyWrapper.java (added)
+++ portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/PolicyWrapper.java Sat Sep 24 05:29:23 2005
@@ -0,0 +1,88 @@
+package org.apache.jetspeed.security;
+
+import java.io.Serializable;
+import java.security.Policy;
+
+/**
+ * <p>
+ * Simple wrapper for security policy providing the ability to add attribute on Policy and how they
+ * should be used by the application.
+ * </p>
+ * 
+ * @author <a href="mailto:LeStrat_David@emc.com">David Le Strat</a>
+ */
+public class PolicyWrapper implements Serializable
+{
+    /** The serial version uid.  */
+    private static final long serialVersionUID = 3386468724328997598L;
+
+    /** The policy. */
+    private Policy policy;
+
+    /** Whether to use as a policy. */
+    private boolean useAsPolicy = false;
+
+    /** Whether to use as a default policy. */
+    private boolean defaultPolicy = false;
+
+    /**
+     * @param policy
+     * @param useAsPolicy
+     * @param defaultPolicy
+     */
+    public PolicyWrapper(Policy policy, boolean useAsPolicy, boolean defaultPolicy)
+    {
+        this.policy = policy;
+        this.useAsPolicy = useAsPolicy;
+        this.defaultPolicy = defaultPolicy;
+    }
+
+    /**
+     * @return Returns the policy.
+     */
+    public Policy getPolicy()
+    {
+        return this.policy;
+    }
+
+    /**
+     * @param policy The policy to set.
+     */
+    public void setPolicy(Policy policy)
+    {
+        this.policy = policy;
+    }
+
+    /**
+     * @return Returns the defaultPolicy.
+     */
+    public boolean isDefaultPolicy()
+    {
+        return defaultPolicy;
+    }
+
+    /**
+     * @param defaultPolicy The defaultPolicy to set.
+     */
+    public void setDefaultPolicy(boolean defaultPolicy)
+    {
+        this.defaultPolicy = defaultPolicy;
+    }
+
+    /**
+     * @return Returns the useAsPolicy.
+     */
+    public boolean isUseAsPolicy()
+    {
+        return useAsPolicy;
+    }
+
+    /**
+     * @param useAsPolicy The useAsPolicy to set.
+     */
+    public void setUseAsPolicy(boolean useAsPolicy)
+    {
+        this.useAsPolicy = useAsPolicy;
+    }
+
+}

Modified: portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/SecurityHelper.java
URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/SecurityHelper.java?rev=291290&r1=291289&r2=291290&view=diff
==============================================================================
--- portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/SecurityHelper.java (original)
+++ portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/SecurityHelper.java Sat Sep 24 05:29:23 2005
@@ -14,7 +14,10 @@
  */
 package org.apache.jetspeed.security;
 
+import java.security.Permission;
+import java.security.PermissionCollection;
 import java.security.Principal;
+import java.util.Enumeration;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedList;
@@ -23,20 +26,30 @@
 
 import javax.security.auth.Subject;
 
-import org.apache.jetspeed.security.impl.UserPrincipalImpl;
-import org.apache.jetspeed.security.impl.RolePrincipalImpl;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.apache.jetspeed.security.impl.GroupPrincipalImpl;
+import org.apache.jetspeed.security.impl.RolePrincipalImpl;
+import org.apache.jetspeed.security.impl.UserPrincipalImpl;
 
 /**
- * <p>Security helper.</p>
+ * <p>
+ * Security helper.
+ * </p>
+ * 
  * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
  * @version $Id$
  */
 public class SecurityHelper
 {
+    private static final Log log = LogFactory.getLog(SecurityHelper.class);
+
     /**
-     * <p>Given a subject, finds the first principal of the given classe for that subject.
-     * If a principal of the given classe is not found, null is returned.</p>
+     * <p>
+     * Given a subject, finds the first principal of the given classe for that subject. If a
+     * principal of the given classe is not found, null is returned.
+     * </p>
+     * 
      * @param subject The subject supplying the principals.
      * @param classe A class or interface derived from java.security.InternalPrincipal.
      * @return The first principal matching a principal classe parameter.
@@ -58,9 +71,12 @@
     }
 
     /**
-     * <p>Given a subject, finds the first principal of the given classe for that subject.
-     * If a principal of the given classe is not found, then the first
-     * other principal is returned. If the list is empty, null is returned.</p>
+     * <p>
+     * Given a subject, finds the first principal of the given classe for that subject. If a
+     * principal of the given classe is not found, then the first other principal is returned. If
+     * the list is empty, null is returned.
+     * </p>
+     * 
      * @param subject The subject supplying the principals.
      * @param classe A class or interface derived from java.security.InternalPrincipal.
      * @return The first principal matching a principal classe parameter.
@@ -88,10 +104,45 @@
         }
         return principal;
     }
+    
+    /**
+     * <p>
+     * Returns the first matching principal of a given type.
+     * </p>
+     * 
+     * @param principals The array of pricinpals
+     * @param classe The class of Principal
+     * @return The principal.
+     */
+    public static Principal getBestPrincipal(Principal[] principals, Class classe)
+    {
+
+        Principal principal = null;
+        for (int i = 0; i < principals.length; i++)
+        {
+            Principal p = (Principal) principals[i];
+            if (classe.isInstance(p))
+            {
+                principal = p;
+                break;
+            }
+            else
+            {
+                if (principal == null)
+                {
+                    principal = p;
+                }
+            }
+        }
+        return principal;
+    }
 
     /**
-     * <p>Utility method used to retrieve the Preferences API absolute/full
-     * path from a given principal.</p>
+     * <p>
+     * Utility method used to retrieve the Preferences API absolute/full path from a given
+     * principal.
+     * </p>
+     * 
      * @param principal The principal.
      * @return The Preferences absolute/full path.
      */
@@ -117,7 +168,10 @@
     }
 
     /**
-     * <p>Utility method to create a subject.</p>
+     * <p>
+     * Utility method to create a subject.
+     * </p>
+     * 
      * @param principalName The user principal name.
      * @return The subject.
      */
@@ -128,10 +182,13 @@
         principals.add(principal);
         return new Subject(true, principals, new HashSet(), new HashSet());
     }
-    
+
     /**
-     * <p>Given a subject, finds all principals of the given classe for that subject.
-     * If no principals of the given class is not found, null is returned.</p>
+     * <p>
+     * Given a subject, finds all principals of the given classe for that subject. If no principals
+     * of the given class is not found, null is returned.
+     * </p>
+     * 
      * @param subject The subject supplying the principals.
      * @param classe A class or interface derived from java.security.InternalPrincipal.
      * @return A List of all principals of type Principal matching a principal classe parameter.
@@ -150,10 +207,12 @@
         }
         return result;
     }
-    
-    /** 
-     * <p>Given a subject, find the (first) PasswordCredential from the
-     * private credentials</p>
+
+    /**
+     * <p>
+     * Given a subject, find the (first) PasswordCredential from the private credentials
+     * </p>
+     * 
      * @param subject The subject
      * @return the PasswordCredential or null if not found.
      */
@@ -165,9 +224,41 @@
             Object o = iter.next();
             if (o instanceof PasswordCredential)
             {
-                return (PasswordCredential)o;
+                return (PasswordCredential) o;
             }
         }
         return null;
+    }
+
+    /**
+     * <p>
+     * Adds a collection of permsToAdd to a collection of existing permissions.
+     * </p>
+     * 
+     * @param perms The existing permissions.
+     * @param permsToAdd The permissions to add.
+     */
+    public static void addPermissions(PermissionCollection perms, PermissionCollection permsToAdd)
+    {
+        int permsAdded = 0;
+        if (null != permsToAdd)
+        {
+            Enumeration permsToAddEnum = permsToAdd.elements();
+            while (permsToAddEnum.hasMoreElements())
+            {
+                permsAdded++;
+                Permission currPerm = (Permission) permsToAddEnum.nextElement();
+                perms.add(currPerm);
+                if (log.isDebugEnabled())
+                {
+                    log.debug("Adding the permission: [class, " + currPerm.getClass().getName() + "], " + "[name, "
+                            + currPerm.getName() + "], " + "[actions, " + currPerm.getActions() + "]");
+                }
+            }
+        }
+        if ((permsAdded == 0) && log.isDebugEnabled())
+        {
+            log.debug("No permissions to add...");
+        }
     }
 }

Added: portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/SecurityPolicies.java
URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/SecurityPolicies.java?rev=291290&view=auto
==============================================================================
--- portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/SecurityPolicies.java (added)
+++ portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/SecurityPolicies.java Sat Sep 24 05:29:23 2005
@@ -0,0 +1,120 @@
+package org.apache.jetspeed.security;
+
+import java.security.Policy;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * <p>
+ * This class is used to hold the security that will be used when applying security policies. It
+ * uses a singleton pattern to maintain state of the policies configured in the consuming engine.
+ * </p>
+ * 
+ * @author <a href="mailto:dlestrat@apache.org">David Le Strat</a>
+ */
+public class SecurityPolicies
+{
+    /** The singleton instance. */
+    private static SecurityPolicies instance = null;
+
+    /** The list of wrapped policies. */
+    private List wrappedPolicies = new ArrayList();
+
+    /** The list of policies. */
+    private List policies = new ArrayList();
+
+    /** The list of used policies. */
+    private List usedPolicies = new ArrayList();
+
+    /**
+     * Default contructor. Private to force singleton.
+     */
+    private SecurityPolicies()
+    {
+    }
+
+    /**
+     * <p>
+     * Returns the singleton instance for SecurityPolicies.
+     * </p>
+     * 
+     * @return The instance of SecurityPolicies
+     */
+    public static SecurityPolicies getInstance()
+    {
+        if (instance == null)
+        {
+            instance = new SecurityPolicies();
+        }
+        return instance;
+    }
+
+    /**
+     * <p>
+     * Adds a policy to the list of policies to enforces.
+     * </p>
+     * 
+     * @param wrappedPolicy The {@link PolicyWrapper} to add.
+     */
+    public void addPolicy(PolicyWrapper wrappedPolicy)
+    {
+        if (null != wrappedPolicy)
+        {
+            wrappedPolicies.add(wrappedPolicy);
+            policies.add(wrappedPolicy.getPolicy());
+            if (wrappedPolicy.isUseAsPolicy())
+            {
+                usedPolicies.add(wrappedPolicy.getPolicy());
+            }
+        }
+
+    }
+
+    /**
+     * <p>
+     * Returns the security policies to enforce as list of {@link Policy}.
+     * </p>
+     * 
+     * @return The policies.
+     */
+    public List getPolicies()
+    {
+        return policies;
+    }
+
+    /**
+     * <p>
+     * Returns the security policies to be enforced as list of {@link Policy}.
+     * </p>
+     * 
+     * @return The used policies.
+     */
+    public List getUsedPolicies()
+    {
+        return usedPolicies;
+    }
+
+    /**
+     * <p>
+     * Returns the security policies to enforce as list of {@link PolicyWrapper}.
+     * </p>
+     * 
+     * @return The policies.
+     */
+    public List getWrappedPolicies()
+    {
+        return wrappedPolicies;
+    }
+
+    /**
+     * <p>
+     * Removes a policy from the list of policies to enforces.
+     * </p>
+     * 
+     * @param policy The {@link Policy} to add.
+     */
+    public void removePolicy(PolicyWrapper policy)
+    {
+        wrappedPolicies.remove(policy);
+    }
+}

Modified: portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/impl/AuthorizationProviderImpl.java
URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/impl/AuthorizationProviderImpl.java?rev=291290&r1=291289&r2=291290&view=diff
==============================================================================
--- portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/impl/AuthorizationProviderImpl.java (original)
+++ portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/impl/AuthorizationProviderImpl.java Sat Sep 24 05:29:23 2005
@@ -1,50 +1,105 @@
 /* Copyright 2004 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.
-*/
+ *
+ * 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.jetspeed.security.impl;
 
 import java.security.Policy;
-import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.apache.jetspeed.security.AuthorizationProvider;
+import org.apache.jetspeed.security.PolicyWrapper;
+import org.apache.jetspeed.security.SecurityPolicies;
 
 /**
  * @see org.apache.jetspeed.security.AuthorizationProvider
- * @author <a href="mailto:LeStrat_David@emc.com">David Le Strat </a> 
+ * @author <a href="mailto:LeStrat_David@emc.com">David Le Strat </a>
  */
 public class AuthorizationProviderImpl implements AuthorizationProvider
 {
 
-    /** The list of {@link Policy}. */
-    private List policies = new ArrayList();
-    
-    public AuthorizationProviderImpl(Policy policy)
+    private static final Log log = LogFactory.getLog(AuthorizationProviderImpl.class);
+
+    /**
+     * <p>
+     * Constructor for adding another policy to be enforced. This constructor makes the assumption
+     * that the input policy should be used as the primary policy.
+     * </p>
+     * 
+     * @param policy The policy to configure.
+     * @param useDefaultPolicy Whether to also use the default policy.
+     */
+    public AuthorizationProviderImpl(Policy policy, boolean useDefaultPolicy)
     {
-        // The policy.
+        List securityPolicies = SecurityPolicies.getInstance().getPolicies();
+        // Add the default policy to the list of SecurityPolicies.
+        Policy defaultPolicy = Policy.getPolicy();
+        if (!securityPolicies.contains(defaultPolicy))
+        {
+            if (log.isDebugEnabled())
+            {
+                log.debug("Adding default policy to security policies: " + defaultPolicy.getClass().getName());
+            }
+            PolicyWrapper defaultPolicyWrap = new PolicyWrapper(defaultPolicy, useDefaultPolicy, true);
+            SecurityPolicies.getInstance().addPolicy(defaultPolicyWrap);
+        }
+
+        if (!securityPolicies.contains(policy))
+        {
+            if (log.isDebugEnabled())
+            {
+                log.debug("Adding custom policy to security policies: " + policy.getClass().getName());
+            }
+            PolicyWrapper policyWrap = new PolicyWrapper(policy, true, false);
+            SecurityPolicies.getInstance().addPolicy(policyWrap);
+        }
+
+        // Use the primary policy.
+        if (log.isDebugEnabled())
+        {
+            log.debug("Setting current policy: " + policy.getClass().getName());
+        }
         Policy.setPolicy(policy);
         Policy.getPolicy().refresh();
-        
-        policies.add(policy);
     }
-    
+
     /**
      * @see org.apache.jetspeed.security.AuthorizationProvider#getPolicies()
      */
     public List getPolicies()
     {
-        return policies;
+        return SecurityPolicies.getInstance().getPolicies();
     }
-    
+
+    /**
+     * @see org.apache.jetspeed.security.AuthorizationProvider#useDefaultPolicy(boolean)
+     */
+    public void useDefaultPolicy(boolean whetherToUseDefaultPolicy)
+    {
+        List wrappedPolicies = SecurityPolicies.getInstance().getWrappedPolicies();
+        if (whetherToUseDefaultPolicy)
+        {
+            for (int i = 0; i < wrappedPolicies.size(); i++)
+            {
+                PolicyWrapper currWrappedPolicy = (PolicyWrapper) wrappedPolicies.get(i);
+                if (currWrappedPolicy.isDefaultPolicy())
+                {
+                    currWrappedPolicy.setUseAsPolicy(true);
+                }
+            }
+        }
+    }
+
 }

Modified: portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/impl/BasePrincipalImpl.java
URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/impl/BasePrincipalImpl.java?rev=291290&r1=291289&r2=291290&view=diff
==============================================================================
--- portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/impl/BasePrincipalImpl.java (original)
+++ portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/impl/BasePrincipalImpl.java Sat Sep 24 05:29:23 2005
@@ -17,16 +17,29 @@
 import org.apache.jetspeed.security.BasePrincipal;
 
 /**
- * <p>{@link BasePrincipal} interface implementation.</p>
+ * <p>
+ * {@link BasePrincipal} interface implementation.
+ * </p>
+ * 
  * @author <a href="mailto:dlestrat@apache.org">David Le Strat</a>
  */
 public class BasePrincipalImpl implements BasePrincipal
 {
+    
+    /** The version uid. */
+    private static final long serialVersionUID = 5687385387290144541L;
+
+    /** The principal name. */
     private final String name;
+
+    /** The full path. */
     private final String fullPath;
 
     /**
-     * <p>Principal constructor given a name and preferences root.</p>
+     * <p>
+     * Principal constructor given a name and preferences root.
+     * </p>
+     * 
      * @param name The principal name.
      * @param prefsRoot The preferences root node.
      */
@@ -59,9 +72,12 @@
     {
         return this.name.hashCode();
     }
-    
+
     /**
-     * <p>Returns a string representation of this principal.</p>
+     * <p>
+     * Returns a string representation of this principal.
+     * </p>
+     * 
      * @return A string representation of this principal.
      */
     public String toString()
@@ -70,10 +86,17 @@
     }
 
     /**
-     * <p>Gets the principal implementation full path from the principal name.</p>
-     * <p>Hierarchical principal names should follow: {principal}.{subprincipal}.
-     * "." is used as the separator for hierarchical elements.</p>
-     * <p>The implementation path follow /PREFS_{PRINCIPAL}_ROOT/{principal}/{subprincipal}.</p>        
+     * <p>
+     * Gets the principal implementation full path from the principal name.
+     * </p>
+     * <p>
+     * Hierarchical principal names should follow: {principal}.{subprincipal}. "." is used as the
+     * separator for hierarchical elements.
+     * </p>
+     * <p>
+     * The implementation path follow /PREFS_{PRINCIPAL}_ROOT/{principal}/{subprincipal}.
+     * </p>
+     * 
      * @param name The principal name.
      * @param prefsRoot The preferences root node.
      * @return The preferences full path / principal name.
@@ -89,10 +112,17 @@
     }
 
     /**
-     * <p>Gets the principal name from the principal implementation full path.</p>
-     * <p>Hierarchical principal names should follow: {principal}.{subprincipal}.
-     * "." is used as the separator for hierarchical elements.</p>
-     * <p>The implementation path follow /PREFS_{PRINCIPAL}_ROOT/{principal}/{subprincipal}.</p>        
+     * <p>
+     * Gets the principal name from the principal implementation full path.
+     * </p>
+     * <p>
+     * Hierarchical principal names should follow: {principal}.{subprincipal}. "." is used as the
+     * separator for hierarchical elements.
+     * </p>
+     * <p>
+     * The implementation path follow /PREFS_{PRINCIPAL}_ROOT/{principal}/{subprincipal}.
+     * </p>
+     * 
      * @param fullPath The principal full path.
      * @param prefsRoot The preferences root node.
      * @return The principal name.
@@ -116,20 +146,20 @@
     }
 
     private boolean enabled = true;
-    
-    /** 
+
+    /**
      * @see org.apache.jetspeed.security.BasePrincipal#isEnabled()
      */
     public boolean isEnabled()
     {
         return enabled;
     }
-    
-    /** 
+
+    /**
      * @see org.apache.jetspeed.security.BasePrincipal#setEnabled(boolean)
      */
     public void setEnabled(boolean enabled)
     {
         this.enabled = enabled;
-    }    
+    }
 }

Added: portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/impl/PermissionManagerImpl.java
URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/impl/PermissionManagerImpl.java?rev=291290&view=auto
==============================================================================
--- portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/impl/PermissionManagerImpl.java (added)
+++ portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/impl/PermissionManagerImpl.java Sat Sep 24 05:29:23 2005
@@ -0,0 +1,436 @@
+/* Copyright 2004 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.jetspeed.security.impl;
+
+import java.lang.reflect.Constructor;
+import java.security.Permission;
+import java.security.Permissions;
+import java.security.Principal;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jetspeed.i18n.KeyedMessage;
+import org.apache.jetspeed.security.PermissionManager;
+import org.apache.jetspeed.security.RolePrincipal;
+import org.apache.jetspeed.security.SecurityException;
+import org.apache.jetspeed.security.SecurityHelper;
+import org.apache.jetspeed.security.UserPrincipal;
+import org.apache.jetspeed.security.om.InternalPermission;
+import org.apache.jetspeed.security.om.InternalPrincipal;
+import org.apache.jetspeed.security.om.impl.InternalPermissionImpl;
+import org.apache.jetspeed.security.om.impl.InternalPrincipalImpl;
+import org.apache.jetspeed.util.ArgUtil;
+import org.apache.ojb.broker.query.Criteria;
+import org.apache.ojb.broker.query.Query;
+import org.apache.ojb.broker.query.QueryFactory;
+import org.springframework.orm.ojb.support.PersistenceBrokerDaoSupport;
+
+/**
+ * <p>
+ * Implementation for managing {@link Permission}and permission association to
+ * {@link Principal}. Permissions are used to manage Principals access
+ * entitlement on specified resources.
+ * </p>
+ * <p>
+ * For instance:
+ * </p>
+ * 
+ * <pre><code>
+ * 
+ *  
+ *   grant principal o.a.j.security.UserPrincipal &quot;theUserPrincipal&quot;
+ *   {
+ *       permission o.a.j.security.PortletPermission &quot;myportlet&quot;, &quot;view,edit,minimize,maximize&quot;;
+ *   };
+ *   
+ *  
+ * </code>
+ * 
+ *  &lt;pre&gt;
+ *   @author &lt;a href=&quot;mailto:dlestrat@apache.org&quot;&gt;David Le Strat&lt;/a&gt;
+ * 
+ * 
+ */
+public class PermissionManagerImpl extends PersistenceBrokerDaoSupport implements PermissionManager 
+{
+    private static final Log log = LogFactory.getLog(PermissionManagerImpl.class);
+    
+    /**
+     * @see org.apache.jetspeed.security.PermissionManager#getPermissions(java.security.Principal)
+     */
+    public Permissions getPermissions(Principal principal)
+    {
+        String fullPath = SecurityHelper.getPreferencesFullPath(principal);
+        ArgUtil.notNull(new Object[] { fullPath }, new String[] { "fullPath" },
+                "removePermission(java.security.Principal)");
+
+        // Remove permissions on principal.
+        InternalPrincipal internalPrincipal = getInternalPrincipal(fullPath);
+        Collection internalPermissions = new ArrayList();
+        if (null != internalPrincipal)
+        {
+            internalPermissions = internalPrincipal.getPermissions();
+        }
+        Permissions permissions = new Permissions();
+        appendSecurityPermissions(internalPermissions, permissions);
+        return permissions;
+    }
+
+    /**
+     * @see org.apache.jetspeed.security.PermissionManager#getPermissions(java.util.Collection)
+     */
+    public Permissions getPermissions(Collection principals)
+    {
+        ArgUtil.notNull(new Object[] { principals }, new String[] { "principals" },
+                "getPermissions(java.util.Collection)");
+
+        Permissions permissions = new Permissions();
+        Collection principalsFullPath = getPrincipalsFullPath(principals);
+        if ((null != principalsFullPath) && principalsFullPath.size() > 0)
+        {
+            Criteria filter = new Criteria();
+            filter.addIn("fullPath", principalsFullPath);
+            Query query = QueryFactory.newQuery(InternalPrincipalImpl.class, filter);
+            Collection internalPrincipals = getPersistenceBrokerTemplate().getCollectionByQuery(query);
+            Iterator internalPrincipalsIter = internalPrincipals.iterator();
+            while (internalPrincipalsIter.hasNext())
+            {
+                InternalPrincipal internalPrincipal = (InternalPrincipal) internalPrincipalsIter.next();
+                Collection internalPermissions = internalPrincipal.getPermissions();
+                if (null != internalPermissions)
+                {
+                    permissions = appendSecurityPermissions(internalPermissions, permissions);
+                }
+            }
+        }
+        return permissions;
+    }
+
+    /**
+     * <p>
+     * Get the full path for the {@link Principal}in the collection.
+     * </p>
+     * 
+     * @param principals The collection of principals.
+     * @return The collection of principals names.
+     */
+    private Collection getPrincipalsFullPath(Collection principals)
+    {
+        Collection principalsFullPath = new ArrayList();
+        Iterator principalsIterator = principals.iterator();
+        while (principalsIterator.hasNext())
+        {
+            Principal principal = (Principal) principalsIterator.next();
+            String fullPath = SecurityHelper.getPreferencesFullPath(principal);
+            if (null != fullPath)
+            {
+                principalsFullPath.add(fullPath);
+            }
+        }
+        return principalsFullPath;
+    }
+
+    /**
+     * <p>
+     * Iterate through a collection of {@link InternalPermission}and build a
+     * unique collection of {@link java.security.Permission}.
+     * </p>
+     * 
+     * @param omPermissions The collection of {@link InternalPermission}.
+     * @return The collection of {@link java.security.Permission}.
+     */
+    private Permissions appendSecurityPermissions(Collection omPermissions, Permissions permissions)
+    {     
+        Iterator internalPermissionsIter = omPermissions.iterator();
+        while (internalPermissionsIter.hasNext())
+        {
+            InternalPermission internalPermission = (InternalPermission) internalPermissionsIter.next();
+            Permission permission = null;
+            try
+            {
+                Class permissionClass = Class.forName(internalPermission.getClassname());
+                Class[] parameterTypes = { String.class, String.class };
+                Constructor permissionConstructor = permissionClass.getConstructor(parameterTypes);
+                Object[] initArgs = { internalPermission.getName(), internalPermission.getActions() };
+                permission = (Permission) permissionConstructor.newInstance(initArgs);
+                if(!Collections.list(permissions.elements()).contains(permission))
+                {
+                    if (log.isDebugEnabled())
+                    {
+                        log.debug("Adding permimssion: [class, " + permission.getClass().getName() + "], " + "[name, "
+                                + permission.getName() + "], " + "[actions, " + permission.getActions() + "]");
+                    }                   
+                    permissions.add(permission);
+                }
+            }
+            catch (Exception e)
+            {
+                e.printStackTrace();
+            }
+        }
+        return permissions;
+    }
+
+    /**
+     * @see org.apache.jetspeed.security.PermissionManager#addPermission(java.security.Permission)
+     */
+    public void addPermission(Permission permission) throws SecurityException
+    {
+        ArgUtil.notNull(new Object[] { permission }, new String[] { "permission" },
+                "addPermission(java.security.Permission)");
+
+        InternalPermission internalPermission = new InternalPermissionImpl(permission.getClass().getName(), permission
+                .getName(), permission.getActions());
+        try
+        {            
+            getPersistenceBrokerTemplate().store(internalPermission);            
+        }
+        catch (Exception e)
+        {
+            KeyedMessage msg = SecurityException.UNEXPECTED.create("PermissionManager.addPermission",
+                                                                   "store", e.getMessage());
+            logger.error(msg, e);            
+            throw new SecurityException(msg, e);
+        }
+    }
+
+    /**
+     * @see org.apache.jetspeed.security.PermissionManager#removePermission(java.security.Permission)
+     */
+    public void removePermission(Permission permission) throws SecurityException
+    {
+        ArgUtil.notNull(new Object[] { permission }, new String[] { "permission" },
+                "removePermission(java.security.Permission)");
+
+        InternalPermission internalPermission = getInternalPermission(permission);
+        if (null != internalPermission)
+        {
+            try
+            {
+                // Remove permission.
+                getPersistenceBrokerTemplate().delete(internalPermission);
+            }
+            catch (Exception e)
+            {
+                KeyedMessage msg = SecurityException.UNEXPECTED.create("PermissionManager.removePermission",
+                                                                       "delete", e.getMessage());
+                logger.error(msg, e);            
+                throw new SecurityException(msg, e);
+            }
+        }
+    }
+
+    /**
+     * @see org.apache.jetspeed.security.PermissionManager#removePermissions(java.security.Principal)
+     */
+    public void removePermissions(Principal principal) throws SecurityException
+    {
+        String fullPath = SecurityHelper.getPreferencesFullPath(principal);
+        ArgUtil.notNull(new Object[] { fullPath }, new String[] { "fullPath" },
+                "removePermission(java.security.Principal)");
+
+        // Remove permissions on principal.
+        InternalPrincipal internalPrincipal = getInternalPrincipal(fullPath);
+        if (null != internalPrincipal)
+        {
+            Collection internalPermissions = internalPrincipal.getPermissions();
+            if (null != internalPermissions)
+            {
+                internalPermissions.clear();
+            }
+            try
+            {
+                internalPrincipal.setModifiedDate(new Timestamp(System.currentTimeMillis()));
+                internalPrincipal.setPermissions(internalPermissions);
+                
+                getPersistenceBrokerTemplate().store(internalPrincipal);
+            }
+            catch (Exception e)
+            {
+                KeyedMessage msg = SecurityException.UNEXPECTED.create("PermissionManager.removePermissions",
+                                                                       "store", e.getMessage());
+                logger.error(msg, e);                
+                throw new SecurityException(msg, e);
+            }
+        }
+    }
+
+    /**
+     * @see org.apache.jetspeed.security.PermissionManager#grantPermission(java.security.Principal,
+     *      java.security.Permission)
+     */
+    public void grantPermission(Principal principal, Permission permission) throws SecurityException
+    {
+        String fullPath = SecurityHelper.getPreferencesFullPath(principal);
+        ArgUtil.notNull(new Object[] { fullPath, permission }, new String[] { "fullPath", "permission" },
+                "grantPermission(java.security.Principal, java.security.Permission)");
+
+        Collection internalPermissions = new ArrayList();
+
+        InternalPrincipal internalPrincipal = getInternalPrincipal(fullPath);
+        if (null == internalPrincipal)
+        {
+            if ( principal instanceof UserPrincipal )
+            {
+                throw new SecurityException(SecurityException.USER_DOES_NOT_EXIST.create(principal.getName()));
+            }
+            else if ( principal instanceof RolePrincipal )
+            {
+                throw new SecurityException(SecurityException.ROLE_DOES_NOT_EXIST.create(principal.getName()));
+            }
+            // must/should be GroupPrincipal
+            throw new SecurityException(SecurityException.GROUP_DOES_NOT_EXIST.create(principal.getName()));
+        }
+        InternalPermission internalPermission = getInternalPermission(permission);
+        if (null == internalPermission)
+        {
+            throw new SecurityException(SecurityException.PERMISSION_DOES_NOT_EXIST.create(permission.getName()));
+        }
+
+        if (null != internalPrincipal.getPermissions())
+        {
+            internalPermissions.addAll(internalPrincipal.getPermissions());
+        }
+        if (!internalPermissions.contains(internalPermission))
+        {
+            internalPermissions.add(internalPermission);
+        }
+        try
+        {
+            internalPrincipal.setModifiedDate(new Timestamp(System.currentTimeMillis()));
+            internalPrincipal.setPermissions(internalPermissions);
+            
+            getPersistenceBrokerTemplate().store(internalPrincipal);
+        }
+        catch (Exception e)
+        {
+            KeyedMessage msg = SecurityException.UNEXPECTED.create("PermissionManager.grantPermission",
+                                                                   "store", e.getMessage());
+            logger.error(msg, e);            
+            throw new SecurityException(msg, e);
+        }
+    }
+
+    /**
+     * @see org.apache.jetspeed.security.PermissionManager#permissionExists(java.security.Permission)
+     */
+    public boolean permissionExists(Permission permission)
+    {
+        boolean permissionExists = true;
+        InternalPermission internalPermission = getInternalPermission(permission);
+        if (null == internalPermission)
+        {
+            permissionExists = false;
+        }
+        return permissionExists;
+    }
+
+    /**
+     * @see org.apache.jetspeed.security.PermissionManager#revokePermission(java.security.Principal,
+     *      java.security.Permission)
+     */
+    public void revokePermission(Principal principal, Permission permission) throws SecurityException
+    {
+        String fullPath = SecurityHelper.getPreferencesFullPath(principal);
+        ArgUtil.notNull(new Object[] { fullPath, permission }, new String[] { "fullPath", "permission" },
+                "revokePermission(java.security.Principal, java.security.Permission)");
+
+        // Remove permissions on principal.
+        InternalPrincipal internalPrincipal = getInternalPrincipal(fullPath);
+        if (null != internalPrincipal)
+        {
+            Collection internalPermissions = internalPrincipal.getPermissions();
+            if (null != internalPermissions)
+            {
+                boolean revokePermission = false;
+                ArrayList newInternalPermissions = new ArrayList();
+                Iterator internalPermissionsIter = internalPermissions.iterator();
+                while (internalPermissionsIter.hasNext())
+                {
+                    InternalPermission internalPermission = (InternalPermission) internalPermissionsIter.next();
+                    if (!((internalPermission.getClassname().equals(permission.getClass().getName()))
+                            && (internalPermission.getName().equals(permission.getName())) && (internalPermission.getActions()
+                            .equals(permission.getActions()))))
+                    {
+                        newInternalPermissions.add(internalPermission);
+                    }
+                    else
+                    {
+                        revokePermission = true;
+                    }
+                }
+                if (revokePermission)
+                {
+                    try
+                    {
+                        internalPrincipal.setModifiedDate(new Timestamp(System.currentTimeMillis()));
+                        internalPrincipal.setPermissions(newInternalPermissions);
+
+                        getPersistenceBrokerTemplate().store(internalPrincipal);
+                    }
+                    catch (Exception e)
+                    {
+                        KeyedMessage msg = SecurityException.UNEXPECTED.create("PermissionManager.revokePermission",
+                                                                               "store", e.getMessage());
+                        logger.error(msg, e);                      
+                        throw new SecurityException(msg, e);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * <p>
+     * Returns the {@link InternalPrincipal}from the full path.
+     * </p>
+     * 
+     * @param fullPath The full path.
+     * @return The {@link InternalPrincipal}.
+     */
+    InternalPrincipal getInternalPrincipal(String fullPath)
+    {
+        Criteria filter = new Criteria();
+        filter.addEqualTo("fullPath", fullPath);
+        Query query = QueryFactory.newQuery(InternalPrincipalImpl.class, filter);
+        InternalPrincipal internalPrincipal = (InternalPrincipal) getPersistenceBrokerTemplate().getObjectByQuery(query);
+        return internalPrincipal;
+    }
+
+    /**
+     * <p>
+     * Returns the {@link InternalPermission} from a Permission.
+     * </p>
+     * 
+     * @param permission The permission.
+     * @return The {@link InternalPermission}.
+     */
+    InternalPermission getInternalPermission(Permission permission)
+    {
+        Criteria filter = new Criteria();
+        filter.addEqualTo("classname", permission.getClass().getName());
+        filter.addEqualTo("name", permission.getName());
+        filter.addEqualTo("actions", permission.getActions());
+        Query query = QueryFactory.newQuery(InternalPermissionImpl.class, filter);
+        InternalPermission internalPermission = (InternalPermission) getPersistenceBrokerTemplate().getObjectByQuery(query);
+        return internalPermission;
+    }
+
+}
\ No newline at end of file

Modified: portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/impl/RdbmsPolicy.java
URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/impl/RdbmsPolicy.java?rev=291290&r1=291289&r2=291290&view=diff
==============================================================================
--- portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/impl/RdbmsPolicy.java (original)
+++ portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/impl/RdbmsPolicy.java Sat Sep 24 05:29:23 2005
@@ -14,48 +14,61 @@
  */
 package org.apache.jetspeed.security.impl;
 
-import java.security.AccessController;
-import java.security.AccessControlContext;
+import java.security.AllPermission;
 import java.security.CodeSource;
-import java.security.Permissions;
+import java.security.Permission;
 import java.security.PermissionCollection;
+import java.security.Permissions;
 import java.security.Policy;
-
-import javax.security.auth.Subject;
+import java.security.Principal;
+import java.security.ProtectionDomain;
+import java.util.Arrays;
+import java.util.List;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-
 import org.apache.jetspeed.security.PermissionManager;
+import org.apache.jetspeed.security.SecurityHelper;
+import org.apache.jetspeed.security.SecurityPolicies;
 
 /**
- * <p>Policy implementation using a relational database as persistent datastore.</p>
- * <p>This code was partially inspired from articles from:<br>
+ * <p>
+ * Policy implementation using a relational database as persistent datastore.
+ * </p>
+ * <p>
+ * This code was partially inspired from articles from:<br>
  * <ul>
- *    <li><a href="http://www-106.ibm.com/developerworks/library/j-jaas/">
- *    Extend JAAS for class instance-level authorization.</a></li>
- *    <li><a href="http://www.javageeks.com/Papers/JavaPolicy/index.html">
- *    When "java.policy" Just Isn't Good Enough.</li>
- * </ul></p>
+ * <li><a href="http://www.ibm.com/developerworks/library/j-jaas/"> Extend JAAS for class
+ * instance-level authorization.</a></li>
+ * <li><a href="http://www.javageeks.com/Papers/JavaPolicy/index.html"> When "java.policy" Just
+ * Isn't Good Enough.</li>
+ * </ul>
+ * </p>
+ * 
  * @author <a href="mailto:dlestrat@apache.org">David Le Strat</a>
- *
  */
 public class RdbmsPolicy extends Policy
 {
     private static final Log log = LogFactory.getLog(RdbmsPolicy.class);
 
-    /** <p>Default Policy.</p> */
-    private static String defaultPolicy = "sun.security.provider.PolicyFile";
-
-    /** <p>InternalPermission Manager Service.</p> */
+    /**
+     * <p>
+     * InternalPermission Manager Service.
+     * </p>
+     */
     private PermissionManager pms = null;
 
     /**
-     * <p>Default constructor.</p>
+     * <p>
+     * Default constructor.
+     * </p>
      */
     public RdbmsPolicy(PermissionManager pms)
     {
-        if (log.isDebugEnabled()) log.debug("RdbmsPolicy constructed.");
+        if (log.isDebugEnabled())
+        {
+            log.debug("RdbmsPolicy constructed.");
+        }
         this.pms = pms;
     }
 
@@ -64,97 +77,134 @@
      */
     public void refresh()
     {
-        if (log.isDebugEnabled()) log.debug("RdbmsPolicy refresh called.");
+        if (log.isDebugEnabled())
+        {
+            log.debug("RdbmsPolicy refresh called.");
+        }
     }
 
     /**
-     * <p>Get permissions will check for permissions against the configured
-     * RDBMS.  If no permissions is found for the {@link AccessControlContext}
-     * {@link Subject} principals or if the {@link Subject} is null, the default
-     * policy will be used.</p>
-     * <p>The default policy defaults to {@link sun.security.provider.PolicyFile}.
-     * If the system uses a different <code>policy.provider</code>, the default policy
-     * should be set using <code>RdbmsPolicy.setDefaultPolicy()</code> when the
-     * application start/initializes.</p>
-     * @param codeSource The codeSource.
-     * @see java.security.Policy#getPermissions(java.security.CodeSource)
+     * <p>
+     * Check that the permission is implied for the protection domain. This will check for
+     * permissions against the configured RDBMS and all {@link SecurityPolicies} configured through
+     * the AuthorizationProvider.
+     * </p>
+     * <p>
+     * The default policy is by default part of the {@link SecurityPolicies} and will only if
+     * configured through assembly.
+     * </p>
+     * 
+     * @see java.security.Policy#implies(java.security.ProtectionDomain, java.security.Permission)
      */
-    public PermissionCollection getPermissions(CodeSource codeSource)
+    public boolean implies(ProtectionDomain protectionDomain, Permission permission)
     {
-        if (log.isDebugEnabled()) log.debug("getPermissions called for '" + codeSource + "'.");
-
-        Permissions perms = null;
-
-        // In the policy, the Subject should come from the context?
-        AccessControlContext context = AccessController.getContext();
-        Subject user = Subject.getSubject(context);
-        if (null != user)
-        {
-            // Add permission associated with the Subject Principals to Permissions.
-            // Get the permissions
-            perms = pms.getPermissions(user.getPrincipals());
-        }
-        if (null != perms)
-        {         
-            return perms;
+        Principal[] principals = protectionDomain.getPrincipals();
+        PermissionCollection perms = new Permissions();
+        boolean permImplied = false;
+        if ((null != principals) && (principals.length > 0))
+        {
+            // We need to authorize java permissions.
+            // Without this check, we get a ClassCircularityError in Tomcat.
+            if (permission.getClass().getName().startsWith("java"))
+            {
+                perms.add(new AllPermission());
+            }
+            else
+            {
+                if (log.isDebugEnabled())
+                {
+                    log.debug("Implying permission [class, " + permission.getClass().getName() + "], " + "[name, "
+                            + permission.getName() + "], " + "[actions, " + permission.getActions() + "] for: ");
+                    log.debug("\tCodeSource:" + protectionDomain.getCodeSource().getLocation().getPath());
+                    for (int i = 0; i < principals.length; i++)
+                    {
+                        log.debug("\tPrincipal[" + i + "]: [name, " + principals[i].getName() + "], [class, "
+                                + principals[i].getClass() + "]");
+                    }
+                }
+                perms = pms.getPermissions(Arrays.asList(principals));
+            }
         }
         else
         {
-            // TODO Is there a better way to do this?
-            // If the permission is not found here then delegate it
-            // to the standard java Policy class instance.
-            Policy.setPolicy(RdbmsPolicy.getDefaultPolicy());
-            Policy policy = Policy.getPolicy();
-            policy.refresh();
-            PermissionCollection defaultPerms = policy.getPermissions(codeSource);
-            // Revert back to the current policy.
-            Policy.setPolicy(this);
-            // Return the default permission collection.
-            return defaultPerms;
+            // No principal is returned from the subject.
+            // For security check, be sure to use doAsPrivileged(theSubject, anAction, null)...
+            // We grant access when no principal is associated to the subject.
+            perms.add(new AllPermission());
         }
+        if (null != perms)
+        {
+            permImplied = perms.implies(permission);
+        }
+        return permImplied;
     }
 
     /**
-     * <p>Utility method to set the default policy when initializing the application
-     * using the security service.</p>
-     * <p>This can be useful if the default java policy is not {@link sun.security.provider.PolicyFile}.
-     * This way the <code>RdbmsPolicy</code> will check credentials against the default policy if no permissions
-     * are returned when checking againt the <code>RdbmsPolicy</code>.</p>
-     * @param policy The default policy.
+     * @see java.security.Policy#getPermissions(java.security.ProtectionDomain)
      */
-    public static void setDefaultPolicy(Policy policy)
+    public PermissionCollection getPermissions(ProtectionDomain domain)
     {
-        RdbmsPolicy.defaultPolicy = policy.getClass().getName();
+        PermissionCollection otherPerms = new Permissions();
+        if (null != domain)
+        {
+            otherPerms = getPermissions(domain.getCodeSource());
+        }
+        return otherPerms;
     }
 
     /**
-     * <p>Utility method to get the system default policy.</p>
-     * <p>This can be useful if the default java policy is not {@link sun.security.provider.PolicyFile}.
-     * This way the <code>RdbmsPolicy</code> will check credentials against the default policy if no permissions
-     * are returned when checking againt the <code>RdbmsPolicy</code>.</p>
-     * @return The default policy.
+     * <p>
+     * The RdbmsPolicy does not protect code source per say, but will return the protected code
+     * source from the other configured policies.
+     * </p>
+     * 
+     * @see java.security.Policy#getPermissions(java.security.CodeSource)
      */
-    public static Policy getDefaultPolicy()
+    public PermissionCollection getPermissions(CodeSource codeSource)
     {
-        try
-        {
-            Class policyClass = Class.forName(RdbmsPolicy.defaultPolicy);
-            return (Policy) policyClass.newInstance();
-        }
-        catch (ClassNotFoundException cnfe)
+        if (log.isDebugEnabled())
         {
-            cnfe.printStackTrace();
+            log.debug("getPermissions called for '" + codeSource + "'.");
         }
-        catch (InstantiationException ie)
+        PermissionCollection otherPerms = getOtherPoliciesPermissions(codeSource);
+
+        return otherPerms;
+    }
+
+    /**
+     * <p>
+     * Gets all the permissions that should be enforced through the other policies configured.
+     * </p>
+     * 
+     * @param codeSource The CodeSource.
+     * @return A collection of permissions as a {@link PermissionCollection}
+     */
+    private PermissionCollection getOtherPoliciesPermissions(CodeSource codeSource)
+    {
+        if (log.isDebugEnabled())
         {
-            ie.printStackTrace();
+            log.debug("Checking other policies permissions.");
         }
-        catch (IllegalAccessException iae)
-        {
-            iae.printStackTrace();
+        log.debug("CodeSource: " + codeSource.getLocation().getPath());
+
+        List securityPolicies = SecurityPolicies.getInstance().getUsedPolicies();
+        PermissionCollection otherPerms = new Permissions();
+        for (int i = 0; i < securityPolicies.size(); i++)
+        {
+            Policy currPolicy = (Policy) securityPolicies.get(i);
+            if (!currPolicy.getClass().equals(getClass()))
+            {
+                if (log.isDebugEnabled())
+                {
+                    log.debug("Checking policy: " + currPolicy.getClass().getName());
+                }
+                PermissionCollection currPerms = currPolicy.getPermissions(codeSource);
+                SecurityHelper.addPermissions(otherPerms, currPerms);
+            }
         }
 
-        return null;
+        // Return the default permission collection.
+        return otherPerms;
     }
 
 }

Modified: portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/util/test/AbstractSecurityTestcase.java
URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/util/test/AbstractSecurityTestcase.java?rev=291290&r1=291289&r2=291290&view=diff
==============================================================================
--- portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/util/test/AbstractSecurityTestcase.java (original)
+++ portals/jetspeed-2/trunk/components/security/src/java/org/apache/jetspeed/security/util/test/AbstractSecurityTestcase.java Sat Sep 24 05:29:23 2005
@@ -41,6 +41,7 @@
 
 /**
  * @author <a href="mailto:sweaver@einnovation.com">Scott T. Weaver </a>
+ * @author <a href="mailto:dlestrat@apache.org">David Le Strat </a>
  * @version $Id$
  *  
  */
@@ -109,15 +110,9 @@
         ums = (UserManager) ctx.getBean("org.apache.jetspeed.security.UserManager");
         gms = (GroupManager) ctx.getBean("org.apache.jetspeed.security.GroupManager");
         rms = (RoleManager) ctx.getBean("org.apache.jetspeed.security.RoleManager");
-        
-        // Login module.
-        //new LoginModuleProxyImpl(ums);
-
-        
+                
         // Authorization.
         pms = (PermissionManager) ctx.getBean("org.apache.jetspeed.security.PermissionManager");
-        //Policy policy = new RdbmsPolicy(pms);
-        //new AuthorizationProviderImpl(policy);
     }
 
     /**

Modified: portals/jetspeed-2/trunk/components/security/src/test/org/apache/jetspeed/security/TestRdbmsPolicy.java
URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/trunk/components/security/src/test/org/apache/jetspeed/security/TestRdbmsPolicy.java?rev=291290&r1=291289&r2=291290&view=diff
==============================================================================
--- portals/jetspeed-2/trunk/components/security/src/test/org/apache/jetspeed/security/TestRdbmsPolicy.java (original)
+++ portals/jetspeed-2/trunk/components/security/src/test/org/apache/jetspeed/security/TestRdbmsPolicy.java Sat Sep 24 05:29:23 2005
@@ -16,6 +16,7 @@
 
 import java.security.AccessControlException;
 import java.security.AccessController;
+import java.security.Policy;
 import java.security.PrivilegedAction;
 
 import javax.security.auth.Subject;
@@ -34,7 +35,11 @@
  */
 public class TestRdbmsPolicy extends AbstractSecurityTestcase
 {
-    /** <p>The JAAS login context.</p> */
+    /**
+     * <p>
+     * The JAAS login context.
+     * </p>
+     */
     private LoginContext loginContext = null;
 
     /**
@@ -42,7 +47,7 @@
      */
     public void setUp() throws Exception
     {
-        super.setUp();      
+        super.setUp();
         initUser();
 
         // Let's login in.
@@ -66,7 +71,6 @@
      */
     public void tearDown() throws Exception
     {
-        
 
         // Logout.
         try
@@ -82,26 +86,33 @@
         super.tearDown();
     }
 
-   public static Test suite()
+    public static Test suite()
     {
         // All methods starting with "test" will be executed in the test suite.
         return new TestSuite(TestRdbmsPolicy.class);
     }
-    
+
     /**
-     * <p>Executing this test requires adding an entry to java.policy.</p>
-     * <p>A possible entry would be to grant for all principals:</p>
+     * <p>
+     * Executing this test requires adding an entry to java.policy.
+     * </p>
+     * <p>
+     * A possible entry would be to grant for all principals:
+     * </p>
+     * 
      * <pre><code>
-     * grant
-     * {
-     *     permission org.apache.jetspeed.security.auth.PortletPermission "myportlet", "view";
-     * }
+     *  grant
+     *  {
+     *      permission org.apache.jetspeed.security.auth.PortletPermission &quot;myportlet&quot;, &quot;view&quot;;
+     *  }
      * </code></pre>
-     * <p>Such an entry would also test the Rdbms defaulting behavior if no
-     * entry is provided in the database for the tested Subject InternalUserPrincipal.</p>
+     * 
+     * <p>
+     * Such an entry would also test the Rdbms defaulting behavior if no entry is provided in the
+     * database for the tested Subject InternalUserPrincipal.
+     * </p>
      */
-    /*
-    public void testPermissionWithSubjectInContructor()
+    /*public void testPermissionWithSubjectInContructor()
     {
         // InternalPermission should be granted.
         PortletPermission perm1 = new PortletPermission("myportlet", "view", loginContext.getSubject());
@@ -113,7 +124,7 @@
         {
             assertTrue("did not authorize view permission on the portlet.", false);
         }
-    
+
         // InternalPermission should be denied.
         PortletPermission perm2 = new PortletPermission("myportlet", "edit", loginContext.getSubject());
         try
@@ -124,34 +135,42 @@
         catch (AccessControlException ace)
         {
         }
-    
+
         // Subject is omitted. InternalPermission should be denied.
         PortletPermission perm3 = new PortletPermission("myportlet", "view");
         try
         {
             AccessController.checkPermission(perm3);
-            //assertTrue("did not deny permission with no subject passed.", false);
+            // assertTrue("did not deny permission with no subject passed.", false);
         }
         catch (AccessControlException ace)
         {
         }
-    }
-    */
-
+    }*/
+    
+    /**
+     * <p>
+     * Test the policy with the default spring setting where the default underlying policy is not
+     * applied.
+     * </p>
+     */
     public void testPermissionWithSubjectInAccessControlContext()
     {
+        
         // InternalPermission should be granted.
         try
         {
-            Subject.doAs(loginContext.getSubject(), new PrivilegedAction()
+            Subject.doAsPrivileged(loginContext.getSubject(), new PrivilegedAction()
             {
                 public Object run()
                 {
                     PortletPermission perm1 = new PortletPermission("myportlet", "view");
+                    System.out.println("\t\t[TestRdbmsPolicy] Check access control for permission: [myportlet, view]");
+                    System.out.println("\t\t                  with policy: " + Policy.getPolicy().getClass().getName());
                     AccessController.checkPermission(perm1);
                     return null;
                 }
-            });
+            }, null);
         }
         catch (AccessControlException ace)
         {
@@ -161,24 +180,41 @@
         // Should be denied.
         try
         {
-            Subject.doAs(loginContext.getSubject(), new PrivilegedAction()
+            Subject.doAsPrivileged(loginContext.getSubject(), new PrivilegedAction()
             {
                 public Object run()
                 {
                     PortletPermission perm2 = new PortletPermission("myportlet", "secure");
+                    System.out.println("\t\t[TestRdbmsPolicy] Check access control for permission: [myportlet, secure]");
+                    System.out.println("\t\t                  with policy: " + Policy.getPolicy().getClass().getName());
                     AccessController.checkPermission(perm2);
                     return null;
                 }
-            });
-            assertTrue("did not deny delete permission on the portlet.", false);
+            }, null);
+            assertTrue("did not deny secure permission on the portlet.", false);
         }
         catch (AccessControlException ace)
         {
         }
     }
+    
+    /**
+     * <p>
+     * Test the policy with the default policy being evaluated as well.
+     * </p>
+     */
+    public void testPermissionWithSubjectInAccessControlContextAndDefaultPolicy()
+    {
+        System.out.println("\n\n\t\t[TestRdbmsPolicy] Test with default Policy enabled.");
+        AuthorizationProvider atzProvider = (AuthorizationProvider) ctx.getBean("org.apache.jetspeed.security.AuthorizationProvider");
+        atzProvider.useDefaultPolicy(true);
+        testPermissionWithSubjectInAccessControlContext();
+    }
 
     /**
-     * <p>Initialize user test object.</p>
+     * <p>
+     * Initialize user test object.
+     * </p>
      */
     protected void initUser()
     {
@@ -196,22 +232,24 @@
         {
             pms.addPermission(perm1);
             pms.addPermission(perm2);
-            
+
             pms.grantPermission(user, perm1);
             pms.grantPermission(user, perm2);
         }
         catch (SecurityException sex)
         {
             sex.printStackTrace();
-        }      
+        }
     }
 
     /**
-     * <p>Destroy user test object.</p>
+     * <p>
+     * Destroy user test object.
+     * </p>
      */
     protected void destroyUser() throws Exception
     {
-        ums.removeUser("anon");       
+        ums.removeUser("anon");
         // Remove permissions.
         PortletPermission perm1 = new PortletPermission("myportlet", "view");
         PortletPermission perm2 = new PortletPermission("myportlet", "view, edit");

Modified: portals/jetspeed-2/trunk/components/security/xdocs/atz-jaas.xml
URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/trunk/components/security/xdocs/atz-jaas.xml?rev=291290&r1=291289&r2=291290&view=diff
==============================================================================
--- portals/jetspeed-2/trunk/components/security/xdocs/atz-jaas.xml (original)
+++ portals/jetspeed-2/trunk/components/security/xdocs/atz-jaas.xml Sat Sep 24 05:29:23 2005
@@ -24,22 +24,28 @@
     <body>
         <section name="Overview of JAAS Authorization">
             <p>
-                A good overview of JAAS authorization is provided on 
-                <a href="http://java.sun.com/j2se/1.4.2/docs/guide/security/spec/security-spec.doc2.html">Sun's web site</a>.
-                At a high level, JAAS authorization leverages:
+                A good overview of JAAS authorization is provided on
+                <a href="http://java.sun.com/j2se/1.4.2/docs/guide/security/spec/security-spec.doc2.html">Sun's web site</a>
+                . At a high level, JAAS authorization leverages:
                 <ul>
-                    <li><a href="http://java.sun.com/j2se/1.4.2/docs/api/java/security/Permission.html">Permission</a>
-                    that associates actions to resources.</li>
-                    <li><a href="http://java.sun.com/j2se/1.4.2/docs/api/java/security/Principal.html">Principal</a>
-                    that represents an entity in the system.  In Jetspeed 2, 3 principals are used to represent users,
-                    roles and groups.</li>
-                    <li><a href="http://java.sun.com/j2se/1.4.2/docs/api/java/security/Policy.html">Policy</a>
-                    that associates principals to permissions.</li>
+                    <li>
+                        <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/security/Permission.html">Permission</a>
+                        that associates actions to resources.
+                    </li>
+                    <li>
+                        <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/security/Principal.html">Principal</a>
+                        that represents an entity in the system. In Jetspeed 2, 3 principals are used to represent users, roles and groups.
+                    </li>
+                    <li>
+                        <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/security/Policy.html">Policy</a>
+                        that associates principals to permissions.
+                    </li>
                 </ul>
-            </p>   
+            </p>
             <p>
                 Jetspeed 2 provides a custom policy implemention that allow the portal to secure resources as follow:
-                <source><![CDATA[
+                <source>
+                    <![CDATA[
 grant principal o.a.j.security.UserPrincipal "theUserPrincipal" {
   permission o.a.j.security.PagePermission "mypage", "view";
   permission o.a.j.security.PortletPermission "myportlet", "view,edit,minimize,maximize";
@@ -58,57 +64,112 @@
   permission o.a.j.security.TabPermission "mytab", "view";
 };]]>
                 </source>
-            </p> 
+            </p>
             <p>
-                The custom security policy provides a <code>java.security.Policy</code> implementation that
-                stores the association between principals and permissions in a relational database as opposed to
-                leveraging the default JDK policy.  In the case of Sun's JDK, the default policy is 
+                The custom security policy provides a
+                <code>java.security.Policy</code>
+                implementation that stores the association between principals and permissions in a relational database as opposed to leveraging the default JDK
+                policy. In the case of Sun's JDK, the default policy is
                 <a href="http://java.sun.com/j2se/1.4.2/docs/guide/security/PolicyFiles.html#DefaultImpl">sun.security.provider.PolicyFile</a>
                 a file based policy.
             </p>
             <p>
-                In the code sample above, the <code>UserPrincipal</code> identify with the <code>Principal.getName()</code> 
-                &quot;theUserPrincipal&quot; has permission to &quot;view&quot; the page called &quot;mypage&quot;, to
-                &quot;view,edit,minimize,maximize&quot; the portlet portlet called &quot;myportlet&quot;      
+                In the code sample above, the
+                <code>UserPrincipal</code>
+                identify with the
+                <code>Principal.getName()</code>
+                &quot;theUserPrincipal&quot; has permission to &quot;view&quot; the page called &quot;mypage&quot;, to &quot;view,edit,minimize,maximize&quot;
+                the portlet portlet called &quot;myportlet&quot;
             </p>
             <p>
-                The <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/security/AccessController.html">AccessController</a>
-                validates a <code>Subject</code> permissions.  For instance, a page permission check would perform the following
-                check:
-                <source><![CDATA[
+                The
+                <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/security/AccessController.html">AccessController</a>
+                validates a
+                <code>Subject</code>
+                permissions. For instance, a page permission check would perform the following check:
+                <source>
+                    <![CDATA[
 PagePermission permission = new PagePermission(path, actions);
 AccessController.checkPermission(permission);                
-                ]]></source>
+                ]]>
+                </source>
             </p>
         </section>
         <section name="Jetspeed JAAS Policy">
             <p>
-                The <code>RdbmsPolicy</code> implements <code>java.security.Policy</code>.  It leverages the 
-                <code>PermissionManager</code> to get the permissions associated with a given <code>Subject</code>
+                The
+                <code>RdbmsPolicy</code>
+                implements
+                <code>java.security.Policy</code>
+                . It leverages the
+                <code>PermissionManager</code>
+                to get the permissions associated with a given
+                <code>Subject</code>
                 principals.
-                <source><![CDATA[
+                <source>
+                    <![CDATA[
 pms.getPermissions(user.getPrincipals());
-                ]]></source>
-                The class diagram below illustrate the association between the <code>RdbmsPolicy</code> and 
-                the <code>PermissionManager</code>.
+                ]]>
+                </source>
+                The class diagram below illustrate the association between the
+                <code>RdbmsPolicy</code>
+                and the
+                <code>PermissionManager</code>
+                .
             </p>
             <p>
-                A good article on custom policies implementation is available on 
-                <a href="http://www-106.ibm.com/developerworks/library/j-jaas/?n-j-442">IBM web site</a>.
+                A good article on custom policies implementation is available on
+                <a href="http://www-106.ibm.com/developerworks/library/j-jaas/?n-j-442">IBM web site</a>
+                .
             </p>
             <p>
-                <img src="images/rdbms-policy-c.gif" border="0"/>
+                <img src="images/rdbms-policy-c.gif" border="0" />
             </p>
             <p>
-                To get more detail about the implementation of the <code>PermissionManager</code>, see 
-                <a href="permission.html">PermissionManager Overview</a>.
+                To get more detail about the implementation of the
+                <code>PermissionManager</code>
+                , see
+                <a href="permission.html">PermissionManager Overview</a>
+                .
             </p>
             <p>
-                <u>Note:</u> The current <code>RdbmsPolicy</code> manages the policies to apply.  It applies <code>RdbmsPolicy</code>
-                in conjunction with the default policy configured in the runtime environment. 
-                Jetspeed 2 should explore providing
-                <a href="http://java.sun.com/j2ee/javaacc/index.html">JACC</a> adapters for its custom policy for
-                specific application servers.
+                <u>Note:</u>
+                The current
+                <code>RdbmsPolicy</code>
+                manages the policies to apply. It applies
+                <code>RdbmsPolicy</code>
+                in conjunction with the default policy configured in the runtime environment. Jetspeed 2 should explore providing
+                <a href="http://java.sun.com/j2ee/javaacc/index.html">JACC</a>
+                adapters for its custom policy for specific application servers.
+            </p>
+        </section>
+        <section name="Authorization Provider and Policy Configuration">
+            <p>
+                The
+                <code>AuthorizationProvider</code>
+                configures the authorization policies to be used by Jetspeed 2 and keeps the list of such policies in the
+                <code>SecurityPolicies</code>
+                singleton. The
+                <code>RdbmsPolicy</code>
+                when getting the permissions for access control will execute its policy as well as all the policies configured in
+                <code>SecurityPolicies</code>
+                . If the
+                <code>AuthorizationProvider</code>
+                was constructed with
+                <code>useDefaultPolicy</code>
+                set to true, the default JDK or application server policy will be applied when getting the permissions.
+            </p>
+            <p>
+                <u>Note:</u>
+                The
+                <code>RbmsPolicy</code>
+                permission check is concerned about the principals associated to the
+                <code>Subject</code>, therefore where performing an access control check, 
+                the check should be performed with the following call:
+                <code>doAsPrivileged(theSubject, anAction, null)</code>.  By passing a null
+                <code>AccessContolContext</code>, the caller is essentially saying: 
+                "I don't care who called me, the only important thing is whether I have permission when associated with the
+                given subject".
             </p>
         </section>
     </body>



---------------------------------------------------------------------
To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
For additional commands, e-mail: jetspeed-dev-help@portals.apache.org