[jboss-cvs] Picketbox SVN: r46 - in trunk/picketbox: src/test/java/org/picketbox/test/api and 3 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Sun Feb 28 17:22:05 EST 2010


Author: sguilhen at redhat.com
Date: 2010-02-28 17:22:04 -0500 (Sun, 28 Feb 2010)
New Revision: 46

Added:
   trunk/picketbox/src/test/java/org/picketbox/test/api/InstanceBasedAuthorizationUnitTestCase.java
   trunk/picketbox/src/test/java/org/picketbox/test/pojos/MemoryOnlyACLStrategy.java
   trunk/picketbox/src/test/resources/config/acl-authorization.conf
Modified:
   trunk/picketbox/pom.xml
   trunk/picketbox/src/test/resources/defaultRoles.properties
   trunk/picketbox/src/test/resources/defaultUsers.properties
Log:
Added test case to show the usage of ACLs to implement instance-based authorization

Modified: trunk/picketbox/pom.xml
===================================================================
--- trunk/picketbox/pom.xml	2010-02-25 03:24:29 UTC (rev 45)
+++ trunk/picketbox/pom.xml	2010-02-28 22:22:04 UTC (rev 46)
@@ -45,5 +45,18 @@
          <version>4.8.1</version>
          <scope>test</scope>
       </dependency>
+      <!-- these dependencies are needed because ACL impl classes are annotated - this must be fixed as we don't want to bring these deps in -->
+      <dependency>
+         <groupId>javax.persistence</groupId>
+         <artifactId>persistence-api</artifactId>
+         <version>1.0</version>
+         <scope>test</scope>
+      </dependency>
+      <dependency>
+         <groupId>org.hibernate</groupId>
+         <artifactId>hibernate-annotations</artifactId>
+         <version>3.3.0.ga</version>
+         <scope>test</scope>
+      </dependency>
     </dependencies>
 </project>

Added: trunk/picketbox/src/test/java/org/picketbox/test/api/InstanceBasedAuthorizationUnitTestCase.java
===================================================================
--- trunk/picketbox/src/test/java/org/picketbox/test/api/InstanceBasedAuthorizationUnitTestCase.java	                        (rev 0)
+++ trunk/picketbox/src/test/java/org/picketbox/test/api/InstanceBasedAuthorizationUnitTestCase.java	2010-02-28 22:22:04 UTC (rev 46)
@@ -0,0 +1,221 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors. 
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.picketbox.test.api;
+
+import java.net.URI;
+import java.security.Principal;
+import java.security.acl.Group;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.security.auth.Subject;
+
+import junit.framework.TestCase;
+
+import org.jboss.security.AuthenticationManager;
+import org.jboss.security.AuthorizationManager;
+import org.jboss.security.acl.ACLEntry;
+import org.jboss.security.acl.ACLEntryImpl;
+import org.jboss.security.acl.ACLPersistenceStrategy;
+import org.jboss.security.acl.BasicACLPermission;
+import org.jboss.security.acl.CompositeACLPermission;
+import org.jboss.security.authorization.AuthorizationContext;
+import org.jboss.security.authorization.Resource;
+import org.jboss.security.authorization.ResourceType;
+import org.jboss.security.identity.plugins.IdentityFactory;
+import org.picketbox.config.PicketBoxConfiguration;
+import org.picketbox.factories.SecurityFactory;
+import org.picketbox.test.pojos.MemoryOnlyACLStrategy;
+
+/**
+ * <p>
+ * This {@code TestCase} tests the behavior of the instance-based authorization mechanism (ACLs). All tests use a
+ * memory-based {@code ACLPersistenceStrategy} implementation. Real world scenarios will most likely require an
+ * implementation that stores the ACLs on the file systems or databases.
+ * </p>
+ * 
+ * @author <a href="mailto:sguilhen at redhat.com">Stefan Guilhen</a>
+ */
+public class InstanceBasedAuthorizationUnitTestCase extends TestCase
+{
+   private final String securityDomainName = "test";
+
+   private final String configFile = "config/acl-authorization.conf";
+
+   private boolean initialized;
+
+   @Override
+   protected void setUp() throws Exception
+   {
+      super.setUp();
+      // setup the test ACLs only once.
+      if (!this.initialized)
+      {
+         ACLPersistenceStrategy strategy = new MemoryOnlyACLStrategy();
+
+         // create an ACL for an important project file.
+         Resource importantResource = new TestResource("file://documents/project/important-file");
+         // project managers may read, update and delete the file.
+         ACLEntry entry1 = new ACLEntryImpl(new CompositeACLPermission(BasicACLPermission.values()), "manager");
+         // project developers can only view the contents of the file.
+         ACLEntry entry2 = new ACLEntryImpl(BasicACLPermission.READ, "developer");
+         Collection<ACLEntry> entries = new ArrayList<ACLEntry>();
+         entries.add(entry1);
+         entries.add(entry2);
+         // create and register the ACLs in the persistence strategy.
+         strategy.createACL(importantResource, entries);
+         this.initialized = true;
+      }
+   }
+
+   /**
+    * <p>
+    * This test verifies if the instance-based authorization mechanism correctly grants/denies access to resources
+    * according to the permissions that have been specified in ACLs.  
+    * </p>
+    * 
+    * @throws Exception if an error occurs while running the test.
+    */
+   public void testInstanceBasedAuthorization() throws Exception
+   {
+      SecurityFactory.prepare();
+      try
+      {
+         PicketBoxConfiguration idtrustConfig = new PicketBoxConfiguration();
+         idtrustConfig.load(configFile);
+
+         AuthenticationManager authManager = SecurityFactory.getAuthenticationManager(securityDomainName);
+         assertNotNull(authManager);
+
+         // bob, the project manager authenticates to the system.
+         Subject subject = new Subject();
+         boolean result = authManager.isValid(this.getPrincipal("bob"), "bobpass", subject);
+         assertTrue("Unexpected authentication error", result);
+
+         // now bob wants to update the important project file. We must check if he has permission to do so.
+         Resource resource = new TestResource("file://documents/project/important-file");
+         AuthorizationManager authzManager = SecurityFactory.getAuthorizationManager(securityDomainName);
+         assertNotNull(authzManager);
+
+         // first we get bob's roles from the subject (the ACL entries have roles as keys).
+         Group roles = subject.getPrincipals(Group.class).iterator().next();
+         assertEquals("Unexpected group name", "Roles", roles.getName());
+         Enumeration<?> rolesEnum = roles.members();
+
+         // now we must check if any of bob's roles has the permission to update the file.
+         int decision = AuthorizationContext.DENY;
+         while (rolesEnum.hasMoreElements() && decision == AuthorizationContext.DENY)
+         {
+            Principal role = (Principal) rolesEnum.nextElement();
+            decision = authzManager.authorize(resource, IdentityFactory.createIdentity(role.getName()),
+                  BasicACLPermission.UPDATE);
+         }
+         // as we know, bob is a manager, so the final decision should allow him to update the project file.
+         assertEquals("Unexpected authorization decision", AuthorizationContext.PERMIT, decision);
+         
+         // now alice, the project developer, authenticates to the system.
+         subject = new Subject();
+         result = authManager.isValid(this.getPrincipal("alice"), "alicepass", subject);
+         assertTrue("Unexpected authentication error", result);
+         
+         // alice tries to delete the important project file. We must check if she has sufficient permissions.
+         // first we get alice's roles from the subject.
+         roles = subject.getPrincipals(Group.class).iterator().next();
+         assertEquals("Unexpected group name", "Roles", roles.getName());
+         rolesEnum = roles.members();
+
+         // then we check if any of alice's roles has the permission to delete the file.
+         decision = AuthorizationContext.DENY;
+         while (rolesEnum.hasMoreElements() && decision == AuthorizationContext.DENY)
+         {
+            Principal role = (Principal) rolesEnum.nextElement();
+            decision = authzManager.authorize(resource, IdentityFactory.createIdentity(role.getName()),
+                  BasicACLPermission.DELETE);
+         }
+         // as we know, alice is only a developer, so the final decision should prevent her from deleting the file.
+         assertEquals("Unexpected authorization decision", AuthorizationContext.DENY, decision);
+      }
+      finally
+      {
+         SecurityFactory.release();
+      }
+   }
+
+   private Principal getPrincipal(final String name)
+   {
+      return new Principal()
+      {
+         public String getName()
+         {
+            return name;
+         }
+      };
+   }
+
+   class TestResource implements Resource
+   {
+      private URI resourceURI;
+
+      private Map<String, Object> contextMap;
+      
+      public TestResource(String resourceURI)
+      {
+         this.resourceURI = URI.create(resourceURI);
+         this.contextMap = new HashMap<String, Object>();
+      }
+
+      public ResourceType getLayer()
+      {
+         return ResourceType.ACL;
+      }
+
+      public Map<String, Object> getMap()
+      {
+         return this.contextMap;
+      }
+
+      /**
+       * <p>
+       * Let's consider two {@code TestResources} to be equal if they have the same resource URI.
+       * </p>
+       */
+      @Override
+      public boolean equals(Object obj)
+      {
+         if (obj instanceof TestResource)
+         {
+            TestResource other = (TestResource) obj;
+            return other.resourceURI.equals(this.resourceURI);
+         }
+         return false;
+      }
+
+      @Override
+      public int hashCode()
+      {
+         return this.resourceURI.hashCode();
+      }
+   }
+}

Added: trunk/picketbox/src/test/java/org/picketbox/test/pojos/MemoryOnlyACLStrategy.java
===================================================================
--- trunk/picketbox/src/test/java/org/picketbox/test/pojos/MemoryOnlyACLStrategy.java	                        (rev 0)
+++ trunk/picketbox/src/test/java/org/picketbox/test/pojos/MemoryOnlyACLStrategy.java	2010-02-28 22:22:04 UTC (rev 46)
@@ -0,0 +1,115 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors. 
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.picketbox.test.pojos;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.jboss.security.acl.ACL;
+import org.jboss.security.acl.ACLEntry;
+import org.jboss.security.acl.ACLImpl;
+import org.jboss.security.acl.ACLPersistenceStrategy;
+import org.jboss.security.authorization.Resource;
+
+/**
+ * <p>
+ * This class implements an {@code ACLPersistenceStrategy} that maintains the ACLs in memory.
+ * NOTE: this class is not thread safe and should be used solely for testing purposes.
+ * </p>
+ * 
+ * @author <a href="mailto:sguilhen at redhat.com">Stefan Guilhen</a>
+ */
+public class MemoryOnlyACLStrategy implements ACLPersistenceStrategy
+{
+   
+   private static final Map<Resource, ACL> acls = new HashMap<Resource, ACL>();
+   
+   /*
+    * (non-Javadoc)
+    * @see org.jboss.security.acl.ACLPersistenceStrategy#createACL(org.jboss.security.authorization.Resource)
+    */
+   public ACL createACL(Resource resource)
+   {
+      ACL acl = new ACLImpl(resource);
+      acls.put(resource, acl);
+      return acl;
+   }
+
+   /*
+    * (non-Javadoc)
+    * @see org.jboss.security.acl.ACLPersistenceStrategy#createACL(org.jboss.security.authorization.Resource, java.util.Collection)
+    */
+   public ACL createACL(Resource resource, Collection<ACLEntry> entries)
+   {
+      ACL acl = new ACLImpl(resource.toString(), entries);
+      acls.put(resource, acl);
+      return acl;
+   }
+
+   /*
+    * (non-Javadoc)
+    * @see org.jboss.security.acl.ACLPersistenceStrategy#getACL(org.jboss.security.authorization.Resource)
+    */
+   public ACL getACL(Resource resource)
+   {
+      return acls.get(resource);
+   }
+
+   /*
+    * (non-Javadoc)
+    * @see org.jboss.security.acl.ACLPersistenceStrategy#getACLs()
+    */
+   public Collection<ACL> getACLs()
+   {
+      return acls.values();
+   }
+
+   /*
+    * (non-Javadoc)
+    * @see org.jboss.security.acl.ACLPersistenceStrategy#removeACL(org.jboss.security.acl.ACL)
+    */
+   public boolean removeACL(ACL acl)
+   {
+      return this.removeACL(acl.getResource());
+   }
+
+   /*
+    * (non-Javadoc)
+    * @see org.jboss.security.acl.ACLPersistenceStrategy#removeACL(org.jboss.security.authorization.Resource)
+    */
+   public boolean removeACL(Resource resource)
+   {
+      ACL removedACL = acls.remove(resource);
+      return removedACL != null;
+   }
+
+   /*
+    * (non-Javadoc)
+    * @see org.jboss.security.acl.ACLPersistenceStrategy#updateACL(org.jboss.security.acl.ACL)
+    */
+   public boolean updateACL(ACL acl)
+   {
+      ACL updatedACL = acls.put(acl.getResource(), acl);
+      return updatedACL != null;
+   }
+}

Added: trunk/picketbox/src/test/resources/config/acl-authorization.conf
===================================================================
--- trunk/picketbox/src/test/resources/config/acl-authorization.conf	                        (rev 0)
+++ trunk/picketbox/src/test/resources/config/acl-authorization.conf	2010-02-28 22:22:04 UTC (rev 46)
@@ -0,0 +1,22 @@
+<?xml version='1.0'?> 
+ 
+<policy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+         xsi:schemaLocation="urn:jboss:security-config:5.0"
+         xmlns="urn:jboss:security-config:5.0"
+         xmlns:jbxb="urn:jboss:security-config:5.0">
+   <application-policy name = "test"> 
+       <authentication>
+          <login-module code = "org.jboss.security.auth.spi.UsersRolesLoginModule"
+             flag = "required"> 
+             <module-option name = "name">1.1</module-option>
+             <module-option name = "succeed">true</module-option>
+             <module-option name = "throwEx">false</module-option> 
+          </login-module> 
+       </authentication> 
+       <acl>
+          <acl-module code="org.jboss.security.acl.ACLProviderImpl" flag="required">
+            <module-option name="persistenceStrategy">org.picketbox.test.pojos.MemoryOnlyACLStrategy</module-option>
+          </acl-module>
+       </acl>
+    </application-policy>  
+</policy> 
\ No newline at end of file

Modified: trunk/picketbox/src/test/resources/defaultRoles.properties
===================================================================
--- trunk/picketbox/src/test/resources/defaultRoles.properties	2010-02-25 03:24:29 UTC (rev 45)
+++ trunk/picketbox/src/test/resources/defaultRoles.properties	2010-02-28 22:22:04 UTC (rev 46)
@@ -1 +1,3 @@
-anil=validuser
\ No newline at end of file
+anil=validuser
+bob=manager,developer
+alice=developer
\ No newline at end of file

Modified: trunk/picketbox/src/test/resources/defaultUsers.properties
===================================================================
--- trunk/picketbox/src/test/resources/defaultUsers.properties	2010-02-25 03:24:29 UTC (rev 45)
+++ trunk/picketbox/src/test/resources/defaultUsers.properties	2010-02-28 22:22:04 UTC (rev 46)
@@ -1 +1,3 @@
-anil=pass
\ No newline at end of file
+anil=pass
+bob=bobpass
+alice=alicepass
\ No newline at end of file




More information about the jboss-cvs-commits mailing list