[seam-commits] Seam SVN: r12451 - in modules/security/trunk/impl: src/main/java/org/jboss/seam/security and 4 other directories.

seam-commits at lists.jboss.org seam-commits at lists.jboss.org
Tue Apr 13 06:22:30 EDT 2010


Author: shane.bryzak at jboss.com
Date: 2010-04-13 06:22:26 -0400 (Tue, 13 Apr 2010)
New Revision: 12451

Added:
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/callbacks/
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/crypto/
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/jaas/
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/jaas/SeamLoginModule.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/management/
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/management/IdentityManager.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/management/JpaIdentityStore.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/management/action/RoleAction.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/management/action/UserAction.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/management/action/UserSearch.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/permission/
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/permission/JpaPermissionStore.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/permission/RuleBasedPermissionResolver.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/util/
Removed:
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/jaas/SeamLoginModule.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/management/IdentityManager.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/management/IdentityStoreEntityClasses.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/management/JpaIdentityStore.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/management/JpaIdentityStoreConfig.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/management/action/RoleAction.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/management/action/UserAction.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/management/action/UserSearch.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/permission/JpaPermissionStore.java
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/permission/RuleBasedPermissionResolver.java
Modified:
   modules/security/trunk/impl/pom.xml
   modules/security/trunk/impl/src/main/java/org/jboss/seam/security/IdentityImpl.java
Log:
refactored


Modified: modules/security/trunk/impl/pom.xml
===================================================================
--- modules/security/trunk/impl/pom.xml	2010-04-13 10:16:35 UTC (rev 12450)
+++ modules/security/trunk/impl/pom.xml	2010-04-13 10:22:26 UTC (rev 12451)
@@ -51,6 +51,13 @@
          <groupId>org.jboss.seam</groupId>
          <artifactId>seam-persistence</artifactId>
       </dependency>
+
+      <dependency>
+         <groupId>org.jboss.seam.security</groupId>
+         <artifactId>seam-security-api</artifactId>
+         <version>${project.version}</version>
+         <scope>compile</scope>
+      </dependency>
        
       <dependency>
          <groupId>org.hibernate</groupId>

Modified: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/IdentityImpl.java
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/IdentityImpl.java	2010-04-13 10:16:35 UTC (rev 12450)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/IdentityImpl.java	2010-04-13 10:22:26 UTC (rev 12451)
@@ -46,13 +46,13 @@
 import org.slf4j.LoggerFactory;
 
 /**
- * API for authorization and authentication via Seam security.
+ * Identity implementation for authorization and authentication via Seam security.
  * 
  * @author Shane Bryzak
  */
 @Named
 @SessionScoped
-public class Identity implements Serializable
+public class IdentityImpl implements Identity, Serializable
 {
    private static final long serialVersionUID = 3751659008033189259L;
    
@@ -98,24 +98,12 @@
       securityEnabled = enabled;
    }
    
-   /**
-    * Simple check that returns true if the user is logged in, without attempting to authenticate
-    * 
-    * @return true if the user is logged in
-    */
    public boolean isLoggedIn()
    {
       // If there is a principal set, then the user is logged in.
       return getPrincipal() != null;
    }
    
-   /**
-    * Will attempt to authenticate quietly if the user's credentials are set and they haven't
-    * authenticated already.  A quiet authentication doesn't throw any exceptions if authentication
-    * fails.
-    * 
-    * @return true if the user is logged in, false otherwise
-    */
    public boolean tryLogin()
    {      
       if (!authenticating && getPrincipal() == null && credentials.isSet() && 
@@ -198,18 +186,6 @@
       checkRestriction(expressions.createValueExpression(expr, Boolean.class).toUnifiedValueExpression());
    }*/
 
-   /**
-    * Attempts to authenticate the user.  This method is distinct to the
-    * authenticate() method in that it raises events in response to whether
-    * authentication is successful or not.  The following events may be raised
-    * by calling login():
-    * 
-    * org.jboss.seam.security.loginSuccessful - raised when authentication is successful
-    * org.jboss.seam.security.loginFailed - raised when authentication fails
-    * org.jboss.seam.security.alreadyLoggedIn - raised if the user is already authenticated
-    * 
-    * @return String returns "loggedIn" if user is authenticated, or null if not.
-    */
    public String login()
    {
       try
@@ -259,11 +235,6 @@
       return null;
    }
    
-   /**
-    * Attempts a quiet login, suppressing any login exceptions and not creating
-    * any faces messages. This method is intended to be used primarily as an
-    * internal API call, however has been made public for convenience.
-    */
    public void quietLogin()
    {
       try
@@ -475,12 +446,6 @@
       }
    }
 
-   /**
-    * Checks if the authenticated user is a member of the specified role.
-    * 
-    * @param role String The name of the role to check
-    * @return boolean True if the user is a member of the specified role
-    */
    public boolean hasRole(String role)
    {
       if (!securityEnabled) return true;
@@ -498,14 +463,6 @@
       return false;
    }
    
-   /**
-    * Adds a role to the authenticated user.  If the user is not logged in,
-    * the role will be added to a list of roles that will be granted to the
-    * user upon successful authentication, but only during the authentication
-    * process.
-    * 
-    * @param role The name of the role to add
-    */
    public boolean addRole(String role)
    {
       if (role == null || "".equals(role)) return false;
@@ -558,13 +515,6 @@
       }
    }
    
-   /**
-    * Checks that the current authenticated user is a member of
-    * the specified role.
-    * 
-    * @param role String The name of the role to check
-    * @throws AuthorizationException if the authenticated user is not a member of the role
-    */
    public void checkRole(String role)
    {
       tryLogin();

Copied: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/callbacks (from rev 12256, modules/security/trunk/core/src/main/java/org/jboss/seam/security/callbacks)

Copied: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/crypto (from rev 12256, modules/security/trunk/core/src/main/java/org/jboss/seam/security/crypto)

Copied: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/jaas (from rev 12256, modules/security/trunk/core/src/main/java/org/jboss/seam/security/jaas)

Deleted: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/jaas/SeamLoginModule.java
===================================================================
--- modules/security/trunk/core/src/main/java/org/jboss/seam/security/jaas/SeamLoginModule.java	2010-03-24 09:14:40 UTC (rev 12256)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/jaas/SeamLoginModule.java	2010-04-13 10:22:26 UTC (rev 12451)
@@ -1,150 +0,0 @@
-package org.jboss.seam.security.jaas;
-
-import static org.jboss.seam.security.Identity.ROLES_GROUP;
-
-import java.security.acl.Group;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import javax.security.auth.Subject;
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.NameCallback;
-import javax.security.auth.callback.PasswordCallback;
-import javax.security.auth.login.LoginException;
-import javax.security.auth.spi.LoginModule;
-
-import org.jboss.seam.security.SimpleGroup;
-import org.jboss.seam.security.SimplePrincipal;
-import org.jboss.seam.security.callbacks.AuthenticatorCallback;
-import org.jboss.seam.security.callbacks.IdentityCallback;
-import org.jboss.seam.security.callbacks.IdentityManagerCallback;
-import org.jboss.seam.security.management.IdentityManager;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Performs authentication using a Seam component or Identity Management
- * 
- * @author Shane Bryzak
- */
-public class SeamLoginModule implements LoginModule
-{   
-   private Logger log = LoggerFactory.getLogger(SeamLoginModule.class);
-   
-   protected Set<String> roles = new HashSet<String>();
-   
-   protected Subject subject;
-   protected Map<String,?> options;
-   protected CallbackHandler callbackHandler;
-   
-   protected String username;
-   
-   public boolean abort() throws LoginException
-   {
-      return true;
-   }
-
-   public boolean commit() throws LoginException
-   {        
-      subject.getPrincipals().add(new SimplePrincipal(username));
-      
-      Group roleGroup = null;
-      
-      for ( Group g : subject.getPrincipals(Group.class) )      
-      {
-         if ( ROLES_GROUP.equalsIgnoreCase( g.getName() ) )
-         {
-            roleGroup = g;
-            break;
-         }
-      }
-
-      if (roleGroup == null) roleGroup = new SimpleGroup(ROLES_GROUP);
-
-      for (String role : roles)
-      {
-         roleGroup.addMember(new SimplePrincipal(role));
-      }
-      
-      subject.getPrincipals().add(roleGroup);
-      
-      return true;
-   }
-
-   public void initialize(Subject subject, CallbackHandler callbackHandler,
-         Map<String, ?> sharedState, Map<String, ?> options)
-   {
-      this.subject = subject;
-      this.options = options;
-      this.callbackHandler = callbackHandler;
-   }
-
-   public boolean login() 
-      throws LoginException
-   {      
-      PasswordCallback cbPassword = null; 
-      try
-      {
-         NameCallback cbName = new NameCallback("Enter username");
-         cbPassword = new PasswordCallback("Enter password", false);
-         
-         IdentityCallback idCallback = new IdentityCallback();
-         AuthenticatorCallback authCallback = new AuthenticatorCallback();
-         IdentityManagerCallback idmCallback = new IdentityManagerCallback();
-      
-         // Get the username, password and identity from the callback handler
-         callbackHandler.handle(new Callback[] { cbName, cbPassword, idCallback, authCallback, idmCallback });
-         
-         username = cbName.getName();
-         
-         // If an authenticator method has been specified, use that to authenticate
-         if (authCallback.getAuthenticator() != null)
-         {
-            return authCallback.getAuthenticator().authenticate();
-         }
-                  
-         // Otherwise if identity management is enabled, use it.
-         IdentityManager identityManager = idmCallback.getIdentityManager();
-         if (identityManager != null && identityManager.isEnabled())
-         {            
-            boolean success = identityManager.authenticate(username, 
-                  new String(cbPassword.getPassword()));
-            
-            if (success)
-            {
-               for (String role : identityManager.getImpliedRoles(username))
-               {
-                  idCallback.getIdentity().addRole(role);
-               }
-            }
-            
-            return success;
-         }
-         else
-         {
-            log.error("No authentication method defined - " +
-                  "please define authenticate-method for <security:identity/> in components.xml");
-            throw new LoginException("No authentication method defined");
-         }
-      }
-      catch (Exception ex)
-      {
-         log.error("Error logging in", ex);
-         LoginException le = new LoginException(ex.getMessage());
-         le.initCause(ex);
-         throw le;
-      }      
-      finally
-      {
-         cbPassword.clearPassword();
-      }
-   }
-
-   public boolean logout() throws LoginException
-   {
-      return true;
-   }
-}

Copied: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/jaas/SeamLoginModule.java (from rev 12320, modules/security/trunk/core/src/main/java/org/jboss/seam/security/jaas/SeamLoginModule.java)
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/jaas/SeamLoginModule.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/jaas/SeamLoginModule.java	2010-04-13 10:22:26 UTC (rev 12451)
@@ -0,0 +1,149 @@
+package org.jboss.seam.security.jaas;
+
+import static org.jboss.seam.security.Identity.ROLES_GROUP;
+
+import java.security.acl.Group;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.spi.LoginModule;
+
+import org.jboss.seam.security.SimpleGroup;
+import org.jboss.seam.security.SimplePrincipal;
+import org.jboss.seam.security.callbacks.AuthenticatorCallback;
+import org.jboss.seam.security.callbacks.IdentityCallback;
+import org.jboss.seam.security.callbacks.IdentityManagerCallback;
+import org.jboss.seam.security.management.IdentityManager;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Performs authentication using a Seam component or Identity Management
+ * 
+ * @author Shane Bryzak
+ */
+public class SeamLoginModule implements LoginModule
+{   
+   private Logger log = LoggerFactory.getLogger(SeamLoginModule.class);
+   
+   protected Set<String> roles = new HashSet<String>();
+   
+   protected Subject subject;
+   protected Map<String,?> options;
+   protected CallbackHandler callbackHandler;
+   
+   protected String username;
+   
+   public boolean abort() throws LoginException
+   {
+      return true;
+   }
+
+   public boolean commit() throws LoginException
+   {        
+      subject.getPrincipals().add(new SimplePrincipal(username));
+      
+      Group roleGroup = null;
+      
+      for ( Group g : subject.getPrincipals(Group.class) )      
+      {
+         if ( ROLES_GROUP.equalsIgnoreCase( g.getName() ) )
+         {
+            roleGroup = g;
+            break;
+         }
+      }
+
+      if (roleGroup == null) roleGroup = new SimpleGroup(ROLES_GROUP);
+
+      for (String role : roles)
+      {
+         roleGroup.addMember(new SimplePrincipal(role));
+      }
+      
+      subject.getPrincipals().add(roleGroup);
+      
+      return true;
+   }
+
+   public void initialize(Subject subject, CallbackHandler callbackHandler,
+         Map<String, ?> sharedState, Map<String, ?> options)
+   {
+      this.subject = subject;
+      this.options = options;
+      this.callbackHandler = callbackHandler;
+   }
+
+   public boolean login() 
+      throws LoginException
+   {      
+      PasswordCallback cbPassword = null; 
+      try
+      {
+         NameCallback cbName = new NameCallback("Enter username");
+         cbPassword = new PasswordCallback("Enter password", false);
+         
+         IdentityCallback idCallback = new IdentityCallback();
+         AuthenticatorCallback authCallback = new AuthenticatorCallback();
+         IdentityManagerCallback idmCallback = new IdentityManagerCallback();
+      
+         // Get the username, password and identity from the callback handler
+         callbackHandler.handle(new Callback[] { cbName, cbPassword, idCallback, authCallback, idmCallback });
+         
+         username = cbName.getName();
+         
+         // If an authenticator method has been specified, use that to authenticate
+         if (authCallback.getAuthenticator() != null)
+         {
+            return authCallback.getAuthenticator().authenticate();
+         }
+                  
+         // Otherwise if identity management is enabled, use it.
+         IdentityManager identityManager = idmCallback.getIdentityManager();
+         if (identityManager != null && identityManager.isEnabled())
+         {            
+            boolean success = identityManager.authenticate(username, 
+                  new String(cbPassword.getPassword()));
+            
+            if (success)
+            {
+               for (String role : identityManager.getImpliedRoles(username))
+               {
+                  idCallback.getIdentity().addRole(role);
+               }
+            }
+            
+            return success;
+         }
+         else
+         {
+            log.error("No Authenticator bean found.");
+            throw new LoginException("No Authenticator bean found");
+         }
+      }
+      catch (Exception ex)
+      {
+         log.error("Error logging in", ex);
+         LoginException le = new LoginException(ex.getMessage());
+         le.initCause(ex);
+         throw le;
+      }      
+      finally
+      {
+         cbPassword.clearPassword();
+      }
+   }
+
+   public boolean logout() throws LoginException
+   {
+      return true;
+   }
+}

Copied: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/management (from rev 12256, modules/security/trunk/core/src/main/java/org/jboss/seam/security/management)

Deleted: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/management/IdentityManager.java
===================================================================
--- modules/security/trunk/core/src/main/java/org/jboss/seam/security/management/IdentityManager.java	2010-03-24 09:14:40 UTC (rev 12256)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/management/IdentityManager.java	2010-04-13 10:22:26 UTC (rev 12451)
@@ -1,268 +0,0 @@
-package org.jboss.seam.security.management;
-
-import java.io.Serializable;
-import java.security.Principal;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
-import javax.enterprise.context.RequestScoped;
-import javax.enterprise.inject.spi.BeanManager;
-import javax.inject.Inject;
-import javax.inject.Named;
-
-import org.jboss.seam.security.Identity;
-import org.jboss.seam.security.util.Strings;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Identity Management API, deals with user name/password-based identity management.
- * 
- * @author Shane Bryzak
- */
- at Named
- at RequestScoped
-public class IdentityManager implements Serializable
-{
-   private static final long serialVersionUID = 6864253169970552893L;
-   
-   public static final String USER_PERMISSION_NAME = "seam.user";
-   public static final String ROLE_PERMISSION_NAME = "seam.role";
-   
-   public static final String PERMISSION_CREATE = "create";
-   public static final String PERMISSION_READ = "read";
-   public static final String PERMISSION_UPDATE = "update";
-   public static final String PERMISSION_DELETE = "delete";
-   
-   private Logger log = LoggerFactory.getLogger(IdentityManager.class);
-   
-   @Inject BeanManager manager;
-   @Inject Identity identity;
-   
-   @Inject private IdentityStore identityStore;
-   private IdentityStore roleIdentityStore;
-   
-   @Inject
-   public void create()
-   {
-      if (roleIdentityStore == null && identityStore != null)
-      {
-         roleIdentityStore = identityStore;
-      }
-      
-      if (identityStore == null || roleIdentityStore == null)
-      {
-         log.warn("no identity store available - please configure an identityStore if identity " +
-               "management is required.");
-      }
-   }
-   
-   public boolean createUser(String name, String password)
-   {
-      return createUser(name, password, null, null);
-   }
-
-   public boolean createUser(String name, String password, String firstname, String lastname)
-   {
-      identity.checkPermission(USER_PERMISSION_NAME, PERMISSION_CREATE);
-      return identityStore.createUser(name, password, firstname, lastname);
-   }
-   
-   public boolean deleteUser(String name)
-   {
-      identity.checkPermission(USER_PERMISSION_NAME, PERMISSION_DELETE);
-      return identityStore.deleteUser(name);
-   }
-   
-   public boolean enableUser(String name)
-   {
-      identity.checkPermission(USER_PERMISSION_NAME, PERMISSION_UPDATE);
-      return identityStore.enableUser(name);
-   }
-   
-   public boolean disableUser(String name)
-   {
-      identity.checkPermission(USER_PERMISSION_NAME, PERMISSION_UPDATE);
-      return identityStore.disableUser(name);
-   }
-   
-   public boolean changePassword(String name, String password)
-   {
-      identity.checkPermission(USER_PERMISSION_NAME, PERMISSION_UPDATE);
-      return identityStore.changePassword(name, password);
-   }
-   
-   public boolean isUserEnabled(String name)
-   {
-      identity.checkPermission(USER_PERMISSION_NAME, PERMISSION_READ);
-      return identityStore.isUserEnabled(name);
-   }
-   
-   public boolean grantRole(String name, String role)
-   {
-      identity.checkPermission(USER_PERMISSION_NAME, PERMISSION_UPDATE);
-      return roleIdentityStore.grantRole(name, role);
-   }
-   
-   public boolean revokeRole(String name, String role)
-   {
-      identity.checkPermission(USER_PERMISSION_NAME, PERMISSION_UPDATE);
-      return roleIdentityStore.revokeRole(name, role);
-   }
-   
-   public boolean createRole(String role)
-   {
-      identity.checkPermission(ROLE_PERMISSION_NAME, PERMISSION_CREATE);
-      return roleIdentityStore.createRole(role);
-   }
-   
-   public boolean deleteRole(String role)
-   {
-      identity.checkPermission(ROLE_PERMISSION_NAME, PERMISSION_DELETE);
-      return roleIdentityStore.deleteRole(role);
-   }
-   
-   public boolean addRoleToGroup(String role, String group)
-   {
-      identity.checkPermission(ROLE_PERMISSION_NAME, PERMISSION_UPDATE);
-      return roleIdentityStore.addRoleToGroup(role, group);
-   }
-   
-   public boolean removeRoleFromGroup(String role, String group)
-   {
-      identity.checkPermission(ROLE_PERMISSION_NAME, PERMISSION_UPDATE);
-      return roleIdentityStore.removeRoleFromGroup(role, group);
-   }
-   
-   public boolean userExists(String name)
-   {
-      identity.checkPermission(USER_PERMISSION_NAME, PERMISSION_READ);
-      return identityStore.userExists(name);
-   }
-   
-   public boolean roleExists(String name)
-   {
-      return roleIdentityStore.roleExists(name);
-   }
-   
-   public List<String> listUsers()
-   {
-      identity.checkPermission(USER_PERMISSION_NAME, PERMISSION_READ);
-      List<String> users = identityStore.listUsers();
-      
-      Collections.sort(users, new Comparator<String>() {
-         public int compare(String value1, String value2) {
-            return value1.compareTo(value2);
-         }
-      });
-      
-      return users;
-   }
-   
-   public List<String> listUsers(String filter)
-   {
-      identity.checkPermission(USER_PERMISSION_NAME, PERMISSION_READ);
-      List<String> users = identityStore.listUsers(filter);
-      
-      Collections.sort(users, new Comparator<String>() {
-         public int compare(String value1, String value2) {
-            return value1.compareTo(value2);
-         }
-      });
-      
-      return users;
-   }
-   
-   public List<String> listRoles()
-   {
-      identity.checkPermission(ROLE_PERMISSION_NAME, PERMISSION_READ);
-      List<String> roles = roleIdentityStore.listRoles();
-      
-      Collections.sort(roles, new Comparator<String>() {
-         public int compare(String value1, String value2) {
-            return value1.compareTo(value2);
-         }
-      });
-      
-      return roles;
-   }
-   
-   public List<String> listGrantableRoles()
-   {
-      List<String> roles = roleIdentityStore.listGrantableRoles();
-      
-      Collections.sort(roles, new Comparator<String>() {
-         public int compare(String value1, String value2) {
-            return value1.compareTo(value2);
-         }
-      });
-      
-      return roles;
-   }
-   
-   /**
-    * Returns a list of the roles that are explicitly granted to the specified user;
-    * 
-    * @param name The user for which to return a list of roles
-    * @return List containing the names of the granted roles
-    */
-   public List<String> getGrantedRoles(String name)
-   {
-      return roleIdentityStore.getGrantedRoles(name);
-   }
-   
-   /**
-    * Returns a list of roles that are either explicitly or indirectly granted to the specified user.
-    * 
-    * @param name The user for which to return the list of roles
-    * @return List containing the names of the implied roles
-    */
-   public List<String> getImpliedRoles(String name)
-   {
-      return roleIdentityStore.getImpliedRoles(name);
-   }
-   
-   public List<Principal> listMembers(String role)
-   {
-      identity.checkPermission(ROLE_PERMISSION_NAME, PERMISSION_READ);
-      return roleIdentityStore.listMembers(role);
-   }
-   
-   public List<String> getRoleGroups(String name)
-   {
-      return roleIdentityStore.getRoleGroups(name);
-   }
-   
-   public boolean authenticate(String username, String password)
-   {
-      if (Strings.isEmpty(username)) return false;
-      return identityStore.authenticate(username, password);
-   }
-   
-   public IdentityStore getIdentityStore()
-   {
-      return identityStore;
-   }
-   
-   public void setIdentityStore(IdentityStore identityStore)
-   {
-      this.identityStore = identityStore;
-   }
-   
-   public IdentityStore getRoleIdentityStore()
-   {
-      return roleIdentityStore;
-   }
-   
-   public void setRoleIdentityStore(IdentityStore roleIdentityStore)
-   {
-      this.roleIdentityStore = roleIdentityStore;
-   }
-   
-   public boolean isEnabled()
-   {
-      return identityStore != null && roleIdentityStore != null;
-   }
-   
-}

Copied: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/management/IdentityManager.java (from rev 12399, modules/security/trunk/core/src/main/java/org/jboss/seam/security/management/IdentityManager.java)
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/management/IdentityManager.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/management/IdentityManager.java	2010-04-13 10:22:26 UTC (rev 12451)
@@ -0,0 +1,274 @@
+package org.jboss.seam.security.management;
+
+import java.io.Serializable;
+import java.security.Principal;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import javax.annotation.PostConstruct;
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.jboss.seam.security.Identity;
+import org.jboss.seam.security.util.Strings;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Identity Management API, deals with user name/password-based identity management.
+ * 
+ * @author Shane Bryzak
+ */
+ at Named @ApplicationScoped
+public class IdentityManager implements Serializable
+{
+   private static final long serialVersionUID = 6864253169970552893L;
+   
+   public static final String USER_PERMISSION_NAME = "seam.user";
+   public static final String ROLE_PERMISSION_NAME = "seam.role";
+   
+   public static final String PERMISSION_CREATE = "create";
+   public static final String PERMISSION_READ = "read";
+   public static final String PERMISSION_UPDATE = "update";
+   public static final String PERMISSION_DELETE = "delete";
+   
+   private Logger log = LoggerFactory.getLogger(IdentityManager.class);
+   
+   @Inject BeanManager manager;
+   @Inject Identity identity;
+   
+   private IdentityStore identityStore;
+   private IdentityStore roleIdentityStore;
+   
+   @PostConstruct
+   public void create()
+   {
+      if (roleIdentityStore == null && identityStore != null)
+      {
+         roleIdentityStore = identityStore;
+      }
+      
+      if (identityStore == null)
+      {
+         log.warn("No identity store available - please configure an identityStore if identity " +
+               "management is required.");
+      }
+      
+      if (roleIdentityStore == null)
+      {
+         log.warn("No role identity store available - please configure a roleIdentityStore if identity " +
+               "management is required.");
+      }
+   }
+   
+   public boolean createUser(String name, String password)
+   {
+      return createUser(name, password, null, null);
+   }
+
+   public boolean createUser(String name, String password, String firstname, String lastname)
+   {
+      identity.checkPermission(USER_PERMISSION_NAME, PERMISSION_CREATE);
+      return identityStore.createUser(name, password, firstname, lastname);
+   }
+   
+   public boolean deleteUser(String name)
+   {
+      identity.checkPermission(USER_PERMISSION_NAME, PERMISSION_DELETE);
+      return identityStore.deleteUser(name);
+   }
+   
+   public boolean enableUser(String name)
+   {
+      identity.checkPermission(USER_PERMISSION_NAME, PERMISSION_UPDATE);
+      return identityStore.enableUser(name);
+   }
+   
+   public boolean disableUser(String name)
+   {
+      identity.checkPermission(USER_PERMISSION_NAME, PERMISSION_UPDATE);
+      return identityStore.disableUser(name);
+   }
+   
+   public boolean changePassword(String name, String password)
+   {
+      identity.checkPermission(USER_PERMISSION_NAME, PERMISSION_UPDATE);
+      return identityStore.changePassword(name, password);
+   }
+   
+   public boolean isUserEnabled(String name)
+   {
+      identity.checkPermission(USER_PERMISSION_NAME, PERMISSION_READ);
+      return identityStore.isUserEnabled(name);
+   }
+   
+   public boolean grantRole(String name, String role)
+   {
+      identity.checkPermission(USER_PERMISSION_NAME, PERMISSION_UPDATE);
+      return roleIdentityStore.grantRole(name, role);
+   }
+   
+   public boolean revokeRole(String name, String role)
+   {
+      identity.checkPermission(USER_PERMISSION_NAME, PERMISSION_UPDATE);
+      return roleIdentityStore.revokeRole(name, role);
+   }
+   
+   public boolean createRole(String role)
+   {
+      identity.checkPermission(ROLE_PERMISSION_NAME, PERMISSION_CREATE);
+      return roleIdentityStore.createRole(role);
+   }
+   
+   public boolean deleteRole(String role)
+   {
+      identity.checkPermission(ROLE_PERMISSION_NAME, PERMISSION_DELETE);
+      return roleIdentityStore.deleteRole(role);
+   }
+   
+   public boolean addRoleToGroup(String role, String group)
+   {
+      identity.checkPermission(ROLE_PERMISSION_NAME, PERMISSION_UPDATE);
+      return roleIdentityStore.addRoleToGroup(role, group);
+   }
+   
+   public boolean removeRoleFromGroup(String role, String group)
+   {
+      identity.checkPermission(ROLE_PERMISSION_NAME, PERMISSION_UPDATE);
+      return roleIdentityStore.removeRoleFromGroup(role, group);
+   }
+   
+   public boolean userExists(String name)
+   {
+      identity.checkPermission(USER_PERMISSION_NAME, PERMISSION_READ);
+      return identityStore.userExists(name);
+   }
+   
+   public boolean roleExists(String name)
+   {
+      return roleIdentityStore.roleExists(name);
+   }
+   
+   public List<String> getUsers()
+   {
+      identity.checkPermission(USER_PERMISSION_NAME, PERMISSION_READ);
+      List<String> users = identityStore.listUsers();
+      
+      Collections.sort(users, new Comparator<String>() {
+         public int compare(String value1, String value2) {
+            return value1.compareTo(value2);
+         }
+      });
+      
+      return users;
+   }
+   
+   public List<String> getUsers(String filter)
+   {
+      identity.checkPermission(USER_PERMISSION_NAME, PERMISSION_READ);
+      List<String> users = identityStore.listUsers(filter);
+      
+      Collections.sort(users, new Comparator<String>() {
+         public int compare(String value1, String value2) {
+            return value1.compareTo(value2);
+         }
+      });
+      
+      return users;
+   }
+   
+   public List<String> getRoles()
+   {
+      identity.checkPermission(ROLE_PERMISSION_NAME, PERMISSION_READ);
+      List<String> roles = roleIdentityStore.listRoles();
+      
+      Collections.sort(roles, new Comparator<String>() {
+         public int compare(String value1, String value2) {
+            return value1.compareTo(value2);
+         }
+      });
+      
+      return roles;
+   }
+   
+   public List<String> getGrantableRoles()
+   {
+      List<String> roles = roleIdentityStore.listGrantableRoles();
+      
+      Collections.sort(roles, new Comparator<String>() {
+         public int compare(String value1, String value2) {
+            return value1.compareTo(value2);
+         }
+      });
+      
+      return roles;
+   }
+   
+   /**
+    * Returns a list of the roles that are explicitly granted to the specified user;
+    * 
+    * @param name The user for which to return a list of roles
+    * @return List containing the names of the granted roles
+    */
+   public List<String> getGrantedRoles(String name)
+   {
+      return roleIdentityStore.getGrantedRoles(name);
+   }
+   
+   /**
+    * Returns a list of roles that are either explicitly or indirectly granted to the specified user.
+    * 
+    * @param name The user for which to return the list of roles
+    * @return List containing the names of the implied roles
+    */
+   public List<String> getImpliedRoles(String name)
+   {
+      return roleIdentityStore.getImpliedRoles(name);
+   }
+   
+   public List<Principal> listMembers(String role)
+   {
+      identity.checkPermission(ROLE_PERMISSION_NAME, PERMISSION_READ);
+      return roleIdentityStore.listMembers(role);
+   }
+   
+   public List<String> getRoleGroups(String name)
+   {
+      return roleIdentityStore.getRoleGroups(name);
+   }
+   
+   public boolean authenticate(String username, String password)
+   {
+      if (Strings.isEmpty(username)) return false;
+      return identityStore.authenticate(username, password);
+   }
+   
+   public IdentityStore getIdentityStore()
+   {
+      return identityStore;
+   }
+   
+   public void setIdentityStore(IdentityStore identityStore)
+   {
+      this.identityStore = identityStore;
+   }
+   
+   public IdentityStore getRoleIdentityStore()
+   {
+      return roleIdentityStore;
+   }
+   
+   public void setRoleIdentityStore(IdentityStore roleIdentityStore)
+   {
+      this.roleIdentityStore = roleIdentityStore;
+   }
+   
+   public boolean isEnabled()
+   {
+      return identityStore != null && roleIdentityStore != null;
+   }
+   
+}

Deleted: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/management/IdentityStoreEntityClasses.java
===================================================================
--- modules/security/trunk/core/src/main/java/org/jboss/seam/security/management/IdentityStoreEntityClasses.java	2010-03-24 09:14:40 UTC (rev 12256)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/management/IdentityStoreEntityClasses.java	2010-04-13 10:22:26 UTC (rev 12451)
@@ -1,16 +0,0 @@
-package org.jboss.seam.security.management;
-
-import javax.enterprise.context.ApplicationScoped;
-
-/**
- * FIXME a hack until we get some proper bean configuration
- * 
- * @author Shane Bryzak
- *
- */
- at ApplicationScoped
-public interface IdentityStoreEntityClasses
-{
-   Class<?> getUserEntityClass();
-   Class<?> getRoleEntityClass();
-}

Deleted: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/management/JpaIdentityStore.java
===================================================================
--- modules/security/trunk/core/src/main/java/org/jboss/seam/security/management/JpaIdentityStore.java	2010-03-24 09:14:40 UTC (rev 12256)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/management/JpaIdentityStore.java	2010-04-13 10:22:26 UTC (rev 12451)
@@ -1,912 +0,0 @@
-package org.jboss.seam.security.management;
-
-import java.io.Serializable;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.security.GeneralSecurityException;
-import java.security.Principal;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import javax.enterprise.context.RequestScoped;
-import javax.inject.Inject;
-import javax.enterprise.inject.Instance;
-import javax.enterprise.inject.spi.BeanManager;
-import javax.persistence.EntityManager;
-import javax.persistence.NoResultException;
-import javax.persistence.PersistenceContext;
-
-import org.jboss.seam.security.Role;
-import org.jboss.seam.security.SimplePrincipal;
-import org.jboss.seam.security.crypto.BinTools;
-import org.jboss.seam.security.events.PrePersistUserEvent;
-import org.jboss.seam.security.events.PrePersistUserRoleEvent;
-import org.jboss.seam.security.events.UserAuthenticatedEvent;
-import org.jboss.seam.security.events.UserCreatedEvent;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * The default identity store implementation, uses JPA as its persistence mechanism.
- * 
- * @author Shane Bryzak
- */
- at RequestScoped
-public class JpaIdentityStore implements IdentityStore, Serializable
-{
-   private static final long serialVersionUID = 1171875389743972646L;
-
-   protected FeatureSet featureSet;
-
-   private Logger log = LoggerFactory.getLogger(JpaIdentityStore.class);
-          
-   @PersistenceContext EntityManager entityManager;
-   
-   @Inject Instance<PasswordHash> passwordHashInstance;
-  
-   private JpaIdentityStoreConfig config;
-   private BeanManager manager;
-   
-   public Set<Feature> getFeatures()
-   {
-      return featureSet.getFeatures();
-   }
-   
-   public void setFeatures(Set<Feature> features)
-   {
-      featureSet = new FeatureSet(features);
-   }
-   
-   public boolean supportsFeature(Feature feature)
-   {
-      return featureSet.supports(feature);
-   }
-   
-   @Inject
-   public void init(JpaIdentityStoreConfig config, BeanManager manager)
-   {
-      this.config = config;
-      this.manager = manager;
-      
-      if (featureSet == null)
-      {
-         featureSet = new FeatureSet();
-         featureSet.enableAll();
-      }
-      
-      if (config.getUserEntityClass() == null)
-      {
-         log.error("Error in JpaIdentityStore configuration - userClass must be configured.");
-         return;
-      }
-   }
-   
-   public boolean createUser(String username, String password, String firstname, String lastname)
-   {
-      try
-      {
-         if (config.getUserEntityClass() == null)
-         {
-            throw new IdentityManagementException("Could not create account, userClass not set");
-         }
-         
-         if (userExists(username))
-         {
-            throw new IdentityManagementException("Could not create account, already exists");
-         }
-         
-         Object user = config.getUserEntityClass().newInstance();
-
-         config.getUserPrincipalProperty().setValue(user, username);
-
-         if (config.getUserFirstNameProperty().isSet()) config.getUserFirstNameProperty().setValue(user, firstname);
-         if (config.getUserLastNameProperty().isSet()) config.getUserLastNameProperty().setValue(user, lastname);
-         
-         if (password == null)
-         {
-            if (config.getUserEnabledProperty().isSet()) config.getUserEnabledProperty().setValue(user, false);
-         }
-         else
-         {
-            setUserPassword(user, password);
-            if (config.getUserEnabledProperty().isSet()) config.getUserEnabledProperty().setValue(user, true);
-         }
-         
-         manager.fireEvent(new PrePersistUserEvent(user));
-         
-         entityManager.persist(user);
-
-         manager.fireEvent(new UserCreatedEvent(user));
-         
-         return true;
-      }
-      catch (Exception ex)
-      {
-         if (ex instanceof IdentityManagementException)
-         {
-            throw (IdentityManagementException) ex;
-         }
-         else
-         {
-            throw new IdentityManagementException("Could not create account", ex);
-         }
-      }
-   }
-   
-   protected void setUserPassword(Object user, String password)
-   {
-      if (config.getPasswordSaltProperty().isSet())
-      {
-         byte[] salt = generateUserSalt(user);
-         config.getPasswordSaltProperty().setValue(user, BinTools.bin2hex(salt));
-         config.getUserPasswordProperty().setValue(user, generatePasswordHash(password, salt));
-      }
-      else
-      {
-         config.getUserPasswordProperty().setValue(user, generatePasswordHash(password, getUserAccountSalt(user)));
-      }
-   }
-   
-   /**
-    * @deprecated Use JpaIdentityStore.generateRandomSalt(Object) instead
-    */
-   @Deprecated
-   protected String getUserAccountSalt(Object user)
-   {
-      // By default, we'll use the user's username as the password salt
-      return config.getUserPrincipalProperty().getValue(user).toString();
-   }
-   
-   /**
-    * Generates a 64 bit random salt value
-    */
-   public byte[] generateUserSalt(Object user)
-   {
-      return getPasswordHash().generateRandomSalt();
-   }
-   
-   public boolean createUser(String username, String password)
-   {
-      return createUser(username, password, null, null);
-   }
-   
-   public boolean deleteUser(String name)
-   {
-      Object user = lookupUser(name);
-      if (user == null)
-      {
-         throw new NoSuchUserException("Could not delete, user '" + name + "' does not exist");
-      }
-      
-      entityManager.remove(user);
-      return true;
-   }
-   
-   @SuppressWarnings("unchecked")
-   public boolean grantRole(String username, String role)
-   {
-      if (config.getRoleEntityClass() == null) return false;
-      
-      Object user = lookupUser(username);
-      if (user == null)
-      {
-         if (config.getUserPasswordProperty().isSet())
-         {
-            // If no userPasswordProperty is set, it means that authentication is being performed
-            // by another identity store and this one is just managing roles
-            throw new NoSuchUserException("Could not grant role, no such user '" + username + "'");
-         }
-         else
-         {
-            // We need to create a new user object
-            if (createUser(username, null))
-            {
-               user = lookupUser(username);
-            }
-            else
-            {
-               throw new IdentityManagementException(
-                     "Could not grant role - user does not exist and an attempt to create the user failed.");
-            }
-         }
-      }
-      
-      Object roleToGrant = lookupRole(role);
-      if (roleToGrant == null)
-      {
-         throw new NoSuchRoleException("Could not grant role, role '" + role + "' does not exist");
-      }
-      
-      Collection<?> userRoles = (Collection<?>) config.getUserRolesProperty().getValue(user);
-      if (userRoles == null)
-      {
-         Type propType = config.getUserRolesProperty().getPropertyType();
-         Class<?> collectionType;
-         
-         if (propType instanceof Class && Collection.class.isAssignableFrom((Class<?>) propType))
-         {
-            collectionType = (Class<?>) propType;
-         }
-         else if (propType instanceof ParameterizedType &&
-                  Collection.class.isAssignableFrom((Class<?>) ((ParameterizedType) propType).getRawType()))
-         {
-            collectionType = (Class<?>) ((ParameterizedType) propType).getRawType();
-         }
-         else
-         {
-            throw new IllegalStateException("Could not determine collection type for user roles.");
-         }
-         
-         // This should either be a Set, or a List...
-         if (Set.class.isAssignableFrom(collectionType))
-         {
-            userRoles = new HashSet<Object>();
-         }
-         else if (List.class.isAssignableFrom(collectionType))
-         {
-            userRoles = new ArrayList<Object>();
-         }
-         
-         config.getUserRolesProperty().setValue(user, userRoles);
-      }
-      else if (((Collection<?>) config.getUserRolesProperty().getValue(user)).contains(roleToGrant))
-      {
-         return false;
-      }
-
-      if (config.getXrefEntityClass() == null)
-      {
-         // If this is a Many-To-Many relationship, simply add the role
-         ((Collection<Object>) config.getUserRolesProperty().getValue(user)).add(roleToGrant);
-      }
-      else
-      {
-         // Otherwise we need to insert a cross-reference entity instance
-         try
-         {
-            Object xref = config.getXrefEntityClass().newInstance();
-            config.getXrefUserProperty().setValue(xref, user);
-            config.getXrefRoleProperty().setValue(xref, roleToGrant);
-            
-            manager.fireEvent(new PrePersistUserRoleEvent(xref));
-            
-            ((Collection<Object>) config.getUserRolesProperty().getValue(user)).add(entityManager.merge(xref));
-         }
-         catch (Exception ex)
-         {
-            throw new IdentityManagementException("Error creating cross-reference role record.", ex);
-         }
-      }
-      
-      return true;
-   }
-   
-   public boolean revokeRole(String username, String role)
-   {
-      Object user = lookupUser(username);
-      if (user == null)
-      {
-         throw new NoSuchUserException("Could not revoke role, no such user '" + username + "'");
-      }
-      
-      Object roleToRevoke = lookupRole(role);
-      if (roleToRevoke == null)
-      {
-         throw new NoSuchRoleException("Could not revoke role, role '" + role + "' does not exist");
-      }
-             
-      boolean success = false;
-      
-      if (config.getXrefEntityClass() == null)
-      {
-         success = ((Collection<?>) config.getUserRolesProperty().getValue(user)).remove(roleToRevoke);
-      }
-      else
-      {
-         Collection<?> roles = ((Collection<?>) config.getUserRolesProperty().getValue(user));
-
-         for (Object xref : roles)
-         {
-            if (config.getXrefRoleProperty().getValue(xref).equals(roleToRevoke))
-            {
-               success = roles.remove(xref);
-               break;
-            }
-         }
-      }
-
-      return success;
-   }
-   
-   @SuppressWarnings("unchecked")
-   public boolean addRoleToGroup(String role, String group)
-   {
-      if (!config.getRoleGroupsProperty().isSet()) return false;
-      
-      Object targetRole = lookupRole(role);
-      if (targetRole == null)
-      {
-         throw new NoSuchUserException("Could not add role to group, no such role '" + role + "'");
-      }
-      
-      Object targetGroup = lookupRole(group);
-      if (targetGroup == null)
-      {
-         throw new NoSuchRoleException("Could not grant role, group '" + group + "' does not exist");
-      }
-      
-      Collection<?> roleGroups = (Collection<?>) config.getRoleGroupsProperty().getValue(targetRole);
-      if (roleGroups == null)
-      {
-         // This should either be a Set, or a List...
-         Class<?> rawType = null;
-         if (config.getRoleGroupsProperty().getPropertyType() instanceof ParameterizedType)
-         {
-            rawType = (Class<?>) ((ParameterizedType) config.getRoleGroupsProperty().getPropertyType()).getRawType();
-         }
-         else
-         {
-            return false;
-         }
-          
-         if (Set.class.isAssignableFrom(rawType))
-         {
-            roleGroups = new HashSet<Object>();
-         }
-         else if (List.class.isAssignableFrom(rawType))
-         {
-            roleGroups = new ArrayList<Object>();
-         }
-         
-         config.getRoleGroupsProperty().setValue(targetRole, roleGroups);
-      }
-      else if (((Collection<?>) config.getRoleGroupsProperty().getValue(targetRole)).contains(targetGroup))
-      {
-         return false;
-      }
-
-      ((Collection<Object>) config.getRoleGroupsProperty().getValue(targetRole)).add(targetGroup);
-      
-      return true;
-   }
-
-   public boolean removeRoleFromGroup(String role, String group)
-   {
-      if (!config.getRoleGroupsProperty().isSet()) return false;
-      
-      Object roleToRemove = lookupRole(role);
-      if (role == null)
-      {
-         throw new NoSuchUserException("Could not remove role from group, no such role '" + role + "'");
-      }
-      
-      Object targetGroup = lookupRole(group);
-      if (targetGroup == null)
-      {
-         throw new NoSuchRoleException("Could not remove role from group, no such group '" + group + "'");
-      }
-       
-      boolean success = ((Collection<?>) config.getRoleGroupsProperty().getValue(roleToRemove)).remove(targetGroup);
-      
-      return success;
-   }
-   
-   public boolean createRole(String role)
-   {
-      try
-      {
-         if (config.getRoleEntityClass() == null)
-         {
-            throw new IdentityManagementException("Could not create role, roleClass not set");
-         }
-         
-         if (roleExists(role))
-         {
-            throw new IdentityManagementException("Could not create role, already exists");
-         }
-         
-         Object instance = config.getRoleEntityClass().newInstance();
-         config.getRoleNameProperty().setValue(instance, role);
-         entityManager.persist(instance);
-         
-         return true;
-      }
-      catch (Exception ex)
-      {
-         if (ex instanceof IdentityManagementException)
-         {
-            throw (IdentityManagementException) ex;
-         }
-         else
-         {
-            throw new IdentityManagementException("Could not create role", ex);
-         }
-      }
-   }
-   
-   public boolean deleteRole(String role)
-   {
-      Object roleToDelete = lookupRole(role);
-      if (roleToDelete == null)
-      {
-         throw new NoSuchRoleException("Could not delete role, role '" + role + "' does not exist");
-      }
-      
-      if (config.getXrefEntityClass() != null)
-      {
-         entityManager.createQuery("delete " + config.getXrefEntityClass().getName() + " where role = :role")
-         .setParameter("role", roleToDelete)
-         .executeUpdate();
-      }
-      else
-      {
-         List<String> users = listUserMembers(role);
-         for (String user : users)
-         {
-            revokeRole(user, role);
-         }
-      }
-      
-      List<String> roles = listRoleMembers(role);
-      for (String r : roles)
-      {
-         removeRoleFromGroup(r, role);
-      }
-            
-      entityManager.remove(roleToDelete);
-      return true;
-   }
-   
-   public boolean enableUser(String name)
-   {
-      if (!config.getUserEnabledProperty().isSet())
-      {
-         log.debug("Can not enable user, no @UserEnabled property configured in userClass " +
-               config.getUserEntityClass().getName());
-         return false;
-      }
-      
-      Object user = lookupUser(name);
-      if (user == null)
-      {
-         throw new NoSuchUserException("Could not enable user, user '" + name + "' does not exist");
-      }
-      
-      // Can't enable an already-enabled user, return false
-      if (((Boolean) config.getUserEnabledProperty().getValue(user)) == true)
-      {
-         return false;
-      }
-      
-      config.getUserEnabledProperty().setValue(user, true);
-      return true;
-   }
-   
-   public boolean disableUser(String name)
-   {
-      if (!config.getUserEnabledProperty().isSet())
-      {
-         log.debug("Can not disable user, no @UserEnabled property configured in userClass " +
-               config.getUserEntityClass().getName());
-         return false;
-      }
-      
-      Object user = lookupUser(name);
-      if (user == null)
-      {
-         throw new NoSuchUserException("Could not disable user, user '" + name + "' does not exist");
-      }
-      
-      // Can't disable an already-disabled user, return false
-      if (((Boolean) config.getUserEnabledProperty().getValue(user)) == false)
-      {
-         return false;
-      }
-      
-      config.getUserEnabledProperty().setValue(user, false);
-      return true;
-   }
-   
-   public boolean changePassword(String username, String password)
-   {
-      Object user = lookupUser(username);
-      if (user == null)
-      {
-         throw new NoSuchUserException("Could not change password, user '" + username + "' does not exist");
-      }
-      
-      setUserPassword(user, password);
-      
-      return true;
-   }
-   
-   public boolean userExists(String name)
-   {
-      return lookupUser(name) != null;
-   }
-   
-   public boolean roleExists(String name)
-   {
-      return lookupRole(name) != null;
-   }
-   
-   public boolean isUserEnabled(String name)
-   {
-      Object user = lookupUser(name);
-      return user != null && (!config.getUserEnabledProperty().isSet() ||
-            (((Boolean) config.getUserEnabledProperty().getValue(user))) == true);
-   }
-   
-   public List<String> getGrantedRoles(String name)
-   {
-      Object user = lookupUser(name);
-      if (user == null)
-      {
-         throw new NoSuchUserException("No such user '" + name + "'");
-      }
-
-      List<String> roles = new ArrayList<String>();
-      
-      Collection<?> userRoles = (Collection<?>) config.getUserRolesProperty().getValue(user);
-      if (userRoles != null)
-      {
-         for (Object role : userRoles)
-         {
-            if (config.getXrefEntityClass() == null)
-            {
-               roles.add((String) config.getRoleNameProperty().getValue(role));
-            }
-            else
-            {
-               Object xref = config.getRoleNameProperty().getValue(role);
-               Object userRole = config.getXrefRoleProperty().getValue(xref);
-               roles.add((String) config.getRoleNameProperty().getValue(userRole));
-            }
-         }
-      }
-      
-      return roles;
-   }
-   
-   public List<String> getRoleGroups(String name)
-   {
-      Object role = lookupRole(name);
-      if (role == null)
-      {
-         throw new NoSuchUserException("No such role '" + name + "'");
-      }
-
-      List<String> groups = new ArrayList<String>();
-      
-      if (config.getRoleGroupsProperty().isSet())
-      {
-         Collection<?> roleGroups = (Collection<?>) config.getRoleGroupsProperty().getValue(role);
-         if (roleGroups != null)
-         {
-            for (Object group : roleGroups)
-            {
-               groups.add((String) config.getRoleNameProperty().getValue(group));
-            }
-         }
-      }
-      
-      return groups;
-   }
-   
-   public List<String> getImpliedRoles(String name)
-   {
-      Object user = lookupUser(name);
-      if (user == null)
-      {
-         throw new NoSuchUserException("No such user '" + name + "'");
-      }
-
-      Set<String> roles = new HashSet<String>();
-      Collection<?> userRoles = (Collection<?>) config.getUserRolesProperty().getValue(user);
-      if (userRoles != null)
-      {
-         for (Object role : userRoles)
-         {
-            addRoleAndMemberships((String) config.getRoleNameProperty().getValue(role), roles);
-         }
-      }
-      
-      return new ArrayList<String>(roles);
-   }
-   
-   private void addRoleAndMemberships(String role, Set<String> roles)
-   {
-      if (roles.add(role))
-      {
-         Object instance = lookupRole(role);
-         
-         if (config.getRoleGroupsProperty().isSet())
-         {
-            Collection<?> groups = (Collection<?>) config.getRoleGroupsProperty().getValue(instance);
-            
-            if (groups != null)
-            {
-               for (Object group : groups)
-               {
-                  addRoleAndMemberships((String) config.getRoleNameProperty().getValue(group), roles);
-               }
-            }
-         }
-      }
-   }
-   
-   public String generatePasswordHash(String password, byte[] salt)
-   {
-      if (config.getPasswordSaltProperty().isSet())
-      {
-         try
-         {
-            return getPasswordHash().createPasswordKey(password.toCharArray(), salt,
-                  config.getUserPasswordProperty().getAnnotation().iterations());
-         }
-         catch (GeneralSecurityException ex)
-         {
-            throw new IdentityManagementException("Exception generating password hash", ex);
-         }
-      }
-      else
-      {
-         return generatePasswordHash(password, new String(salt));
-      }
-   }
-   
-   /**
-    * 
-    * @deprecated Use JpaIdentityStore.generatePasswordHash(String, byte[]) instead
-    */
-   @Deprecated
-   protected String generatePasswordHash(String password, String salt)
-   {
-      String algorithm = config.getUserPasswordProperty().getAnnotation().hash();
-      
-      if (algorithm == null || "".equals(algorithm))
-      {
-         if (salt == null || "".equals(salt))
-         {
-            return getPasswordHash().generateHash(password);
-         }
-         else
-         {
-            return getPasswordHash().generateSaltedHash(password, salt);
-         }
-      }
-      else if ("none".equalsIgnoreCase(algorithm))
-      {
-         return password;
-      }
-      else
-      {
-         if (salt == null || "".equals(salt))
-         {
-            return getPasswordHash().generateHash(password, algorithm);
-         }
-         else
-         {
-            return getPasswordHash().generateSaltedHash(password, salt, algorithm);
-         }
-      }
-   }
-   
-   public boolean authenticate(String username, String password)
-   {
-      Object user = lookupUser(username);
-      if (user == null || (config.getUserEnabledProperty().isSet() &&
-            ((Boolean) config.getUserEnabledProperty().getValue(user) == false)))
-      {
-         return false;
-      }
-      
-      String passwordHash = null;
-      
-      if (config.getPasswordSaltProperty().isSet())
-      {
-         String encodedSalt = (String) config.getPasswordSaltProperty().getValue(user);
-         if (encodedSalt == null)
-         {
-            throw new IdentityManagementException("A @PasswordSalt property was found on entity " + user +
-                  ", but it contains no value");
-         }
-         
-         passwordHash = generatePasswordHash(password, BinTools.hex2bin(encodedSalt));
-      }
-      else
-      {
-         passwordHash = generatePasswordHash(password, getUserAccountSalt(user));
-      }
-      
-       
-      boolean success = passwordHash.equals(config.getUserPasswordProperty().getValue(user));
-            
-      if (success)
-      {
-         manager.fireEvent(new UserAuthenticatedEvent(user));
-      }
-      
-      return success;
-   }
-   
-   public Object lookupUser(String username)
-   {
-      try
-      {
-         Object user = entityManager.createQuery(
-            "select u from " + config.getUserEntityClass().getName() + " u where " +
-            config.getUserPrincipalProperty().getName() + " = :username")
-            .setParameter("username", username)
-            .getSingleResult();
-         
-         return user;
-      }
-      catch (NoResultException ex)
-      {
-         return null;
-      }
-   }
-   
-   public String getUserName(Object user)
-   {
-      return (String) config.getUserPrincipalProperty().getValue(user);
-   }
-   
-   public String getRoleName(Object role)
-   {
-      return (String) config.getRoleNameProperty().getValue(role);
-   }
-   
-   public boolean isRoleConditional(String role)
-   {
-      return config.getRoleConditionalProperty().isSet() ? (Boolean) config.getRoleConditionalProperty().getValue(
-            lookupRole(role)) : false;
-   }
-   
-   public Object lookupRole(String role)
-   {
-      try
-      {
-         Object value = entityManager.createQuery(
-            "select r from " + config.getRoleEntityClass().getName() + " r where " + config.getRoleNameProperty().getName() +
-            " = :role")
-            .setParameter("role", role)
-            .getSingleResult();
-         
-         return value;
-      }
-      catch (NoResultException ex)
-      {
-         return null;
-      }
-   }
-   
-   @SuppressWarnings("unchecked")
-   public List<String> listUsers()
-   {
-      return entityManager.createQuery(
-            "select u." + config.getUserPrincipalProperty().getName() + " from " +
-            config.getUserEntityClass().getName() + " u")
-            .getResultList();
-   }
-   
-   @SuppressWarnings("unchecked")
-   public List<String> listUsers(String filter)
-   {
-      return entityManager.createQuery(
-            "select u." + config.getUserPrincipalProperty().getName() + " from " + config.getUserEntityClass().getName() +
-            " u where lower(" + config.getUserPrincipalProperty().getName() + ") like :username")
-            .setParameter("username", "%" + (filter != null ? filter.toLowerCase() : "") +
-                  "%")
-            .getResultList();
-   }
-
-   @SuppressWarnings("unchecked")
-   public List<String> listRoles()
-   {
-      return entityManager.createQuery(
-            "select r." + config.getRoleNameProperty().getName() + " from " +
-            config.getRoleEntityClass().getName() + " r").getResultList();
-   }
-   
-   public List<Principal> listMembers(String role)
-   {
-      List<Principal> members = new ArrayList<Principal>();
-      
-      for (String user : listUserMembers(role))
-      {
-         members.add(new SimplePrincipal(user));
-      }
-      
-      for (String roleName : listRoleMembers(role))
-      {
-         members.add(new Role(roleName));
-      }
-      
-      return members;
-   }
-   
-   @SuppressWarnings("unchecked")
-   private List<String> listUserMembers(String role)
-   {
-      Object roleEntity = lookupRole(role);
-
-      if (config.getXrefEntityClass() == null)
-      {
-         return entityManager.createQuery("select u." +
-               config.getUserPrincipalProperty().getName() +
-               " from " + config.getUserEntityClass().getName() + " u where :role member of u." +
-               config.getUserRolesProperty().getName())
-               .setParameter("role", roleEntity)
-               .getResultList();
-      }
-      else
-      {
-         List<?> xrefs = entityManager.createQuery("select x from " +
-               config.getXrefEntityClass().getName() + " x where x." +
-               config.getXrefRoleProperty().getName() + " = :role")
-               .setParameter("role", roleEntity)
-               .getResultList();
-
-         List<String> members = new ArrayList<String>();
-         
-         for (Object xref : xrefs)
-         {
-            Object user = config.getXrefUserProperty().getValue(xref);
-            members.add(config.getUserPrincipalProperty().getValue(user).toString());
-         }
-         
-         return members;
-      }
-     
-   }
-   
-   @SuppressWarnings("unchecked")
-   private List<String> listRoleMembers(String role)
-   {
-      if (config.getRoleGroupsProperty().isSet())
-      {
-         Object roleEntity = lookupRole(role);
-         
-         return entityManager.createQuery("select r." +
-               config.getRoleNameProperty().getName() +
-               " from " + config.getRoleEntityClass().getName() + " r where :role member of r." +
-               config.getRoleGroupsProperty().getName())
-               .setParameter("role", roleEntity)
-               .getResultList();
-      }
-      
-      return null;
-   }
-   
-   @SuppressWarnings("unchecked")
-   public List<String> listGrantableRoles()
-   {
-      StringBuilder roleQuery = new StringBuilder();
-      
-      roleQuery.append("select r.");
-      roleQuery.append(config.getRoleNameProperty().getName());
-      roleQuery.append(" from ");
-      roleQuery.append(config.getRoleEntityClass().getName());
-      roleQuery.append(" r");
-      
-      if (config.getRoleConditionalProperty().isSet())
-      {
-         roleQuery.append(" where r.");
-         roleQuery.append(config.getRoleConditionalProperty().getName());
-         roleQuery.append(" = false");
-      }
-      
-      return entityManager.createQuery(roleQuery.toString()).getResultList();
-   }
-   
-   protected PasswordHash getPasswordHash()
-   {
-      return passwordHashInstance.get();
-   }
-}

Copied: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/management/JpaIdentityStore.java (from rev 12439, modules/security/trunk/core/src/main/java/org/jboss/seam/security/management/JpaIdentityStore.java)
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/management/JpaIdentityStore.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/management/JpaIdentityStore.java	2010-04-13 10:22:26 UTC (rev 12451)
@@ -0,0 +1,1080 @@
+package org.jboss.seam.security.management;
+
+import java.io.Serializable;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.security.GeneralSecurityException;
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.inject.Instance;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.inject.Inject;
+import javax.persistence.EntityManager;
+import javax.persistence.NoResultException;
+
+import org.jboss.seam.security.Role;
+import org.jboss.seam.security.SimplePrincipal;
+import org.jboss.seam.security.annotations.management.PasswordSalt;
+import org.jboss.seam.security.annotations.management.RoleConditional;
+import org.jboss.seam.security.annotations.management.RoleGroups;
+import org.jboss.seam.security.annotations.management.RoleName;
+import org.jboss.seam.security.annotations.management.UserEnabled;
+import org.jboss.seam.security.annotations.management.UserFirstName;
+import org.jboss.seam.security.annotations.management.UserLastName;
+import org.jboss.seam.security.annotations.management.UserPassword;
+import org.jboss.seam.security.annotations.management.UserPrincipal;
+import org.jboss.seam.security.annotations.management.UserRoles;
+import org.jboss.seam.security.crypto.BinTools;
+import org.jboss.seam.security.events.PrePersistUserEvent;
+import org.jboss.seam.security.events.PrePersistUserRoleEvent;
+import org.jboss.seam.security.events.UserAuthenticatedEvent;
+import org.jboss.seam.security.events.UserCreatedEvent;
+import org.jboss.seam.security.util.AnnotatedBeanProperty;
+import org.jboss.seam.security.util.TypedBeanProperty;
+import org.jboss.seam.transaction.Transactional;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The default identity store implementation, uses JPA as its persistence mechanism.
+ * 
+ * @author Shane Bryzak
+ */
+public @ApplicationScoped @Transactional class JpaIdentityStore implements IdentityStore, Serializable
+{
+   private static final long serialVersionUID = 1171875389743972646L;
+
+   protected FeatureSet featureSet;
+
+   private Logger log = LoggerFactory.getLogger(JpaIdentityStore.class);
+          
+   @Inject Instance<EntityManager> entityManagerInstance;
+   
+   @Inject Instance<PasswordHash> passwordHashInstance;
+   
+   @Inject BeanManager manager;
+  
+   private Class<?> userEntityClass;
+   private Class<?> roleEntityClass;
+   private Class<?> xrefEntityClass;
+   private TypedBeanProperty xrefUserProperty;
+   private TypedBeanProperty xrefRoleProperty;
+   
+   private AnnotatedBeanProperty<UserPrincipal> userPrincipalProperty;
+   private AnnotatedBeanProperty<UserPassword> userPasswordProperty;
+   private AnnotatedBeanProperty<PasswordSalt> passwordSaltProperty;
+   private AnnotatedBeanProperty<UserRoles> userRolesProperty;
+   private AnnotatedBeanProperty<UserEnabled> userEnabledProperty;
+   private AnnotatedBeanProperty<UserFirstName> userFirstNameProperty;
+   private AnnotatedBeanProperty<UserLastName> userLastNameProperty;
+   private AnnotatedBeanProperty<RoleName> roleNameProperty;
+   private AnnotatedBeanProperty<RoleGroups> roleGroupsProperty;
+   private AnnotatedBeanProperty<RoleConditional> roleConditionalProperty;
+   
+   public Set<Feature> getFeatures()
+   {
+      return featureSet.getFeatures();
+   }
+   
+   public void setFeatures(Set<Feature> features)
+   {
+      featureSet = new FeatureSet(features);
+   }
+   
+   public boolean supportsFeature(Feature feature)
+   {
+      return featureSet.supports(feature);
+   }
+   
+   @Inject
+   public void init()
+   {      
+      if (featureSet == null)
+      {
+         featureSet = new FeatureSet();
+         featureSet.enableAll();
+      }
+      
+      userPrincipalProperty = new AnnotatedBeanProperty<UserPrincipal>(getUserEntityClass(), UserPrincipal.class);
+      userPasswordProperty = new AnnotatedBeanProperty<UserPassword>(getUserEntityClass(), UserPassword.class);
+      passwordSaltProperty = new AnnotatedBeanProperty<PasswordSalt>(getUserEntityClass(), PasswordSalt.class);
+      userRolesProperty = new AnnotatedBeanProperty<UserRoles>(getUserEntityClass(), UserRoles.class);
+      userEnabledProperty = new AnnotatedBeanProperty<UserEnabled>(getUserEntityClass(), UserEnabled.class);
+      userFirstNameProperty = new AnnotatedBeanProperty<UserFirstName>(getUserEntityClass(), UserFirstName.class);
+      userLastNameProperty = new AnnotatedBeanProperty<UserLastName>(getUserEntityClass(), UserLastName.class);
+             
+      if (!userPrincipalProperty.isSet())
+      {
+         throw new IdentityManagementException("Invalid userClass " + getUserEntityClass().getName() +
+               " - required annotation @UserPrincipal not found on any Field or Method.");
+      }
+      
+      if (!userRolesProperty.isSet())
+      {
+         throw new IdentityManagementException("Invalid userClass " + getUserEntityClass().getName() +
+         " - required annotation @UserRoles not found on any Field or Method.");
+      }
+      
+      if (getRoleEntityClass() != null)
+      {
+         roleNameProperty = new AnnotatedBeanProperty<RoleName>(getRoleEntityClass(), RoleName.class);
+         roleGroupsProperty = new AnnotatedBeanProperty<RoleGroups>(getRoleEntityClass(), RoleGroups.class);
+         roleConditionalProperty = new AnnotatedBeanProperty<RoleConditional>(getRoleEntityClass(), RoleConditional.class);
+         
+         if (!roleNameProperty.isSet())
+         {
+            throw new IdentityManagementException("Invalid roleClass " + getRoleEntityClass().getName() +
+            " - required annotation @RoleName not found on any Field or Method.");
+         }
+                 
+         Type type = userRolesProperty.getPropertyType();
+         if (type instanceof ParameterizedType &&
+               Collection.class.isAssignableFrom((Class<?>) ((ParameterizedType) type).getRawType()))
+         {
+            Type genType = Object.class;
+
+            for (Type t : ((ParameterizedType) type).getActualTypeArguments())
+            {
+               genType = t;
+               break;
+            }
+         
+            // If the @UserRoles property isn't a collection of <roleClass>, then assume the relationship
+            // is going through a cross-reference table
+            if (!genType.equals(getRoleEntityClass()))
+            {
+               xrefEntityClass = (Class<?>) genType;
+               xrefUserProperty = new TypedBeanProperty(xrefEntityClass, getUserEntityClass());
+               xrefRoleProperty = new TypedBeanProperty(xrefEntityClass, getRoleEntityClass());
+               
+               if (!xrefUserProperty.isSet())
+               {
+                  throw new IdentityManagementException("Error configuring JpaIdentityStore - it looks like " +
+                        "you're using a cross-reference table, however the user property cannot be determined.");
+               }
+               
+               if (!xrefRoleProperty.isSet())
+               {
+                  throw new IdentityManagementException("Error configuring JpaIdentityStore - it looks like " +
+                  "you're using a cross-reference table, however the role property cannot be determined.");
+               }
+            }
+         }
+      }      
+   }
+   
+   public boolean createUser(String username, String password, String firstname, String lastname)
+   {
+      try
+      {
+         if (getUserEntityClass() == null)
+         {
+            throw new IdentityManagementException("Could not create account, userClass not set");
+         }
+         
+         if (userExists(username))
+         {
+            throw new IdentityManagementException("Could not create account, already exists");
+         }
+         
+         Object user = getUserEntityClass().newInstance();
+
+         getUserPrincipalProperty().setValue(user, username);
+
+         if (getUserFirstNameProperty().isSet()) getUserFirstNameProperty().setValue(user, firstname);
+         if (getUserLastNameProperty().isSet()) getUserLastNameProperty().setValue(user, lastname);
+         
+         if (password == null)
+         {
+            if (getUserEnabledProperty().isSet()) getUserEnabledProperty().setValue(user, false);
+         }
+         else
+         {
+            setUserPassword(user, password);
+            if (getUserEnabledProperty().isSet()) getUserEnabledProperty().setValue(user, true);
+         }
+         
+         manager.fireEvent(new PrePersistUserEvent(user));
+         
+         getEntityManager().persist(user);
+
+         manager.fireEvent(new UserCreatedEvent(user));
+         
+         return true;
+      }
+      catch (Exception ex)
+      {
+         if (ex instanceof IdentityManagementException)
+         {
+            throw (IdentityManagementException) ex;
+         }
+         else
+         {
+            throw new IdentityManagementException("Could not create account", ex);
+         }
+      }
+   }
+   
+   protected void setUserPassword(Object user, String password)
+   {
+      if (getPasswordSaltProperty().isSet())
+      {
+         byte[] salt = generateUserSalt(user);
+         getPasswordSaltProperty().setValue(user, BinTools.bin2hex(salt));
+         getUserPasswordProperty().setValue(user, generatePasswordHash(password, salt));
+      }
+      else
+      {
+         getUserPasswordProperty().setValue(user, generatePasswordHash(password, getUserAccountSalt(user)));
+      }
+   }
+   
+   /**
+    * @deprecated Use JpaIdentityStore.generateRandomSalt(Object) instead
+    */
+   @Deprecated
+   protected String getUserAccountSalt(Object user)
+   {
+      // By default, we'll use the user's username as the password salt
+      return getUserPrincipalProperty().getValue(user).toString();
+   }
+   
+   /**
+    * Generates a 64 bit random salt value
+    */
+   public byte[] generateUserSalt(Object user)
+   {
+      return getPasswordHash().generateRandomSalt();
+   }
+   
+   public boolean createUser(String username, String password)
+   {
+      return createUser(username, password, null, null);
+   }
+   
+   public boolean deleteUser(String name)
+   {
+      Object user = lookupUser(name);
+      if (user == null)
+      {
+         throw new NoSuchUserException("Could not delete, user '" + name + "' does not exist");
+      }
+      
+      getEntityManager().remove(user);
+      return true;
+   }
+   
+   @SuppressWarnings("unchecked")
+   public boolean grantRole(String username, String role)
+   {
+      if (getRoleEntityClass() == null) return false;
+      
+      Object user = lookupUser(username);
+      if (user == null)
+      {
+         if (getUserPasswordProperty().isSet())
+         {
+            // If no userPasswordProperty is set, it means that authentication is being performed
+            // by another identity store and this one is just managing roles
+            throw new NoSuchUserException("Could not grant role, no such user '" + username + "'");
+         }
+         else
+         {
+            // We need to create a new user object
+            if (createUser(username, null))
+            {
+               user = lookupUser(username);
+            }
+            else
+            {
+               throw new IdentityManagementException(
+                     "Could not grant role - user does not exist and an attempt to create the user failed.");
+            }
+         }
+      }
+      
+      Object roleToGrant = lookupRole(role);
+      if (roleToGrant == null)
+      {
+         throw new NoSuchRoleException("Could not grant role, role '" + role + "' does not exist");
+      }
+      
+      Collection<?> userRoles = (Collection<?>) getUserRolesProperty().getValue(user);
+      if (userRoles == null)
+      {
+         Type propType = getUserRolesProperty().getPropertyType();
+         Class<?> collectionType;
+         
+         if (propType instanceof Class && Collection.class.isAssignableFrom((Class<?>) propType))
+         {
+            collectionType = (Class<?>) propType;
+         }
+         else if (propType instanceof ParameterizedType &&
+                  Collection.class.isAssignableFrom((Class<?>) ((ParameterizedType) propType).getRawType()))
+         {
+            collectionType = (Class<?>) ((ParameterizedType) propType).getRawType();
+         }
+         else
+         {
+            throw new IllegalStateException("Could not determine collection type for user roles.");
+         }
+         
+         // This should either be a Set, or a List...
+         if (Set.class.isAssignableFrom(collectionType))
+         {
+            userRoles = new HashSet<Object>();
+         }
+         else if (List.class.isAssignableFrom(collectionType))
+         {
+            userRoles = new ArrayList<Object>();
+         }
+         
+         getUserRolesProperty().setValue(user, userRoles);
+      }
+      else if (((Collection<?>) getUserRolesProperty().getValue(user)).contains(roleToGrant))
+      {
+         return false;
+      }
+
+      if (getXrefEntityClass() == null)
+      {
+         // If this is a Many-To-Many relationship, simply add the role
+         ((Collection<Object>) getUserRolesProperty().getValue(user)).add(roleToGrant);
+      }
+      else
+      {
+         // Otherwise we need to insert a cross-reference entity instance
+         try
+         {
+            Object xref = getXrefEntityClass().newInstance();
+            getXrefUserProperty().setValue(xref, user);
+            getXrefRoleProperty().setValue(xref, roleToGrant);
+            
+            manager.fireEvent(new PrePersistUserRoleEvent(xref));
+            
+            ((Collection<Object>) getUserRolesProperty().getValue(user)).add(getEntityManager().merge(xref));
+         }
+         catch (Exception ex)
+         {
+            throw new IdentityManagementException("Error creating cross-reference role record.", ex);
+         }
+      }
+      
+      return true;
+   }
+   
+   public boolean revokeRole(String username, String role)
+   {
+      Object user = lookupUser(username);
+      if (user == null)
+      {
+         throw new NoSuchUserException("Could not revoke role, no such user '" + username + "'");
+      }
+      
+      Object roleToRevoke = lookupRole(role);
+      if (roleToRevoke == null)
+      {
+         throw new NoSuchRoleException("Could not revoke role, role '" + role + "' does not exist");
+      }
+             
+      boolean success = false;
+      
+      if (getXrefEntityClass() == null)
+      {
+         success = ((Collection<?>) getUserRolesProperty().getValue(user)).remove(roleToRevoke);
+      }
+      else
+      {
+         Collection<?> roles = ((Collection<?>) getUserRolesProperty().getValue(user));
+
+         for (Object xref : roles)
+         {
+            if (getXrefRoleProperty().getValue(xref).equals(roleToRevoke))
+            {
+               success = roles.remove(xref);
+               break;
+            }
+         }
+      }
+
+      return success;
+   }
+   
+   @SuppressWarnings("unchecked")
+   public boolean addRoleToGroup(String role, String group)
+   {
+      if (!getRoleGroupsProperty().isSet()) return false;
+      
+      Object targetRole = lookupRole(role);
+      if (targetRole == null)
+      {
+         throw new NoSuchUserException("Could not add role to group, no such role '" + role + "'");
+      }
+      
+      Object targetGroup = lookupRole(group);
+      if (targetGroup == null)
+      {
+         throw new NoSuchRoleException("Could not grant role, group '" + group + "' does not exist");
+      }
+      
+      Collection<?> roleGroups = (Collection<?>) getRoleGroupsProperty().getValue(targetRole);
+      if (roleGroups == null)
+      {
+         // This should either be a Set, or a List...
+         Class<?> rawType = null;
+         if (getRoleGroupsProperty().getPropertyType() instanceof ParameterizedType)
+         {
+            rawType = (Class<?>) ((ParameterizedType) getRoleGroupsProperty().getPropertyType()).getRawType();
+         }
+         else
+         {
+            return false;
+         }
+          
+         if (Set.class.isAssignableFrom(rawType))
+         {
+            roleGroups = new HashSet<Object>();
+         }
+         else if (List.class.isAssignableFrom(rawType))
+         {
+            roleGroups = new ArrayList<Object>();
+         }
+         
+         getRoleGroupsProperty().setValue(targetRole, roleGroups);
+      }
+      else if (((Collection<?>) getRoleGroupsProperty().getValue(targetRole)).contains(targetGroup))
+      {
+         return false;
+      }
+
+      ((Collection<Object>) getRoleGroupsProperty().getValue(targetRole)).add(targetGroup);
+      
+      return true;
+   }
+
+   public boolean removeRoleFromGroup(String role, String group)
+   {
+      if (!getRoleGroupsProperty().isSet()) return false;
+      
+      Object roleToRemove = lookupRole(role);
+      if (role == null)
+      {
+         throw new NoSuchUserException("Could not remove role from group, no such role '" + role + "'");
+      }
+      
+      Object targetGroup = lookupRole(group);
+      if (targetGroup == null)
+      {
+         throw new NoSuchRoleException("Could not remove role from group, no such group '" + group + "'");
+      }
+       
+      boolean success = ((Collection<?>) getRoleGroupsProperty().getValue(roleToRemove)).remove(targetGroup);
+      
+      return success;
+   }
+   
+   public boolean createRole(String role)
+   {
+      try
+      {
+         if (getRoleEntityClass() == null)
+         {
+            throw new IdentityManagementException("Could not create role, roleClass not set");
+         }
+         
+         if (roleExists(role))
+         {
+            throw new IdentityManagementException("Could not create role, already exists");
+         }
+         
+         Object instance = getRoleEntityClass().newInstance();
+         getRoleNameProperty().setValue(instance, role);
+         getEntityManager().persist(instance);
+         
+         return true;
+      }
+      catch (Exception ex)
+      {
+         if (ex instanceof IdentityManagementException)
+         {
+            throw (IdentityManagementException) ex;
+         }
+         else
+         {
+            throw new IdentityManagementException("Could not create role", ex);
+         }
+      }
+   }
+   
+   public boolean deleteRole(String role)
+   {
+      Object roleToDelete = lookupRole(role);
+      if (roleToDelete == null)
+      {
+         throw new NoSuchRoleException("Could not delete role, role '" + role + "' does not exist");
+      }
+      
+      if (getXrefEntityClass() != null)
+      {
+         getEntityManager().createQuery("delete " + getXrefEntityClass().getName() + " where role = :role")
+         .setParameter("role", roleToDelete)
+         .executeUpdate();
+      }
+      else
+      {
+         List<String> users = listUserMembers(role);
+         for (String user : users)
+         {
+            revokeRole(user, role);
+         }
+      }
+      
+      List<String> roles = listRoleMembers(role);
+      for (String r : roles)
+      {
+         removeRoleFromGroup(r, role);
+      }
+            
+      getEntityManager().remove(roleToDelete);
+      return true;
+   }
+   
+   public boolean enableUser(String name)
+   {
+      if (!getUserEnabledProperty().isSet())
+      {
+         log.debug("Can not enable user, no @UserEnabled property configured in userClass " +
+               getUserEntityClass().getName());
+         return false;
+      }
+      
+      Object user = lookupUser(name);
+      if (user == null)
+      {
+         throw new NoSuchUserException("Could not enable user, user '" + name + "' does not exist");
+      }
+      
+      // Can't enable an already-enabled user, return false
+      if (((Boolean) getUserEnabledProperty().getValue(user)) == true)
+      {
+         return false;
+      }
+      
+      getUserEnabledProperty().setValue(user, true);
+      return true;
+   }
+   
+   public boolean disableUser(String name)
+   {
+      if (!getUserEnabledProperty().isSet())
+      {
+         log.debug("Can not disable user, no @UserEnabled property configured in userClass " +
+               getUserEntityClass().getName());
+         return false;
+      }
+      
+      Object user = lookupUser(name);
+      if (user == null)
+      {
+         throw new NoSuchUserException("Could not disable user, user '" + name + "' does not exist");
+      }
+      
+      // Can't disable an already-disabled user, return false
+      if (((Boolean) getUserEnabledProperty().getValue(user)) == false)
+      {
+         return false;
+      }
+      
+      getUserEnabledProperty().setValue(user, false);
+      return true;
+   }
+   
+   public boolean changePassword(String username, String password)
+   {
+      Object user = lookupUser(username);
+      if (user == null)
+      {
+         throw new NoSuchUserException("Could not change password, user '" + username + "' does not exist");
+      }
+      
+      setUserPassword(user, password);
+      
+      return true;
+   }
+   
+   public boolean userExists(String name)
+   {
+      return lookupUser(name) != null;
+   }
+   
+   public boolean roleExists(String name)
+   {
+      return lookupRole(name) != null;
+   }
+   
+   public boolean isUserEnabled(String name)
+   {
+      Object user = lookupUser(name);
+      return user != null && (!getUserEnabledProperty().isSet() ||
+            (((Boolean) getUserEnabledProperty().getValue(user))) == true);
+   }
+   
+   public List<String> getGrantedRoles(String name)
+   {
+      Object user = lookupUser(name);
+      if (user == null)
+      {
+         throw new NoSuchUserException("No such user '" + name + "'");
+      }
+
+      List<String> roles = new ArrayList<String>();
+      
+      Collection<?> userRoles = (Collection<?>) getUserRolesProperty().getValue(user);
+      if (userRoles != null)
+      {
+         for (Object role : userRoles)
+         {
+            if (getXrefEntityClass() == null)
+            {
+               roles.add((String) getRoleNameProperty().getValue(role));
+            }
+            else
+            {
+               Object xref = getRoleNameProperty().getValue(role);
+               Object userRole = getXrefRoleProperty().getValue(xref);
+               roles.add((String) getRoleNameProperty().getValue(userRole));
+            }
+         }
+      }
+      
+      return roles;
+   }
+   
+   public List<String> getRoleGroups(String name)
+   {
+      Object role = lookupRole(name);
+      if (role == null)
+      {
+         throw new NoSuchUserException("No such role '" + name + "'");
+      }
+
+      List<String> groups = new ArrayList<String>();
+      
+      if (getRoleGroupsProperty().isSet())
+      {
+         Collection<?> roleGroups = (Collection<?>) getRoleGroupsProperty().getValue(role);
+         if (roleGroups != null)
+         {
+            for (Object group : roleGroups)
+            {
+               groups.add((String) getRoleNameProperty().getValue(group));
+            }
+         }
+      }
+      
+      return groups;
+   }
+   
+   public List<String> getImpliedRoles(String name)
+   {
+      Object user = lookupUser(name);
+      if (user == null)
+      {
+         throw new NoSuchUserException("No such user '" + name + "'");
+      }
+
+      Set<String> roles = new HashSet<String>();
+      Collection<?> userRoles = (Collection<?>) getUserRolesProperty().getValue(user);
+      if (userRoles != null)
+      {
+         for (Object role : userRoles)
+         {
+            addRoleAndMemberships((String) getRoleNameProperty().getValue(role), roles);
+         }
+      }
+      
+      return new ArrayList<String>(roles);
+   }
+   
+   private void addRoleAndMemberships(String role, Set<String> roles)
+   {
+      if (roles.add(role))
+      {
+         Object instance = lookupRole(role);
+         
+         if (getRoleGroupsProperty().isSet())
+         {
+            Collection<?> groups = (Collection<?>) getRoleGroupsProperty().getValue(instance);
+            
+            if (groups != null)
+            {
+               for (Object group : groups)
+               {
+                  addRoleAndMemberships((String) getRoleNameProperty().getValue(group), roles);
+               }
+            }
+         }
+      }
+   }
+   
+   public String generatePasswordHash(String password, byte[] salt)
+   {
+      if (getPasswordSaltProperty().isSet())
+      {
+         try
+         {
+            return getPasswordHash().createPasswordKey(password.toCharArray(), salt,
+                  getUserPasswordProperty().getAnnotation().iterations());
+         }
+         catch (GeneralSecurityException ex)
+         {
+            throw new IdentityManagementException("Exception generating password hash", ex);
+         }
+      }
+      else
+      {
+         return generatePasswordHash(password, new String(salt));
+      }
+   }
+   
+   /**
+    * 
+    * @deprecated Use JpaIdentityStore.generatePasswordHash(String, byte[]) instead
+    */
+   @Deprecated
+   protected String generatePasswordHash(String password, String salt)
+   {
+      String algorithm = getUserPasswordProperty().getAnnotation().hash();
+      
+      if (algorithm == null || "".equals(algorithm))
+      {
+         if (salt == null || "".equals(salt))
+         {
+            return getPasswordHash().generateHash(password);
+         }
+         else
+         {
+            return getPasswordHash().generateSaltedHash(password, salt);
+         }
+      }
+      else if ("none".equalsIgnoreCase(algorithm))
+      {
+         return password;
+      }
+      else
+      {
+         if (salt == null || "".equals(salt))
+         {
+            return getPasswordHash().generateHash(password, algorithm);
+         }
+         else
+         {
+            return getPasswordHash().generateSaltedHash(password, salt, algorithm);
+         }
+      }
+   }
+   
+   public boolean authenticate(String username, String password)
+   {
+      Object user = lookupUser(username);
+      if (user == null || (getUserEnabledProperty().isSet() &&
+            ((Boolean) getUserEnabledProperty().getValue(user) == false)))
+      {
+         return false;
+      }
+      
+      String passwordHash = null;
+      
+      if (getPasswordSaltProperty().isSet())
+      {
+         String encodedSalt = (String) getPasswordSaltProperty().getValue(user);
+         if (encodedSalt == null)
+         {
+            throw new IdentityManagementException("A @PasswordSalt property was found on entity " + user +
+                  ", but it contains no value");
+         }
+         
+         passwordHash = generatePasswordHash(password, BinTools.hex2bin(encodedSalt));
+      }
+      else
+      {
+         passwordHash = generatePasswordHash(password, getUserAccountSalt(user));
+      }
+      
+       
+      boolean success = passwordHash.equals(getUserPasswordProperty().getValue(user));
+            
+      if (success)
+      {
+         manager.fireEvent(new UserAuthenticatedEvent(user));
+      }
+      
+      return success;
+   }
+   
+   public Object lookupUser(String username)
+   {
+      try
+      {
+         Object user = getEntityManager().createQuery(
+            "select u from " + getUserEntityClass().getName() + " u where u." +
+            getUserPrincipalProperty().getName() + " = :username")
+            .setParameter("username", username)
+            .getSingleResult();
+         
+         return user;
+      }
+      catch (NoResultException ex)
+      {
+         return null;
+      }
+   }
+   
+   public String getUserName(Object user)
+   {
+      return (String) getUserPrincipalProperty().getValue(user);
+   }
+   
+   public String getRoleName(Object role)
+   {
+      return (String) getRoleNameProperty().getValue(role);
+   }
+   
+   public boolean isRoleConditional(String role)
+   {
+      return getRoleConditionalProperty().isSet() ? (Boolean) getRoleConditionalProperty().getValue(
+            lookupRole(role)) : false;
+   }
+   
+   public Object lookupRole(String role)
+   {
+      try
+      {
+         Object value = getEntityManager().createQuery(
+            "select r from " + getRoleEntityClass().getName() + " r where " + getRoleNameProperty().getName() +
+            " = :role")
+            .setParameter("role", role)
+            .getSingleResult();
+         
+         return value;
+      }
+      catch (NoResultException ex)
+      {
+         return null;
+      }
+   }
+   
+   @SuppressWarnings("unchecked")
+   public List<String> listUsers()
+   {
+      return getEntityManager().createQuery(
+            "select u." + getUserPrincipalProperty().getName() + " from " +
+            getUserEntityClass().getName() + " u")
+            .getResultList();
+   }
+   
+   @SuppressWarnings("unchecked")
+   public List<String> listUsers(String filter)
+   {
+      return getEntityManager().createQuery(
+            "select u." + getUserPrincipalProperty().getName() + " from " + getUserEntityClass().getName() +
+            " u where lower(" + getUserPrincipalProperty().getName() + ") like :username")
+            .setParameter("username", "%" + (filter != null ? filter.toLowerCase() : "") +
+                  "%")
+            .getResultList();
+   }
+
+   @SuppressWarnings("unchecked")
+   public List<String> listRoles()
+   {
+      return getEntityManager().createQuery(
+            "select r." + getRoleNameProperty().getName() + " from " +
+            getRoleEntityClass().getName() + " r").getResultList();
+   }
+   
+   public List<Principal> listMembers(String role)
+   {
+      List<Principal> members = new ArrayList<Principal>();
+      
+      for (String user : listUserMembers(role))
+      {
+         members.add(new SimplePrincipal(user));
+      }
+      
+      for (String roleName : listRoleMembers(role))
+      {
+         members.add(new Role(roleName));
+      }
+      
+      return members;
+   }
+   
+   @SuppressWarnings("unchecked")
+   private List<String> listUserMembers(String role)
+   {
+      Object roleEntity = lookupRole(role);
+
+      if (getXrefEntityClass() == null)
+      {
+         return getEntityManager().createQuery("select u." +
+               getUserPrincipalProperty().getName() +
+               " from " + getUserEntityClass().getName() + " u where :role member of u." +
+               getUserRolesProperty().getName())
+               .setParameter("role", roleEntity)
+               .getResultList();
+      }
+      else
+      {
+         List<?> xrefs = getEntityManager().createQuery("select x from " +
+               getXrefEntityClass().getName() + " x where x." +
+               getXrefRoleProperty().getName() + " = :role")
+               .setParameter("role", roleEntity)
+               .getResultList();
+
+         List<String> members = new ArrayList<String>();
+         
+         for (Object xref : xrefs)
+         {
+            Object user = getXrefUserProperty().getValue(xref);
+            members.add(getUserPrincipalProperty().getValue(user).toString());
+         }
+         
+         return members;
+      }
+     
+   }
+   
+   @SuppressWarnings("unchecked")
+   private List<String> listRoleMembers(String role)
+   {
+      if (getRoleGroupsProperty().isSet())
+      {
+         Object roleEntity = lookupRole(role);
+         
+         return getEntityManager().createQuery("select r." +
+               getRoleNameProperty().getName() +
+               " from " + getRoleEntityClass().getName() + " r where :role member of r." +
+               getRoleGroupsProperty().getName())
+               .setParameter("role", roleEntity)
+               .getResultList();
+      }
+      
+      return null;
+   }
+   
+   @SuppressWarnings("unchecked")
+   public List<String> listGrantableRoles()
+   {
+      StringBuilder roleQuery = new StringBuilder();
+      
+      roleQuery.append("select r.");
+      roleQuery.append(getRoleNameProperty().getName());
+      roleQuery.append(" from ");
+      roleQuery.append(getRoleEntityClass().getName());
+      roleQuery.append(" r");
+      
+      if (getRoleConditionalProperty().isSet())
+      {
+         roleQuery.append(" where r.");
+         roleQuery.append(getRoleConditionalProperty().getName());
+         roleQuery.append(" = false");
+      }
+      
+      return getEntityManager().createQuery(roleQuery.toString()).getResultList();
+   }
+   
+   protected EntityManager getEntityManager()
+   {
+      EntityManager em = entityManagerInstance.get();
+      em.joinTransaction();
+      return em;
+   }
+   
+   protected PasswordHash getPasswordHash()
+   {
+      return passwordHashInstance.get();
+   }
+   
+   public Class<?> getUserEntityClass()
+   {     
+      return userEntityClass;
+   }
+   
+   public void setUserEntityClass(Class<?> userEntityClass)
+   {
+      this.userEntityClass = userEntityClass;
+   }
+   
+   public Class<?> getRoleEntityClass()
+   {      
+      return roleEntityClass;
+   }
+   
+   public void setRoleEntityClass(Class<?> roleEntityClass)
+   {
+      this.roleEntityClass = roleEntityClass;
+   }
+   
+   public Class<?> getXrefEntityClass()
+   {
+      return xrefEntityClass;
+   }
+   
+   public TypedBeanProperty getXrefUserProperty()
+   {
+      return xrefUserProperty;
+   }
+   
+   public TypedBeanProperty getXrefRoleProperty()
+   {
+      return xrefRoleProperty;
+   }
+   
+   public AnnotatedBeanProperty<UserPrincipal> getUserPrincipalProperty()
+   {
+      return userPrincipalProperty;
+   }
+   
+   public AnnotatedBeanProperty<UserPassword> getUserPasswordProperty()
+   {
+      return userPasswordProperty;
+   }
+   
+   public AnnotatedBeanProperty<PasswordSalt> getPasswordSaltProperty() {
+      return passwordSaltProperty;
+   }
+   
+   public AnnotatedBeanProperty<UserRoles> getUserRolesProperty() {
+      return userRolesProperty;
+   }
+   
+   public AnnotatedBeanProperty<UserEnabled> getUserEnabledProperty() {
+      return userEnabledProperty;
+   }
+   
+   public AnnotatedBeanProperty<UserFirstName> getUserFirstNameProperty() {
+      return userFirstNameProperty;
+   }
+   
+   public AnnotatedBeanProperty<UserLastName> getUserLastNameProperty() {
+      return userLastNameProperty;
+   }
+      
+   public AnnotatedBeanProperty<RoleName> getRoleNameProperty() {
+      return roleNameProperty;
+   }
+   
+   public AnnotatedBeanProperty<RoleGroups> getRoleGroupsProperty() {
+      return roleGroupsProperty;
+   }
+   
+   public AnnotatedBeanProperty<RoleConditional> getRoleConditionalProperty() {
+      return roleConditionalProperty;
+   }   
+}

Deleted: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/management/JpaIdentityStoreConfig.java
===================================================================
--- modules/security/trunk/core/src/main/java/org/jboss/seam/security/management/JpaIdentityStoreConfig.java	2010-03-24 09:14:40 UTC (rev 12256)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/management/JpaIdentityStoreConfig.java	2010-04-13 10:22:26 UTC (rev 12451)
@@ -1,209 +0,0 @@
-package org.jboss.seam.security.management;
-
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.util.Collection;
-
-import javax.enterprise.context.ApplicationScoped;
-import javax.inject.Inject;
-
-import org.jboss.seam.security.annotations.management.PasswordSalt;
-import org.jboss.seam.security.annotations.management.RoleConditional;
-import org.jboss.seam.security.annotations.management.RoleGroups;
-import org.jboss.seam.security.annotations.management.RoleName;
-import org.jboss.seam.security.annotations.management.UserEnabled;
-import org.jboss.seam.security.annotations.management.UserFirstName;
-import org.jboss.seam.security.annotations.management.UserLastName;
-import org.jboss.seam.security.annotations.management.UserPassword;
-import org.jboss.seam.security.annotations.management.UserPrincipal;
-import org.jboss.seam.security.annotations.management.UserRoles;
-import org.jboss.seam.security.util.AnnotatedBeanProperty;
-import org.jboss.seam.security.util.TypedBeanProperty;
-
-/**
- * The configuration for JpaIdentityStore
- * 
- * @author Shane Bryzak
- */
- at ApplicationScoped
-public class JpaIdentityStoreConfig
-{
-   private Class<?> userEntityClass;
-   private Class<?> roleEntityClass;
-   private Class<?> xrefEntityClass;
-   private TypedBeanProperty xrefUserProperty;
-   private TypedBeanProperty xrefRoleProperty;
-   
-   private AnnotatedBeanProperty<UserPrincipal> userPrincipalProperty;
-   private AnnotatedBeanProperty<UserPassword> userPasswordProperty;
-   private AnnotatedBeanProperty<PasswordSalt> passwordSaltProperty;
-   private AnnotatedBeanProperty<UserRoles> userRolesProperty;
-   private AnnotatedBeanProperty<UserEnabled> userEnabledProperty;
-   private AnnotatedBeanProperty<UserFirstName> userFirstNameProperty;
-   private AnnotatedBeanProperty<UserLastName> userLastNameProperty;
-   private AnnotatedBeanProperty<RoleName> roleNameProperty;
-   private AnnotatedBeanProperty<RoleGroups> roleGroupsProperty;
-   private AnnotatedBeanProperty<RoleConditional> roleConditionalProperty;
-      
-   //@Current // FIXME temporarily disable!!
-   IdentityStoreEntityClasses entityClasses;
-   
-   @Inject
-   public void initProperties()
-   {
-      userPrincipalProperty = new AnnotatedBeanProperty<UserPrincipal>(getUserEntityClass(), UserPrincipal.class);
-      userPasswordProperty = new AnnotatedBeanProperty<UserPassword>(getUserEntityClass(), UserPassword.class);
-      passwordSaltProperty = new AnnotatedBeanProperty<PasswordSalt>(getUserEntityClass(), PasswordSalt.class);
-      userRolesProperty = new AnnotatedBeanProperty<UserRoles>(getUserEntityClass(), UserRoles.class);
-      userEnabledProperty = new AnnotatedBeanProperty<UserEnabled>(getUserEntityClass(), UserEnabled.class);
-      userFirstNameProperty = new AnnotatedBeanProperty<UserFirstName>(getUserEntityClass(), UserFirstName.class);
-      userLastNameProperty = new AnnotatedBeanProperty<UserLastName>(getUserEntityClass(), UserLastName.class);
-             
-      if (!userPrincipalProperty.isSet())
-      {
-         throw new IdentityManagementException("Invalid userClass " + getUserEntityClass().getName() +
-               " - required annotation @UserPrincipal not found on any Field or Method.");
-      }
-      
-      if (!userRolesProperty.isSet())
-      {
-         throw new IdentityManagementException("Invalid userClass " + getUserEntityClass().getName() +
-         " - required annotation @UserRoles not found on any Field or Method.");
-      }
-      
-      if (getRoleEntityClass() != null)
-      {
-         roleNameProperty = new AnnotatedBeanProperty<RoleName>(getRoleEntityClass(), RoleName.class);
-         roleGroupsProperty = new AnnotatedBeanProperty<RoleGroups>(getRoleEntityClass(), RoleGroups.class);
-         roleConditionalProperty = new AnnotatedBeanProperty<RoleConditional>(getRoleEntityClass(), RoleConditional.class);
-         
-         if (!roleNameProperty.isSet())
-         {
-            throw new IdentityManagementException("Invalid roleClass " + getRoleEntityClass().getName() +
-            " - required annotation @RoleName not found on any Field or Method.");
-         }
-                 
-         Type type = userRolesProperty.getPropertyType();
-         if (type instanceof ParameterizedType &&
-               Collection.class.isAssignableFrom((Class<?>) ((ParameterizedType) type).getRawType()))
-         {
-            Type genType = Object.class;
-
-            for (Type t : ((ParameterizedType) type).getActualTypeArguments())
-            {
-               genType = t;
-               break;
-            }
-         
-            // If the @UserRoles property isn't a collection of <roleClass>, then assume the relationship
-            // is going through a cross-reference table
-            if (!genType.equals(getRoleEntityClass()))
-            {
-               xrefEntityClass = (Class<?>) genType;
-               xrefUserProperty = new TypedBeanProperty(xrefEntityClass, getUserEntityClass());
-               xrefRoleProperty = new TypedBeanProperty(xrefEntityClass, getRoleEntityClass());
-               
-               if (!xrefUserProperty.isSet())
-               {
-                  throw new IdentityManagementException("Error configuring JpaIdentityStore - it looks like " +
-                        "you're using a cross-reference table, however the user property cannot be determined.");
-               }
-               
-               if (!xrefRoleProperty.isSet())
-               {
-                  throw new IdentityManagementException("Error configuring JpaIdentityStore - it looks like " +
-                  "you're using a cross-reference table, however the role property cannot be determined.");
-               }
-            }
-         }
-      }
-   }
-      
-   public Class<?> getUserEntityClass()
-   {
-      if (userEntityClass == null)
-      {
-         userEntityClass = entityClasses.getUserEntityClass();
-      }
-      
-      return userEntityClass;
-   }
-   
-   public void setUserEntityClass(Class<?> userEntityClass)
-   {
-      this.userEntityClass = userEntityClass;
-   }
-   
-   public Class<?> getRoleEntityClass()
-   {
-      if (roleEntityClass == null)
-      {
-         roleEntityClass = entityClasses.getRoleEntityClass();
-      }
-      
-      return roleEntityClass;
-   }
-   
-   public void setRoleEntityClass(Class<?> roleEntityClass)
-   {
-      this.roleEntityClass = roleEntityClass;
-   }
-   
-   public Class<?> getXrefEntityClass()
-   {
-      return xrefEntityClass;
-   }
-   
-   public TypedBeanProperty getXrefUserProperty()
-   {
-      return xrefUserProperty;
-   }
-   
-   public TypedBeanProperty getXrefRoleProperty()
-   {
-      return xrefRoleProperty;
-   }
-   
-   public AnnotatedBeanProperty<UserPrincipal> getUserPrincipalProperty()
-   {
-      return userPrincipalProperty;
-   }
-   
-   public AnnotatedBeanProperty<UserPassword> getUserPasswordProperty()
-   {
-      return userPasswordProperty;
-   }
-   
-   public AnnotatedBeanProperty<PasswordSalt> getPasswordSaltProperty() {
-      return passwordSaltProperty;
-   }
-   
-   public AnnotatedBeanProperty<UserRoles> getUserRolesProperty() {
-      return userRolesProperty;
-   }
-   
-   public AnnotatedBeanProperty<UserEnabled> getUserEnabledProperty() {
-      return userEnabledProperty;
-   }
-   
-   public AnnotatedBeanProperty<UserFirstName> getUserFirstNameProperty() {
-      return userFirstNameProperty;
-   }
-   
-   public AnnotatedBeanProperty<UserLastName> getUserLastNameProperty() {
-      return userLastNameProperty;
-   }
-      
-   public AnnotatedBeanProperty<RoleName> getRoleNameProperty() {
-      return roleNameProperty;
-   }
-   
-   public AnnotatedBeanProperty<RoleGroups> getRoleGroupsProperty() {
-      return roleGroupsProperty;
-   }
-   
-   public AnnotatedBeanProperty<RoleConditional> getRoleConditionalProperty() {
-      return roleConditionalProperty;
-   }
-      
-}

Deleted: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/management/action/RoleAction.java
===================================================================
--- modules/security/trunk/core/src/main/java/org/jboss/seam/security/management/action/RoleAction.java	2010-03-24 09:14:40 UTC (rev 12256)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/management/action/RoleAction.java	2010-04-13 10:22:26 UTC (rev 12451)
@@ -1,123 +0,0 @@
-package org.jboss.seam.security.management.action;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.enterprise.context.Conversation;
-import javax.enterprise.context.ConversationScoped;
-import javax.inject.Inject;
-import javax.inject.Named;
-
-import org.jboss.seam.security.management.IdentityManager;
-
- at Named
- at ConversationScoped
-public class RoleAction implements Serializable
-{
-   private static final long serialVersionUID = -4215849488301658353L;
-   
-   private String originalRole;
-   private String role;
-   private List<String> groups;
-   
-   @Inject IdentityManager identityManager;
-   @Inject Conversation conversation;
-   
-   public void createRole()
-   {
-      conversation.begin();
-      groups = new ArrayList<String>();
-   }
-   
-   public void editRole(String role)
-   {
-      conversation.begin();
-      
-      this.originalRole = role;
-      this.role = role;
-      groups = identityManager.getRoleGroups(role);
-   }
-      
-   public String save()
-   {
-      if (role != null && originalRole != null && !role.equals(originalRole))
-      {
-         identityManager.deleteRole(originalRole);
-      }
-      
-      if (identityManager.roleExists(role))
-      {
-         return saveExistingRole();
-      }
-      else
-      {
-         return saveNewRole();
-      }
-   }
-   
-   private String saveNewRole()
-   {
-      boolean success = identityManager.createRole(role);
-      
-      if (success)
-      {
-         for (String r : groups)
-         {
-            identityManager.addRoleToGroup(role, r);
-         }
-         
-         conversation.end();
-      }
-      
-      return "success";
-   }
-   
-   private String saveExistingRole()
-   {
-      List<String> grantedRoles = identityManager.getRoleGroups(role);
-      
-      if (grantedRoles != null)
-      {
-         for (String r : grantedRoles)
-         {
-            if (!groups.contains(r)) identityManager.removeRoleFromGroup(role, r);
-         }
-      }
-      
-      for (String r : groups)
-      {
-         if (grantedRoles == null || !grantedRoles.contains(r)) identityManager.addRoleToGroup(role, r);
-      }
-               
-      conversation.end();
-      return "success";
-   }
-   
-   public String getRole()
-   {
-      return role;
-   }
-   
-   public List<String> getAssignableRoles()
-   {
-      List<String> roles = identityManager.listGrantableRoles();
-      roles.remove(role);
-      return roles;
-   }
-   
-   public void setRole(String role)
-   {
-      this.role = role;
-   }
-
-   public List<String> getGroups()
-   {
-      return groups;
-   }
-   
-   public void setGroups(List<String> groups)
-   {
-      this.groups = groups;
-   }
-}
\ No newline at end of file

Copied: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/management/action/RoleAction.java (from rev 12399, modules/security/trunk/core/src/main/java/org/jboss/seam/security/management/action/RoleAction.java)
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/management/action/RoleAction.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/management/action/RoleAction.java	2010-04-13 10:22:26 UTC (rev 12451)
@@ -0,0 +1,123 @@
+package org.jboss.seam.security.management.action;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.enterprise.context.Conversation;
+import javax.enterprise.context.ConversationScoped;
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.jboss.seam.security.management.IdentityManager;
+
+ at Named
+ at ConversationScoped
+public class RoleAction implements Serializable
+{
+   private static final long serialVersionUID = -4215849488301658353L;
+   
+   private String originalRole;
+   private String role;
+   private List<String> groups;
+   
+   @Inject IdentityManager identityManager;
+   @Inject Conversation conversation;
+   
+   public void createRole()
+   {
+      conversation.begin();
+      groups = new ArrayList<String>();
+   }
+   
+   public void editRole(String role)
+   {
+      conversation.begin();
+      
+      this.originalRole = role;
+      this.role = role;
+      groups = identityManager.getRoleGroups(role);
+   }
+      
+   public String save()
+   {
+      if (role != null && originalRole != null && !role.equals(originalRole))
+      {
+         identityManager.deleteRole(originalRole);
+      }
+      
+      if (identityManager.roleExists(role))
+      {
+         return saveExistingRole();
+      }
+      else
+      {
+         return saveNewRole();
+      }
+   }
+   
+   private String saveNewRole()
+   {
+      boolean success = identityManager.createRole(role);
+      
+      if (success)
+      {
+         for (String r : groups)
+         {
+            identityManager.addRoleToGroup(role, r);
+         }
+         
+         conversation.end();
+      }
+      
+      return "success";
+   }
+   
+   private String saveExistingRole()
+   {
+      List<String> grantedRoles = identityManager.getRoleGroups(role);
+      
+      if (grantedRoles != null)
+      {
+         for (String r : grantedRoles)
+         {
+            if (!groups.contains(r)) identityManager.removeRoleFromGroup(role, r);
+         }
+      }
+      
+      for (String r : groups)
+      {
+         if (grantedRoles == null || !grantedRoles.contains(r)) identityManager.addRoleToGroup(role, r);
+      }
+               
+      conversation.end();
+      return "success";
+   }
+   
+   public String getRole()
+   {
+      return role;
+   }
+   
+   public List<String> getAssignableRoles()
+   {
+      List<String> roles = identityManager.getGrantableRoles();
+      roles.remove(role);
+      return roles;
+   }
+   
+   public void setRole(String role)
+   {
+      this.role = role;
+   }
+
+   public List<String> getGroups()
+   {
+      return groups;
+   }
+   
+   public void setGroups(List<String> groups)
+   {
+      this.groups = groups;
+   }
+}
\ No newline at end of file

Deleted: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/management/action/UserAction.java
===================================================================
--- modules/security/trunk/core/src/main/java/org/jboss/seam/security/management/action/UserAction.java	2010-03-24 09:14:40 UTC (rev 12256)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/management/action/UserAction.java	2010-04-13 10:22:26 UTC (rev 12451)
@@ -1,212 +0,0 @@
-package org.jboss.seam.security.management.action;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.enterprise.context.Conversation;
-import javax.enterprise.context.ConversationScoped;
-import javax.inject.Inject;
-import javax.inject.Named;
-
-import org.jboss.seam.security.management.IdentityManager;
-
-/**
- * A conversation-scoped component for creating and managing user accounts
- * 
- * @author Shane Bryzak
- */
- at Named
- at ConversationScoped
-public class UserAction implements Serializable
-{
-   private String firstname;
-   private String lastname;
-   private String username;
-   private String password;
-   private String confirm;
-   private List<String> roles;
-   private boolean enabled;
-   
-   private boolean newUserFlag;
-   
-   @Inject IdentityManager identityManager;
-   @Inject Conversation conversation;
-      
-   public void createUser()
-   {
-      conversation.begin();
-      roles = new ArrayList<String>();
-      newUserFlag = true;
-   }
-   
-   public void editUser(String username)
-   {
-      conversation.begin();
-      this.username = username;
-      roles = identityManager.getGrantedRoles(username);
-      enabled = identityManager.isUserEnabled(username);
-      newUserFlag = false;
-   }
-      
-   public String save()
-   {
-      if (newUserFlag)
-      {
-         return saveNewUser();
-      }
-      else
-      {
-         return saveExistingUser();
-      }
-   }
-   
-   private String saveNewUser()
-   {
-      if (password == null || !password.equals(confirm))
-      {
-         // TODO - add control message
-         //StatusMessages.instance().addToControl("password", "Passwords do not match");
-         return "failure";
-      }
-      
-      boolean success = identityManager.createUser(username, password, firstname, lastname);
-      
-      if (success)
-      {
-         for (String role : roles)
-         {
-            identityManager.grantRole(username, role);
-         }
-         
-         if (!enabled)
-         {
-            identityManager.disableUser(username);
-         }
-         
-         conversation.end();
-         
-         return "success";
-      }
-      
-      return "failure";
-   }
-   
-   private String saveExistingUser()
-   {
-      // Check if a new password has been entered
-      if (password != null && !"".equals(password))
-      {
-         if (!password.equals(confirm))
-         {
-            // TODO - add control message
-            // StatusMessages.instance().addToControl("password", "Passwords do not match");
-            return "failure";
-         }
-         else
-         {
-            identityManager.changePassword(username, password);
-         }
-      }
-      
-      List<String> grantedRoles = identityManager.getGrantedRoles(username);
-      
-      if (grantedRoles != null)
-      {
-         for (String role : grantedRoles)
-         {
-            if (!roles.contains(role)) identityManager.revokeRole(username, role);
-         }
-      }
-      
-      for (String role : roles)
-      {
-         if (grantedRoles == null || !grantedRoles.contains(role))
-         {
-            identityManager.grantRole(username, role);
-         }
-      }
-      
-      if (enabled)
-      {
-         identityManager.enableUser(username);
-      }
-      else
-      {
-         identityManager.disableUser(username);
-      }
-         
-      conversation.end();
-      return "success";
-   }
-   
-   public String getFirstname()
-   {
-      return firstname;
-   }
-   
-   public void setFirstname(String firstname)
-   {
-      this.firstname = firstname;
-   }
-   
-   public String getLastname()
-   {
-      return lastname;
-   }
-   
-   public void setLastname(String lastname)
-   {
-      this.lastname = lastname;
-   }
-   
-   public String getUsername()
-   {
-      return username;
-   }
-   
-   public void setUsername(String username)
-   {
-      this.username = username;
-   }
-   
-   public String getPassword()
-   {
-      return password;
-   }
-   
-   public void setPassword(String password)
-   {
-      this.password = password;
-   }
-   
-   public String getConfirm()
-   {
-      return confirm;
-   }
-   
-   public void setConfirm(String confirm)
-   {
-      this.confirm = confirm;
-   }
-   
-   public List<String> getRoles()
-   {
-      return roles;
-   }
-   
-   public void setRoles(List<String> roles)
-   {
-      this.roles = roles;
-   }
-   
-   public boolean isEnabled()
-   {
-      return enabled;
-   }
-   
-   public void setEnabled(boolean enabled)
-   {
-      this.enabled = enabled;
-   }
-}
\ No newline at end of file

Copied: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/management/action/UserAction.java (from rev 12399, modules/security/trunk/core/src/main/java/org/jboss/seam/security/management/action/UserAction.java)
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/management/action/UserAction.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/management/action/UserAction.java	2010-04-13 10:22:26 UTC (rev 12451)
@@ -0,0 +1,214 @@
+package org.jboss.seam.security.management.action;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.enterprise.context.Conversation;
+import javax.enterprise.context.ConversationScoped;
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.jboss.seam.security.management.IdentityManager;
+
+/**
+ * A conversation-scoped component for creating and managing user accounts
+ * 
+ * @author Shane Bryzak
+ */
+ at Named
+ at ConversationScoped
+public class UserAction implements Serializable
+{
+   private static final long serialVersionUID = 5820385095080724087L;
+   
+   private String firstname;
+   private String lastname;
+   private String username;
+   private String password;
+   private String confirm;
+   private List<String> roles;
+   private boolean enabled;
+   
+   private boolean newUserFlag;
+   
+   @Inject IdentityManager identityManager;
+   @Inject Conversation conversation;
+      
+   public void createUser()
+   {
+      conversation.begin();
+      roles = new ArrayList<String>();
+      newUserFlag = true;
+   }
+   
+   public void editUser(String username)
+   {
+      conversation.begin();
+      this.username = username;
+      roles = identityManager.getGrantedRoles(username);
+      enabled = identityManager.isUserEnabled(username);
+      newUserFlag = false;
+   }
+      
+   public String save()
+   {
+      if (newUserFlag)
+      {
+         return saveNewUser();
+      }
+      else
+      {
+         return saveExistingUser();
+      }
+   }
+   
+   private String saveNewUser()
+   {
+      if (password == null || !password.equals(confirm))
+      {
+         // TODO - add control message
+         //StatusMessages.instance().addToControl("password", "Passwords do not match");
+         return "failure";
+      }
+      
+      boolean success = identityManager.createUser(username, password, firstname, lastname);
+      
+      if (success)
+      {
+         for (String role : roles)
+         {
+            identityManager.grantRole(username, role);
+         }
+         
+         if (!enabled)
+         {
+            identityManager.disableUser(username);
+         }
+         
+         conversation.end();
+         
+         return "success";
+      }
+      
+      return "failure";
+   }
+   
+   private String saveExistingUser()
+   {
+      // Check if a new password has been entered
+      if (password != null && !"".equals(password))
+      {
+         if (!password.equals(confirm))
+         {
+            // TODO - add control message
+            // StatusMessages.instance().addToControl("password", "Passwords do not match");
+            return "failure";
+         }
+         else
+         {
+            identityManager.changePassword(username, password);
+         }
+      }
+      
+      List<String> grantedRoles = identityManager.getGrantedRoles(username);
+      
+      if (grantedRoles != null)
+      {
+         for (String role : grantedRoles)
+         {
+            if (!roles.contains(role)) identityManager.revokeRole(username, role);
+         }
+      }
+      
+      for (String role : roles)
+      {
+         if (grantedRoles == null || !grantedRoles.contains(role))
+         {
+            identityManager.grantRole(username, role);
+         }
+      }
+      
+      if (enabled)
+      {
+         identityManager.enableUser(username);
+      }
+      else
+      {
+         identityManager.disableUser(username);
+      }
+         
+      conversation.end();
+      return "success";
+   }
+   
+   public String getFirstname()
+   {
+      return firstname;
+   }
+   
+   public void setFirstname(String firstname)
+   {
+      this.firstname = firstname;
+   }
+   
+   public String getLastname()
+   {
+      return lastname;
+   }
+   
+   public void setLastname(String lastname)
+   {
+      this.lastname = lastname;
+   }
+   
+   public String getUsername()
+   {
+      return username;
+   }
+   
+   public void setUsername(String username)
+   {
+      this.username = username;
+   }
+   
+   public String getPassword()
+   {
+      return password;
+   }
+   
+   public void setPassword(String password)
+   {
+      this.password = password;
+   }
+   
+   public String getConfirm()
+   {
+      return confirm;
+   }
+   
+   public void setConfirm(String confirm)
+   {
+      this.confirm = confirm;
+   }
+   
+   public List<String> getRoles()
+   {
+      return roles;
+   }
+   
+   public void setRoles(List<String> roles)
+   {
+      this.roles = roles;
+   }
+   
+   public boolean isEnabled()
+   {
+      return enabled;
+   }
+   
+   public void setEnabled(boolean enabled)
+   {
+      this.enabled = enabled;
+   }
+}
\ No newline at end of file

Deleted: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/management/action/UserSearch.java
===================================================================
--- modules/security/trunk/core/src/main/java/org/jboss/seam/security/management/action/UserSearch.java	2010-03-24 09:14:40 UTC (rev 12256)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/management/action/UserSearch.java	2010-04-13 10:22:26 UTC (rev 12451)
@@ -1,50 +0,0 @@
-package org.jboss.seam.security.management.action;
-
-import java.io.Serializable;
-
-import javax.enterprise.context.SessionScoped;
-import javax.inject.Named;
-
- at Named
- at SessionScoped
-public class UserSearch implements Serializable
-{
-   private static final long serialVersionUID = 8592034786339372510L;
-
-   /*
-   @DataModel
-   List<String> users;
-   
-   @DataModelSelection
-   String selectedUser;
-   
-   @Current IdentityManager identityManager;
-   
-   public void loadUsers()
-   {
-      users = identityManager.listUsers();
-   }
-   
-   public String getUserRoles(String username)
-   {
-      List<String> roles = identityManager.getGrantedRoles(username);
-      
-      if (roles == null) return "";
-      
-      StringBuilder sb = new StringBuilder();
-      
-      for (String role : roles)
-      {
-         sb.append((sb.length() > 0 ? ", " : "") + role);
-      }
-      
-      return sb.toString();
-   }
-   
-   public String getSelectedUser()
-   {
-      return selectedUser;
-   }
-   
-   */
-}
\ No newline at end of file

Copied: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/management/action/UserSearch.java (from rev 12399, modules/security/trunk/core/src/main/java/org/jboss/seam/security/management/action/UserSearch.java)
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/management/action/UserSearch.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/management/action/UserSearch.java	2010-04-13 10:22:26 UTC (rev 12451)
@@ -0,0 +1,56 @@
+package org.jboss.seam.security.management.action;
+
+import java.io.Serializable;
+import java.util.List;
+
+import javax.enterprise.context.SessionScoped;
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.jboss.seam.security.management.IdentityManager;
+
+ at Named
+ at SessionScoped
+public class UserSearch implements Serializable
+{
+   private static final long serialVersionUID = 8592034786339372510L;
+
+   List<String> users;
+   
+   //@DataModelSelection
+   //String selectedUser;
+   
+   @Inject IdentityManager identityManager;
+   
+   public void loadUsers()
+   {
+      users = identityManager.getUsers();
+   }
+   
+   public String getUserRoles(String username)
+   {
+      List<String> roles = identityManager.getGrantedRoles(username);
+      
+      if (roles == null) return "";
+      
+      StringBuilder sb = new StringBuilder();
+      
+      for (String role : roles)
+      {
+         sb.append((sb.length() > 0 ? ", " : "") + role);
+      }
+      
+      return sb.toString();
+   }
+   
+   //public String getSelectedUser()
+   //{
+      //return selectedUser;
+   //}
+   
+   public List<String> getUsers()
+   {
+      return users;
+   }   
+   
+}
\ No newline at end of file

Copied: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/permission (from rev 12256, modules/security/trunk/core/src/main/java/org/jboss/seam/security/permission)

Deleted: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/permission/JpaPermissionStore.java
===================================================================
--- modules/security/trunk/core/src/main/java/org/jboss/seam/security/permission/JpaPermissionStore.java	2010-03-24 09:14:40 UTC (rev 12256)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/permission/JpaPermissionStore.java	2010-04-13 10:22:26 UTC (rev 12451)
@@ -1,802 +0,0 @@
-package org.jboss.seam.security.permission;
-
-import java.io.Serializable;
-import java.security.Principal;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.enterprise.context.ApplicationScoped;
-import javax.enterprise.inject.Instance;
-import javax.enterprise.inject.spi.BeanManager;
-import javax.inject.Inject;
-import javax.persistence.EntityManager;
-import javax.persistence.Query;
-
-import org.jboss.seam.security.Role;
-import org.jboss.seam.security.annotations.permission.PermissionAction;
-import org.jboss.seam.security.annotations.permission.PermissionDiscriminator;
-import org.jboss.seam.security.annotations.permission.PermissionRole;
-import org.jboss.seam.security.annotations.permission.PermissionTarget;
-import org.jboss.seam.security.annotations.permission.PermissionUser;
-import org.jboss.seam.security.management.IdentityManager;
-import org.jboss.seam.security.management.IdentityStore;
-import org.jboss.seam.security.management.JpaIdentityStore;
-import org.jboss.seam.security.management.LdapIdentityStore;
-import org.jboss.seam.security.permission.PermissionMetadata.ActionSet;
-import org.jboss.seam.security.util.AnnotatedBeanProperty;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * A permission store implementation that uses JPA as its persistence mechanism.
- * 
- * @author Shane Bryzak
- */
- at ApplicationScoped
-public class JpaPermissionStore implements PermissionStore, Serializable
-{
-   private static final long serialVersionUID = 4764590939669047915L;
-   
-   private Logger log = LoggerFactory.getLogger(LdapIdentityStore.class);
-   
-   private enum Discrimination { user, role, either }
-   
-   private Class<?> userPermissionClass;
-   private Class<?> rolePermissionClass;
-      
-   private AnnotatedBeanProperty<PermissionUser> userProperty;
-   private AnnotatedBeanProperty<PermissionRole> roleProperty;
-   
-   private AnnotatedBeanProperty<PermissionTarget> targetProperty;
-   private AnnotatedBeanProperty<PermissionAction> actionProperty;
-   private AnnotatedBeanProperty<PermissionDiscriminator> discriminatorProperty;
-   
-   private AnnotatedBeanProperty<PermissionTarget> roleTargetProperty;
-   private AnnotatedBeanProperty<PermissionAction> roleActionProperty;
-   
-   private Map<Integer,String> queryCache = new HashMap<Integer,String>();
-     
-   private PermissionMetadata metadata;
-   
-   @Inject IdentifierPolicy identifierPolicy;
-   @Inject BeanManager manager;
-   @Inject IdentityManager identityManager;
-   @Inject IdentityStore identityStore;
-   
-   @Inject Instance<EntityManager> entityManagerInstance;
-   
-   @Inject
-   public void init()
-   {
-      metadata = new PermissionMetadata();
-      
-      // TODO see if we can scan for this automatically
-      if (userPermissionClass == null)
-      {
-         log.debug("No permissionClass set, JpaPermissionStore will be unavailable.");
-         return;
-      }
-      
-      initProperties();
-   }
-   
-   protected void initProperties()
-   {
-      userProperty = new AnnotatedBeanProperty<PermissionUser>(userPermissionClass, PermissionUser.class);
-      targetProperty = new AnnotatedBeanProperty<PermissionTarget>(userPermissionClass, PermissionTarget.class);
-      actionProperty = new AnnotatedBeanProperty<PermissionAction>(userPermissionClass, PermissionAction.class);
-      
-      if (rolePermissionClass != null)
-      {
-         roleProperty = new AnnotatedBeanProperty<PermissionRole>(rolePermissionClass, PermissionRole.class);
-         if (roleProperty.isSet())
-         {
-            roleTargetProperty = new AnnotatedBeanProperty<PermissionTarget>(rolePermissionClass,
-                  PermissionTarget.class);
-            roleActionProperty = new AnnotatedBeanProperty<PermissionAction>(rolePermissionClass,
-                  PermissionAction.class);
-         }
-      }
-      else
-      {
-         roleProperty = new AnnotatedBeanProperty<PermissionRole>(userPermissionClass, PermissionRole.class);
-         if (roleProperty.isSet())
-         {
-            discriminatorProperty = new AnnotatedBeanProperty<PermissionDiscriminator>(userPermissionClass,
-                  PermissionDiscriminator.class);
-         }
-      }
-      
-      if (!userProperty.isSet())
-      {
-         throw new RuntimeException("Invalid userPermissionClass " + userPermissionClass.getName() +
-               " - required annotation @PermissionUser not found on any Field or Method.");
-      }
-
-      if (rolePermissionClass != null)
-      {
-         if (!roleProperty.isSet())
-         {
-            throw new RuntimeException("Invalid rolePermissionClass " + rolePermissionClass.getName() +
-                  " - required annotation @PermissionRole not found on any Field or Method.");
-         }
-         
-         if (!roleTargetProperty.isSet())
-         {
-            throw new RuntimeException("Invalid rolePermissionClass " + rolePermissionClass.getName() +
-                  " - required annotation @PermissionTarget not found on any Field or Method.");
-         }
-         
-         if (!roleActionProperty.isSet())
-         {
-            throw new RuntimeException("Invalid rolePermissionClass " + rolePermissionClass.getName() +
-                  " - required annotation @PermissionAction not found on any Field or Method.");
-         }
-      }
-      else if (!discriminatorProperty.isSet())
-      {
-         throw new RuntimeException("Invalid userPermissionClass " + userPermissionClass.getName() +
-               " - no rolePermissionClass set and @PermissionDiscriminator annotation not found on " +
-               "any Field or Method");
-      }
-   }
-   
-   /**
-    * Creates a Query that returns a list of permission records for the specified parameters.
-    * 
-    * @param target The target of the permission, may be null
-    * @param targets A set of permission targets, may be null
-    * @param recipient The permission recipient, may be null
-    * @param discrimination A discrimination (either user, role or both), required
-    * @return Query The query generated for the provided parameters
-    */
-   protected Query createPermissionQuery(Object target, Set targets, Principal recipient, Discrimination discrimination)
-   {
-      if (target != null && targets != null)
-      {
-         throw new IllegalArgumentException("Cannot specify both target and targets");
-      }
-      
-      int queryKey = (target != null) ? 1 : 0;
-      queryKey |= (targets != null) ? 2 : 0;
-      queryKey |= (recipient != null) ? 4 : 0;
-      queryKey |= (discrimination.equals(Discrimination.user) ? 8 : 0);
-      queryKey |= (discrimination.equals(Discrimination.role) ? 16 : 0);
-      queryKey |= (discrimination.equals(Discrimination.either) ? 32 : 0);
-      
-      boolean isRole = discrimination.equals(Discrimination.role);
-      boolean useRoleTable = isRole && rolePermissionClass != null;
-      
-      if (!queryCache.containsKey(queryKey))
-      {
-         boolean conditionsAdded = false;
-         
-         StringBuilder q = new StringBuilder();
-         q.append("select p from ");
-         q.append(useRoleTable ? rolePermissionClass.getName() : userPermissionClass.getName());
-         q.append(" p");
-         
-         if (target != null)
-         {
-            q.append(" where p.");
-            q.append(useRoleTable ? roleTargetProperty.getName() : targetProperty.getName());
-            q.append(" = :target");
-            conditionsAdded = true;
-         }
-         
-         if (targets != null)
-         {
-            q.append(" where p.");
-            q.append(useRoleTable ? roleTargetProperty.getName() : targetProperty.getName());
-            q.append(" in (:targets)");
-            conditionsAdded = true;
-         }
-         
-         if (recipient != null)
-         {
-            q.append(conditionsAdded ? " and p." : " where p.");
-            q.append(isRole ? roleProperty.getName() : userProperty.getName());
-            q.append(" = :recipient");
-            conditionsAdded = true;
-         }
-         
-         // If there is no discrimination, then don't add such a condition to the query
-         if (!discrimination.equals(Discrimination.either) && discriminatorProperty != null)
-         {
-            q.append(conditionsAdded ? " and p." : " where p.");
-            q.append(discriminatorProperty.getName());
-            q.append(" = :discriminator");
-            conditionsAdded = true;
-         }
-         
-         queryCache.put(queryKey, q.toString());
-      }
-      
-      Query query = lookupEntityManager().createQuery(queryCache.get(queryKey));
-      
-      if (target != null) query.setParameter("target", identifierPolicy.getIdentifier(target));
-      
-      if (targets != null)
-      {
-         Set<String> identifiers = new HashSet<String>();
-         for (Object t : targets)
-         {
-            identifiers.add(identifierPolicy.getIdentifier(t));
-         }
-         query.setParameter("targets", identifiers);
-      }
-      
-      
-      if (recipient != null) query.setParameter("recipient", resolvePrincipalEntity(recipient));
-      
-      if (!discrimination.equals(Discrimination.either) && discriminatorProperty != null)
-      {
-         query.setParameter("discriminator", getDiscriminatorValue(
-               discrimination.equals(Discrimination.role)));
-      }
-      
-      return query;
-   }
-   
-   public boolean grantPermission(Permission permission)
-   {
-      return updatePermissionActions(permission.getTarget(), permission.getRecipient(),
-            new String[] {permission.getAction()}, true);
-   }
-   
-   public boolean revokePermission(Permission permission)
-   {
-      return updatePermissionActions(permission.getTarget(), permission.getRecipient(),
-            new String[] { permission.getAction() }, false);
-   }
-      
-   /**
-    * This is where the bulk of the actual work happens.
-    * 
-    * @param target The target object to update permissions for
-    * @param recipient The recipient to update permissions for
-    * @param actions The actions that will be updated
-    * @param set true if the specified actions are to be granted, false if they are to be revoked
-    * @return true if the operation is successful
-    */
-   protected boolean updatePermissionActions(Object target, Principal recipient, String[] actions,
-         boolean set)
-   {
-      boolean recipientIsRole = recipient instanceof Role;
-      
-      try
-      {
-         if (recipientIsRole)
-         {
-            if (rolePermissionClass != null)
-            {
-               List permissions = createPermissionQuery(target, null, recipient, Discrimination.role).getResultList();
-
-               if (permissions.isEmpty())
-               {
-                  if (!set) return true;
-                  
-                  ActionSet actionSet = metadata.createActionSet(target.getClass(), null);
-                  for (String action : actions)
-                  {
-                     actionSet.add(action);
-                  }
-                  
-                  Object instance = rolePermissionClass.newInstance();
-                  roleTargetProperty.setValue(instance, identifierPolicy.getIdentifier(target));
-                  roleActionProperty.setValue(instance, actionSet.toString());
-                  roleProperty.setValue(instance, resolvePrincipalEntity(recipient));
-                  lookupEntityManager().persist(instance);
-                  return true;
-               }
-                              
-               Object instance = permissions.get(0);
-               
-               ActionSet actionSet = metadata.createActionSet(target.getClass(),
-                     roleActionProperty.getValue(instance).toString());
-               
-               for (String action : actions)
-               {
-                  if (set)
-                  {
-                     actionSet.add(action);
-                  }
-                  else
-                  {
-                     actionSet.remove(action);
-                  }
-               }
-               
-               if (permissions.size() > 1)
-               {
-                  // This is where it gets a little messy.. if there is more than one permission
-                  // record, then we need to consolidate them all into just the first one
-                  for (Object p : permissions)
-                  {
-                     actionSet.addMembers(roleActionProperty.getValue(p).toString());
-                     if (!p.equals(instance))
-                     {
-                        lookupEntityManager().remove(p);
-                     }
-                  }
-               }
-                  
-               if (!actionSet.isEmpty())
-               {
-                  roleActionProperty.setValue(instance, actionSet.toString());
-                  lookupEntityManager().merge(instance);
-               }
-               else
-               {
-                  // No actions remaining in set, so just remove the record
-                  lookupEntityManager().remove(instance);
-               }
-               
-               return true;
-            }
-            
-            if (!discriminatorProperty.isSet())
-            {
-               throw new RuntimeException("Could not grant permission, rolePermissionClass not set");
-            }
-         }
-         
-         if (userPermissionClass == null)
-         {
-            throw new RuntimeException("Could not grant permission, userPermissionClass not set");
-         }
-                         
-         List permissions = createPermissionQuery(target, null, recipient, recipientIsRole ?
-               Discrimination.role : Discrimination.user).getResultList();
-
-         if (permissions.isEmpty())
-         {
-            if (!set) return true;
-            
-            ActionSet actionSet = metadata.createActionSet(target.getClass(), null);
-            for (String action : actions)
-            {
-               actionSet.add(action);
-            }
-            
-            Object instance = userPermissionClass.newInstance();
-            targetProperty.setValue(instance, identifierPolicy.getIdentifier(target));
-            actionProperty.setValue(instance, actionSet.toString());
-            
-            if (recipientIsRole)
-            {
-               roleProperty.setValue(instance, resolvePrincipalEntity(recipient));
-            }
-            else
-            {
-               userProperty.setValue(instance, resolvePrincipalEntity(recipient));
-            }
-                       
-            if (discriminatorProperty.isSet())
-            {
-               PermissionDiscriminator discriminator = discriminatorProperty.getAnnotation();
-               discriminatorProperty.setValue(instance, recipientIsRole ? discriminator.roleValue() :
-                  discriminator.userValue());
-            }
-            
-            lookupEntityManager().persist(instance);
-            return true;
-         }
-                        
-         Object instance = permissions.get(0);
-         
-         ActionSet actionSet = metadata.createActionSet(target.getClass(),
-               actionProperty.getValue(instance).toString());
-         
-         for (String action : actions)
-         {
-            if (set)
-            {
-               actionSet.add(action);
-            }
-            else
-            {
-               actionSet.remove(action);
-            }
-         }
-         
-         if (permissions.size() > 1)
-         {
-            // Same as with roles, consolidate the records if there is more than one
-            for (Object p : permissions)
-            {
-               actionSet.addMembers(actionProperty.getValue(p).toString());
-               if (!p.equals(instance))
-               {
-                  lookupEntityManager().remove(p);
-               }
-            }
-         }
-            
-         if (!actionSet.isEmpty())
-         {
-            actionProperty.setValue(instance, actionSet.toString());
-            lookupEntityManager().merge(instance);
-         }
-         else
-         {
-            // No actions remaining in set, so just remove the record
-            lookupEntityManager().remove(instance);
-         }
-         
-         return true;
-      }
-      catch (Exception ex)
-      {
-         throw new RuntimeException("Could not grant permission", ex);
-      }
-   }
-   
-   public boolean grantPermissions(List<Permission> permissions)
-   {
-      // Target/Recipient/Action map
-      Map<Object,Map<Principal,List<Permission>>> groupedPermissions = groupPermissions(permissions);
-      
-      for (Object target : groupedPermissions.keySet())
-      {
-         Map<Principal,List<Permission>> recipientPermissions = groupedPermissions.get(target);
-                  
-         for (Principal recipient : recipientPermissions.keySet())
-         {
-            List<Permission> ps = recipientPermissions.get(recipient);
-            String[] actions = new String[ps.size()];
-            for (int i = 0; i < ps.size(); i++) actions[i] = ps.get(i).getAction();
-            updatePermissionActions(target, recipient, actions, true);
-         }
-      }
-      
-      return true;
-   }
-   
-   public boolean revokePermissions(List<Permission> permissions)
-   {
-      // Target/Recipient/Action map
-      Map<Object,Map<Principal,List<Permission>>> groupedPermissions = groupPermissions(permissions);
-      
-      for (Object target : groupedPermissions.keySet())
-      {
-         Map<Principal,List<Permission>> recipientPermissions = groupedPermissions.get(target);
-                  
-         for (Principal recipient : recipientPermissions.keySet())
-         {
-            List<Permission> ps = recipientPermissions.get(recipient);
-            String[] actions = new String[ps.size()];
-            for (int i = 0; i < ps.size(); i++) actions[i] = ps.get(i).getAction();
-            updatePermissionActions(target, recipient, actions, false);
-         }
-      }
-      
-      return true;
-   }
-   
-   /**
-    * Groups a list of arbitrary permissions into a more easily-consumed structure
-    * 
-    * @param permissions The list of permissions to group
-    * @return
-    */
-   private Map<Object,Map<Principal,List<Permission>>> groupPermissions(List<Permission> permissions)
-   {
-      // Target/Recipient/Action map
-      Map<Object,Map<Principal,List<Permission>>> groupedPermissions = new HashMap<Object,Map<Principal,List<Permission>>>();
-      
-      for (Permission permission : permissions)
-      {
-         if (!groupedPermissions.containsKey(permission.getTarget()))
-         {
-            groupedPermissions.put(permission.getTarget(), new HashMap<Principal,List<Permission>>());
-         }
-         
-         Map<Principal,List<Permission>> recipientPermissions = groupedPermissions.get(permission.getTarget());
-         if (!recipientPermissions.containsKey(permission.getRecipient()))
-         {
-            List<Permission> perms = new ArrayList<Permission>();
-            perms.add(permission);
-            recipientPermissions.put(permission.getRecipient(), perms);
-         }
-         else
-         {
-            recipientPermissions.get(permission.getRecipient()).add(permission);
-         }
-      }
-
-      return groupedPermissions;
-   }
-   
-   private String getDiscriminatorValue(boolean isRole)
-   {
-      PermissionDiscriminator discriminator = discriminatorProperty.getAnnotation();
-      return isRole ? discriminator.roleValue() : discriminator.userValue();
-   }
-
-   /**
-    * If the user or role properties in the entity class refer to other entities, then this method
-    * uses the JpaIdentityStore (if available) to lookup that user or role entity.  Otherwise it
-    * simply returns the name of the recipient.
-    * 
-    * @param recipient
-    * @return The entity or name representing the permission recipient
-    */
-   protected Object resolvePrincipalEntity(Principal recipient)
-   {
-      boolean recipientIsRole = recipient instanceof Role;
-            
-      if (identityStore != null && identityStore instanceof JpaIdentityStore)
-      {
-         // TODO review this code
-         
-         if (recipientIsRole && roleProperty.isSet() //&&
-               //roleProperty.getPropertyType().equals(config.getRoleEntityClass()))
-               )
-         {
-            return ((JpaIdentityStore) identityStore).lookupRole(recipient.getName());
-         }
-         //else if (userProperty.getPropertyType().equals(config.getUserEntityClass()))
-         //{
-            //return ((JpaIdentityStore) identityStore).lookupUser(recipient.getName());
-         //}
-      }
-      
-      return recipient.getName();
-   }
-   
-   protected Principal resolvePrincipal(Object principal, boolean isUser)
-   {
-      identityManager.getRoleIdentityStore();
-         
-      // TODO review this
-      
-      /*
-      if (principal instanceof String)
-      {
-         return isUser ? new SimplePrincipal((String) principal) : new Role((String) principal,
-               identityStore == null ? false : identityStore.isRoleConditional((String) principal));
-      }
-      
-      if (identityStore != null)
-      {
-         if (isUser && config.getUserEntityClass().isAssignableFrom(principal.getClass()))
-         {
-            return new SimplePrincipal(identityStore.getUserName(principal));
-         }
-         
-         if (!isUser && config.getRoleEntityClass().isAssignableFrom(principal.getClass()))
-         {
-            String name = identityStore.getRoleName(principal);
-            return new Role(name, identityStore.isRoleConditional(name));
-         }
-      }*/
-      
-      throw new IllegalArgumentException("Cannot resolve principal name for principal " + principal);
-   }
-
-   /**
-    * Returns a list of all user and role permissions for the specified action for all specified target objects
-    */
-   public List<Permission> listPermissions(Set<Object> targets, String action)
-   {
-      // TODO limit the number of targets passed at a single time to 25
-      return listPermissions(null, targets, action);
-   }
-   
-   /**
-    * Returns a list of all user and role permissions for a specific permission target and action.
-    */
-   public List<Permission> listPermissions(Object target, String action)
-   {
-      return listPermissions(target, null, action);
-   }
-   
-   protected List<Permission> listPermissions(Object target, Set<Object> targets, String action)
-   {
-      if (target != null && targets != null)
-      {
-         throw new IllegalArgumentException("Cannot specify both target and targets");
-      }
-      
-      List<Permission> permissions = new ArrayList<Permission>();
-      
-      if (targets != null && targets.isEmpty()) return permissions;
-      
-      // First query for user permissions
-      Query permissionQuery = targets != null ?
-            createPermissionQuery(null, targets, null, Discrimination.either) :
-            createPermissionQuery(target, null, null, Discrimination.either);
-            
-      List<?> userPermissions = permissionQuery.getResultList();
-      
-      Map<String,Principal> principalCache = new HashMap<String,Principal>();
-      
-      boolean useDiscriminator = rolePermissionClass == null && discriminatorProperty.isSet();
-      
-      Map<String,Object> identifierCache = null;
-      
-      if (targets != null)
-      {
-         identifierCache = new HashMap<String,Object>();
-         
-         for (Object t : targets)
-         {
-            identifierCache.put(identifierPolicy.getIdentifier(t), t);
-         }
-      }
-      
-      for (Object permission : userPermissions)
-      {
-         ActionSet actionSet = null;
-         
-         if (targets != null)
-         {
-            target = identifierCache.get(targetProperty.getValue(permission));
-            if (target != null)
-            {
-               actionSet = metadata.createActionSet(target.getClass(),
-                  actionProperty.getValue(permission).toString());
-            }
-         }
-         else
-         {
-            actionSet = metadata.createActionSet(target.getClass(),
-                  actionProperty.getValue(permission).toString());
-         }
-         
-         if (target != null && (action == null || (actionSet != null && actionSet.contains(action))))
-         {
-            boolean isUser = true;
-            
-            if (useDiscriminator &&
-               discriminatorProperty.getAnnotation().roleValue().equals(
-                     discriminatorProperty.getValue(permission)))
-            {
-               isUser = false;
-            }
-
-            Principal principal = lookupPrincipal(principalCache, permission, isUser);
-            
-            if (action != null)
-            {
-               permissions.add(new Permission(target, action, principal));
-            }
-            else
-            {
-               for (String a : actionSet.members())
-               {
-                  permissions.add(new Permission(target, a, principal));
-               }
-            }
-         }
-      }
-      
-      // If we have a separate class for role permissions, then query them now
-      if (rolePermissionClass != null)
-      {
-         permissionQuery = targets != null ?
-               createPermissionQuery(null, targets, null, Discrimination.role) :
-               createPermissionQuery(target, null, null, Discrimination.role);
-         List<?> rolePermissions = permissionQuery.getResultList();
-         
-         for (Object permission : rolePermissions)
-         {
-            ActionSet actionSet = null;
-            
-            if (targets != null)
-            {
-               target = identifierCache.get(roleTargetProperty.getValue(permission));
-               if (target != null)
-               {
-                  actionSet = metadata.createActionSet(target.getClass(),
-                     roleActionProperty.getValue(permission).toString());
-               }
-            }
-            else
-            {
-               actionSet = metadata.createActionSet(target.getClass(),
-                     roleActionProperty.getValue(permission).toString());
-            }
-                       
-            if (target != null && (action == null || (actionSet != null && actionSet.contains(action))))
-            {
-               Principal principal = lookupPrincipal(principalCache, permission, false);
-               
-               if (action != null)
-               {
-                  permissions.add(new Permission(target, action, principal));
-               }
-               else
-               {
-                  for (String a : actionSet.members())
-                  {
-                     permissions.add(new Permission(target, a, principal));
-                  }
-               }
-            }
-         }
-      }
-      
-      return permissions;
-   }
-   
-   private Principal lookupPrincipal(Map<String,Principal> cache, Object permission, boolean isUser)
-   {
-      Principal principal = resolvePrincipal(isUser ? userProperty.getValue(permission) :
-         roleProperty.getValue(permission), isUser);
-      
-      String key = (isUser ? "u:" : "r:") + principal.getName();
-      
-      if (!cache.containsKey(key))
-      {
-         cache.put(key, principal);
-      }
-      else
-      {
-         principal = cache.get(key);
-      }
-      
-      return principal;
-   }
-
-   public List<Permission> listPermissions(Object target)
-   {
-      return listPermissions(target, null);
-   }
-   
-   public List<String> listAvailableActions(Object target)
-   {
-      return metadata.listAllowableActions(target.getClass());
-   }
-
-   private EntityManager lookupEntityManager()
-   {
-      return entityManagerInstance.get();
-   }
-   
-   public Class<?> getUserPermissionClass()
-   {
-      return userPermissionClass;
-   }
-   
-   public void setUserPermissionClass(Class<?> userPermissionClass)
-   {
-      this.userPermissionClass = userPermissionClass;
-   }
-   
-   public Class<?> getRolePermissionClass()
-   {
-      return rolePermissionClass;
-   }
-   
-   public void setRolePermissionClass(Class<?> rolePermissionClass)
-   {
-      this.rolePermissionClass = rolePermissionClass;
-   }
-   
-   public void clearPermissions(Object target)
-   {
-      EntityManager em = lookupEntityManager();
-      String identifier = identifierPolicy.getIdentifier(target);
-      
-      em.createQuery(
-            "delete from " + userPermissionClass.getName() + " p where p." +
-            targetProperty.getName() + " = :target")
-            .setParameter("target", identifier)
-            .executeUpdate();
-      
-      if (rolePermissionClass != null)
-      {
-         em.createQuery(
-               "delete from " + rolePermissionClass.getName() + " p where p." +
-               roleTargetProperty.getName() + " = :target")
-               .setParameter("target", identifier)
-               .executeUpdate();
-      }
-   }
-}

Copied: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/permission/JpaPermissionStore.java (from rev 12277, modules/security/trunk/core/src/main/java/org/jboss/seam/security/permission/JpaPermissionStore.java)
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/permission/JpaPermissionStore.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/permission/JpaPermissionStore.java	2010-04-13 10:22:26 UTC (rev 12451)
@@ -0,0 +1,803 @@
+package org.jboss.seam.security.permission;
+
+import java.io.Serializable;
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.inject.Instance;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.inject.Inject;
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import org.jboss.seam.security.Role;
+import org.jboss.seam.security.annotations.permission.PermissionAction;
+import org.jboss.seam.security.annotations.permission.PermissionDiscriminator;
+import org.jboss.seam.security.annotations.permission.PermissionRole;
+import org.jboss.seam.security.annotations.permission.PermissionTarget;
+import org.jboss.seam.security.annotations.permission.PermissionUser;
+import org.jboss.seam.security.management.IdentityManager;
+import org.jboss.seam.security.management.IdentityStore;
+import org.jboss.seam.security.management.JpaIdentityStore;
+import org.jboss.seam.security.management.LdapIdentityStore;
+import org.jboss.seam.security.permission.PermissionMetadata.ActionSet;
+import org.jboss.seam.security.util.AnnotatedBeanProperty;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A permission store implementation that uses JPA as its persistence mechanism.
+ * 
+ * @author Shane Bryzak
+ */
+ at ApplicationScoped
+public class JpaPermissionStore implements PermissionStore, Serializable
+{
+   private static final long serialVersionUID = 4764590939669047915L;
+   
+   private Logger log = LoggerFactory.getLogger(LdapIdentityStore.class);
+   
+   private enum Discrimination { user, role, either }
+   
+   private Class<?> userPermissionClass;
+   private Class<?> rolePermissionClass;
+      
+   private AnnotatedBeanProperty<PermissionUser> userProperty;
+   private AnnotatedBeanProperty<PermissionRole> roleProperty;
+   
+   private AnnotatedBeanProperty<PermissionTarget> targetProperty;
+   private AnnotatedBeanProperty<PermissionAction> actionProperty;
+   private AnnotatedBeanProperty<PermissionDiscriminator> discriminatorProperty;
+   
+   private AnnotatedBeanProperty<PermissionTarget> roleTargetProperty;
+   private AnnotatedBeanProperty<PermissionAction> roleActionProperty;
+   
+   private Map<Integer,String> queryCache = new HashMap<Integer,String>();
+     
+   private PermissionMetadata metadata;
+   
+   @Inject IdentifierPolicy identifierPolicy;
+   @Inject BeanManager manager;
+   @Inject IdentityManager identityManager;
+   //@Inject IdentityStore identityStore;
+   
+   @Inject Instance<EntityManager> entityManagerInstance;
+   
+   @Inject
+   public void init()
+   {
+      metadata = new PermissionMetadata();
+      
+      // TODO see if we can scan for this automatically
+      if (userPermissionClass == null)
+      {
+         log.debug("No permissionClass set, JpaPermissionStore will be unavailable.");
+         return;
+      }
+      
+      initProperties();
+   }
+   
+   protected void initProperties()
+   {
+      userProperty = new AnnotatedBeanProperty<PermissionUser>(userPermissionClass, PermissionUser.class);
+      targetProperty = new AnnotatedBeanProperty<PermissionTarget>(userPermissionClass, PermissionTarget.class);
+      actionProperty = new AnnotatedBeanProperty<PermissionAction>(userPermissionClass, PermissionAction.class);
+      
+      if (rolePermissionClass != null)
+      {
+         roleProperty = new AnnotatedBeanProperty<PermissionRole>(rolePermissionClass, PermissionRole.class);
+         if (roleProperty.isSet())
+         {
+            roleTargetProperty = new AnnotatedBeanProperty<PermissionTarget>(rolePermissionClass,
+                  PermissionTarget.class);
+            roleActionProperty = new AnnotatedBeanProperty<PermissionAction>(rolePermissionClass,
+                  PermissionAction.class);
+         }
+      }
+      else
+      {
+         roleProperty = new AnnotatedBeanProperty<PermissionRole>(userPermissionClass, PermissionRole.class);
+         if (roleProperty.isSet())
+         {
+            discriminatorProperty = new AnnotatedBeanProperty<PermissionDiscriminator>(userPermissionClass,
+                  PermissionDiscriminator.class);
+         }
+      }
+      
+      if (!userProperty.isSet())
+      {
+         throw new RuntimeException("Invalid userPermissionClass " + userPermissionClass.getName() +
+               " - required annotation @PermissionUser not found on any Field or Method.");
+      }
+
+      if (rolePermissionClass != null)
+      {
+         if (!roleProperty.isSet())
+         {
+            throw new RuntimeException("Invalid rolePermissionClass " + rolePermissionClass.getName() +
+                  " - required annotation @PermissionRole not found on any Field or Method.");
+         }
+         
+         if (!roleTargetProperty.isSet())
+         {
+            throw new RuntimeException("Invalid rolePermissionClass " + rolePermissionClass.getName() +
+                  " - required annotation @PermissionTarget not found on any Field or Method.");
+         }
+         
+         if (!roleActionProperty.isSet())
+         {
+            throw new RuntimeException("Invalid rolePermissionClass " + rolePermissionClass.getName() +
+                  " - required annotation @PermissionAction not found on any Field or Method.");
+         }
+      }
+      else if (!discriminatorProperty.isSet())
+      {
+         throw new RuntimeException("Invalid userPermissionClass " + userPermissionClass.getName() +
+               " - no rolePermissionClass set and @PermissionDiscriminator annotation not found on " +
+               "any Field or Method");
+      }
+   }
+   
+   /**
+    * Creates a Query that returns a list of permission records for the specified parameters.
+    * 
+    * @param target The target of the permission, may be null
+    * @param targets A set of permission targets, may be null
+    * @param recipient The permission recipient, may be null
+    * @param discrimination A discrimination (either user, role or both), required
+    * @return Query The query generated for the provided parameters
+    */
+   protected Query createPermissionQuery(Object target, Set targets, Principal recipient, Discrimination discrimination)
+   {
+      if (target != null && targets != null)
+      {
+         throw new IllegalArgumentException("Cannot specify both target and targets");
+      }
+      
+      int queryKey = (target != null) ? 1 : 0;
+      queryKey |= (targets != null) ? 2 : 0;
+      queryKey |= (recipient != null) ? 4 : 0;
+      queryKey |= (discrimination.equals(Discrimination.user) ? 8 : 0);
+      queryKey |= (discrimination.equals(Discrimination.role) ? 16 : 0);
+      queryKey |= (discrimination.equals(Discrimination.either) ? 32 : 0);
+      
+      boolean isRole = discrimination.equals(Discrimination.role);
+      boolean useRoleTable = isRole && rolePermissionClass != null;
+      
+      if (!queryCache.containsKey(queryKey))
+      {
+         boolean conditionsAdded = false;
+         
+         StringBuilder q = new StringBuilder();
+         q.append("select p from ");
+         q.append(useRoleTable ? rolePermissionClass.getName() : userPermissionClass.getName());
+         q.append(" p");
+         
+         if (target != null)
+         {
+            q.append(" where p.");
+            q.append(useRoleTable ? roleTargetProperty.getName() : targetProperty.getName());
+            q.append(" = :target");
+            conditionsAdded = true;
+         }
+         
+         if (targets != null)
+         {
+            q.append(" where p.");
+            q.append(useRoleTable ? roleTargetProperty.getName() : targetProperty.getName());
+            q.append(" in (:targets)");
+            conditionsAdded = true;
+         }
+         
+         if (recipient != null)
+         {
+            q.append(conditionsAdded ? " and p." : " where p.");
+            q.append(isRole ? roleProperty.getName() : userProperty.getName());
+            q.append(" = :recipient");
+            conditionsAdded = true;
+         }
+         
+         // If there is no discrimination, then don't add such a condition to the query
+         if (!discrimination.equals(Discrimination.either) && discriminatorProperty != null)
+         {
+            q.append(conditionsAdded ? " and p." : " where p.");
+            q.append(discriminatorProperty.getName());
+            q.append(" = :discriminator");
+            conditionsAdded = true;
+         }
+         
+         queryCache.put(queryKey, q.toString());
+      }
+      
+      Query query = lookupEntityManager().createQuery(queryCache.get(queryKey));
+      
+      if (target != null) query.setParameter("target", identifierPolicy.getIdentifier(target));
+      
+      if (targets != null)
+      {
+         Set<String> identifiers = new HashSet<String>();
+         for (Object t : targets)
+         {
+            identifiers.add(identifierPolicy.getIdentifier(t));
+         }
+         query.setParameter("targets", identifiers);
+      }
+      
+      
+      if (recipient != null) query.setParameter("recipient", resolvePrincipalEntity(recipient));
+      
+      if (!discrimination.equals(Discrimination.either) && discriminatorProperty != null)
+      {
+         query.setParameter("discriminator", getDiscriminatorValue(
+               discrimination.equals(Discrimination.role)));
+      }
+      
+      return query;
+   }
+   
+   public boolean grantPermission(Permission permission)
+   {
+      return updatePermissionActions(permission.getTarget(), permission.getRecipient(),
+            new String[] {permission.getAction()}, true);
+   }
+   
+   public boolean revokePermission(Permission permission)
+   {
+      return updatePermissionActions(permission.getTarget(), permission.getRecipient(),
+            new String[] { permission.getAction() }, false);
+   }
+      
+   /**
+    * This is where the bulk of the actual work happens.
+    * 
+    * @param target The target object to update permissions for
+    * @param recipient The recipient to update permissions for
+    * @param actions The actions that will be updated
+    * @param set true if the specified actions are to be granted, false if they are to be revoked
+    * @return true if the operation is successful
+    */
+   protected boolean updatePermissionActions(Object target, Principal recipient, String[] actions,
+         boolean set)
+   {
+      boolean recipientIsRole = recipient instanceof Role;
+      
+      try
+      {
+         if (recipientIsRole)
+         {
+            if (rolePermissionClass != null)
+            {
+               List permissions = createPermissionQuery(target, null, recipient, Discrimination.role).getResultList();
+
+               if (permissions.isEmpty())
+               {
+                  if (!set) return true;
+                  
+                  ActionSet actionSet = metadata.createActionSet(target.getClass(), null);
+                  for (String action : actions)
+                  {
+                     actionSet.add(action);
+                  }
+                  
+                  Object instance = rolePermissionClass.newInstance();
+                  roleTargetProperty.setValue(instance, identifierPolicy.getIdentifier(target));
+                  roleActionProperty.setValue(instance, actionSet.toString());
+                  roleProperty.setValue(instance, resolvePrincipalEntity(recipient));
+                  lookupEntityManager().persist(instance);
+                  return true;
+               }
+                              
+               Object instance = permissions.get(0);
+               
+               ActionSet actionSet = metadata.createActionSet(target.getClass(),
+                     roleActionProperty.getValue(instance).toString());
+               
+               for (String action : actions)
+               {
+                  if (set)
+                  {
+                     actionSet.add(action);
+                  }
+                  else
+                  {
+                     actionSet.remove(action);
+                  }
+               }
+               
+               if (permissions.size() > 1)
+               {
+                  // This is where it gets a little messy.. if there is more than one permission
+                  // record, then we need to consolidate them all into just the first one
+                  for (Object p : permissions)
+                  {
+                     actionSet.addMembers(roleActionProperty.getValue(p).toString());
+                     if (!p.equals(instance))
+                     {
+                        lookupEntityManager().remove(p);
+                     }
+                  }
+               }
+                  
+               if (!actionSet.isEmpty())
+               {
+                  roleActionProperty.setValue(instance, actionSet.toString());
+                  lookupEntityManager().merge(instance);
+               }
+               else
+               {
+                  // No actions remaining in set, so just remove the record
+                  lookupEntityManager().remove(instance);
+               }
+               
+               return true;
+            }
+            
+            if (!discriminatorProperty.isSet())
+            {
+               throw new RuntimeException("Could not grant permission, rolePermissionClass not set");
+            }
+         }
+         
+         if (userPermissionClass == null)
+         {
+            throw new RuntimeException("Could not grant permission, userPermissionClass not set");
+         }
+                         
+         List permissions = createPermissionQuery(target, null, recipient, recipientIsRole ?
+               Discrimination.role : Discrimination.user).getResultList();
+
+         if (permissions.isEmpty())
+         {
+            if (!set) return true;
+            
+            ActionSet actionSet = metadata.createActionSet(target.getClass(), null);
+            for (String action : actions)
+            {
+               actionSet.add(action);
+            }
+            
+            Object instance = userPermissionClass.newInstance();
+            targetProperty.setValue(instance, identifierPolicy.getIdentifier(target));
+            actionProperty.setValue(instance, actionSet.toString());
+            
+            if (recipientIsRole)
+            {
+               roleProperty.setValue(instance, resolvePrincipalEntity(recipient));
+            }
+            else
+            {
+               userProperty.setValue(instance, resolvePrincipalEntity(recipient));
+            }
+                       
+            if (discriminatorProperty.isSet())
+            {
+               PermissionDiscriminator discriminator = discriminatorProperty.getAnnotation();
+               discriminatorProperty.setValue(instance, recipientIsRole ? discriminator.roleValue() :
+                  discriminator.userValue());
+            }
+            
+            lookupEntityManager().persist(instance);
+            return true;
+         }
+                        
+         Object instance = permissions.get(0);
+         
+         ActionSet actionSet = metadata.createActionSet(target.getClass(),
+               actionProperty.getValue(instance).toString());
+         
+         for (String action : actions)
+         {
+            if (set)
+            {
+               actionSet.add(action);
+            }
+            else
+            {
+               actionSet.remove(action);
+            }
+         }
+         
+         if (permissions.size() > 1)
+         {
+            // Same as with roles, consolidate the records if there is more than one
+            for (Object p : permissions)
+            {
+               actionSet.addMembers(actionProperty.getValue(p).toString());
+               if (!p.equals(instance))
+               {
+                  lookupEntityManager().remove(p);
+               }
+            }
+         }
+            
+         if (!actionSet.isEmpty())
+         {
+            actionProperty.setValue(instance, actionSet.toString());
+            lookupEntityManager().merge(instance);
+         }
+         else
+         {
+            // No actions remaining in set, so just remove the record
+            lookupEntityManager().remove(instance);
+         }
+         
+         return true;
+      }
+      catch (Exception ex)
+      {
+         throw new RuntimeException("Could not grant permission", ex);
+      }
+   }
+   
+   public boolean grantPermissions(List<Permission> permissions)
+   {
+      // Target/Recipient/Action map
+      Map<Object,Map<Principal,List<Permission>>> groupedPermissions = groupPermissions(permissions);
+      
+      for (Object target : groupedPermissions.keySet())
+      {
+         Map<Principal,List<Permission>> recipientPermissions = groupedPermissions.get(target);
+                  
+         for (Principal recipient : recipientPermissions.keySet())
+         {
+            List<Permission> ps = recipientPermissions.get(recipient);
+            String[] actions = new String[ps.size()];
+            for (int i = 0; i < ps.size(); i++) actions[i] = ps.get(i).getAction();
+            updatePermissionActions(target, recipient, actions, true);
+         }
+      }
+      
+      return true;
+   }
+   
+   public boolean revokePermissions(List<Permission> permissions)
+   {
+      // Target/Recipient/Action map
+      Map<Object,Map<Principal,List<Permission>>> groupedPermissions = groupPermissions(permissions);
+      
+      for (Object target : groupedPermissions.keySet())
+      {
+         Map<Principal,List<Permission>> recipientPermissions = groupedPermissions.get(target);
+                  
+         for (Principal recipient : recipientPermissions.keySet())
+         {
+            List<Permission> ps = recipientPermissions.get(recipient);
+            String[] actions = new String[ps.size()];
+            for (int i = 0; i < ps.size(); i++) actions[i] = ps.get(i).getAction();
+            updatePermissionActions(target, recipient, actions, false);
+         }
+      }
+      
+      return true;
+   }
+   
+   /**
+    * Groups a list of arbitrary permissions into a more easily-consumed structure
+    * 
+    * @param permissions The list of permissions to group
+    * @return
+    */
+   private Map<Object,Map<Principal,List<Permission>>> groupPermissions(List<Permission> permissions)
+   {
+      // Target/Recipient/Action map
+      Map<Object,Map<Principal,List<Permission>>> groupedPermissions = new HashMap<Object,Map<Principal,List<Permission>>>();
+      
+      for (Permission permission : permissions)
+      {
+         if (!groupedPermissions.containsKey(permission.getTarget()))
+         {
+            groupedPermissions.put(permission.getTarget(), new HashMap<Principal,List<Permission>>());
+         }
+         
+         Map<Principal,List<Permission>> recipientPermissions = groupedPermissions.get(permission.getTarget());
+         if (!recipientPermissions.containsKey(permission.getRecipient()))
+         {
+            List<Permission> perms = new ArrayList<Permission>();
+            perms.add(permission);
+            recipientPermissions.put(permission.getRecipient(), perms);
+         }
+         else
+         {
+            recipientPermissions.get(permission.getRecipient()).add(permission);
+         }
+      }
+
+      return groupedPermissions;
+   }
+   
+   private String getDiscriminatorValue(boolean isRole)
+   {
+      PermissionDiscriminator discriminator = discriminatorProperty.getAnnotation();
+      return isRole ? discriminator.roleValue() : discriminator.userValue();
+   }
+
+   /**
+    * If the user or role properties in the entity class refer to other entities, then this method
+    * uses the JpaIdentityStore (if available) to lookup that user or role entity.  Otherwise it
+    * simply returns the name of the recipient.
+    * 
+    * @param recipient
+    * @return The entity or name representing the permission recipient
+    */
+   protected Object resolvePrincipalEntity(Principal recipient)
+   {
+      boolean recipientIsRole = recipient instanceof Role;
+            
+      if (identityManager.getIdentityStore() != null && 
+            identityManager.getIdentityStore() instanceof JpaIdentityStore)
+      {
+         // TODO review this code
+         
+         if (recipientIsRole && roleProperty.isSet() //&&
+               //roleProperty.getPropertyType().equals(config.getRoleEntityClass()))
+               )
+         {
+            return ((JpaIdentityStore) identityManager.getIdentityStore()).lookupRole(recipient.getName());
+         }
+         //else if (userProperty.getPropertyType().equals(config.getUserEntityClass()))
+         //{
+            //return ((JpaIdentityStore) identityStore).lookupUser(recipient.getName());
+         //}
+      }
+      
+      return recipient.getName();
+   }
+   
+   protected Principal resolvePrincipal(Object principal, boolean isUser)
+   {
+      identityManager.getRoleIdentityStore();
+         
+      // TODO review this
+      
+      /*
+      if (principal instanceof String)
+      {
+         return isUser ? new SimplePrincipal((String) principal) : new Role((String) principal,
+               identityStore == null ? false : identityStore.isRoleConditional((String) principal));
+      }
+      
+      if (identityStore != null)
+      {
+         if (isUser && config.getUserEntityClass().isAssignableFrom(principal.getClass()))
+         {
+            return new SimplePrincipal(identityStore.getUserName(principal));
+         }
+         
+         if (!isUser && config.getRoleEntityClass().isAssignableFrom(principal.getClass()))
+         {
+            String name = identityStore.getRoleName(principal);
+            return new Role(name, identityStore.isRoleConditional(name));
+         }
+      }*/
+      
+      throw new IllegalArgumentException("Cannot resolve principal name for principal " + principal);
+   }
+
+   /**
+    * Returns a list of all user and role permissions for the specified action for all specified target objects
+    */
+   public List<Permission> listPermissions(Set<Object> targets, String action)
+   {
+      // TODO limit the number of targets passed at a single time to 25
+      return listPermissions(null, targets, action);
+   }
+   
+   /**
+    * Returns a list of all user and role permissions for a specific permission target and action.
+    */
+   public List<Permission> listPermissions(Object target, String action)
+   {
+      return listPermissions(target, null, action);
+   }
+   
+   protected List<Permission> listPermissions(Object target, Set<Object> targets, String action)
+   {
+      if (target != null && targets != null)
+      {
+         throw new IllegalArgumentException("Cannot specify both target and targets");
+      }
+      
+      List<Permission> permissions = new ArrayList<Permission>();
+      
+      if (targets != null && targets.isEmpty()) return permissions;
+      
+      // First query for user permissions
+      Query permissionQuery = targets != null ?
+            createPermissionQuery(null, targets, null, Discrimination.either) :
+            createPermissionQuery(target, null, null, Discrimination.either);
+            
+      List<?> userPermissions = permissionQuery.getResultList();
+      
+      Map<String,Principal> principalCache = new HashMap<String,Principal>();
+      
+      boolean useDiscriminator = rolePermissionClass == null && discriminatorProperty.isSet();
+      
+      Map<String,Object> identifierCache = null;
+      
+      if (targets != null)
+      {
+         identifierCache = new HashMap<String,Object>();
+         
+         for (Object t : targets)
+         {
+            identifierCache.put(identifierPolicy.getIdentifier(t), t);
+         }
+      }
+      
+      for (Object permission : userPermissions)
+      {
+         ActionSet actionSet = null;
+         
+         if (targets != null)
+         {
+            target = identifierCache.get(targetProperty.getValue(permission));
+            if (target != null)
+            {
+               actionSet = metadata.createActionSet(target.getClass(),
+                  actionProperty.getValue(permission).toString());
+            }
+         }
+         else
+         {
+            actionSet = metadata.createActionSet(target.getClass(),
+                  actionProperty.getValue(permission).toString());
+         }
+         
+         if (target != null && (action == null || (actionSet != null && actionSet.contains(action))))
+         {
+            boolean isUser = true;
+            
+            if (useDiscriminator &&
+               discriminatorProperty.getAnnotation().roleValue().equals(
+                     discriminatorProperty.getValue(permission)))
+            {
+               isUser = false;
+            }
+
+            Principal principal = lookupPrincipal(principalCache, permission, isUser);
+            
+            if (action != null)
+            {
+               permissions.add(new Permission(target, action, principal));
+            }
+            else
+            {
+               for (String a : actionSet.members())
+               {
+                  permissions.add(new Permission(target, a, principal));
+               }
+            }
+         }
+      }
+      
+      // If we have a separate class for role permissions, then query them now
+      if (rolePermissionClass != null)
+      {
+         permissionQuery = targets != null ?
+               createPermissionQuery(null, targets, null, Discrimination.role) :
+               createPermissionQuery(target, null, null, Discrimination.role);
+         List<?> rolePermissions = permissionQuery.getResultList();
+         
+         for (Object permission : rolePermissions)
+         {
+            ActionSet actionSet = null;
+            
+            if (targets != null)
+            {
+               target = identifierCache.get(roleTargetProperty.getValue(permission));
+               if (target != null)
+               {
+                  actionSet = metadata.createActionSet(target.getClass(),
+                     roleActionProperty.getValue(permission).toString());
+               }
+            }
+            else
+            {
+               actionSet = metadata.createActionSet(target.getClass(),
+                     roleActionProperty.getValue(permission).toString());
+            }
+                       
+            if (target != null && (action == null || (actionSet != null && actionSet.contains(action))))
+            {
+               Principal principal = lookupPrincipal(principalCache, permission, false);
+               
+               if (action != null)
+               {
+                  permissions.add(new Permission(target, action, principal));
+               }
+               else
+               {
+                  for (String a : actionSet.members())
+                  {
+                     permissions.add(new Permission(target, a, principal));
+                  }
+               }
+            }
+         }
+      }
+      
+      return permissions;
+   }
+   
+   private Principal lookupPrincipal(Map<String,Principal> cache, Object permission, boolean isUser)
+   {
+      Principal principal = resolvePrincipal(isUser ? userProperty.getValue(permission) :
+         roleProperty.getValue(permission), isUser);
+      
+      String key = (isUser ? "u:" : "r:") + principal.getName();
+      
+      if (!cache.containsKey(key))
+      {
+         cache.put(key, principal);
+      }
+      else
+      {
+         principal = cache.get(key);
+      }
+      
+      return principal;
+   }
+
+   public List<Permission> listPermissions(Object target)
+   {
+      return listPermissions(target, null);
+   }
+   
+   public List<String> listAvailableActions(Object target)
+   {
+      return metadata.listAllowableActions(target.getClass());
+   }
+
+   private EntityManager lookupEntityManager()
+   {
+      return entityManagerInstance.get();
+   }
+   
+   public Class<?> getUserPermissionClass()
+   {
+      return userPermissionClass;
+   }
+   
+   public void setUserPermissionClass(Class<?> userPermissionClass)
+   {
+      this.userPermissionClass = userPermissionClass;
+   }
+   
+   public Class<?> getRolePermissionClass()
+   {
+      return rolePermissionClass;
+   }
+   
+   public void setRolePermissionClass(Class<?> rolePermissionClass)
+   {
+      this.rolePermissionClass = rolePermissionClass;
+   }
+   
+   public void clearPermissions(Object target)
+   {
+      EntityManager em = lookupEntityManager();
+      String identifier = identifierPolicy.getIdentifier(target);
+      
+      em.createQuery(
+            "delete from " + userPermissionClass.getName() + " p where p." +
+            targetProperty.getName() + " = :target")
+            .setParameter("target", identifier)
+            .executeUpdate();
+      
+      if (rolePermissionClass != null)
+      {
+         em.createQuery(
+               "delete from " + rolePermissionClass.getName() + " p where p." +
+               roleTargetProperty.getName() + " = :target")
+               .setParameter("target", identifier)
+               .executeUpdate();
+      }
+   }
+}

Deleted: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/permission/RuleBasedPermissionResolver.java
===================================================================
--- modules/security/trunk/core/src/main/java/org/jboss/seam/security/permission/RuleBasedPermissionResolver.java	2010-03-24 09:14:40 UTC (rev 12256)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/permission/RuleBasedPermissionResolver.java	2010-04-13 10:22:26 UTC (rev 12451)
@@ -1,294 +0,0 @@
-package org.jboss.seam.security.permission;
-
-import java.io.Serializable;
-import java.security.Principal;
-import java.security.acl.Group;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-import javax.enterprise.context.SessionScoped;
-import javax.inject.Inject;
-import javax.enterprise.inject.spi.BeanManager;
-import javax.enterprise.event.Observes;
-
-import org.drools.FactHandle;
-import org.drools.RuleBase;
-import org.drools.StatefulSession;
-import org.drools.ClassObjectFilter;
-import org.jboss.seam.drools.SeamGlobalResolver;
-import org.jboss.seam.security.Identity;
-import org.jboss.seam.security.Role;
-import org.jboss.seam.security.events.LoggedOutEvent;
-import org.jboss.seam.security.events.PostAuthenticateEvent;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * A permission resolver that uses a Drools rule base to perform permission checks
- * 
- * @author Shane Bryzak
- */
- at SessionScoped
-public class RuleBasedPermissionResolver implements PermissionResolver, Serializable
-{
-   private static final long serialVersionUID = -7572627522601793024L;
-
-   private Logger log = LoggerFactory.getLogger(RuleBasedPermissionResolver.class);
-   
-   private StatefulSession securityContext;
-   
-   private RuleBase securityRules;
-   
-   @Inject BeanManager manager;
-   @Inject Identity identity;
-   
-   @Inject
-   public boolean create()
-   {
-      initSecurityContext();
-      return getSecurityContext() != null;
-   }
-   
-   protected void initSecurityContext()
-   {
-      if (getSecurityRules() != null)
-      {
-         setSecurityContext(getSecurityRules().newStatefulSession(false));
-         getSecurityContext().setGlobalResolver(new SeamGlobalResolver(getSecurityContext().getGlobalResolver()));
-      }
-   }
-   
-   /**
-    * Performs a permission check for the specified name and action
-    * 
-    * @param target Object The target of the permission check
-    * @param action String The action to be performed on the target
-    * @return boolean True if the user has the specified permission
-    */
-   public boolean hasPermission(Object target, String action)
-   {
-      StatefulSession securityContext = getSecurityContext();
-      
-      if (securityContext == null) return false;
-      
-      List<FactHandle> handles = new ArrayList<FactHandle>();
-
-      PermissionCheck check;
-      
-      synchronized( securityContext )
-      {
-         if (!(target instanceof String) && !(target instanceof Class))
-         {
-            handles.add( securityContext.insert(target) );
-         }
-         else if (target instanceof Class)
-         {
-            // TODO fix
-            String componentName = null; // manager. Seam.getComponentName((Class) target);
-            target = componentName != null ? componentName : ((Class) target).getName();
-         }
-         
-         check = new PermissionCheck(target, action);
-         
-         try
-         {
-            synchronizeContext();
-            
-            handles.add( securityContext.insert(check) );
-   
-            securityContext.fireAllRules();
-         }
-         finally
-         {
-            for (FactHandle handle : handles)
-            {
-               securityContext.retract(handle);
-            }
-         }
-      }
-      
-      return check.isGranted();
-   }
-   
-   public void filterSetByAction(Set<Object> targets, String action)
-   {
-      Iterator iter = targets.iterator();
-      while (iter.hasNext())
-      {
-         Object target = iter.next();
-         if (hasPermission(target, action)) iter.remove();
-      }
-   }
-   
-   public boolean checkConditionalRole(String roleName, Object target, String action)
-   {
-      StatefulSession securityContext = getSecurityContext();
-      if (securityContext == null) return false;
-      
-      RoleCheck roleCheck = new RoleCheck(roleName);
-      
-      List<FactHandle> handles = new ArrayList<FactHandle>();
-      PermissionCheck check = new PermissionCheck(target, action);
-      
-      synchronized( securityContext )
-      {
-         if (!(target instanceof String) && !(target instanceof Class))
-         {
-            handles.add( securityContext.insert(target) );
-         }
-         else if (target instanceof Class)
-         {
-            // TODO fix
-            String componentName = null; //Seam.getComponentName((Class) target);
-            target = componentName != null ? componentName : ((Class) target).getName();
-         }
-         
-         try
-         {
-            handles.add( securityContext.insert(check));
-            
-            // Check if there are any additional requirements
-            securityContext.fireAllRules();
-            if (check.hasRequirements())
-            {
-               for (String requirement : check.getRequirements())
-               {
-                  // TODO fix
-                  Object value = null; // Contexts.lookupInStatefulContexts(requirement);
-                  if (value != null)
-                  {
-                     handles.add (securityContext.insert(value));
-                  }
-               }
-            }
-            
-            synchronizeContext();
-
-            handles.add( securityContext.insert(roleCheck));
-            handles.add( securityContext.insert(check));
-            
-            securityContext.fireAllRules();
-         }
-         finally
-         {
-            for (FactHandle handle : handles)
-            {
-               securityContext.retract(handle);
-            }
-         }
-      }
-      
-      return roleCheck.isGranted();
-   }
-   
-   @SuppressWarnings("unchecked")
-   public void unAuthenticate(@Observes LoggedOutEvent event)
-   {
-      if (getSecurityContext() != null)
-      {
-         getSecurityContext().dispose();
-         setSecurityContext(null);
-      }
-      initSecurityContext();
-   }
-   
-   /**
-    *  Synchronises the state of the security context with that of the subject
-    */
-   private void synchronizeContext()
-   {
-      if (getSecurityContext() != null)
-      {
-         getSecurityContext().insert(identity.getPrincipal());
-         
-         for ( Group sg : identity.getSubject().getPrincipals(Group.class) )
-         {
-            if ( Identity.ROLES_GROUP.equals( sg.getName() ) )
-            {
-               Enumeration e = sg.members();
-               while (e.hasMoreElements())
-               {
-                  Principal role = (Principal) e.nextElement();
-   
-                  boolean found = false;
-                  Iterator<Role> iter = (Iterator<Role>) getSecurityContext()
-                     .iterateObjects(new ClassObjectFilter(Role.class));
-                  while (iter.hasNext())
-                  {
-                     Role r = iter.next();
-                     if (r.getName().equals(role.getName()))
-                     {
-                        found = true;
-                        break;
-                     }
-                  }
-                  
-                  if (!found)
-                  {
-                     getSecurityContext().insert(new Role(role.getName()));
-                  }
-                  
-               }
-            }
-         }
-         
-         Iterator<Role> iter = (Iterator<Role>) getSecurityContext()
-            .iterateObjects(new ClassObjectFilter(Role.class));
-         while (iter.hasNext())
-         {
-            Role r = iter.next();
-            if (!identity.hasRole(r.getName()))
-            {
-               FactHandle fh = getSecurityContext().getFactHandle(r);
-               getSecurityContext().retract(fh);
-            }
-         }
-      }
-   }
-   
-   
-   public StatefulSession getSecurityContext()
-   {
-      return securityContext;
-   }
-   
-   public void setSecurityContext(StatefulSession securityContext)
-   {
-      this.securityContext = securityContext;
-   }
-   
-
-   public RuleBase getSecurityRules()
-   {
-      return securityRules;
-   }
-
-   public void setSecurityRules(RuleBase securityRules)
-   {
-      this.securityRules = securityRules;
-   }
-   
-   /**
-    * Post-authentication event observer
-    */
-   public void setUserAccountInSecurityContext(@Observes PostAuthenticateEvent event)
-   {
-      if (getSecurityContext() != null)
-      {
-         getSecurityContext().insert(identity.getPrincipal());
-
-         // If we were authenticated with the JpaIdentityStore, then insert the authenticated
-         // UserAccount into the security context.
-         
-         // TODO fix
-         /*if (Contexts.isEventContextActive() && Contexts.isSessionContextActive() &&
-               Contexts.getEventContext().isSet(JpaIdentityStore.AUTHENTICATED_USER))
-         {
-            getSecurityContext().insert(Contexts.getEventContext().get(JpaIdentityStore.AUTHENTICATED_USER));
-         }*/
-      }
-   }
-}

Copied: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/permission/RuleBasedPermissionResolver.java (from rev 12377, modules/security/trunk/core/src/main/java/org/jboss/seam/security/permission/RuleBasedPermissionResolver.java)
===================================================================
--- modules/security/trunk/impl/src/main/java/org/jboss/seam/security/permission/RuleBasedPermissionResolver.java	                        (rev 0)
+++ modules/security/trunk/impl/src/main/java/org/jboss/seam/security/permission/RuleBasedPermissionResolver.java	2010-04-13 10:22:26 UTC (rev 12451)
@@ -0,0 +1,294 @@
+package org.jboss.seam.security.permission;
+
+import java.io.Serializable;
+import java.security.Principal;
+import java.security.acl.Group;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import javax.enterprise.context.SessionScoped;
+import javax.inject.Inject;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.event.Observes;
+
+import org.drools.KnowledgeBase;
+import org.drools.RuleBase;
+import org.drools.StatefulSession;
+import org.drools.ClassObjectFilter;
+import org.drools.runtime.StatefulKnowledgeSession;
+import org.drools.runtime.rule.FactHandle;
+//import org.jboss.seam.drools.SeamGlobalResolver;
+import org.jboss.seam.security.Identity;
+import org.jboss.seam.security.Role;
+import org.jboss.seam.security.events.LoggedOutEvent;
+import org.jboss.seam.security.events.PostAuthenticateEvent;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A permission resolver that uses a Drools rule base to perform permission checks
+ * 
+ * @author Shane Bryzak
+ */
+ at SessionScoped
+public class RuleBasedPermissionResolver implements PermissionResolver, Serializable
+{
+   private static final long serialVersionUID = -7572627522601793024L;
+
+   private Logger log = LoggerFactory.getLogger(RuleBasedPermissionResolver.class);
+   
+   private StatefulKnowledgeSession securityContext;
+   
+   private KnowledgeBase securityRules;
+   
+   @Inject BeanManager manager;
+   @Inject Identity identity;
+   
+   @Inject
+   public boolean create()
+   {
+      initSecurityContext();
+      return getSecurityContext() != null;
+   }
+   
+   protected void initSecurityContext()
+   {
+      if (getSecurityRules() != null)
+      {
+         setSecurityContext(getSecurityRules().newStatefulKnowledgeSession());
+         //getSecurityContext().setGlobalResolver(new SeamGlobalResolver(getSecurityContext().getGlobalResolver()));
+      }
+   }
+   
+   /**
+    * Performs a permission check for the specified name and action
+    * 
+    * @param target Object The target of the permission check
+    * @param action String The action to be performed on the target
+    * @return boolean True if the user has the specified permission
+    */
+   public boolean hasPermission(Object target, String action)
+   {
+      StatefulKnowledgeSession securityContext = getSecurityContext();
+      
+      if (securityContext == null) return false;
+      
+      List<FactHandle> handles = new ArrayList<FactHandle>();
+
+      PermissionCheck check;
+      
+      synchronized( securityContext )
+      {
+         if (!(target instanceof String) && !(target instanceof Class))
+         {
+            handles.add( securityContext.insert(target) );
+         }
+         else if (target instanceof Class)
+         {
+            // TODO fix
+            String componentName = null; // manager. Seam.getComponentName((Class) target);
+            target = componentName != null ? componentName : ((Class) target).getName();
+         }
+         
+         check = new PermissionCheck(target, action);
+         
+         try
+         {
+            synchronizeContext();
+            
+            handles.add( securityContext.insert(check) );
+   
+            securityContext.fireAllRules();
+         }
+         finally
+         {
+            for (FactHandle handle : handles)
+            {
+               securityContext.retract(handle);
+            }
+         }
+      }
+      
+      return check.isGranted();
+   }
+   
+   public void filterSetByAction(Set<Object> targets, String action)
+   {
+      Iterator iter = targets.iterator();
+      while (iter.hasNext())
+      {
+         Object target = iter.next();
+         if (hasPermission(target, action)) iter.remove();
+      }
+   }
+   
+   public boolean checkConditionalRole(String roleName, Object target, String action)
+   {
+      StatefulKnowledgeSession securityContext = getSecurityContext();
+      if (securityContext == null) return false;
+      
+      RoleCheck roleCheck = new RoleCheck(roleName);
+      
+      List<FactHandle> handles = new ArrayList<FactHandle>();
+      PermissionCheck check = new PermissionCheck(target, action);
+      
+      synchronized( securityContext )
+      {
+         if (!(target instanceof String) && !(target instanceof Class))
+         {
+            handles.add( securityContext.insert(target) );
+         }
+         else if (target instanceof Class)
+         {
+            // TODO fix
+            String componentName = null; //Seam.getComponentName((Class) target);
+            target = componentName != null ? componentName : ((Class) target).getName();
+         }
+         
+         try
+         {
+            handles.add( securityContext.insert(check));
+            
+            // Check if there are any additional requirements
+            securityContext.fireAllRules();
+            if (check.hasRequirements())
+            {
+               for (String requirement : check.getRequirements())
+               {
+                  // TODO fix
+                  Object value = null; // Contexts.lookupInStatefulContexts(requirement);
+                  if (value != null)
+                  {
+                     handles.add (securityContext.insert(value));
+                  }
+               }
+            }
+            
+            synchronizeContext();
+
+            handles.add( securityContext.insert(roleCheck));
+            handles.add( securityContext.insert(check));
+            
+            securityContext.fireAllRules();
+         }
+         finally
+         {
+            for (FactHandle handle : handles)
+            {
+               securityContext.retract(handle);
+            }
+         }
+      }
+      
+      return roleCheck.isGranted();
+   }
+   
+   @SuppressWarnings("unchecked")
+   public void unAuthenticate(@Observes LoggedOutEvent event)
+   {
+      if (getSecurityContext() != null)
+      {
+         getSecurityContext().dispose();
+         setSecurityContext(null);
+      }
+      initSecurityContext();
+   }
+   
+   /**
+    *  Synchronises the state of the security context with that of the subject
+    */
+   private void synchronizeContext()
+   {
+      if (getSecurityContext() != null)
+      {
+         getSecurityContext().insert(identity.getPrincipal());
+         
+         for ( Group sg : identity.getSubject().getPrincipals(Group.class) )
+         {
+            if ( Identity.ROLES_GROUP.equals( sg.getName() ) )
+            {
+               Enumeration e = sg.members();
+               while (e.hasMoreElements())
+               {
+                  Principal role = (Principal) e.nextElement();
+   
+                  boolean found = false;
+                  Iterator<?> iter = getSecurityContext().getObjects(new ClassObjectFilter(Role.class)).iterator();
+                  while (iter.hasNext())
+                  {
+                     Role r = (Role) iter.next();
+                     if (r.getName().equals(role.getName()))
+                     {
+                        found = true;
+                        break;
+                     }
+                  }
+                  
+                  if (!found)
+                  {
+                     getSecurityContext().insert(new Role(role.getName()));
+                  }
+                  
+               }
+            }
+         }
+         
+         Iterator<?> iter = getSecurityContext().getObjects(new ClassObjectFilter(Role.class)).iterator();
+         while (iter.hasNext())
+         {
+            Role r = (Role) iter.next();
+            if (!identity.hasRole(r.getName()))
+            {
+               FactHandle fh = getSecurityContext().getFactHandle(r);
+               getSecurityContext().retract(fh);
+            }
+         }
+      }
+   }
+   
+   
+   public StatefulKnowledgeSession getSecurityContext()
+   {
+      return securityContext;
+   }
+   
+   public void setSecurityContext(StatefulKnowledgeSession securityContext)
+   {
+      this.securityContext = securityContext;
+   }
+   
+
+   public KnowledgeBase getSecurityRules()
+   {
+      return securityRules;
+   }
+
+   public void setSecurityRules(KnowledgeBase securityRules)
+   {
+      this.securityRules = securityRules;
+   }
+   
+   /**
+    * Post-authentication event observer
+    */
+   public void setUserAccountInSecurityContext(@Observes PostAuthenticateEvent event)
+   {
+      if (getSecurityContext() != null)
+      {
+         getSecurityContext().insert(identity.getPrincipal());
+
+         // If we were authenticated with the JpaIdentityStore, then insert the authenticated
+         // UserAccount into the security context.
+         
+         // TODO fix
+         /*if (Contexts.isEventContextActive() && Contexts.isSessionContextActive() &&
+               Contexts.getEventContext().isSet(JpaIdentityStore.AUTHENTICATED_USER))
+         {
+            getSecurityContext().insert(Contexts.getEventContext().get(JpaIdentityStore.AUTHENTICATED_USER));
+         }*/
+      }
+   }
+}

Copied: modules/security/trunk/impl/src/main/java/org/jboss/seam/security/util (from rev 12256, modules/security/trunk/core/src/main/java/org/jboss/seam/security/util)



More information about the seam-commits mailing list