[seam-commits] Seam SVN: r10476 - in trunk: modules/trunk/security/src/main/java/org/jboss/seam/security/crypto and 6 other directories.

seam-commits at lists.jboss.org seam-commits at lists.jboss.org
Sun Apr 19 05:44:30 EDT 2009


Author: shane.bryzak at jboss.com
Date: 2009-04-19 05:44:29 -0400 (Sun, 19 Apr 2009)
New Revision: 10476

Added:
   trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/AuthorizationException.java
   trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/Configuration.java
   trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/Credentials.java
   trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/EntityAction.java
   trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/EntityPermissionChecker.java
   trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/EntitySecurityListener.java
   trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/FacesSecurityEvents.java
   trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/HibernateSecurityInterceptor.java
   trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/Identity.java
   trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/JpaTokenStore.java
   trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/NotLoggedInException.java
   trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/RememberMe.java
   trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/Role.java
   trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/RunAsOperation.java
   trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/SecurityFunctions.java
   trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/SecurityInterceptor.java
   trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/SimpleGroup.java
   trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/SimplePrincipal.java
   trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/TokenStore.java
   trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/crypto/
   trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/digest/
   trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/jaas/
   trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/management/
   trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/openid/
   trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/package-info.java
   trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/permission/
Removed:
   trunk/src/main/org/jboss/seam/security/AuthorizationException.java
   trunk/src/main/org/jboss/seam/security/Configuration.java
   trunk/src/main/org/jboss/seam/security/Credentials.java
   trunk/src/main/org/jboss/seam/security/EntityAction.java
   trunk/src/main/org/jboss/seam/security/EntityPermissionChecker.java
   trunk/src/main/org/jboss/seam/security/EntitySecurityListener.java
   trunk/src/main/org/jboss/seam/security/FacesSecurityEvents.java
   trunk/src/main/org/jboss/seam/security/HibernateSecurityInterceptor.java
   trunk/src/main/org/jboss/seam/security/Identity.java
   trunk/src/main/org/jboss/seam/security/JpaTokenStore.java
   trunk/src/main/org/jboss/seam/security/NotLoggedInException.java
   trunk/src/main/org/jboss/seam/security/RememberMe.java
   trunk/src/main/org/jboss/seam/security/Role.java
   trunk/src/main/org/jboss/seam/security/RunAsOperation.java
   trunk/src/main/org/jboss/seam/security/SecurityFunctions.java
   trunk/src/main/org/jboss/seam/security/SecurityInterceptor.java
   trunk/src/main/org/jboss/seam/security/SimpleGroup.java
   trunk/src/main/org/jboss/seam/security/SimplePrincipal.java
   trunk/src/main/org/jboss/seam/security/TokenStore.java
   trunk/src/main/org/jboss/seam/security/crypto/
   trunk/src/main/org/jboss/seam/security/digest/
   trunk/src/main/org/jboss/seam/security/jaas/
   trunk/src/main/org/jboss/seam/security/management/
   trunk/src/main/org/jboss/seam/security/openid/
   trunk/src/main/org/jboss/seam/security/package-info.java
   trunk/src/main/org/jboss/seam/security/permission/
Log:
move security module

Copied: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/AuthorizationException.java (from rev 10443, trunk/src/main/org/jboss/seam/security/AuthorizationException.java)
===================================================================
--- trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/AuthorizationException.java	                        (rev 0)
+++ trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/AuthorizationException.java	2009-04-19 09:44:29 UTC (rev 10476)
@@ -0,0 +1,17 @@
+package org.jboss.seam.security;
+
+import javax.ejb.ApplicationException;
+
+/**
+ * Thrown when an authenticated user has insufficient rights to carry out an action.
+ * 
+ * @author Shane Bryzak
+ */
+ at ApplicationException(rollback=true)
+public class AuthorizationException extends RuntimeException
+{ 
+   public AuthorizationException(String message)
+   {
+      super(message);
+   }
+}


Property changes on: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/AuthorizationException.java
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:mergeinfo
   + 
Name: svn:eol-style
   + native

Copied: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/Configuration.java (from rev 10443, trunk/src/main/org/jboss/seam/security/Configuration.java)
===================================================================
--- trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/Configuration.java	                        (rev 0)
+++ trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/Configuration.java	2009-04-19 09:44:29 UTC (rev 10476)
@@ -0,0 +1,75 @@
+package org.jboss.seam.security;
+
+import static org.jboss.seam.ScopeType.APPLICATION;
+import static org.jboss.seam.annotations.Install.BUILT_IN;
+
+import java.util.HashMap;
+
+import javax.security.auth.login.AppConfigurationEntry;
+import javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag;
+
+import org.jboss.seam.Component;
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.Factory;
+import org.jboss.seam.annotations.Install;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.intercept.BypassInterceptors;
+import org.jboss.seam.contexts.Contexts;
+import org.jboss.seam.security.jaas.SeamLoginModule;
+
+/**
+ * Factory for the JAAS Configuration used by Seam Security.
+ * 
+ * @author Shane Bryzak
+ *
+ */
+ at Name("org.jboss.seam.security.configurationFactory")
+ at BypassInterceptors
+ at Scope(ScopeType.STATELESS)
+ at Install(precedence = BUILT_IN)
+public class Configuration
+{
+   static final String DEFAULT_JAAS_CONFIG_NAME = "default";   
+
+   protected javax.security.auth.login.Configuration createConfiguration()
+   {
+      return new javax.security.auth.login.Configuration()
+      {
+         private AppConfigurationEntry[] aces = { createAppConfigurationEntry() };
+         
+         @Override
+         public AppConfigurationEntry[] getAppConfigurationEntry(String name)
+         {
+            return DEFAULT_JAAS_CONFIG_NAME.equals(name) ? aces : null;
+         }
+         
+         @Override
+         public void refresh() {}
+      };
+   }
+
+   protected AppConfigurationEntry createAppConfigurationEntry()
+   {
+      return new AppConfigurationEntry( 
+            SeamLoginModule.class.getName(), 
+            LoginModuleControlFlag.REQUIRED, 
+            new HashMap<String,String>() 
+         );
+   }
+   
+   @Factory(value="org.jboss.seam.security.configuration", autoCreate=true, scope=APPLICATION)
+   public javax.security.auth.login.Configuration getConfiguration()
+   {
+      return createConfiguration();
+   }
+
+   public static javax.security.auth.login.Configuration instance()
+   {
+      if ( !Contexts.isApplicationContextActive() )
+      {
+         throw new IllegalStateException("No active application scope");
+      }
+      return (javax.security.auth.login.Configuration) Component.getInstance("org.jboss.seam.security.configuration");
+   }
+}


Property changes on: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/Configuration.java
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:mergeinfo
   + 
Name: svn:eol-style
   + native

Copied: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/Credentials.java (from rev 10443, trunk/src/main/org/jboss/seam/security/Credentials.java)
===================================================================
--- trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/Credentials.java	                        (rev 0)
+++ trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/Credentials.java	2009-04-19 09:44:29 UTC (rev 10476)
@@ -0,0 +1,139 @@
+package org.jboss.seam.security;
+
+import static org.jboss.seam.ScopeType.SESSION;
+import static org.jboss.seam.annotations.Install.BUILT_IN;
+
+import java.io.IOException;
+import java.io.Serializable;
+
+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.callback.UnsupportedCallbackException;
+
+import org.jboss.seam.annotations.Install;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.intercept.BypassInterceptors;
+import org.jboss.seam.core.Events;
+import org.jboss.seam.log.LogProvider;
+import org.jboss.seam.log.Logging;
+
+ at Name("org.jboss.seam.security.credentials")
+ at Scope(SESSION)
+ at Install(precedence = BUILT_IN)
+ at BypassInterceptors
+public class Credentials implements Serializable
+{
+   public static final String EVENT_INIT_CREDENTIALS = "org.jboss.seam.security.initCredentials";
+   public static final String EVENT_CREDENTIALS_UPDATED = "org.jboss.seam.security.credentialsUpdated";
+   
+   private static final LogProvider log = Logging.getLogProvider(Credentials.class);
+   
+   private String username;
+   private String password;
+   
+   private boolean invalid = false;
+   
+   private boolean initialized;
+   
+   public boolean isInitialized()
+   {
+      return initialized;
+   }
+   
+   public void setInitialized(boolean initialized)
+   {
+      this.initialized = initialized;
+   }
+   
+   public String getUsername()
+   {
+      if (!isInitialized() && Events.exists())
+      {
+         setInitialized(true);
+         Events.instance().raiseEvent(EVENT_INIT_CREDENTIALS, this);
+      }
+      
+      return username;
+   }
+   
+   public void setUsername(String username)
+   {
+      if (this.username != username && (this.username == null || !this.username.equals(username)))
+      {
+         this.username = username;
+         invalid = false;
+         if (Events.exists()) Events.instance().raiseEvent(EVENT_CREDENTIALS_UPDATED);
+      }
+   }
+   
+   public String getPassword()
+   {
+      return password;
+   }
+   
+   public void setPassword(String password)
+   {
+      if (this.password != password && (this.password == null || !this.password.equals(password)))
+      {
+         this.password = password;
+         invalid = false;
+         if (Events.exists()) Events.instance().raiseEvent(EVENT_CREDENTIALS_UPDATED);
+      } 
+   }
+   
+   public boolean isSet()
+   {
+      return getUsername() != null && password != null;      
+   }
+   
+   public boolean isInvalid()
+   {
+      return invalid;
+   }
+   
+   public void invalidate()
+   {
+      invalid = true;
+   }
+   
+   public void clear()
+   {
+      username = null;
+      password = null;
+   }
+   
+   
+   /**
+    * Creates a callback handler that can handle a standard username/password
+    * callback, using the username and password properties.
+    */
+   public CallbackHandler createCallbackHandler()
+   {
+      return new CallbackHandler() 
+      {
+         public void handle(Callback[] callbacks) 
+            throws IOException, UnsupportedCallbackException 
+         {
+            for (int i=0; i < callbacks.length; i++)
+            {
+               if (callbacks[i] instanceof NameCallback)
+               {
+                  ( (NameCallback) callbacks[i] ).setName(getUsername());
+               }
+               else if (callbacks[i] instanceof PasswordCallback)
+               {
+                  ( (PasswordCallback) callbacks[i] ).setPassword( getPassword() != null ? 
+                           getPassword().toCharArray() : null );
+               }
+               else
+               {
+                  log.warn("Unsupported callback " + callbacks[i]);
+               }
+            }
+         }
+      };
+   }   
+}


Property changes on: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/Credentials.java
___________________________________________________________________
Name: svn:mergeinfo
   + 

Copied: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/EntityAction.java (from rev 10443, trunk/src/main/org/jboss/seam/security/EntityAction.java)
===================================================================
--- trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/EntityAction.java	                        (rev 0)
+++ trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/EntityAction.java	2009-04-19 09:44:29 UTC (rev 10476)
@@ -0,0 +1,23 @@
+package org.jboss.seam.security;
+
+/**
+ * Actions that may be performed upon entities
+ * in JPA or Hibernate.
+ * 
+ * @author Shane Bryzak
+ * 
+ */
+public enum EntityAction { 
+   
+   READ, 
+   INSERT, 
+   UPDATE, 
+   DELETE;
+   
+   @Override
+   public String toString()
+   {
+      return super.name().toLowerCase();
+   }
+   
+}
\ No newline at end of file


Property changes on: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/EntityAction.java
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:mergeinfo
   + 
Name: svn:eol-style
   + native

Copied: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/EntityPermissionChecker.java (from rev 10443, trunk/src/main/org/jboss/seam/security/EntityPermissionChecker.java)
===================================================================
--- trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/EntityPermissionChecker.java	                        (rev 0)
+++ trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/EntityPermissionChecker.java	2009-04-19 09:44:29 UTC (rev 10476)
@@ -0,0 +1,124 @@
+package org.jboss.seam.security;
+
+import static org.jboss.seam.ScopeType.APPLICATION;
+import static org.jboss.seam.annotations.Install.BUILT_IN;
+
+import java.lang.reflect.Method;
+
+import javax.persistence.EntityManager;
+
+import org.jboss.seam.Component;
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.Install;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.Startup;
+import org.jboss.seam.annotations.intercept.BypassInterceptors;
+import org.jboss.seam.annotations.security.Restrict;
+import org.jboss.seam.contexts.Contexts;
+import org.jboss.seam.persistence.PersistenceProvider;
+import org.jboss.seam.util.Strings;
+
+/**
+ * Entity permission checks
+ * 
+ * @author Shane Bryzak
+ */
+ at Name("org.jboss.seam.security.entityPermissionChecker")
+ at Scope(APPLICATION)
+ at Install(precedence = BUILT_IN)
+ at BypassInterceptors
+ at Startup
+public class EntityPermissionChecker
+{
+   private String entityManagerName = "entityManager";
+   
+   private EntityManager getEntityManager()
+   {
+      return (EntityManager) Component.getInstance(entityManagerName);
+   }
+   
+   public String getEntityManagerName()
+   {
+      return entityManagerName;
+   }
+   
+   public void setEntityManagerName(String name)
+   {
+      this.entityManagerName = name;
+   } 
+   
+   public static EntityPermissionChecker instance()
+   {
+      if ( !Contexts.isApplicationContextActive() )
+      {
+         throw new IllegalStateException("No active application context");
+      }
+
+      EntityPermissionChecker instance = (EntityPermissionChecker) Component.getInstance(
+            EntityPermissionChecker.class, ScopeType.APPLICATION);
+
+      if (instance == null)
+      {
+         throw new IllegalStateException("No EntityPermissionChecker could be created");
+      }
+
+      return instance;      
+   }
+   
+   public void checkEntityPermission(Object entity, EntityAction action)
+   {      
+      if (!Identity.isSecurityEnabled()) return;
+      
+      if (!Contexts.isSessionContextActive()) return;
+      
+      Identity identity = Identity.instance();
+      
+      identity.tryLogin();
+      
+      PersistenceProvider provider = PersistenceProvider.instance(); 
+      Class beanClass = provider.getBeanClass(entity);
+      
+      if (beanClass != null)
+      {        
+         Method m = null;
+         switch (action)
+         {
+            case READ:
+               m = provider.getPostLoadMethod(entity, getEntityManager());
+               break;
+            case INSERT:
+               m = provider.getPrePersistMethod(entity, getEntityManager());
+               break;
+            case UPDATE:
+               m = provider.getPreUpdateMethod(entity, getEntityManager());
+               break;
+            case DELETE:
+               m = provider.getPreRemoveMethod(entity, getEntityManager());
+         }
+         
+         Restrict restrict = null;
+         
+         if (m != null && m.isAnnotationPresent(Restrict.class))
+         {
+            restrict = m.getAnnotation(Restrict.class);
+         }
+         else if (entity.getClass().isAnnotationPresent(Restrict.class))
+         {
+            restrict = entity.getClass().getAnnotation(Restrict.class);
+         }
+
+         if (restrict != null)
+         {
+            if (Strings.isEmpty(restrict.value()))
+            {
+               identity.checkPermission(entity, action.toString());
+            }
+            else
+            {
+               identity.checkRestriction(restrict.value());
+            }
+         }
+      }
+   }  
+}


Property changes on: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/EntityPermissionChecker.java
___________________________________________________________________
Name: svn:mergeinfo
   + 

Copied: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/EntitySecurityListener.java (from rev 10443, trunk/src/main/org/jboss/seam/security/EntitySecurityListener.java)
===================================================================
--- trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/EntitySecurityListener.java	                        (rev 0)
+++ trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/EntitySecurityListener.java	2009-04-19 09:44:29 UTC (rev 10476)
@@ -0,0 +1,44 @@
+package org.jboss.seam.security;
+
+import static org.jboss.seam.security.EntityAction.DELETE;
+import static org.jboss.seam.security.EntityAction.INSERT;
+import static org.jboss.seam.security.EntityAction.READ;
+import static org.jboss.seam.security.EntityAction.UPDATE;
+
+import javax.persistence.PostLoad;
+import javax.persistence.PrePersist;
+import javax.persistence.PreRemove;
+import javax.persistence.PreUpdate;
+
+
+/**
+ * Facilitates security checks for entity beans.
+ * 
+ * @author Shane Bryzak
+ */
+public class EntitySecurityListener
+{
+   @PostLoad
+   public void postLoad(Object entity)
+   {
+      EntityPermissionChecker.instance().checkEntityPermission(entity, READ);
+   }
+   
+   @PrePersist
+   public void prePersist(Object entity)
+   { 
+      EntityPermissionChecker.instance().checkEntityPermission(entity, INSERT);
+   }
+   
+   @PreUpdate
+   public void preUpdate(Object entity)
+   {
+      EntityPermissionChecker.instance().checkEntityPermission(entity, UPDATE);
+   }
+   
+   @PreRemove
+   public void preRemove(Object entity)
+   {
+      EntityPermissionChecker.instance().checkEntityPermission(entity, DELETE);
+   }
+}


Property changes on: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/EntitySecurityListener.java
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:mergeinfo
   + 
Name: svn:eol-style
   + native

Copied: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/FacesSecurityEvents.java (from rev 10443, trunk/src/main/org/jboss/seam/security/FacesSecurityEvents.java)
===================================================================
--- trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/FacesSecurityEvents.java	                        (rev 0)
+++ trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/FacesSecurityEvents.java	2009-04-19 09:44:29 UTC (rev 10476)
@@ -0,0 +1,106 @@
+package org.jboss.seam.security;
+
+import static org.jboss.seam.ScopeType.APPLICATION;
+import static org.jboss.seam.annotations.Install.BUILT_IN;
+
+import javax.security.auth.login.LoginException;
+
+import org.jboss.seam.annotations.Install;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Observer;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.Startup;
+import org.jboss.seam.annotations.intercept.BypassInterceptors;
+import org.jboss.seam.international.StatusMessages;
+import org.jboss.seam.international.StatusMessage.Severity;
+
+/**
+ * Produces FacesMessages in response of certain security events, and helps to decouple the
+ * Identity component from JSF.
+ * 
+ * @author Shane Bryzak
+ */
+ at Name("org.jboss.seam.security.facesSecurityEvents")
+ at Scope(APPLICATION)
+ at Install(precedence = BUILT_IN, classDependencies = "javax.faces.context.FacesContext")
+ at BypassInterceptors
+ at Startup
+public class FacesSecurityEvents 
+{  
+   @Observer(Identity.EVENT_POST_AUTHENTICATE)
+   public void postAuthenticate(Identity identity)
+   {         
+      //org.jboss.security.saml.SSOManager.processManualLoginNotification(
+            //ServletContexts.instance().getRequest(), identity.getPrincipal().getName());
+   }
+   
+   @Observer(Identity.EVENT_LOGIN_FAILED)
+   public void addLoginFailedMessage(LoginException ex)
+   {
+      StatusMessages.instance().addFromResourceBundleOrDefault(
+               getLoginFailedMessageSeverity(), 
+               getLoginFailedMessageKey(), 
+               getLoginFailedMessage(), 
+               ex);
+   }
+
+   public String getLoginFailedMessage()
+   {
+      return "Login failed";
+   }
+
+   public Severity getLoginFailedMessageSeverity()
+   {
+      return Severity.INFO;
+   }
+
+   public String getLoginFailedMessageKey()
+   {
+      return "org.jboss.seam.loginFailed";
+   }
+
+   @Observer(Identity.EVENT_LOGIN_SUCCESSFUL)
+   public void addLoginSuccessfulMessage()
+   {
+      StatusMessages.instance().addFromResourceBundleOrDefault(
+               getLoginSuccessfulMessageSeverity(), 
+               getLoginSuccessfulMessageKey(), 
+               getLoginSuccessfulMessage(), 
+               Identity.instance().getCredentials().getUsername());
+   }
+   
+   @Observer(Identity.EVENT_NOT_LOGGED_IN)
+   public void addNotLoggedInMessage()
+   {      
+      StatusMessages.instance().addFromResourceBundleOrDefault( 
+            Severity.WARN, 
+            "org.jboss.seam.NotLoggedIn", 
+            "Please log in first" 
+         );      
+   }
+
+   public Severity getLoginSuccessfulMessageSeverity()
+   {
+      return Severity.INFO;
+   }
+
+   public String getLoginSuccessfulMessage()
+   {
+      return "Welcome, #0";
+   }
+
+   public String getLoginSuccessfulMessageKey()
+   {
+      return "org.jboss.seam.loginSuccessful";
+   }   
+   
+   @Observer(Identity.EVENT_ALREADY_LOGGED_IN)
+   public void addAlreadyLoggedInMessage()
+   {
+      StatusMessages.instance().addFromResourceBundleOrDefault (
+         Severity.WARN,
+         "org.jboss.seam.AlreadyLoggedIn",
+         "You are already logged in, please log out first if you wish to log in again"
+      );
+   }
+}


Property changes on: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/FacesSecurityEvents.java
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:mergeinfo
   + 
Name: svn:eol-style
   + native

Copied: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/HibernateSecurityInterceptor.java (from rev 10443, trunk/src/main/org/jboss/seam/security/HibernateSecurityInterceptor.java)
===================================================================
--- trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/HibernateSecurityInterceptor.java	                        (rev 0)
+++ trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/HibernateSecurityInterceptor.java	2009-04-19 09:44:29 UTC (rev 10476)
@@ -0,0 +1,100 @@
+package org.jboss.seam.security;
+
+import static org.jboss.seam.security.EntityAction.DELETE;
+import static org.jboss.seam.security.EntityAction.INSERT;
+import static org.jboss.seam.security.EntityAction.READ;
+import static org.jboss.seam.security.EntityAction.UPDATE;
+
+import java.io.Serializable;
+
+import org.hibernate.EmptyInterceptor;
+import org.hibernate.Interceptor;
+import org.hibernate.type.Type;
+import org.jboss.seam.Entity.NotEntityException;
+
+/**
+ * Facilitates security checks for Hibernate entities
+ * 
+ * @author Shane Bryzak
+ *
+ */
+public class HibernateSecurityInterceptor extends EmptyInterceptor
+{
+   private Interceptor wrappedInterceptor;
+   
+   public HibernateSecurityInterceptor(Interceptor wrappedInterceptor)
+   {
+      this.wrappedInterceptor = wrappedInterceptor;
+   }
+   
+   @Override
+   public boolean onLoad(Object entity, Serializable id, Object[] state,
+                      String[] propertyNames, Type[] types)
+   {
+      try
+      {
+         EntityPermissionChecker.instance().checkEntityPermission(entity, READ);
+      }
+      catch (NotEntityException e) 
+      {
+         // Not a JPA entity
+      }
+      
+      return wrappedInterceptor != null ? 
+               wrappedInterceptor.onLoad(entity, id, state, propertyNames, types) : 
+               false;
+   }
+   
+   @Override
+   public void onDelete(Object entity, Serializable id, Object[] state, 
+                        String[] propertyNames, Type[] types)
+   {
+      try
+      {
+         EntityPermissionChecker.instance().checkEntityPermission(entity, DELETE);
+      }
+      catch (NotEntityException e) 
+      {
+         // Not a JPA entity
+      }
+      
+      if (wrappedInterceptor != null)
+         wrappedInterceptor.onDelete(entity, id, state, propertyNames, types);
+   }
+   
+   @Override
+   public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState,
+                   Object[] previousState, String[] propertyNames, Type[] types)
+   {
+      try
+      {
+         EntityPermissionChecker.instance().checkEntityPermission(entity, UPDATE);
+      }
+      catch (NotEntityException e) 
+      {
+         // Not a JPA entity
+      }
+      
+      return wrappedInterceptor != null ? 
+               wrappedInterceptor.onFlushDirty(entity, id, currentState, 
+                        previousState, propertyNames, types) : false;
+   }
+   
+   @Override
+   public boolean onSave(Object entity, Serializable id, Object[] state,
+                      String[] propertyNames, Type[] types)
+   {
+      try
+      {
+         EntityPermissionChecker.instance().checkEntityPermission(entity, INSERT);
+      }
+      catch (NotEntityException e) 
+      {
+         // Not a JPA entity
+      }
+      
+      return wrappedInterceptor != null ? 
+               wrappedInterceptor.onSave(entity, id, state, propertyNames, types) : 
+               false;
+   }       
+}


Property changes on: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/HibernateSecurityInterceptor.java
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:mergeinfo
   + 
Name: svn:eol-style
   + native

Copied: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/Identity.java (from rev 10443, trunk/src/main/org/jboss/seam/security/Identity.java)
===================================================================
--- trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/Identity.java	                        (rev 0)
+++ trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/Identity.java	2009-04-19 09:44:29 UTC (rev 10476)
@@ -0,0 +1,752 @@
+package org.jboss.seam.security;
+
+import static org.jboss.seam.ScopeType.SESSION;
+import static org.jboss.seam.annotations.Install.BUILT_IN;
+
+import java.io.Serializable;
+import java.security.Principal;
+import java.security.acl.Group;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.List;
+
+import javax.security.auth.Subject;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
+
+import org.jboss.seam.Component;
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.Create;
+import org.jboss.seam.annotations.Install;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.Startup;
+import org.jboss.seam.annotations.intercept.BypassInterceptors;
+import org.jboss.seam.contexts.Contexts;
+import org.jboss.seam.core.Events;
+import org.jboss.seam.core.Expressions;
+import org.jboss.seam.core.Expressions.MethodExpression;
+import org.jboss.seam.log.LogProvider;
+import org.jboss.seam.log.Logging;
+import org.jboss.seam.security.permission.PermissionMapper;
+import org.jboss.seam.web.Session;
+
+/**
+ * API for authorization and authentication via Seam security. This base 
+ * implementation supports role-based authorization only. Subclasses may add 
+ * more sophisticated permissioning mechanisms.
+ * 
+ * @author Shane Bryzak
+ */
+ at Name("org.jboss.seam.security.identity")
+ at Scope(SESSION)
+ at Install(precedence = BUILT_IN)
+ at BypassInterceptors
+ at Startup
+public class Identity implements Serializable
+{  
+   private static final long serialVersionUID = 3751659008033189259L;
+   
+   // Event keys
+   public static final String EVENT_LOGIN_SUCCESSFUL = "org.jboss.seam.security.loginSuccessful";
+   public static final String EVENT_LOGIN_FAILED = "org.jboss.seam.security.loginFailed";
+   public static final String EVENT_NOT_LOGGED_IN = "org.jboss.seam.security.notLoggedIn";
+   public static final String EVENT_NOT_AUTHORIZED = "org.jboss.seam.security.notAuthorized";
+   public static final String EVENT_PRE_AUTHENTICATE = "org.jboss.seam.security.preAuthenticate";
+   public static final String EVENT_POST_AUTHENTICATE = "org.jboss.seam.security.postAuthenticate";
+   public static final String EVENT_LOGGED_OUT = "org.jboss.seam.security.loggedOut";
+   public static final String EVENT_ALREADY_LOGGED_IN = "org.jboss.seam.security.alreadyLoggedIn";
+   public static final String EVENT_QUIET_LOGIN = "org.jboss.seam.security.quietLogin";
+   
+   protected static boolean securityEnabled = true;
+   
+   public static final String ROLES_GROUP = "Roles";
+   
+   // Context variables
+   private static final String LOGIN_TRIED = "org.jboss.seam.security.loginTried";
+   private static final String SILENT_LOGIN = "org.jboss.seam.security.silentLogin";
+   
+   private static final LogProvider log = Logging.getLogProvider(Identity.class);
+   
+   private Credentials credentials;
+   
+   private MethodExpression authenticateMethod;
+
+   private Principal principal;   
+   private Subject subject;
+   
+   private RememberMe rememberMe;
+   
+   private transient ThreadLocal<Boolean> systemOp;
+   
+   private String jaasConfigName = null;
+   
+   private List<String> preAuthenticationRoles = new ArrayList<String>();
+   
+   private PermissionMapper permissionMapper;
+   
+   /**
+    * Flag that indicates we are in the process of authenticating
+    */
+   private boolean authenticating = false;
+         
+   @Create
+   public void create()
+   {     
+      subject = new Subject();
+      
+      if (Contexts.isApplicationContextActive())
+      {
+         permissionMapper = (PermissionMapper) Component.getInstance(PermissionMapper.class);                 
+      }    
+      
+      if (Contexts.isSessionContextActive())
+      {
+         rememberMe = (RememberMe) Component.getInstance(RememberMe.class, true);      
+         credentials = (Credentials) Component.getInstance(Credentials.class);         
+      }
+      
+      if (credentials == null)
+      {
+         // Must have credentials for unit tests
+         credentials = new Credentials();
+      }
+   }
+   
+   public static boolean isSecurityEnabled()
+   {
+      return securityEnabled;
+   }
+   
+   public static void setSecurityEnabled(boolean enabled)
+   {
+      securityEnabled = enabled;
+   }
+
+   public static Identity instance()
+   {
+      if ( !Contexts.isSessionContextActive() )
+      {
+         throw new IllegalStateException("No active session context");
+      }
+
+      Identity instance = (Identity) Component.getInstance(Identity.class, ScopeType.SESSION);
+
+      if (instance == null)
+      {
+         throw new IllegalStateException("No Identity could be created");
+      }
+
+      return instance;
+   }
+   
+   /**
+    * 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() &&
+            Contexts.isEventContextActive() &&
+            !Contexts.getEventContext().isSet(LOGIN_TRIED))
+        {
+           Contexts.getEventContext().set(LOGIN_TRIED, true);
+           quietLogin();
+        }     
+        
+        return isLoggedIn();      
+   }
+   
+   @Deprecated
+   public boolean isLoggedIn(boolean attemptLogin)
+   {
+      return attemptLogin ? tryLogin() : isLoggedIn();
+   }
+
+
+    public void acceptExternallyAuthenticatedPrincipal(Principal principal) {
+        getSubject().getPrincipals().add(principal);
+        this.principal = principal;
+    }
+
+   public Principal getPrincipal()
+   {
+      return principal;
+   }
+   
+   public Subject getSubject()
+   {
+      return subject;
+   }
+      
+   /**
+    * Performs an authorization check, based on the specified security expression.
+    * 
+    * @param expr The security expression to evaluate
+    * @throws NotLoggedInException Thrown if the authorization check fails and 
+    * the user is not authenticated
+    * @throws AuthorizationException Thrown if the authorization check fails and
+    * the user is authenticated
+    */
+   public void checkRestriction(String expr)
+   {      
+      if (!securityEnabled) return;
+      
+      if ( !evaluateExpression(expr) )
+      {
+         if ( !isLoggedIn() )
+         {           
+            if (Events.exists()) Events.instance().raiseEvent(EVENT_NOT_LOGGED_IN);
+            log.debug(String.format(
+               "Error evaluating expression [%s] - User not logged in", expr));
+            throw new NotLoggedInException();
+         }
+         else
+         {
+            if (Events.exists()) Events.instance().raiseEvent(EVENT_NOT_AUTHORIZED);
+            throw new AuthorizationException(String.format(
+               "Authorization check failed for expression [%s]", expr));
+         }
+      }
+   }
+
+   /**
+    * 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
+      {            
+         if (isLoggedIn())
+         {
+            // If authentication has already occurred during this request via a silent login,
+            // and login() is explicitly called then we still want to raise the LOGIN_SUCCESSFUL event,
+            // and then return.
+            if (Contexts.isEventContextActive() && Contexts.getEventContext().isSet(SILENT_LOGIN))
+            {
+               if (Events.exists()) Events.instance().raiseEvent(EVENT_LOGIN_SUCCESSFUL);
+               return "loggedIn";            
+            }            
+            
+            if (Events.exists()) Events.instance().raiseEvent(EVENT_ALREADY_LOGGED_IN);
+            return "loggedIn";           
+         }
+         
+         authenticate();
+         
+         if (!isLoggedIn())
+         {
+            throw new LoginException();
+         }
+         
+         if ( log.isDebugEnabled() )
+         {
+            log.debug("Login successful for: " + getCredentials().getUsername());
+         }
+
+         if (Events.exists()) Events.instance().raiseEvent(EVENT_LOGIN_SUCCESSFUL);
+         return "loggedIn";
+      }
+      catch (LoginException ex)
+      {
+         credentials.invalidate();
+         
+         if ( log.isDebugEnabled() )
+         {
+             log.debug("Login failed for: " + getCredentials().getUsername(), ex);
+         }
+         if (Events.exists()) Events.instance().raiseEvent(EVENT_LOGIN_FAILED, ex);
+      }
+      
+      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
+      {
+         if (Events.exists()) Events.instance().raiseEvent(EVENT_QUIET_LOGIN);         
+          
+         // Ensure that we haven't been authenticated as a result of the EVENT_QUIET_LOGIN event
+         if (!isLoggedIn())
+         {
+            if (credentials.isSet()) 
+            {
+               authenticate();
+               if (isLoggedIn() && Contexts.isEventContextActive())
+               {
+                  Contexts.getEventContext().set(SILENT_LOGIN, true);
+               }
+            }
+         }
+      }
+      catch (LoginException ex) 
+      { 
+         credentials.invalidate();
+      }
+   }
+   
+
+
+   /**
+    * 
+    * @throws LoginException
+    */
+   public synchronized void authenticate() 
+      throws LoginException
+   {
+      // If we're already authenticated, then don't authenticate again
+      if (!isLoggedIn() && !credentials.isInvalid())
+      {
+         principal = null;
+         subject = new Subject();
+         authenticate( getLoginContext() );
+      }      
+   }
+
+    
+   protected void authenticate(LoginContext loginContext) 
+      throws LoginException
+   {
+      try
+      {
+         authenticating = true;
+         preAuthenticate();
+         loginContext.login();
+         postAuthenticate();
+      }
+      finally
+      {
+         // Set password to null whether authentication is successful or not
+         credentials.setPassword(null);    
+         authenticating = false;
+      }
+   }
+   
+   /**
+    * Clears any roles added by calling addRole() while not authenticated.  
+    * This method may be overridden by a subclass if different 
+    * pre-authentication logic should occur.
+    */
+   protected void preAuthenticate()
+   {     
+      preAuthenticationRoles.clear();      
+      if (Events.exists()) Events.instance().raiseEvent(EVENT_PRE_AUTHENTICATE);
+   }   
+   
+   /**
+    * Extracts the principal from the subject, and populates the roles of the
+    * authenticated user.  This method may be overridden by a subclass if
+    * different post-authentication logic should occur.
+    */
+   protected void postAuthenticate()
+   {
+      // Populate the working memory with the user's principals
+      for ( Principal p : getSubject().getPrincipals() )
+      {         
+         if ( !(p instanceof Group))
+         {
+            if (principal == null) 
+            {
+               principal = p;
+               break;
+            }            
+         }         
+      }      
+      
+      if (!preAuthenticationRoles.isEmpty() && isLoggedIn())
+      {
+         for (String role : preAuthenticationRoles)
+         {
+            addRole(role);
+         }
+         preAuthenticationRoles.clear();
+      }
+
+      credentials.setPassword(null);
+      
+      if (Events.exists()) Events.instance().raiseEvent(EVENT_POST_AUTHENTICATE, this);      
+   }
+   
+   /**
+    * Resets all security state and credentials
+    */
+   public void unAuthenticate()
+   {      
+      principal = null;
+      subject = new Subject();
+      
+      credentials.clear();
+   }
+
+   protected LoginContext getLoginContext() throws LoginException
+   {
+      if (getJaasConfigName() != null)
+      {
+         return new LoginContext(getJaasConfigName(), getSubject(), 
+                  credentials.createCallbackHandler());
+      }
+      
+      return new LoginContext(Configuration.DEFAULT_JAAS_CONFIG_NAME, getSubject(), 
+            credentials.createCallbackHandler(), Configuration.instance());
+   }
+   
+   public void logout()
+   {
+      if (isLoggedIn())
+      {
+         unAuthenticate();
+         Session.instance().invalidate();
+         if (Events.exists()) Events.instance().raiseEvent(EVENT_LOGGED_OUT);
+      }
+   }
+
+   /**
+    * 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;
+      if (systemOp != null && Boolean.TRUE.equals(systemOp.get())) return true;
+      
+      tryLogin();
+      
+      for ( Group sg : getSubject().getPrincipals(Group.class) )      
+      {
+         if ( ROLES_GROUP.equals( sg.getName() ) )
+         {
+            return sg.isMember( new Role(role) );
+         }
+      }
+      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;
+      
+      if (!isLoggedIn())
+      {
+         preAuthenticationRoles.add(role);
+         return false;
+      }
+      else
+      {
+         for ( Group sg : getSubject().getPrincipals(Group.class) )      
+         {
+            if ( ROLES_GROUP.equals( sg.getName() ) )
+            {
+               return sg.addMember(new Role(role));
+            }
+         }
+                  
+         SimpleGroup roleGroup = new SimpleGroup(ROLES_GROUP);
+         roleGroup.addMember(new Role(role));
+         getSubject().getPrincipals().add(roleGroup);
+         return true;
+      }
+   }
+
+   /**
+    * Removes a role from the authenticated user
+    * 
+    * @param role The name of the role to remove
+    */
+   public void removeRole(String role)
+   {     
+      for ( Group sg : getSubject().getPrincipals(Group.class) )      
+      {
+         if ( ROLES_GROUP.equals( sg.getName() ) )
+         {
+            Enumeration e = sg.members();
+            while (e.hasMoreElements())
+            {
+               Principal member = (Principal) e.nextElement();
+               if (member.getName().equals(role))
+               {
+                  sg.removeMember(member);
+                  break;
+               }
+            }
+
+         }
+      }      
+   }   
+   
+   /**
+    * 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();
+      
+      if ( !hasRole(role) )
+      {
+         if ( !isLoggedIn() )
+         {           
+            if (Events.exists()) Events.instance().raiseEvent(EVENT_NOT_LOGGED_IN);
+            throw new NotLoggedInException();
+         }
+         else
+         {
+            if (Events.exists()) Events.instance().raiseEvent(EVENT_NOT_AUTHORIZED);
+            throw new AuthorizationException(String.format(
+                  "Authorization check failed for role [%s]", role));
+         }
+      }
+   }
+
+   /**
+    * Checks that the current authenticated user has permission for
+    * the specified name and action
+    * 
+    * @param name String The permission name
+    * @param action String The permission action
+    * @param arg Object Optional object parameter used to make a permission decision
+    * @throws AuthorizationException if the user does not have the specified permission
+    */
+   public void checkPermission(String name, String action, Object...arg)
+   {
+      if (systemOp != null && Boolean.TRUE.equals(systemOp.get())) return; 
+      
+      tryLogin();
+      
+      if ( !hasPermission(name, action, arg) )
+      {
+         if ( !isLoggedIn() )
+         {
+            if (Events.exists()) Events.instance().raiseEvent(EVENT_NOT_LOGGED_IN);
+            throw new NotLoggedInException();
+         }
+         else
+         {
+            if (Events.exists()) Events.instance().raiseEvent(EVENT_NOT_AUTHORIZED);
+            throw new AuthorizationException(String.format(
+                  "Authorization check failed for permission [%s,%s]", name, action));
+         }
+      }
+   }
+   
+   public void checkPermission(Object target, String action)
+   {
+      if (systemOp != null && Boolean.TRUE.equals(systemOp.get())) return;
+      
+      tryLogin();
+      
+      if ( !hasPermission(target, action) )
+      {
+         if ( !isLoggedIn() )
+         {
+            if (Events.exists()) Events.instance().raiseEvent(EVENT_NOT_LOGGED_IN);
+            throw new NotLoggedInException();            
+         }
+         else
+         {
+            if (Events.exists()) Events.instance().raiseEvent(EVENT_NOT_AUTHORIZED);
+            throw new AuthorizationException(String.format(
+                  "Authorization check failed for permission[%s,%s]", target, action));
+         }
+      }
+   }
+
+   /**
+    * Performs a permission check for the specified name and action
+    * 
+    * @param name String The permission name
+    * @param action String The permission action
+    * @param arg Object Optional object parameter used to make a permission decision
+    * @return boolean True if the user has the specified permission
+    */
+   public boolean hasPermission(String name, String action, Object...arg)
+   {      
+      if (!securityEnabled) return true;
+      if (systemOp != null && Boolean.TRUE.equals(systemOp.get())) return true;   
+      if (permissionMapper == null) return false;
+         
+      if (arg != null)
+      {
+         return permissionMapper.resolvePermission(arg[0], action);
+      }
+      else
+      {
+         return permissionMapper.resolvePermission(name, action);
+      }
+   }   
+   
+   public void filterByPermission(Collection collection, String action)
+   {
+      permissionMapper.filterByPermission(collection, action);  
+   }
+   
+   public boolean hasPermission(Object target, String action)
+   {
+      if (!securityEnabled) return true;
+      if (systemOp != null && Boolean.TRUE.equals(systemOp.get())) return true;     
+      if (permissionMapper == null) return false;
+      if (target == null) return false;
+      
+      return permissionMapper.resolvePermission(target, action);
+   }
+   
+   /**
+    * Evaluates the specified security expression, which must return a boolean
+    * value.
+    * 
+    * @param expr String The expression to evaluate
+    * @return boolean The result of the expression evaluation
+    */
+   protected boolean evaluateExpression(String expr) 
+   {         
+      return Expressions.instance().createValueExpression(expr, Boolean.class).getValue();
+   }   
+   
+   /**
+    * @see org.jboss.seam.security.Credentials#getUsername()
+    */
+   @Deprecated
+   public String getUsername()
+   {
+      return credentials.getUsername();
+   }
+
+   /**
+    * @see org.jboss.seam.security.Credentials#setUsername(String)
+    */
+   @Deprecated
+   public void setUsername(String username)
+   {  
+      credentials.setUsername(username);
+   }
+
+   /**
+    * @see org.jboss.seam.security.Credentials#getPassword()
+    */
+   @Deprecated
+   public String getPassword()
+   {
+      return credentials.getPassword();
+   }
+   
+   /**
+    * @see org.jboss.seam.security.Credentials#setPassword(String)
+    */   
+   @Deprecated
+   public void setPassword(String password)
+   {
+      credentials.setPassword(password);
+   }   
+   
+   /**
+    * @see org.jboss.seam.security.RememberMe#isEnabled()
+    */
+   @Deprecated
+   public boolean isRememberMe()
+   {
+      return rememberMe != null ? rememberMe.isEnabled() : false;
+   }
+   
+   /**
+    * @see org.jboss.seam.security.RememberMe#setEnabled(boolean)
+    */
+   @Deprecated
+   public void setRememberMe(boolean remember)
+   {
+      if (rememberMe != null) rememberMe.setEnabled(remember);
+   }   
+   
+   public Credentials getCredentials()
+   {
+      return credentials;
+   }   
+   
+   public MethodExpression getAuthenticateMethod()
+   {
+      return authenticateMethod;
+   }
+   
+   public void setAuthenticateMethod(MethodExpression authMethod)
+   {
+      this.authenticateMethod = authMethod;
+   }
+   
+   public String getJaasConfigName()
+   {
+      return jaasConfigName;
+   }
+   
+   public void setJaasConfigName(String jaasConfigName)
+   {
+      this.jaasConfigName = jaasConfigName;
+   }
+   
+   synchronized void runAs(RunAsOperation operation)
+   {
+      Principal savedPrincipal = getPrincipal();
+      Subject savedSubject = getSubject();
+      
+      try
+      {
+         principal = operation.getPrincipal();
+         subject = operation.getSubject();
+         
+         if (systemOp == null)
+         {
+            systemOp = new ThreadLocal<Boolean>();
+         }
+         
+         systemOp.set(operation.isSystemOperation());
+         
+         operation.execute();
+      }
+      finally
+      {
+         systemOp.set(false);
+         principal = savedPrincipal;
+         subject = savedSubject;
+      }
+   } 
+}


Property changes on: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/Identity.java
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:mergeinfo
   + 
Name: svn:eol-style
   + native

Copied: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/JpaTokenStore.java (from rev 10443, trunk/src/main/org/jboss/seam/security/JpaTokenStore.java)
===================================================================
--- trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/JpaTokenStore.java	                        (rev 0)
+++ trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/JpaTokenStore.java	2009-04-19 09:44:29 UTC (rev 10476)
@@ -0,0 +1,165 @@
+package org.jboss.seam.security;
+
+import static org.jboss.seam.ScopeType.APPLICATION;
+import static org.jboss.seam.annotations.Install.BUILT_IN;
+
+import java.io.Serializable;
+
+import javax.persistence.EntityManager;
+import javax.persistence.NoResultException;
+import javax.persistence.Query;
+
+import org.jboss.seam.annotations.Create;
+import org.jboss.seam.annotations.Install;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.intercept.BypassInterceptors;
+import org.jboss.seam.annotations.security.TokenUsername;
+import org.jboss.seam.annotations.security.TokenValue;
+import org.jboss.seam.core.Expressions;
+import org.jboss.seam.core.Expressions.ValueExpression;
+import org.jboss.seam.security.management.IdentityManagementException;
+import org.jboss.seam.util.AnnotatedBeanProperty;
+
+/**
+ * A TokenStore implementation, stores tokens inside a database table.
+ * 
+ * @author Shane Bryzak
+ */
+ at Name("org.jboss.seam.security.tokenStore")
+ at Install(precedence = BUILT_IN, value=false) 
+ at Scope(APPLICATION)
+ at BypassInterceptors
+public class JpaTokenStore implements TokenStore, Serializable
+{
+   private Class tokenClass;
+   
+   private ValueExpression<EntityManager> entityManager;    
+   
+   private AnnotatedBeanProperty<TokenUsername> tokenUsernameProperty;
+   private AnnotatedBeanProperty<TokenValue> tokenValueProperty;
+   
+   @Create
+   public void create()
+   {
+      if (entityManager == null)
+      {
+         entityManager = Expressions.instance().createValueExpression("#{entityManager}", EntityManager.class);
+      }       
+      
+      tokenUsernameProperty = new AnnotatedBeanProperty<TokenUsername>(tokenClass, TokenUsername.class);
+      tokenValueProperty = new AnnotatedBeanProperty<TokenValue>(tokenClass, TokenValue.class);
+      
+      if (!tokenUsernameProperty.isSet()) 
+      {
+         throw new IllegalStateException("Invalid tokenClass " + tokenClass.getName() + 
+               " - required annotation @TokenUsername not found on any Field or Method.");
+      }
+      
+      if (!tokenValueProperty.isSet()) 
+      {
+         throw new IllegalStateException("Invalid tokenClass " + tokenClass.getName() + 
+               " - required annotation @TokenValue not found on any Field or Method.");
+      }       
+   }
+   
+   public void createToken(String username, String value)
+   {
+      if (tokenClass == null)
+      {
+         throw new IllegalStateException("Could not create token, tokenClass not set");
+      }   
+      
+      try
+      {
+         Object token = tokenClass.newInstance();
+         
+         tokenUsernameProperty.setValue(token, username);
+         tokenValueProperty.setValue(token, value);
+         
+         lookupEntityManager().persist(token);
+      }
+      catch (Exception ex)
+      {
+         if (ex instanceof IdentityManagementException)
+         {
+            throw (IdentityManagementException) ex;
+         }
+         else
+         {
+            throw new IdentityManagementException("Could not create account", ex);
+         }
+      }       
+   }
+   
+   public boolean validateToken(String username, String value)
+   {
+      return lookupToken(username, value) != null;
+   }
+   
+   public void invalidateToken(String username, String value)
+   {
+      Object token = lookupToken(username, value);
+      if (token != null)
+      {
+         lookupEntityManager().remove(token);
+      }
+   }
+   
+   public void invalidateAll(String username)
+   {
+      Query query = lookupEntityManager().createQuery(
+         "select t from " + tokenClass.getName() + " t where " + tokenUsernameProperty.getName() +
+         " = :username")
+         .setParameter("username", username);
+      
+      for (Object token : query.getResultList())
+      {
+         lookupEntityManager().remove(token);
+      }      
+   }
+   
+   public Object lookupToken(String username, String value)       
+   {
+      try
+      {
+         Object token = lookupEntityManager().createQuery(
+            "select t from " + tokenClass.getName() + " t where " + tokenUsernameProperty.getName() +
+            " = :username and " + tokenValueProperty.getName() + " = :value")
+            .setParameter("username", username)
+            .setParameter("value", value)
+            .getSingleResult();
+         
+         return token;
+      }
+      catch (NoResultException ex)
+      {
+         return null;        
+      }      
+   }   
+   
+   public Class getTokenClass()
+   {
+      return tokenClass;
+   }
+   
+   public void setTokenClass(Class tokenClass)
+   {
+      this.tokenClass = tokenClass;
+   }
+   
+   private EntityManager lookupEntityManager()
+   {
+      return entityManager.getValue();
+   }
+   
+   public ValueExpression getEntityManager()
+   {
+      return entityManager;
+   }
+   
+   public void setEntityManager(ValueExpression expression)
+   {
+      this.entityManager = expression;
+   }    
+}


Property changes on: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/JpaTokenStore.java
___________________________________________________________________
Name: svn:mergeinfo
   + 

Copied: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/NotLoggedInException.java (from rev 10443, trunk/src/main/org/jboss/seam/security/NotLoggedInException.java)
===================================================================
--- trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/NotLoggedInException.java	                        (rev 0)
+++ trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/NotLoggedInException.java	2009-04-19 09:44:29 UTC (rev 10476)
@@ -0,0 +1,11 @@
+package org.jboss.seam.security;
+
+import javax.ejb.ApplicationException;
+
+/**
+ * Thrown when an unauthenticated user attempts to execute a restricted action. 
+ * 
+ * @author Shane Bryzak
+ */
+ at ApplicationException(rollback=true)
+public class NotLoggedInException extends RuntimeException {}


Property changes on: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/NotLoggedInException.java
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:mergeinfo
   + 
Name: svn:eol-style
   + native

Copied: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/RememberMe.java (from rev 10443, trunk/src/main/org/jboss/seam/security/RememberMe.java)
===================================================================
--- trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/RememberMe.java	                        (rev 0)
+++ trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/RememberMe.java	2009-04-19 09:44:29 UTC (rev 10476)
@@ -0,0 +1,410 @@
+package org.jboss.seam.security;
+
+import static org.jboss.seam.ScopeType.SESSION;
+import static org.jboss.seam.annotations.Install.BUILT_IN;
+
+import java.io.Serializable;
+import java.rmi.server.UID;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+import javax.faces.context.FacesContext;
+
+import org.jboss.seam.Component;
+import org.jboss.seam.annotations.Create;
+import org.jboss.seam.annotations.Install;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Observer;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.intercept.BypassInterceptors;
+import org.jboss.seam.faces.Selector;
+import org.jboss.seam.security.management.IdentityManager;
+import org.jboss.seam.util.Base64;
+
+/**
+ * Remember-me functionality is provided by this class, in two different flavours.  The first mode
+ * provides username-only persistence, and is considered to be secure as the user (or their browser)
+ * is still required to provide a password.  The second mode provides an auto-login feature, however
+ * is NOT considered to be secure and is vulnerable to XSS attacks compromising the user's account.
+ * 
+ * Use the auto-login mode with caution!
+ * 
+ * @author Shane Bryzak
+ */
+ at Name("org.jboss.seam.security.rememberMe")
+ at Scope(SESSION)
+ at Install(precedence = BUILT_IN, classDependencies = "javax.faces.context.FacesContext")
+ at BypassInterceptors
+public class RememberMe implements Serializable
+{
+   class UsernameSelector extends Selector
+   {
+      @Override
+      public String getCookieName()
+      {
+         return "org.jboss.seam.security.username";
+      }       
+      
+      @Override
+      public void setDirty()
+      {
+         super.setDirty();
+      }
+      
+      @Override
+      public String getCookieValue()
+      {
+         return super.getCookieValue();
+      }
+      
+      @Override
+      public void clearCookieValue()
+      {
+         super.clearCookieValue();
+      }
+      
+      @Override
+      public void setCookieValueIfEnabled(String value)
+      {
+         super.setCookieValueIfEnabled(value);
+      }
+   }
+   
+   class TokenSelector extends UsernameSelector
+   {
+      @Override
+      public String getCookieName()
+      {
+         return "org.jboss.seam.security.authtoken";
+      }
+   }
+   
+   private class DecodedToken
+   {
+      private String username;
+      private String value;
+      
+      public DecodedToken(String cookieValue)
+      {
+         if (cookieValue != null)
+         {
+            try
+            {
+               String decoded = new String(Base64.decode(cookieValue));         
+               username = decoded.substring(0, decoded.indexOf(':'));
+               value = decoded.substring(decoded.indexOf(':') + 1);
+            }
+            catch (Exception ex)
+            {
+               // swallow
+            }
+         }
+      }
+      
+      public String getUsername()
+      {
+         return username;
+      }
+      
+      public String getValue()
+      {
+         return value;
+      }
+   }
+      
+   private UsernameSelector usernameSelector;
+   
+   private TokenSelector tokenSelector;   
+   private TokenStore tokenStore;
+      
+   private boolean enabled;
+
+   private int cookieMaxAge = Selector.DEFAULT_MAX_AGE;
+   
+   private boolean autoLoggedIn;
+   
+   private Random random = new Random(System.currentTimeMillis());
+   
+   public enum Mode { disabled, usernameOnly, autoLogin}
+   
+   private Mode mode = Mode.usernameOnly;
+   
+   public Mode getMode()
+   {
+      return mode;
+   }
+   
+   public void setMode(Mode mode)
+   {
+      this.mode = mode;
+   }
+   
+   public boolean isEnabled()
+   {
+      return enabled;
+   }
+   
+   public void setEnabled(boolean enabled)
+   {
+      if (this.enabled != enabled)
+      {
+         this.enabled = enabled;
+         // selector is null during component initialization (setup handled in @Create method)
+         if (usernameSelector != null && mode.equals(Mode.usernameOnly))
+         {
+            usernameSelector.setCookieEnabled(enabled);
+            usernameSelector.setDirty();
+         }
+         // selector is null during component initialization (setup handled in @Create method)
+         else if (tokenSelector != null && mode.equals(Mode.autoLogin))
+         {
+            tokenSelector.setCookieEnabled(enabled);
+            tokenSelector.setDirty();
+         }
+      }      
+   }
+
+   public int getCookieMaxAge() {
+       return cookieMaxAge;
+   }
+
+   public void setCookieMaxAge(int cookieMaxAge) {
+       this.cookieMaxAge = cookieMaxAge;
+   }
+   
+   public TokenStore getTokenStore()
+   {
+      return tokenStore;
+   }
+   
+   public void setTokenStore(TokenStore tokenStore)
+   {
+      this.tokenStore = tokenStore;
+   }
+   
+   @Create
+   public void create()
+   {
+      if (mode.equals(Mode.usernameOnly))
+      {      
+         usernameSelector = new UsernameSelector();
+         usernameSelector.setCookieEnabled(enabled);
+      }
+      else if (mode.equals(Mode.autoLogin))
+      {
+         tokenSelector = new TokenSelector();
+         tokenSelector.setCookieEnabled(enabled);
+
+         // Default to JpaTokenStore
+         if (tokenStore == null)
+         {
+            tokenStore = (TokenStore) Component.getInstance(JpaTokenStore.class, true);
+         }         
+      }
+   }
+   
+   protected String generateTokenValue()
+   {
+      StringBuilder sb = new StringBuilder();
+      sb.append(new UID().toString());
+      sb.append(":");
+      sb.append(random.nextLong());
+      return sb.toString();
+   }
+   
+   protected String encodeToken(String username, String value)
+   {
+      StringBuilder sb = new StringBuilder();
+      sb.append(username);
+      sb.append(":");
+      sb.append(value);
+      return Base64.encodeBytes(sb.toString().getBytes());      
+   }
+   
+   public String getCookiePath()
+   {
+      FacesContext ctx = FacesContext.getCurrentInstance();
+      return ctx != null ? ctx.getExternalContext().getRequestContextPath() : null;
+   }
+   
+   @Observer(Credentials.EVENT_INIT_CREDENTIALS)
+   public void initCredentials(Credentials credentials)
+   {     
+      String cookiePath = getCookiePath();
+      
+      if (mode.equals(Mode.usernameOnly))
+      {         
+         if (cookiePath != null)
+         {
+            usernameSelector.setCookiePath(cookiePath);
+         }
+         
+         String username = usernameSelector.getCookieValue();
+         if (username!=null)
+         {
+            setEnabled(true);
+            credentials.setUsername(username);
+         }
+               
+         usernameSelector.setDirty();
+      }
+      else if (mode.equals(Mode.autoLogin))
+      {
+         if (cookiePath != null)
+         {
+            tokenSelector.setCookiePath(cookiePath);
+         }
+         
+         String token = tokenSelector.getCookieValue();
+         if (token != null)
+         {
+            setEnabled(true);
+            
+            DecodedToken decoded = new DecodedToken(token);
+
+            if (tokenStore.validateToken(decoded.getUsername(), decoded.getValue()))
+            {
+               credentials.setUsername(decoded.getUsername());
+               credentials.setPassword(decoded.getValue());               
+            }
+            else
+            {
+               // Have we been compromised? Just in case, invalidate all authentication tokens
+               tokenStore.invalidateAll(decoded.getUsername());
+            }
+         }
+      }
+   }
+   
+   /**
+    * I hate these hacks... 
+    */
+   private class BoolWrapper 
+   {
+      boolean value;
+   }
+   
+   @Observer(Identity.EVENT_QUIET_LOGIN)
+   public void quietLogin()
+   {
+      final Identity identity = Identity.instance();
+      
+      if (mode.equals(Mode.autoLogin) && isEnabled())
+      {
+         final String username = identity.getCredentials().getUsername();    
+         final BoolWrapper userEnabled = new BoolWrapper();
+         final List<String> roles = new ArrayList<String>();
+         
+         // Double check our credentials again
+         if (tokenStore.validateToken(username, identity.getCredentials().getPassword()))
+         {            
+            new RunAsOperation(true) {
+               @Override
+               public void execute()
+               {        
+                  if (IdentityManager.instance().isUserEnabled(username))
+                  {
+                     userEnabled.value = true;
+
+                     for (String role : IdentityManager.instance().getImpliedRoles(username))
+                     {
+                        roles.add(role);
+                     }
+                  }
+               }
+            }.run();
+            
+            if (userEnabled.value)
+            {
+               identity.unAuthenticate();
+               identity.preAuthenticate();
+               
+               // populate the roles
+               for (String role : roles)
+               {
+                  identity.addRole(role);
+               }
+   
+               // Set the principal
+               identity.getSubject().getPrincipals().add(new SimplePrincipal(username));
+               identity.postAuthenticate();
+            
+               autoLoggedIn = true;
+            }
+         }            
+      }
+   }
+   
+   @Observer(Identity.EVENT_LOGGED_OUT)
+   public void loggedOut()
+   {
+      if (mode.equals(Mode.autoLogin))
+      {
+         tokenSelector.clearCookieValue();
+      }
+   }
+   
+   @Observer(Identity.EVENT_POST_AUTHENTICATE)
+   public void postAuthenticate(Identity identity)
+   {
+      if (mode.equals(Mode.usernameOnly))
+      {
+         // Password is set to null during authentication, so we set dirty
+         usernameSelector.setDirty();
+               
+         if ( !enabled )
+         {
+            usernameSelector.clearCookieValue();
+         }
+         else
+         {
+            usernameSelector.setCookieMaxAge(cookieMaxAge);
+            usernameSelector.setCookieValueIfEnabled( Identity.instance().getCredentials().getUsername() );
+         }
+      }
+      else if (mode.equals(Mode.autoLogin))
+      {
+         tokenSelector.setDirty();
+         
+         DecodedToken decoded = new DecodedToken(tokenSelector.getCookieValue());
+         
+         // Invalidate the current token (if it exists) whether enabled or not
+         if (decoded.getUsername() != null)
+         {
+            tokenStore.invalidateToken(decoded.getUsername(), decoded.getValue());
+         }
+         
+         if ( !enabled ) 
+         {
+            tokenSelector.clearCookieValue();         
+         }
+         else
+         {
+            String value = generateTokenValue();
+            tokenStore.createToken(identity.getPrincipal().getName(), value);
+            tokenSelector.setCookieEnabled(enabled);
+            tokenSelector.setCookieMaxAge(cookieMaxAge);
+            tokenSelector.setCookieValueIfEnabled(encodeToken(identity.getPrincipal().getName(), value));            
+         }
+      }
+   }        
+   
+   @Observer(Credentials.EVENT_CREDENTIALS_UPDATED)
+   public void credentialsUpdated()
+   {
+      if (mode.equals(Mode.usernameOnly)) 
+      {
+         usernameSelector.setDirty();
+      }      
+   }      
+   
+   /**
+    * A flag that an application can use to protect sensitive operations if the user has been
+    * auto-authenticated. 
+    */
+   public boolean isAutoLoggedIn()
+   {
+      return autoLoggedIn;
+   }
+}


Property changes on: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/RememberMe.java
___________________________________________________________________
Name: svn:mergeinfo
   + 

Copied: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/Role.java (from rev 10443, trunk/src/main/org/jboss/seam/security/Role.java)
===================================================================
--- trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/Role.java	                        (rev 0)
+++ trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/Role.java	2009-04-19 09:44:29 UTC (rev 10476)
@@ -0,0 +1,28 @@
+package org.jboss.seam.security;
+
+/**
+ * Represents a user role.  A conditional role is a special type of role that is assigned to a user
+ * based on the contextual state of a permission check.
+ *  
+ * @author Shane Bryzak
+ */
+public class Role extends SimplePrincipal
+{   
+   private boolean conditional;
+   
+   public Role(String name)
+   {
+      super(name);
+   }   
+   
+   public Role(String name, boolean conditional)
+   {
+      this(name);
+      this.conditional = conditional;
+   }
+   
+   public boolean isConditional()
+   {
+      return conditional;
+   }
+}


Property changes on: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/Role.java
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:mergeinfo
   + 
Name: svn:eol-style
   + native

Copied: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/RunAsOperation.java (from rev 10443, trunk/src/main/org/jboss/seam/security/RunAsOperation.java)
===================================================================
--- trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/RunAsOperation.java	                        (rev 0)
+++ trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/RunAsOperation.java	2009-04-19 09:44:29 UTC (rev 10476)
@@ -0,0 +1,77 @@
+package org.jboss.seam.security;
+
+import java.security.Principal;
+import java.security.acl.Group;
+
+import javax.security.auth.Subject;
+
+/**
+ * Defines a security operation that can be executed within a particular 
+ * security context.
+ * 
+ * @author Shane Bryzak
+ */
+public abstract class RunAsOperation
+{
+   private Principal principal;
+   private Subject subject;
+   
+   private boolean systemOp = false;
+      
+   public RunAsOperation()
+   {
+      principal = new SimplePrincipal(null);  
+      subject = new Subject();
+   }
+   
+   /**
+    * A system operation allows any security checks to pass
+    * 
+    * @param systemOp
+    */
+   public RunAsOperation(boolean systemOp)
+   {      
+      this();
+      this.systemOp = systemOp;
+   }
+   
+   public abstract void execute();
+   
+   public Principal getPrincipal()
+   {
+      return principal;
+   }
+   
+   public Subject getSubject()
+   {
+      return subject;
+   }
+   
+   public RunAsOperation addRole(String role)
+   {
+      for ( Group sg : getSubject().getPrincipals(Group.class) )      
+      {
+         if ( Identity.ROLES_GROUP.equals( sg.getName() ) )
+         {
+            sg.addMember(new SimplePrincipal(role));
+            break;
+         }
+      }
+               
+      SimpleGroup roleGroup = new SimpleGroup(Identity.ROLES_GROUP);
+      roleGroup.addMember(new SimplePrincipal(role));
+      getSubject().getPrincipals().add(roleGroup); 
+      
+      return this;
+   }
+   
+   public boolean isSystemOperation()
+   {
+      return systemOp;
+   }
+   
+   public void run()
+   {      
+      Identity.instance().runAs(this);
+   }
+}


Property changes on: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/RunAsOperation.java
___________________________________________________________________
Name: svn:mergeinfo
   + 

Copied: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/SecurityFunctions.java (from rev 10443, trunk/src/main/org/jboss/seam/security/SecurityFunctions.java)
===================================================================
--- trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/SecurityFunctions.java	                        (rev 0)
+++ trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/SecurityFunctions.java	2009-04-19 09:44:29 UTC (rev 10476)
@@ -0,0 +1,31 @@
+package org.jboss.seam.security;
+
+/**
+ * Delegating wrapper for EL security functions.
+ * 
+ * @author Shane Bryzak
+ */
+public class SecurityFunctions
+{
+   public static boolean hasRole(String name)
+   {
+      return Identity.instance().hasRole(name);
+   }
+   
+   public static boolean hasPermission(String name, String action, Object arg)
+   {
+      if (arg != null)
+      {
+         return Identity.instance().hasPermission(name, action, arg);
+      }
+      else
+      {
+         return Identity.instance().hasPermission(name, action);
+      }
+   }
+   
+   public static boolean hasPermission(Object target, String action)
+   {
+      return Identity.instance().hasPermission(target, action);
+   }
+}


Property changes on: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/SecurityFunctions.java
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:mergeinfo
   + 
Name: svn:eol-style
   + native

Copied: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/SecurityInterceptor.java (from rev 10443, trunk/src/main/org/jboss/seam/security/SecurityInterceptor.java)
===================================================================
--- trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/SecurityInterceptor.java	                        (rev 0)
+++ trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/SecurityInterceptor.java	2009-04-19 09:44:29 UTC (rev 10476)
@@ -0,0 +1,301 @@
+package org.jboss.seam.security;
+
+import java.io.Serializable;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.jboss.seam.annotations.intercept.AroundInvoke;
+import org.jboss.seam.annotations.intercept.Interceptor;
+import org.jboss.seam.annotations.intercept.InterceptorType;
+import org.jboss.seam.annotations.security.PermissionCheck;
+import org.jboss.seam.annotations.security.Restrict;
+import org.jboss.seam.annotations.security.RoleCheck;
+import org.jboss.seam.async.AsynchronousInterceptor;
+import org.jboss.seam.intercept.AbstractInterceptor;
+import org.jboss.seam.intercept.InvocationContext;
+import org.jboss.seam.transaction.RollbackInterceptor;
+import org.jboss.seam.util.Strings;
+
+/**
+ * Provides authorization services for component invocations.
+ * 
+ * @author Shane Bryzak
+ */
+ at Interceptor(type=InterceptorType.CLIENT, 
+         around=AsynchronousInterceptor.class, within = RollbackInterceptor.class)
+public class SecurityInterceptor extends AbstractInterceptor implements Serializable
+{
+   private static final long serialVersionUID = -6567750187000766925L;
+   
+   /**
+    * You may encounter a JVM bug where the field initializer is not evaluated for a transient field after deserialization.
+    * @see "http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6252102"
+    */
+   private transient volatile Map<Method,Restriction> restrictions = new HashMap<Method,Restriction>();
+   
+   private class Restriction
+   {
+      private String expression;
+      
+      private String permissionTarget;
+      private String permissionAction;
+      
+      private Map<String, Object> methodRestrictions;
+      private Map<Integer,Set<String>> paramRestrictions;
+      private Set<String> roleRestrictions;
+            
+      public void setExpression(String expression)
+      {
+         this.expression = expression;
+      }
+      
+      public void setPermissionTarget(String target)
+      {
+         this.permissionTarget = target;
+      }
+      
+      public void setPermissionAction(String action)
+      {
+         this.permissionAction = action;
+      }
+      
+      public void addMethodRestriction(Object target, String action)
+      {
+         if (methodRestrictions == null)
+         {
+            methodRestrictions = new HashMap<String, Object>();
+         }
+         
+         methodRestrictions.put(action, target);
+      }
+      
+      public void addRoleRestriction(String role)
+      {
+         if (roleRestrictions == null)
+         {
+            roleRestrictions = new HashSet<String>();
+         }
+         
+         roleRestrictions.add(role);
+      }
+      
+      public void addParameterRestriction(int index, String action)
+      {
+         Set<String> actions = null;
+         
+         if (paramRestrictions == null)
+         {
+            paramRestrictions = new HashMap<Integer,Set<String>>();
+         }
+         
+         if (!paramRestrictions.containsKey(index))
+         {
+            actions = new HashSet<String>();
+            paramRestrictions.put(index, actions);
+         }
+         else
+         {
+            actions = paramRestrictions.get(index);
+         }
+         
+         actions.add(action);
+      }
+      
+      public void check(Object[] parameters)
+      {
+         if (Identity.isSecurityEnabled())
+         {
+            if (expression != null)
+            {
+               Identity.instance().checkRestriction(expression);
+            }
+            
+            if (methodRestrictions != null)
+            {
+               for (String action : methodRestrictions.keySet())
+               {
+                  Identity.instance().checkPermission(methodRestrictions.get(action), action);
+               }
+            }
+            
+            if (paramRestrictions != null)
+            {
+               for (Integer idx : paramRestrictions.keySet())
+               {
+                  Set<String> actions = paramRestrictions.get(idx);
+                  for (String action : actions) 
+                  {
+                     Identity.instance().checkPermission(parameters[idx], action);
+                  }
+               }
+            }
+            
+            if (roleRestrictions != null)
+            {
+               for (String role : roleRestrictions)
+               {
+                  Identity.instance().checkRole(role);
+               }
+            }
+            
+            if (permissionTarget != null && permissionAction != null)
+            {
+               Identity.instance().checkPermission(permissionTarget, permissionAction);
+            }
+         }
+      }
+   }
+
+   @AroundInvoke
+   public Object aroundInvoke(InvocationContext invocation) throws Exception
+   {
+      Method interfaceMethod = invocation.getMethod();
+      
+      if (!"hashCode".equals(interfaceMethod.getName()))
+      {
+         Restriction restriction = getRestriction(interfaceMethod);      
+         if ( restriction != null ) restriction.check(invocation.getParameters());
+      }
+
+      return invocation.proceed();
+   }
+
+   private Restriction getRestriction(Method interfaceMethod) throws Exception
+   {
+      // see field declaration as to why this is done
+      if (restrictions == null)
+      {
+         synchronized(this)
+         {
+            restrictions = new HashMap<Method, Restriction>();
+         }
+      }
+      
+      if (!restrictions.containsKey(interfaceMethod))
+      {
+         synchronized(restrictions)
+         {
+            // FIXME this logic should be abstracted rather than sitting in the middle of this interceptor
+            if (!restrictions.containsKey(interfaceMethod))
+            {  
+               Restriction restriction = null;
+               
+               Method method = getComponent().getBeanClass().getMethod( 
+                     interfaceMethod.getName(), interfaceMethod.getParameterTypes() );      
+               
+               Restrict restrict = null;
+               
+               if ( method.isAnnotationPresent(Restrict.class) )
+               {
+                  restrict = method.getAnnotation(Restrict.class);
+               }
+               else if ( getComponent().getBeanClass().isAnnotationPresent(Restrict.class) )
+               {
+                  if ( !getComponent().isLifecycleMethod(method) )
+                  {
+                     restrict = getComponent().getBeanClass().getAnnotation(Restrict.class); 
+                  }
+               }
+               
+               if (restrict != null)
+               {
+                  if (restriction == null) restriction = new Restriction();
+                  
+                  if ( Strings.isEmpty(restrict.value()) )
+                  {
+                     restriction.setPermissionTarget(getComponent().getName());
+                     restriction.setPermissionAction(method.getName());
+                  }
+                  else
+                  {
+                     restriction.setExpression(restrict.value());
+                  }
+               }
+               
+               for (Annotation annotation : method.getDeclaringClass().getAnnotations())
+               {
+                  if (annotation.annotationType().isAnnotationPresent(RoleCheck.class))
+                  {
+                     if (restriction == null) restriction = new Restriction();
+                     restriction.addRoleRestriction(annotation.annotationType().getSimpleName().toLowerCase());
+                  }
+               }
+               
+               for (Annotation annotation : method.getAnnotations())
+               {
+                  if (annotation.annotationType().isAnnotationPresent(PermissionCheck.class))
+                  {
+                     PermissionCheck permissionCheck = annotation.annotationType().getAnnotation(
+                           PermissionCheck.class);
+                     
+                     Method valueMethod = null;
+                     for (Method m : annotation.annotationType().getDeclaredMethods())
+                     {
+                        valueMethod = m;
+                        break;
+                     }
+                     
+                     if (valueMethod != null)
+                     {                        
+                        if (restriction == null) restriction = new Restriction();
+                        Object target = valueMethod.invoke(annotation);
+                        if (!target.equals(void.class))
+                        {
+                           if (restriction == null) restriction = new Restriction();
+                           restriction.addMethodRestriction(target, 
+                                 getPermissionAction(permissionCheck, annotation));
+                        }
+                     }
+                  }
+                  if (annotation.annotationType().isAnnotationPresent(RoleCheck.class))
+                  {
+                     if (restriction == null) restriction = new Restriction();
+                     restriction.addRoleRestriction(annotation.annotationType().getSimpleName().toLowerCase());
+                  }
+               }               
+               
+               for (int i = 0; i < method.getParameterAnnotations().length; i++)
+               {
+                  Annotation[] annotations = method.getParameterAnnotations()[i]; 
+                  for (Annotation annotation : annotations)
+                  {
+                     if (annotation.annotationType().isAnnotationPresent(PermissionCheck.class))
+                     {                        
+                        PermissionCheck permissionCheck = annotation.annotationType().getAnnotation(
+                              PermissionCheck.class);
+                        if (restriction == null) restriction = new Restriction();
+                        restriction.addParameterRestriction(i, 
+                              getPermissionAction(permissionCheck, annotation));                        
+                     }
+                  }
+               }                             
+               
+               restrictions.put(interfaceMethod, restriction);
+               return restriction;
+            }
+         }
+      }
+      return restrictions.get(interfaceMethod);      
+   }
+   
+   private String getPermissionAction(PermissionCheck check, Annotation annotation)
+   {
+      if (!"".equals(check.value()))
+      {
+         return check.value();
+      }
+      else
+      {
+         return annotation.annotationType().getSimpleName().toLowerCase();
+      }
+   }
+   
+   public boolean isInterceptorEnabled()
+   {
+      return getComponent().isSecure() && !getComponent().beanClassHasAnnotation("javax.jws.WebService");
+   }
+}


Property changes on: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/SecurityInterceptor.java
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:mergeinfo
   + 
Name: svn:eol-style
   + native

Copied: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/SimpleGroup.java (from rev 10443, trunk/src/main/org/jboss/seam/security/SimpleGroup.java)
===================================================================
--- trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/SimpleGroup.java	                        (rev 0)
+++ trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/SimpleGroup.java	2009-04-19 09:44:29 UTC (rev 10476)
@@ -0,0 +1,93 @@
+package org.jboss.seam.security;
+
+import java.io.Serializable;
+import java.security.Principal;
+import java.security.acl.Group;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Implementation of the Group interface, used for holding roles etc.
+ * 
+ * @author Shane Bryzak
+ */
+public class SimpleGroup implements Group, Serializable
+{
+   private static final long serialVersionUID = 5766373925836425908L;
+
+   /**
+    * The name of the group
+    */
+   private String name;
+
+   /**
+    * The members of this group
+    */
+   private Set<Principal> members = new HashSet<Principal>();
+
+   public SimpleGroup(String name)
+   {
+      this.name = name;
+   }
+
+   public boolean addMember(Principal user)
+   {
+      return members.add(user);
+   }
+
+   public boolean isMember(Principal member)
+   {
+      if ( members.contains(member) )
+      {
+         return true;
+      }
+      else
+      {
+         for (Principal m : members)
+         {
+            if (m instanceof Group && ((Group) m).isMember(member))
+            {
+               return true;
+            }
+         }
+      }
+      return false;
+   }
+
+   public Enumeration<? extends Principal> members()
+   {
+      return Collections.enumeration(members);
+   }
+
+   public boolean removeMember(Principal user)
+   {
+      return members.remove(user);
+   }
+
+   public String getName()
+   {
+      return name;
+   }
+
+   @Override
+   public boolean equals(Object obj)
+   {
+      if (obj instanceof SimpleGroup)
+      {
+         SimpleGroup other = (SimpleGroup) obj;
+         return other.name.equals(name);
+      }
+      else
+      {
+         return false;
+      }
+   }
+
+   @Override
+   public int hashCode()
+   {
+      return name.hashCode();
+   }
+}


Property changes on: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/SimpleGroup.java
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:mergeinfo
   + 
Name: svn:eol-style
   + native

Copied: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/SimplePrincipal.java (from rev 10443, trunk/src/main/org/jboss/seam/security/SimplePrincipal.java)
===================================================================
--- trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/SimplePrincipal.java	                        (rev 0)
+++ trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/SimplePrincipal.java	2009-04-19 09:44:29 UTC (rev 10476)
@@ -0,0 +1,54 @@
+package org.jboss.seam.security;
+
+import java.io.Serializable;
+import java.security.Principal;
+
+/**
+ * Simple implementation of the Principal interface, supporting a named user.
+ * 
+ * @author Shane Bryzak
+ */
+public class SimplePrincipal implements Principal, Serializable
+{
+   private static final long serialVersionUID = 5609375932836425908L;   
+   
+   private String name;
+   
+   public SimplePrincipal(String name)
+   {
+      this.name = name;
+   }
+   
+   public String getName()
+   {
+      return name;
+   }
+
+   @Override
+   public boolean equals(Object obj)
+   {
+      if (obj instanceof Principal)
+      {
+         Principal other = (Principal) obj;
+         return name == null ?
+                  other.getName() == null :
+                  name.equals( other.getName() );
+      }
+      else
+      {
+         return false;
+      }
+   }
+
+   @Override
+   public int hashCode()
+   {
+      return name != null ? name.hashCode() : super.hashCode();
+   }
+
+   @Override
+   public String toString()
+   {
+      return name;
+   }   
+}


Property changes on: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/SimplePrincipal.java
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:mergeinfo
   + 
Name: svn:eol-style
   + native

Copied: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/TokenStore.java (from rev 10443, trunk/src/main/org/jboss/seam/security/TokenStore.java)
===================================================================
--- trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/TokenStore.java	                        (rev 0)
+++ trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/TokenStore.java	2009-04-19 09:44:29 UTC (rev 10476)
@@ -0,0 +1,15 @@
+package org.jboss.seam.security;
+
+/**
+ * A store containing user authentication tokens.  Used in conjunction with the RememberMe
+ * component to auto-login users that present a valid cookie-based token.
+ * 
+ * @author Shane Bryzak
+ */
+public interface TokenStore
+{
+   void createToken(String username, String value);
+   boolean validateToken(String username, String value);
+   void invalidateToken(String username, String value);
+   void invalidateAll(String username);
+}


Property changes on: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/TokenStore.java
___________________________________________________________________
Name: svn:mergeinfo
   + 

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


Property changes on: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/crypto
___________________________________________________________________
Name: svn:mergeinfo
   + 

Copied: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/digest (from rev 10443, trunk/src/main/org/jboss/seam/security/digest)


Property changes on: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/digest
___________________________________________________________________
Name: svn:mergeinfo
   + 

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


Property changes on: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/jaas
___________________________________________________________________
Name: svn:mergeinfo
   + 

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


Property changes on: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/management
___________________________________________________________________
Name: svn:mergeinfo
   + 

Copied: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/openid (from rev 10443, trunk/src/main/org/jboss/seam/security/openid)


Property changes on: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/openid
___________________________________________________________________
Name: svn:mergeinfo
   + 

Copied: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/package-info.java (from rev 10443, trunk/src/main/org/jboss/seam/security/package-info.java)
===================================================================
--- trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/package-info.java	                        (rev 0)
+++ trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/package-info.java	2009-04-19 09:44:29 UTC (rev 10476)
@@ -0,0 +1,12 @@
+/**
+ * Seam Security
+ * 
+ * @see org.jboss.seam.security.Identity
+ * @see org.jboss.seam.annotations.security.Restrict
+ */
+ at Namespace(value="http://jboss.com/products/seam/security", prefix="org.jboss.seam.security")
+ at AutoCreate
+package org.jboss.seam.security;
+
+import org.jboss.seam.annotations.AutoCreate;
+import org.jboss.seam.annotations.Namespace;


Property changes on: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/package-info.java
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:mergeinfo
   + 
Name: svn:eol-style
   + native

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


Property changes on: trunk/modules/trunk/security/src/main/java/org/jboss/seam/security/permission
___________________________________________________________________
Name: svn:mergeinfo
   + 

Deleted: trunk/src/main/org/jboss/seam/security/AuthorizationException.java
===================================================================
--- trunk/src/main/org/jboss/seam/security/AuthorizationException.java	2009-04-19 09:32:07 UTC (rev 10475)
+++ trunk/src/main/org/jboss/seam/security/AuthorizationException.java	2009-04-19 09:44:29 UTC (rev 10476)
@@ -1,17 +0,0 @@
-package org.jboss.seam.security;
-
-import javax.ejb.ApplicationException;
-
-/**
- * Thrown when an authenticated user has insufficient rights to carry out an action.
- * 
- * @author Shane Bryzak
- */
- at ApplicationException(rollback=true)
-public class AuthorizationException extends RuntimeException
-{ 
-   public AuthorizationException(String message)
-   {
-      super(message);
-   }
-}

Deleted: trunk/src/main/org/jboss/seam/security/Configuration.java
===================================================================
--- trunk/src/main/org/jboss/seam/security/Configuration.java	2009-04-19 09:32:07 UTC (rev 10475)
+++ trunk/src/main/org/jboss/seam/security/Configuration.java	2009-04-19 09:44:29 UTC (rev 10476)
@@ -1,75 +0,0 @@
-package org.jboss.seam.security;
-
-import static org.jboss.seam.ScopeType.APPLICATION;
-import static org.jboss.seam.annotations.Install.BUILT_IN;
-
-import java.util.HashMap;
-
-import javax.security.auth.login.AppConfigurationEntry;
-import javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag;
-
-import org.jboss.seam.Component;
-import org.jboss.seam.ScopeType;
-import org.jboss.seam.annotations.Factory;
-import org.jboss.seam.annotations.Install;
-import org.jboss.seam.annotations.Name;
-import org.jboss.seam.annotations.Scope;
-import org.jboss.seam.annotations.intercept.BypassInterceptors;
-import org.jboss.seam.contexts.Contexts;
-import org.jboss.seam.security.jaas.SeamLoginModule;
-
-/**
- * Factory for the JAAS Configuration used by Seam Security.
- * 
- * @author Shane Bryzak
- *
- */
- at Name("org.jboss.seam.security.configurationFactory")
- at BypassInterceptors
- at Scope(ScopeType.STATELESS)
- at Install(precedence = BUILT_IN)
-public class Configuration
-{
-   static final String DEFAULT_JAAS_CONFIG_NAME = "default";   
-
-   protected javax.security.auth.login.Configuration createConfiguration()
-   {
-      return new javax.security.auth.login.Configuration()
-      {
-         private AppConfigurationEntry[] aces = { createAppConfigurationEntry() };
-         
-         @Override
-         public AppConfigurationEntry[] getAppConfigurationEntry(String name)
-         {
-            return DEFAULT_JAAS_CONFIG_NAME.equals(name) ? aces : null;
-         }
-         
-         @Override
-         public void refresh() {}
-      };
-   }
-
-   protected AppConfigurationEntry createAppConfigurationEntry()
-   {
-      return new AppConfigurationEntry( 
-            SeamLoginModule.class.getName(), 
-            LoginModuleControlFlag.REQUIRED, 
-            new HashMap<String,String>() 
-         );
-   }
-   
-   @Factory(value="org.jboss.seam.security.configuration", autoCreate=true, scope=APPLICATION)
-   public javax.security.auth.login.Configuration getConfiguration()
-   {
-      return createConfiguration();
-   }
-
-   public static javax.security.auth.login.Configuration instance()
-   {
-      if ( !Contexts.isApplicationContextActive() )
-      {
-         throw new IllegalStateException("No active application scope");
-      }
-      return (javax.security.auth.login.Configuration) Component.getInstance("org.jboss.seam.security.configuration");
-   }
-}

Deleted: trunk/src/main/org/jboss/seam/security/Credentials.java
===================================================================
--- trunk/src/main/org/jboss/seam/security/Credentials.java	2009-04-19 09:32:07 UTC (rev 10475)
+++ trunk/src/main/org/jboss/seam/security/Credentials.java	2009-04-19 09:44:29 UTC (rev 10476)
@@ -1,139 +0,0 @@
-package org.jboss.seam.security;
-
-import static org.jboss.seam.ScopeType.SESSION;
-import static org.jboss.seam.annotations.Install.BUILT_IN;
-
-import java.io.IOException;
-import java.io.Serializable;
-
-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.callback.UnsupportedCallbackException;
-
-import org.jboss.seam.annotations.Install;
-import org.jboss.seam.annotations.Name;
-import org.jboss.seam.annotations.Scope;
-import org.jboss.seam.annotations.intercept.BypassInterceptors;
-import org.jboss.seam.core.Events;
-import org.jboss.seam.log.LogProvider;
-import org.jboss.seam.log.Logging;
-
- at Name("org.jboss.seam.security.credentials")
- at Scope(SESSION)
- at Install(precedence = BUILT_IN)
- at BypassInterceptors
-public class Credentials implements Serializable
-{
-   public static final String EVENT_INIT_CREDENTIALS = "org.jboss.seam.security.initCredentials";
-   public static final String EVENT_CREDENTIALS_UPDATED = "org.jboss.seam.security.credentialsUpdated";
-   
-   private static final LogProvider log = Logging.getLogProvider(Credentials.class);
-   
-   private String username;
-   private String password;
-   
-   private boolean invalid = false;
-   
-   private boolean initialized;
-   
-   public boolean isInitialized()
-   {
-      return initialized;
-   }
-   
-   public void setInitialized(boolean initialized)
-   {
-      this.initialized = initialized;
-   }
-   
-   public String getUsername()
-   {
-      if (!isInitialized() && Events.exists())
-      {
-         setInitialized(true);
-         Events.instance().raiseEvent(EVENT_INIT_CREDENTIALS, this);
-      }
-      
-      return username;
-   }
-   
-   public void setUsername(String username)
-   {
-      if (this.username != username && (this.username == null || !this.username.equals(username)))
-      {
-         this.username = username;
-         invalid = false;
-         if (Events.exists()) Events.instance().raiseEvent(EVENT_CREDENTIALS_UPDATED);
-      }
-   }
-   
-   public String getPassword()
-   {
-      return password;
-   }
-   
-   public void setPassword(String password)
-   {
-      if (this.password != password && (this.password == null || !this.password.equals(password)))
-      {
-         this.password = password;
-         invalid = false;
-         if (Events.exists()) Events.instance().raiseEvent(EVENT_CREDENTIALS_UPDATED);
-      } 
-   }
-   
-   public boolean isSet()
-   {
-      return getUsername() != null && password != null;      
-   }
-   
-   public boolean isInvalid()
-   {
-      return invalid;
-   }
-   
-   public void invalidate()
-   {
-      invalid = true;
-   }
-   
-   public void clear()
-   {
-      username = null;
-      password = null;
-   }
-   
-   
-   /**
-    * Creates a callback handler that can handle a standard username/password
-    * callback, using the username and password properties.
-    */
-   public CallbackHandler createCallbackHandler()
-   {
-      return new CallbackHandler() 
-      {
-         public void handle(Callback[] callbacks) 
-            throws IOException, UnsupportedCallbackException 
-         {
-            for (int i=0; i < callbacks.length; i++)
-            {
-               if (callbacks[i] instanceof NameCallback)
-               {
-                  ( (NameCallback) callbacks[i] ).setName(getUsername());
-               }
-               else if (callbacks[i] instanceof PasswordCallback)
-               {
-                  ( (PasswordCallback) callbacks[i] ).setPassword( getPassword() != null ? 
-                           getPassword().toCharArray() : null );
-               }
-               else
-               {
-                  log.warn("Unsupported callback " + callbacks[i]);
-               }
-            }
-         }
-      };
-   }   
-}

Deleted: trunk/src/main/org/jboss/seam/security/EntityAction.java
===================================================================
--- trunk/src/main/org/jboss/seam/security/EntityAction.java	2009-04-19 09:32:07 UTC (rev 10475)
+++ trunk/src/main/org/jboss/seam/security/EntityAction.java	2009-04-19 09:44:29 UTC (rev 10476)
@@ -1,23 +0,0 @@
-package org.jboss.seam.security;
-
-/**
- * Actions that may be performed upon entities
- * in JPA or Hibernate.
- * 
- * @author Shane Bryzak
- * 
- */
-public enum EntityAction { 
-   
-   READ, 
-   INSERT, 
-   UPDATE, 
-   DELETE;
-   
-   @Override
-   public String toString()
-   {
-      return super.name().toLowerCase();
-   }
-   
-}
\ No newline at end of file

Deleted: trunk/src/main/org/jboss/seam/security/EntityPermissionChecker.java
===================================================================
--- trunk/src/main/org/jboss/seam/security/EntityPermissionChecker.java	2009-04-19 09:32:07 UTC (rev 10475)
+++ trunk/src/main/org/jboss/seam/security/EntityPermissionChecker.java	2009-04-19 09:44:29 UTC (rev 10476)
@@ -1,124 +0,0 @@
-package org.jboss.seam.security;
-
-import static org.jboss.seam.ScopeType.APPLICATION;
-import static org.jboss.seam.annotations.Install.BUILT_IN;
-
-import java.lang.reflect.Method;
-
-import javax.persistence.EntityManager;
-
-import org.jboss.seam.Component;
-import org.jboss.seam.ScopeType;
-import org.jboss.seam.annotations.Install;
-import org.jboss.seam.annotations.Name;
-import org.jboss.seam.annotations.Scope;
-import org.jboss.seam.annotations.Startup;
-import org.jboss.seam.annotations.intercept.BypassInterceptors;
-import org.jboss.seam.annotations.security.Restrict;
-import org.jboss.seam.contexts.Contexts;
-import org.jboss.seam.persistence.PersistenceProvider;
-import org.jboss.seam.util.Strings;
-
-/**
- * Entity permission checks
- * 
- * @author Shane Bryzak
- */
- at Name("org.jboss.seam.security.entityPermissionChecker")
- at Scope(APPLICATION)
- at Install(precedence = BUILT_IN)
- at BypassInterceptors
- at Startup
-public class EntityPermissionChecker
-{
-   private String entityManagerName = "entityManager";
-   
-   private EntityManager getEntityManager()
-   {
-      return (EntityManager) Component.getInstance(entityManagerName);
-   }
-   
-   public String getEntityManagerName()
-   {
-      return entityManagerName;
-   }
-   
-   public void setEntityManagerName(String name)
-   {
-      this.entityManagerName = name;
-   } 
-   
-   public static EntityPermissionChecker instance()
-   {
-      if ( !Contexts.isApplicationContextActive() )
-      {
-         throw new IllegalStateException("No active application context");
-      }
-
-      EntityPermissionChecker instance = (EntityPermissionChecker) Component.getInstance(
-            EntityPermissionChecker.class, ScopeType.APPLICATION);
-
-      if (instance == null)
-      {
-         throw new IllegalStateException("No EntityPermissionChecker could be created");
-      }
-
-      return instance;      
-   }
-   
-   public void checkEntityPermission(Object entity, EntityAction action)
-   {      
-      if (!Identity.isSecurityEnabled()) return;
-      
-      if (!Contexts.isSessionContextActive()) return;
-      
-      Identity identity = Identity.instance();
-      
-      identity.tryLogin();
-      
-      PersistenceProvider provider = PersistenceProvider.instance(); 
-      Class beanClass = provider.getBeanClass(entity);
-      
-      if (beanClass != null)
-      {        
-         Method m = null;
-         switch (action)
-         {
-            case READ:
-               m = provider.getPostLoadMethod(entity, getEntityManager());
-               break;
-            case INSERT:
-               m = provider.getPrePersistMethod(entity, getEntityManager());
-               break;
-            case UPDATE:
-               m = provider.getPreUpdateMethod(entity, getEntityManager());
-               break;
-            case DELETE:
-               m = provider.getPreRemoveMethod(entity, getEntityManager());
-         }
-         
-         Restrict restrict = null;
-         
-         if (m != null && m.isAnnotationPresent(Restrict.class))
-         {
-            restrict = m.getAnnotation(Restrict.class);
-         }
-         else if (entity.getClass().isAnnotationPresent(Restrict.class))
-         {
-            restrict = entity.getClass().getAnnotation(Restrict.class);
-         }
-
-         if (restrict != null)
-         {
-            if (Strings.isEmpty(restrict.value()))
-            {
-               identity.checkPermission(entity, action.toString());
-            }
-            else
-            {
-               identity.checkRestriction(restrict.value());
-            }
-         }
-      }
-   }  
-}

Deleted: trunk/src/main/org/jboss/seam/security/EntitySecurityListener.java
===================================================================
--- trunk/src/main/org/jboss/seam/security/EntitySecurityListener.java	2009-04-19 09:32:07 UTC (rev 10475)
+++ trunk/src/main/org/jboss/seam/security/EntitySecurityListener.java	2009-04-19 09:44:29 UTC (rev 10476)
@@ -1,44 +0,0 @@
-package org.jboss.seam.security;
-
-import static org.jboss.seam.security.EntityAction.DELETE;
-import static org.jboss.seam.security.EntityAction.INSERT;
-import static org.jboss.seam.security.EntityAction.READ;
-import static org.jboss.seam.security.EntityAction.UPDATE;
-
-import javax.persistence.PostLoad;
-import javax.persistence.PrePersist;
-import javax.persistence.PreRemove;
-import javax.persistence.PreUpdate;
-
-
-/**
- * Facilitates security checks for entity beans.
- * 
- * @author Shane Bryzak
- */
-public class EntitySecurityListener
-{
-   @PostLoad
-   public void postLoad(Object entity)
-   {
-      EntityPermissionChecker.instance().checkEntityPermission(entity, READ);
-   }
-   
-   @PrePersist
-   public void prePersist(Object entity)
-   { 
-      EntityPermissionChecker.instance().checkEntityPermission(entity, INSERT);
-   }
-   
-   @PreUpdate
-   public void preUpdate(Object entity)
-   {
-      EntityPermissionChecker.instance().checkEntityPermission(entity, UPDATE);
-   }
-   
-   @PreRemove
-   public void preRemove(Object entity)
-   {
-      EntityPermissionChecker.instance().checkEntityPermission(entity, DELETE);
-   }
-}

Deleted: trunk/src/main/org/jboss/seam/security/FacesSecurityEvents.java
===================================================================
--- trunk/src/main/org/jboss/seam/security/FacesSecurityEvents.java	2009-04-19 09:32:07 UTC (rev 10475)
+++ trunk/src/main/org/jboss/seam/security/FacesSecurityEvents.java	2009-04-19 09:44:29 UTC (rev 10476)
@@ -1,106 +0,0 @@
-package org.jboss.seam.security;
-
-import static org.jboss.seam.ScopeType.APPLICATION;
-import static org.jboss.seam.annotations.Install.BUILT_IN;
-
-import javax.security.auth.login.LoginException;
-
-import org.jboss.seam.annotations.Install;
-import org.jboss.seam.annotations.Name;
-import org.jboss.seam.annotations.Observer;
-import org.jboss.seam.annotations.Scope;
-import org.jboss.seam.annotations.Startup;
-import org.jboss.seam.annotations.intercept.BypassInterceptors;
-import org.jboss.seam.international.StatusMessages;
-import org.jboss.seam.international.StatusMessage.Severity;
-
-/**
- * Produces FacesMessages in response of certain security events, and helps to decouple the
- * Identity component from JSF.
- * 
- * @author Shane Bryzak
- */
- at Name("org.jboss.seam.security.facesSecurityEvents")
- at Scope(APPLICATION)
- at Install(precedence = BUILT_IN, classDependencies = "javax.faces.context.FacesContext")
- at BypassInterceptors
- at Startup
-public class FacesSecurityEvents 
-{  
-   @Observer(Identity.EVENT_POST_AUTHENTICATE)
-   public void postAuthenticate(Identity identity)
-   {         
-      //org.jboss.security.saml.SSOManager.processManualLoginNotification(
-            //ServletContexts.instance().getRequest(), identity.getPrincipal().getName());
-   }
-   
-   @Observer(Identity.EVENT_LOGIN_FAILED)
-   public void addLoginFailedMessage(LoginException ex)
-   {
-      StatusMessages.instance().addFromResourceBundleOrDefault(
-               getLoginFailedMessageSeverity(), 
-               getLoginFailedMessageKey(), 
-               getLoginFailedMessage(), 
-               ex);
-   }
-
-   public String getLoginFailedMessage()
-   {
-      return "Login failed";
-   }
-
-   public Severity getLoginFailedMessageSeverity()
-   {
-      return Severity.INFO;
-   }
-
-   public String getLoginFailedMessageKey()
-   {
-      return "org.jboss.seam.loginFailed";
-   }
-
-   @Observer(Identity.EVENT_LOGIN_SUCCESSFUL)
-   public void addLoginSuccessfulMessage()
-   {
-      StatusMessages.instance().addFromResourceBundleOrDefault(
-               getLoginSuccessfulMessageSeverity(), 
-               getLoginSuccessfulMessageKey(), 
-               getLoginSuccessfulMessage(), 
-               Identity.instance().getCredentials().getUsername());
-   }
-   
-   @Observer(Identity.EVENT_NOT_LOGGED_IN)
-   public void addNotLoggedInMessage()
-   {      
-      StatusMessages.instance().addFromResourceBundleOrDefault( 
-            Severity.WARN, 
-            "org.jboss.seam.NotLoggedIn", 
-            "Please log in first" 
-         );      
-   }
-
-   public Severity getLoginSuccessfulMessageSeverity()
-   {
-      return Severity.INFO;
-   }
-
-   public String getLoginSuccessfulMessage()
-   {
-      return "Welcome, #0";
-   }
-
-   public String getLoginSuccessfulMessageKey()
-   {
-      return "org.jboss.seam.loginSuccessful";
-   }   
-   
-   @Observer(Identity.EVENT_ALREADY_LOGGED_IN)
-   public void addAlreadyLoggedInMessage()
-   {
-      StatusMessages.instance().addFromResourceBundleOrDefault (
-         Severity.WARN,
-         "org.jboss.seam.AlreadyLoggedIn",
-         "You are already logged in, please log out first if you wish to log in again"
-      );
-   }
-}

Deleted: trunk/src/main/org/jboss/seam/security/HibernateSecurityInterceptor.java
===================================================================
--- trunk/src/main/org/jboss/seam/security/HibernateSecurityInterceptor.java	2009-04-19 09:32:07 UTC (rev 10475)
+++ trunk/src/main/org/jboss/seam/security/HibernateSecurityInterceptor.java	2009-04-19 09:44:29 UTC (rev 10476)
@@ -1,100 +0,0 @@
-package org.jboss.seam.security;
-
-import static org.jboss.seam.security.EntityAction.DELETE;
-import static org.jboss.seam.security.EntityAction.INSERT;
-import static org.jboss.seam.security.EntityAction.READ;
-import static org.jboss.seam.security.EntityAction.UPDATE;
-
-import java.io.Serializable;
-
-import org.hibernate.EmptyInterceptor;
-import org.hibernate.Interceptor;
-import org.hibernate.type.Type;
-import org.jboss.seam.Entity.NotEntityException;
-
-/**
- * Facilitates security checks for Hibernate entities
- * 
- * @author Shane Bryzak
- *
- */
-public class HibernateSecurityInterceptor extends EmptyInterceptor
-{
-   private Interceptor wrappedInterceptor;
-   
-   public HibernateSecurityInterceptor(Interceptor wrappedInterceptor)
-   {
-      this.wrappedInterceptor = wrappedInterceptor;
-   }
-   
-   @Override
-   public boolean onLoad(Object entity, Serializable id, Object[] state,
-                      String[] propertyNames, Type[] types)
-   {
-      try
-      {
-         EntityPermissionChecker.instance().checkEntityPermission(entity, READ);
-      }
-      catch (NotEntityException e) 
-      {
-         // Not a JPA entity
-      }
-      
-      return wrappedInterceptor != null ? 
-               wrappedInterceptor.onLoad(entity, id, state, propertyNames, types) : 
-               false;
-   }
-   
-   @Override
-   public void onDelete(Object entity, Serializable id, Object[] state, 
-                        String[] propertyNames, Type[] types)
-   {
-      try
-      {
-         EntityPermissionChecker.instance().checkEntityPermission(entity, DELETE);
-      }
-      catch (NotEntityException e) 
-      {
-         // Not a JPA entity
-      }
-      
-      if (wrappedInterceptor != null)
-         wrappedInterceptor.onDelete(entity, id, state, propertyNames, types);
-   }
-   
-   @Override
-   public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState,
-                   Object[] previousState, String[] propertyNames, Type[] types)
-   {
-      try
-      {
-         EntityPermissionChecker.instance().checkEntityPermission(entity, UPDATE);
-      }
-      catch (NotEntityException e) 
-      {
-         // Not a JPA entity
-      }
-      
-      return wrappedInterceptor != null ? 
-               wrappedInterceptor.onFlushDirty(entity, id, currentState, 
-                        previousState, propertyNames, types) : false;
-   }
-   
-   @Override
-   public boolean onSave(Object entity, Serializable id, Object[] state,
-                      String[] propertyNames, Type[] types)
-   {
-      try
-      {
-         EntityPermissionChecker.instance().checkEntityPermission(entity, INSERT);
-      }
-      catch (NotEntityException e) 
-      {
-         // Not a JPA entity
-      }
-      
-      return wrappedInterceptor != null ? 
-               wrappedInterceptor.onSave(entity, id, state, propertyNames, types) : 
-               false;
-   }       
-}

Deleted: trunk/src/main/org/jboss/seam/security/Identity.java
===================================================================
--- trunk/src/main/org/jboss/seam/security/Identity.java	2009-04-19 09:32:07 UTC (rev 10475)
+++ trunk/src/main/org/jboss/seam/security/Identity.java	2009-04-19 09:44:29 UTC (rev 10476)
@@ -1,752 +0,0 @@
-package org.jboss.seam.security;
-
-import static org.jboss.seam.ScopeType.SESSION;
-import static org.jboss.seam.annotations.Install.BUILT_IN;
-
-import java.io.Serializable;
-import java.security.Principal;
-import java.security.acl.Group;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Enumeration;
-import java.util.List;
-
-import javax.security.auth.Subject;
-import javax.security.auth.login.LoginContext;
-import javax.security.auth.login.LoginException;
-
-import org.jboss.seam.Component;
-import org.jboss.seam.ScopeType;
-import org.jboss.seam.annotations.Create;
-import org.jboss.seam.annotations.Install;
-import org.jboss.seam.annotations.Name;
-import org.jboss.seam.annotations.Scope;
-import org.jboss.seam.annotations.Startup;
-import org.jboss.seam.annotations.intercept.BypassInterceptors;
-import org.jboss.seam.contexts.Contexts;
-import org.jboss.seam.core.Events;
-import org.jboss.seam.core.Expressions;
-import org.jboss.seam.core.Expressions.MethodExpression;
-import org.jboss.seam.log.LogProvider;
-import org.jboss.seam.log.Logging;
-import org.jboss.seam.security.permission.PermissionMapper;
-import org.jboss.seam.web.Session;
-
-/**
- * API for authorization and authentication via Seam security. This base 
- * implementation supports role-based authorization only. Subclasses may add 
- * more sophisticated permissioning mechanisms.
- * 
- * @author Shane Bryzak
- */
- at Name("org.jboss.seam.security.identity")
- at Scope(SESSION)
- at Install(precedence = BUILT_IN)
- at BypassInterceptors
- at Startup
-public class Identity implements Serializable
-{  
-   private static final long serialVersionUID = 3751659008033189259L;
-   
-   // Event keys
-   public static final String EVENT_LOGIN_SUCCESSFUL = "org.jboss.seam.security.loginSuccessful";
-   public static final String EVENT_LOGIN_FAILED = "org.jboss.seam.security.loginFailed";
-   public static final String EVENT_NOT_LOGGED_IN = "org.jboss.seam.security.notLoggedIn";
-   public static final String EVENT_NOT_AUTHORIZED = "org.jboss.seam.security.notAuthorized";
-   public static final String EVENT_PRE_AUTHENTICATE = "org.jboss.seam.security.preAuthenticate";
-   public static final String EVENT_POST_AUTHENTICATE = "org.jboss.seam.security.postAuthenticate";
-   public static final String EVENT_LOGGED_OUT = "org.jboss.seam.security.loggedOut";
-   public static final String EVENT_ALREADY_LOGGED_IN = "org.jboss.seam.security.alreadyLoggedIn";
-   public static final String EVENT_QUIET_LOGIN = "org.jboss.seam.security.quietLogin";
-   
-   protected static boolean securityEnabled = true;
-   
-   public static final String ROLES_GROUP = "Roles";
-   
-   // Context variables
-   private static final String LOGIN_TRIED = "org.jboss.seam.security.loginTried";
-   private static final String SILENT_LOGIN = "org.jboss.seam.security.silentLogin";
-   
-   private static final LogProvider log = Logging.getLogProvider(Identity.class);
-   
-   private Credentials credentials;
-   
-   private MethodExpression authenticateMethod;
-
-   private Principal principal;   
-   private Subject subject;
-   
-   private RememberMe rememberMe;
-   
-   private transient ThreadLocal<Boolean> systemOp;
-   
-   private String jaasConfigName = null;
-   
-   private List<String> preAuthenticationRoles = new ArrayList<String>();
-   
-   private PermissionMapper permissionMapper;
-   
-   /**
-    * Flag that indicates we are in the process of authenticating
-    */
-   private boolean authenticating = false;
-         
-   @Create
-   public void create()
-   {     
-      subject = new Subject();
-      
-      if (Contexts.isApplicationContextActive())
-      {
-         permissionMapper = (PermissionMapper) Component.getInstance(PermissionMapper.class);                 
-      }    
-      
-      if (Contexts.isSessionContextActive())
-      {
-         rememberMe = (RememberMe) Component.getInstance(RememberMe.class, true);      
-         credentials = (Credentials) Component.getInstance(Credentials.class);         
-      }
-      
-      if (credentials == null)
-      {
-         // Must have credentials for unit tests
-         credentials = new Credentials();
-      }
-   }
-   
-   public static boolean isSecurityEnabled()
-   {
-      return securityEnabled;
-   }
-   
-   public static void setSecurityEnabled(boolean enabled)
-   {
-      securityEnabled = enabled;
-   }
-
-   public static Identity instance()
-   {
-      if ( !Contexts.isSessionContextActive() )
-      {
-         throw new IllegalStateException("No active session context");
-      }
-
-      Identity instance = (Identity) Component.getInstance(Identity.class, ScopeType.SESSION);
-
-      if (instance == null)
-      {
-         throw new IllegalStateException("No Identity could be created");
-      }
-
-      return instance;
-   }
-   
-   /**
-    * 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() &&
-            Contexts.isEventContextActive() &&
-            !Contexts.getEventContext().isSet(LOGIN_TRIED))
-        {
-           Contexts.getEventContext().set(LOGIN_TRIED, true);
-           quietLogin();
-        }     
-        
-        return isLoggedIn();      
-   }
-   
-   @Deprecated
-   public boolean isLoggedIn(boolean attemptLogin)
-   {
-      return attemptLogin ? tryLogin() : isLoggedIn();
-   }
-
-
-    public void acceptExternallyAuthenticatedPrincipal(Principal principal) {
-        getSubject().getPrincipals().add(principal);
-        this.principal = principal;
-    }
-
-   public Principal getPrincipal()
-   {
-      return principal;
-   }
-   
-   public Subject getSubject()
-   {
-      return subject;
-   }
-      
-   /**
-    * Performs an authorization check, based on the specified security expression.
-    * 
-    * @param expr The security expression to evaluate
-    * @throws NotLoggedInException Thrown if the authorization check fails and 
-    * the user is not authenticated
-    * @throws AuthorizationException Thrown if the authorization check fails and
-    * the user is authenticated
-    */
-   public void checkRestriction(String expr)
-   {      
-      if (!securityEnabled) return;
-      
-      if ( !evaluateExpression(expr) )
-      {
-         if ( !isLoggedIn() )
-         {           
-            if (Events.exists()) Events.instance().raiseEvent(EVENT_NOT_LOGGED_IN);
-            log.debug(String.format(
-               "Error evaluating expression [%s] - User not logged in", expr));
-            throw new NotLoggedInException();
-         }
-         else
-         {
-            if (Events.exists()) Events.instance().raiseEvent(EVENT_NOT_AUTHORIZED);
-            throw new AuthorizationException(String.format(
-               "Authorization check failed for expression [%s]", expr));
-         }
-      }
-   }
-
-   /**
-    * 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
-      {            
-         if (isLoggedIn())
-         {
-            // If authentication has already occurred during this request via a silent login,
-            // and login() is explicitly called then we still want to raise the LOGIN_SUCCESSFUL event,
-            // and then return.
-            if (Contexts.isEventContextActive() && Contexts.getEventContext().isSet(SILENT_LOGIN))
-            {
-               if (Events.exists()) Events.instance().raiseEvent(EVENT_LOGIN_SUCCESSFUL);
-               return "loggedIn";            
-            }            
-            
-            if (Events.exists()) Events.instance().raiseEvent(EVENT_ALREADY_LOGGED_IN);
-            return "loggedIn";           
-         }
-         
-         authenticate();
-         
-         if (!isLoggedIn())
-         {
-            throw new LoginException();
-         }
-         
-         if ( log.isDebugEnabled() )
-         {
-            log.debug("Login successful for: " + getCredentials().getUsername());
-         }
-
-         if (Events.exists()) Events.instance().raiseEvent(EVENT_LOGIN_SUCCESSFUL);
-         return "loggedIn";
-      }
-      catch (LoginException ex)
-      {
-         credentials.invalidate();
-         
-         if ( log.isDebugEnabled() )
-         {
-             log.debug("Login failed for: " + getCredentials().getUsername(), ex);
-         }
-         if (Events.exists()) Events.instance().raiseEvent(EVENT_LOGIN_FAILED, ex);
-      }
-      
-      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
-      {
-         if (Events.exists()) Events.instance().raiseEvent(EVENT_QUIET_LOGIN);         
-          
-         // Ensure that we haven't been authenticated as a result of the EVENT_QUIET_LOGIN event
-         if (!isLoggedIn())
-         {
-            if (credentials.isSet()) 
-            {
-               authenticate();
-               if (isLoggedIn() && Contexts.isEventContextActive())
-               {
-                  Contexts.getEventContext().set(SILENT_LOGIN, true);
-               }
-            }
-         }
-      }
-      catch (LoginException ex) 
-      { 
-         credentials.invalidate();
-      }
-   }
-   
-
-
-   /**
-    * 
-    * @throws LoginException
-    */
-   public synchronized void authenticate() 
-      throws LoginException
-   {
-      // If we're already authenticated, then don't authenticate again
-      if (!isLoggedIn() && !credentials.isInvalid())
-      {
-         principal = null;
-         subject = new Subject();
-         authenticate( getLoginContext() );
-      }      
-   }
-
-    
-   protected void authenticate(LoginContext loginContext) 
-      throws LoginException
-   {
-      try
-      {
-         authenticating = true;
-         preAuthenticate();
-         loginContext.login();
-         postAuthenticate();
-      }
-      finally
-      {
-         // Set password to null whether authentication is successful or not
-         credentials.setPassword(null);    
-         authenticating = false;
-      }
-   }
-   
-   /**
-    * Clears any roles added by calling addRole() while not authenticated.  
-    * This method may be overridden by a subclass if different 
-    * pre-authentication logic should occur.
-    */
-   protected void preAuthenticate()
-   {     
-      preAuthenticationRoles.clear();      
-      if (Events.exists()) Events.instance().raiseEvent(EVENT_PRE_AUTHENTICATE);
-   }   
-   
-   /**
-    * Extracts the principal from the subject, and populates the roles of the
-    * authenticated user.  This method may be overridden by a subclass if
-    * different post-authentication logic should occur.
-    */
-   protected void postAuthenticate()
-   {
-      // Populate the working memory with the user's principals
-      for ( Principal p : getSubject().getPrincipals() )
-      {         
-         if ( !(p instanceof Group))
-         {
-            if (principal == null) 
-            {
-               principal = p;
-               break;
-            }            
-         }         
-      }      
-      
-      if (!preAuthenticationRoles.isEmpty() && isLoggedIn())
-      {
-         for (String role : preAuthenticationRoles)
-         {
-            addRole(role);
-         }
-         preAuthenticationRoles.clear();
-      }
-
-      credentials.setPassword(null);
-      
-      if (Events.exists()) Events.instance().raiseEvent(EVENT_POST_AUTHENTICATE, this);      
-   }
-   
-   /**
-    * Resets all security state and credentials
-    */
-   public void unAuthenticate()
-   {      
-      principal = null;
-      subject = new Subject();
-      
-      credentials.clear();
-   }
-
-   protected LoginContext getLoginContext() throws LoginException
-   {
-      if (getJaasConfigName() != null)
-      {
-         return new LoginContext(getJaasConfigName(), getSubject(), 
-                  credentials.createCallbackHandler());
-      }
-      
-      return new LoginContext(Configuration.DEFAULT_JAAS_CONFIG_NAME, getSubject(), 
-            credentials.createCallbackHandler(), Configuration.instance());
-   }
-   
-   public void logout()
-   {
-      if (isLoggedIn())
-      {
-         unAuthenticate();
-         Session.instance().invalidate();
-         if (Events.exists()) Events.instance().raiseEvent(EVENT_LOGGED_OUT);
-      }
-   }
-
-   /**
-    * 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;
-      if (systemOp != null && Boolean.TRUE.equals(systemOp.get())) return true;
-      
-      tryLogin();
-      
-      for ( Group sg : getSubject().getPrincipals(Group.class) )      
-      {
-         if ( ROLES_GROUP.equals( sg.getName() ) )
-         {
-            return sg.isMember( new Role(role) );
-         }
-      }
-      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;
-      
-      if (!isLoggedIn())
-      {
-         preAuthenticationRoles.add(role);
-         return false;
-      }
-      else
-      {
-         for ( Group sg : getSubject().getPrincipals(Group.class) )      
-         {
-            if ( ROLES_GROUP.equals( sg.getName() ) )
-            {
-               return sg.addMember(new Role(role));
-            }
-         }
-                  
-         SimpleGroup roleGroup = new SimpleGroup(ROLES_GROUP);
-         roleGroup.addMember(new Role(role));
-         getSubject().getPrincipals().add(roleGroup);
-         return true;
-      }
-   }
-
-   /**
-    * Removes a role from the authenticated user
-    * 
-    * @param role The name of the role to remove
-    */
-   public void removeRole(String role)
-   {     
-      for ( Group sg : getSubject().getPrincipals(Group.class) )      
-      {
-         if ( ROLES_GROUP.equals( sg.getName() ) )
-         {
-            Enumeration e = sg.members();
-            while (e.hasMoreElements())
-            {
-               Principal member = (Principal) e.nextElement();
-               if (member.getName().equals(role))
-               {
-                  sg.removeMember(member);
-                  break;
-               }
-            }
-
-         }
-      }      
-   }   
-   
-   /**
-    * 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();
-      
-      if ( !hasRole(role) )
-      {
-         if ( !isLoggedIn() )
-         {           
-            if (Events.exists()) Events.instance().raiseEvent(EVENT_NOT_LOGGED_IN);
-            throw new NotLoggedInException();
-         }
-         else
-         {
-            if (Events.exists()) Events.instance().raiseEvent(EVENT_NOT_AUTHORIZED);
-            throw new AuthorizationException(String.format(
-                  "Authorization check failed for role [%s]", role));
-         }
-      }
-   }
-
-   /**
-    * Checks that the current authenticated user has permission for
-    * the specified name and action
-    * 
-    * @param name String The permission name
-    * @param action String The permission action
-    * @param arg Object Optional object parameter used to make a permission decision
-    * @throws AuthorizationException if the user does not have the specified permission
-    */
-   public void checkPermission(String name, String action, Object...arg)
-   {
-      if (systemOp != null && Boolean.TRUE.equals(systemOp.get())) return; 
-      
-      tryLogin();
-      
-      if ( !hasPermission(name, action, arg) )
-      {
-         if ( !isLoggedIn() )
-         {
-            if (Events.exists()) Events.instance().raiseEvent(EVENT_NOT_LOGGED_IN);
-            throw new NotLoggedInException();
-         }
-         else
-         {
-            if (Events.exists()) Events.instance().raiseEvent(EVENT_NOT_AUTHORIZED);
-            throw new AuthorizationException(String.format(
-                  "Authorization check failed for permission [%s,%s]", name, action));
-         }
-      }
-   }
-   
-   public void checkPermission(Object target, String action)
-   {
-      if (systemOp != null && Boolean.TRUE.equals(systemOp.get())) return;
-      
-      tryLogin();
-      
-      if ( !hasPermission(target, action) )
-      {
-         if ( !isLoggedIn() )
-         {
-            if (Events.exists()) Events.instance().raiseEvent(EVENT_NOT_LOGGED_IN);
-            throw new NotLoggedInException();            
-         }
-         else
-         {
-            if (Events.exists()) Events.instance().raiseEvent(EVENT_NOT_AUTHORIZED);
-            throw new AuthorizationException(String.format(
-                  "Authorization check failed for permission[%s,%s]", target, action));
-         }
-      }
-   }
-
-   /**
-    * Performs a permission check for the specified name and action
-    * 
-    * @param name String The permission name
-    * @param action String The permission action
-    * @param arg Object Optional object parameter used to make a permission decision
-    * @return boolean True if the user has the specified permission
-    */
-   public boolean hasPermission(String name, String action, Object...arg)
-   {      
-      if (!securityEnabled) return true;
-      if (systemOp != null && Boolean.TRUE.equals(systemOp.get())) return true;   
-      if (permissionMapper == null) return false;
-         
-      if (arg != null)
-      {
-         return permissionMapper.resolvePermission(arg[0], action);
-      }
-      else
-      {
-         return permissionMapper.resolvePermission(name, action);
-      }
-   }   
-   
-   public void filterByPermission(Collection collection, String action)
-   {
-      permissionMapper.filterByPermission(collection, action);  
-   }
-   
-   public boolean hasPermission(Object target, String action)
-   {
-      if (!securityEnabled) return true;
-      if (systemOp != null && Boolean.TRUE.equals(systemOp.get())) return true;     
-      if (permissionMapper == null) return false;
-      if (target == null) return false;
-      
-      return permissionMapper.resolvePermission(target, action);
-   }
-   
-   /**
-    * Evaluates the specified security expression, which must return a boolean
-    * value.
-    * 
-    * @param expr String The expression to evaluate
-    * @return boolean The result of the expression evaluation
-    */
-   protected boolean evaluateExpression(String expr) 
-   {         
-      return Expressions.instance().createValueExpression(expr, Boolean.class).getValue();
-   }   
-   
-   /**
-    * @see org.jboss.seam.security.Credentials#getUsername()
-    */
-   @Deprecated
-   public String getUsername()
-   {
-      return credentials.getUsername();
-   }
-
-   /**
-    * @see org.jboss.seam.security.Credentials#setUsername(String)
-    */
-   @Deprecated
-   public void setUsername(String username)
-   {  
-      credentials.setUsername(username);
-   }
-
-   /**
-    * @see org.jboss.seam.security.Credentials#getPassword()
-    */
-   @Deprecated
-   public String getPassword()
-   {
-      return credentials.getPassword();
-   }
-   
-   /**
-    * @see org.jboss.seam.security.Credentials#setPassword(String)
-    */   
-   @Deprecated
-   public void setPassword(String password)
-   {
-      credentials.setPassword(password);
-   }   
-   
-   /**
-    * @see org.jboss.seam.security.RememberMe#isEnabled()
-    */
-   @Deprecated
-   public boolean isRememberMe()
-   {
-      return rememberMe != null ? rememberMe.isEnabled() : false;
-   }
-   
-   /**
-    * @see org.jboss.seam.security.RememberMe#setEnabled(boolean)
-    */
-   @Deprecated
-   public void setRememberMe(boolean remember)
-   {
-      if (rememberMe != null) rememberMe.setEnabled(remember);
-   }   
-   
-   public Credentials getCredentials()
-   {
-      return credentials;
-   }   
-   
-   public MethodExpression getAuthenticateMethod()
-   {
-      return authenticateMethod;
-   }
-   
-   public void setAuthenticateMethod(MethodExpression authMethod)
-   {
-      this.authenticateMethod = authMethod;
-   }
-   
-   public String getJaasConfigName()
-   {
-      return jaasConfigName;
-   }
-   
-   public void setJaasConfigName(String jaasConfigName)
-   {
-      this.jaasConfigName = jaasConfigName;
-   }
-   
-   synchronized void runAs(RunAsOperation operation)
-   {
-      Principal savedPrincipal = getPrincipal();
-      Subject savedSubject = getSubject();
-      
-      try
-      {
-         principal = operation.getPrincipal();
-         subject = operation.getSubject();
-         
-         if (systemOp == null)
-         {
-            systemOp = new ThreadLocal<Boolean>();
-         }
-         
-         systemOp.set(operation.isSystemOperation());
-         
-         operation.execute();
-      }
-      finally
-      {
-         systemOp.set(false);
-         principal = savedPrincipal;
-         subject = savedSubject;
-      }
-   } 
-}

Deleted: trunk/src/main/org/jboss/seam/security/JpaTokenStore.java
===================================================================
--- trunk/src/main/org/jboss/seam/security/JpaTokenStore.java	2009-04-19 09:32:07 UTC (rev 10475)
+++ trunk/src/main/org/jboss/seam/security/JpaTokenStore.java	2009-04-19 09:44:29 UTC (rev 10476)
@@ -1,165 +0,0 @@
-package org.jboss.seam.security;
-
-import static org.jboss.seam.ScopeType.APPLICATION;
-import static org.jboss.seam.annotations.Install.BUILT_IN;
-
-import java.io.Serializable;
-
-import javax.persistence.EntityManager;
-import javax.persistence.NoResultException;
-import javax.persistence.Query;
-
-import org.jboss.seam.annotations.Create;
-import org.jboss.seam.annotations.Install;
-import org.jboss.seam.annotations.Name;
-import org.jboss.seam.annotations.Scope;
-import org.jboss.seam.annotations.intercept.BypassInterceptors;
-import org.jboss.seam.annotations.security.TokenUsername;
-import org.jboss.seam.annotations.security.TokenValue;
-import org.jboss.seam.core.Expressions;
-import org.jboss.seam.core.Expressions.ValueExpression;
-import org.jboss.seam.security.management.IdentityManagementException;
-import org.jboss.seam.util.AnnotatedBeanProperty;
-
-/**
- * A TokenStore implementation, stores tokens inside a database table.
- * 
- * @author Shane Bryzak
- */
- at Name("org.jboss.seam.security.tokenStore")
- at Install(precedence = BUILT_IN, value=false) 
- at Scope(APPLICATION)
- at BypassInterceptors
-public class JpaTokenStore implements TokenStore, Serializable
-{
-   private Class tokenClass;
-   
-   private ValueExpression<EntityManager> entityManager;    
-   
-   private AnnotatedBeanProperty<TokenUsername> tokenUsernameProperty;
-   private AnnotatedBeanProperty<TokenValue> tokenValueProperty;
-   
-   @Create
-   public void create()
-   {
-      if (entityManager == null)
-      {
-         entityManager = Expressions.instance().createValueExpression("#{entityManager}", EntityManager.class);
-      }       
-      
-      tokenUsernameProperty = new AnnotatedBeanProperty<TokenUsername>(tokenClass, TokenUsername.class);
-      tokenValueProperty = new AnnotatedBeanProperty<TokenValue>(tokenClass, TokenValue.class);
-      
-      if (!tokenUsernameProperty.isSet()) 
-      {
-         throw new IllegalStateException("Invalid tokenClass " + tokenClass.getName() + 
-               " - required annotation @TokenUsername not found on any Field or Method.");
-      }
-      
-      if (!tokenValueProperty.isSet()) 
-      {
-         throw new IllegalStateException("Invalid tokenClass " + tokenClass.getName() + 
-               " - required annotation @TokenValue not found on any Field or Method.");
-      }       
-   }
-   
-   public void createToken(String username, String value)
-   {
-      if (tokenClass == null)
-      {
-         throw new IllegalStateException("Could not create token, tokenClass not set");
-      }   
-      
-      try
-      {
-         Object token = tokenClass.newInstance();
-         
-         tokenUsernameProperty.setValue(token, username);
-         tokenValueProperty.setValue(token, value);
-         
-         lookupEntityManager().persist(token);
-      }
-      catch (Exception ex)
-      {
-         if (ex instanceof IdentityManagementException)
-         {
-            throw (IdentityManagementException) ex;
-         }
-         else
-         {
-            throw new IdentityManagementException("Could not create account", ex);
-         }
-      }       
-   }
-   
-   public boolean validateToken(String username, String value)
-   {
-      return lookupToken(username, value) != null;
-   }
-   
-   public void invalidateToken(String username, String value)
-   {
-      Object token = lookupToken(username, value);
-      if (token != null)
-      {
-         lookupEntityManager().remove(token);
-      }
-   }
-   
-   public void invalidateAll(String username)
-   {
-      Query query = lookupEntityManager().createQuery(
-         "select t from " + tokenClass.getName() + " t where " + tokenUsernameProperty.getName() +
-         " = :username")
-         .setParameter("username", username);
-      
-      for (Object token : query.getResultList())
-      {
-         lookupEntityManager().remove(token);
-      }      
-   }
-   
-   public Object lookupToken(String username, String value)       
-   {
-      try
-      {
-         Object token = lookupEntityManager().createQuery(
-            "select t from " + tokenClass.getName() + " t where " + tokenUsernameProperty.getName() +
-            " = :username and " + tokenValueProperty.getName() + " = :value")
-            .setParameter("username", username)
-            .setParameter("value", value)
-            .getSingleResult();
-         
-         return token;
-      }
-      catch (NoResultException ex)
-      {
-         return null;        
-      }      
-   }   
-   
-   public Class getTokenClass()
-   {
-      return tokenClass;
-   }
-   
-   public void setTokenClass(Class tokenClass)
-   {
-      this.tokenClass = tokenClass;
-   }
-   
-   private EntityManager lookupEntityManager()
-   {
-      return entityManager.getValue();
-   }
-   
-   public ValueExpression getEntityManager()
-   {
-      return entityManager;
-   }
-   
-   public void setEntityManager(ValueExpression expression)
-   {
-      this.entityManager = expression;
-   }    
-}

Deleted: trunk/src/main/org/jboss/seam/security/NotLoggedInException.java
===================================================================
--- trunk/src/main/org/jboss/seam/security/NotLoggedInException.java	2009-04-19 09:32:07 UTC (rev 10475)
+++ trunk/src/main/org/jboss/seam/security/NotLoggedInException.java	2009-04-19 09:44:29 UTC (rev 10476)
@@ -1,11 +0,0 @@
-package org.jboss.seam.security;
-
-import javax.ejb.ApplicationException;
-
-/**
- * Thrown when an unauthenticated user attempts to execute a restricted action. 
- * 
- * @author Shane Bryzak
- */
- at ApplicationException(rollback=true)
-public class NotLoggedInException extends RuntimeException {}

Deleted: trunk/src/main/org/jboss/seam/security/RememberMe.java
===================================================================
--- trunk/src/main/org/jboss/seam/security/RememberMe.java	2009-04-19 09:32:07 UTC (rev 10475)
+++ trunk/src/main/org/jboss/seam/security/RememberMe.java	2009-04-19 09:44:29 UTC (rev 10476)
@@ -1,410 +0,0 @@
-package org.jboss.seam.security;
-
-import static org.jboss.seam.ScopeType.SESSION;
-import static org.jboss.seam.annotations.Install.BUILT_IN;
-
-import java.io.Serializable;
-import java.rmi.server.UID;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Random;
-
-import javax.faces.context.FacesContext;
-
-import org.jboss.seam.Component;
-import org.jboss.seam.annotations.Create;
-import org.jboss.seam.annotations.Install;
-import org.jboss.seam.annotations.Name;
-import org.jboss.seam.annotations.Observer;
-import org.jboss.seam.annotations.Scope;
-import org.jboss.seam.annotations.intercept.BypassInterceptors;
-import org.jboss.seam.faces.Selector;
-import org.jboss.seam.security.management.IdentityManager;
-import org.jboss.seam.util.Base64;
-
-/**
- * Remember-me functionality is provided by this class, in two different flavours.  The first mode
- * provides username-only persistence, and is considered to be secure as the user (or their browser)
- * is still required to provide a password.  The second mode provides an auto-login feature, however
- * is NOT considered to be secure and is vulnerable to XSS attacks compromising the user's account.
- * 
- * Use the auto-login mode with caution!
- * 
- * @author Shane Bryzak
- */
- at Name("org.jboss.seam.security.rememberMe")
- at Scope(SESSION)
- at Install(precedence = BUILT_IN, classDependencies = "javax.faces.context.FacesContext")
- at BypassInterceptors
-public class RememberMe implements Serializable
-{
-   class UsernameSelector extends Selector
-   {
-      @Override
-      public String getCookieName()
-      {
-         return "org.jboss.seam.security.username";
-      }       
-      
-      @Override
-      public void setDirty()
-      {
-         super.setDirty();
-      }
-      
-      @Override
-      public String getCookieValue()
-      {
-         return super.getCookieValue();
-      }
-      
-      @Override
-      public void clearCookieValue()
-      {
-         super.clearCookieValue();
-      }
-      
-      @Override
-      public void setCookieValueIfEnabled(String value)
-      {
-         super.setCookieValueIfEnabled(value);
-      }
-   }
-   
-   class TokenSelector extends UsernameSelector
-   {
-      @Override
-      public String getCookieName()
-      {
-         return "org.jboss.seam.security.authtoken";
-      }
-   }
-   
-   private class DecodedToken
-   {
-      private String username;
-      private String value;
-      
-      public DecodedToken(String cookieValue)
-      {
-         if (cookieValue != null)
-         {
-            try
-            {
-               String decoded = new String(Base64.decode(cookieValue));         
-               username = decoded.substring(0, decoded.indexOf(':'));
-               value = decoded.substring(decoded.indexOf(':') + 1);
-            }
-            catch (Exception ex)
-            {
-               // swallow
-            }
-         }
-      }
-      
-      public String getUsername()
-      {
-         return username;
-      }
-      
-      public String getValue()
-      {
-         return value;
-      }
-   }
-      
-   private UsernameSelector usernameSelector;
-   
-   private TokenSelector tokenSelector;   
-   private TokenStore tokenStore;
-      
-   private boolean enabled;
-
-   private int cookieMaxAge = Selector.DEFAULT_MAX_AGE;
-   
-   private boolean autoLoggedIn;
-   
-   private Random random = new Random(System.currentTimeMillis());
-   
-   public enum Mode { disabled, usernameOnly, autoLogin}
-   
-   private Mode mode = Mode.usernameOnly;
-   
-   public Mode getMode()
-   {
-      return mode;
-   }
-   
-   public void setMode(Mode mode)
-   {
-      this.mode = mode;
-   }
-   
-   public boolean isEnabled()
-   {
-      return enabled;
-   }
-   
-   public void setEnabled(boolean enabled)
-   {
-      if (this.enabled != enabled)
-      {
-         this.enabled = enabled;
-         // selector is null during component initialization (setup handled in @Create method)
-         if (usernameSelector != null && mode.equals(Mode.usernameOnly))
-         {
-            usernameSelector.setCookieEnabled(enabled);
-            usernameSelector.setDirty();
-         }
-         // selector is null during component initialization (setup handled in @Create method)
-         else if (tokenSelector != null && mode.equals(Mode.autoLogin))
-         {
-            tokenSelector.setCookieEnabled(enabled);
-            tokenSelector.setDirty();
-         }
-      }      
-   }
-
-   public int getCookieMaxAge() {
-       return cookieMaxAge;
-   }
-
-   public void setCookieMaxAge(int cookieMaxAge) {
-       this.cookieMaxAge = cookieMaxAge;
-   }
-   
-   public TokenStore getTokenStore()
-   {
-      return tokenStore;
-   }
-   
-   public void setTokenStore(TokenStore tokenStore)
-   {
-      this.tokenStore = tokenStore;
-   }
-   
-   @Create
-   public void create()
-   {
-      if (mode.equals(Mode.usernameOnly))
-      {      
-         usernameSelector = new UsernameSelector();
-         usernameSelector.setCookieEnabled(enabled);
-      }
-      else if (mode.equals(Mode.autoLogin))
-      {
-         tokenSelector = new TokenSelector();
-         tokenSelector.setCookieEnabled(enabled);
-
-         // Default to JpaTokenStore
-         if (tokenStore == null)
-         {
-            tokenStore = (TokenStore) Component.getInstance(JpaTokenStore.class, true);
-         }         
-      }
-   }
-   
-   protected String generateTokenValue()
-   {
-      StringBuilder sb = new StringBuilder();
-      sb.append(new UID().toString());
-      sb.append(":");
-      sb.append(random.nextLong());
-      return sb.toString();
-   }
-   
-   protected String encodeToken(String username, String value)
-   {
-      StringBuilder sb = new StringBuilder();
-      sb.append(username);
-      sb.append(":");
-      sb.append(value);
-      return Base64.encodeBytes(sb.toString().getBytes());      
-   }
-   
-   public String getCookiePath()
-   {
-      FacesContext ctx = FacesContext.getCurrentInstance();
-      return ctx != null ? ctx.getExternalContext().getRequestContextPath() : null;
-   }
-   
-   @Observer(Credentials.EVENT_INIT_CREDENTIALS)
-   public void initCredentials(Credentials credentials)
-   {     
-      String cookiePath = getCookiePath();
-      
-      if (mode.equals(Mode.usernameOnly))
-      {         
-         if (cookiePath != null)
-         {
-            usernameSelector.setCookiePath(cookiePath);
-         }
-         
-         String username = usernameSelector.getCookieValue();
-         if (username!=null)
-         {
-            setEnabled(true);
-            credentials.setUsername(username);
-         }
-               
-         usernameSelector.setDirty();
-      }
-      else if (mode.equals(Mode.autoLogin))
-      {
-         if (cookiePath != null)
-         {
-            tokenSelector.setCookiePath(cookiePath);
-         }
-         
-         String token = tokenSelector.getCookieValue();
-         if (token != null)
-         {
-            setEnabled(true);
-            
-            DecodedToken decoded = new DecodedToken(token);
-
-            if (tokenStore.validateToken(decoded.getUsername(), decoded.getValue()))
-            {
-               credentials.setUsername(decoded.getUsername());
-               credentials.setPassword(decoded.getValue());               
-            }
-            else
-            {
-               // Have we been compromised? Just in case, invalidate all authentication tokens
-               tokenStore.invalidateAll(decoded.getUsername());
-            }
-         }
-      }
-   }
-   
-   /**
-    * I hate these hacks... 
-    */
-   private class BoolWrapper 
-   {
-      boolean value;
-   }
-   
-   @Observer(Identity.EVENT_QUIET_LOGIN)
-   public void quietLogin()
-   {
-      final Identity identity = Identity.instance();
-      
-      if (mode.equals(Mode.autoLogin) && isEnabled())
-      {
-         final String username = identity.getCredentials().getUsername();    
-         final BoolWrapper userEnabled = new BoolWrapper();
-         final List<String> roles = new ArrayList<String>();
-         
-         // Double check our credentials again
-         if (tokenStore.validateToken(username, identity.getCredentials().getPassword()))
-         {            
-            new RunAsOperation(true) {
-               @Override
-               public void execute()
-               {        
-                  if (IdentityManager.instance().isUserEnabled(username))
-                  {
-                     userEnabled.value = true;
-
-                     for (String role : IdentityManager.instance().getImpliedRoles(username))
-                     {
-                        roles.add(role);
-                     }
-                  }
-               }
-            }.run();
-            
-            if (userEnabled.value)
-            {
-               identity.unAuthenticate();
-               identity.preAuthenticate();
-               
-               // populate the roles
-               for (String role : roles)
-               {
-                  identity.addRole(role);
-               }
-   
-               // Set the principal
-               identity.getSubject().getPrincipals().add(new SimplePrincipal(username));
-               identity.postAuthenticate();
-            
-               autoLoggedIn = true;
-            }
-         }            
-      }
-   }
-   
-   @Observer(Identity.EVENT_LOGGED_OUT)
-   public void loggedOut()
-   {
-      if (mode.equals(Mode.autoLogin))
-      {
-         tokenSelector.clearCookieValue();
-      }
-   }
-   
-   @Observer(Identity.EVENT_POST_AUTHENTICATE)
-   public void postAuthenticate(Identity identity)
-   {
-      if (mode.equals(Mode.usernameOnly))
-      {
-         // Password is set to null during authentication, so we set dirty
-         usernameSelector.setDirty();
-               
-         if ( !enabled )
-         {
-            usernameSelector.clearCookieValue();
-         }
-         else
-         {
-            usernameSelector.setCookieMaxAge(cookieMaxAge);
-            usernameSelector.setCookieValueIfEnabled( Identity.instance().getCredentials().getUsername() );
-         }
-      }
-      else if (mode.equals(Mode.autoLogin))
-      {
-         tokenSelector.setDirty();
-         
-         DecodedToken decoded = new DecodedToken(tokenSelector.getCookieValue());
-         
-         // Invalidate the current token (if it exists) whether enabled or not
-         if (decoded.getUsername() != null)
-         {
-            tokenStore.invalidateToken(decoded.getUsername(), decoded.getValue());
-         }
-         
-         if ( !enabled ) 
-         {
-            tokenSelector.clearCookieValue();         
-         }
-         else
-         {
-            String value = generateTokenValue();
-            tokenStore.createToken(identity.getPrincipal().getName(), value);
-            tokenSelector.setCookieEnabled(enabled);
-            tokenSelector.setCookieMaxAge(cookieMaxAge);
-            tokenSelector.setCookieValueIfEnabled(encodeToken(identity.getPrincipal().getName(), value));            
-         }
-      }
-   }        
-   
-   @Observer(Credentials.EVENT_CREDENTIALS_UPDATED)
-   public void credentialsUpdated()
-   {
-      if (mode.equals(Mode.usernameOnly)) 
-      {
-         usernameSelector.setDirty();
-      }      
-   }      
-   
-   /**
-    * A flag that an application can use to protect sensitive operations if the user has been
-    * auto-authenticated. 
-    */
-   public boolean isAutoLoggedIn()
-   {
-      return autoLoggedIn;
-   }
-}

Deleted: trunk/src/main/org/jboss/seam/security/Role.java
===================================================================
--- trunk/src/main/org/jboss/seam/security/Role.java	2009-04-19 09:32:07 UTC (rev 10475)
+++ trunk/src/main/org/jboss/seam/security/Role.java	2009-04-19 09:44:29 UTC (rev 10476)
@@ -1,28 +0,0 @@
-package org.jboss.seam.security;
-
-/**
- * Represents a user role.  A conditional role is a special type of role that is assigned to a user
- * based on the contextual state of a permission check.
- *  
- * @author Shane Bryzak
- */
-public class Role extends SimplePrincipal
-{   
-   private boolean conditional;
-   
-   public Role(String name)
-   {
-      super(name);
-   }   
-   
-   public Role(String name, boolean conditional)
-   {
-      this(name);
-      this.conditional = conditional;
-   }
-   
-   public boolean isConditional()
-   {
-      return conditional;
-   }
-}

Deleted: trunk/src/main/org/jboss/seam/security/RunAsOperation.java
===================================================================
--- trunk/src/main/org/jboss/seam/security/RunAsOperation.java	2009-04-19 09:32:07 UTC (rev 10475)
+++ trunk/src/main/org/jboss/seam/security/RunAsOperation.java	2009-04-19 09:44:29 UTC (rev 10476)
@@ -1,77 +0,0 @@
-package org.jboss.seam.security;
-
-import java.security.Principal;
-import java.security.acl.Group;
-
-import javax.security.auth.Subject;
-
-/**
- * Defines a security operation that can be executed within a particular 
- * security context.
- * 
- * @author Shane Bryzak
- */
-public abstract class RunAsOperation
-{
-   private Principal principal;
-   private Subject subject;
-   
-   private boolean systemOp = false;
-      
-   public RunAsOperation()
-   {
-      principal = new SimplePrincipal(null);  
-      subject = new Subject();
-   }
-   
-   /**
-    * A system operation allows any security checks to pass
-    * 
-    * @param systemOp
-    */
-   public RunAsOperation(boolean systemOp)
-   {      
-      this();
-      this.systemOp = systemOp;
-   }
-   
-   public abstract void execute();
-   
-   public Principal getPrincipal()
-   {
-      return principal;
-   }
-   
-   public Subject getSubject()
-   {
-      return subject;
-   }
-   
-   public RunAsOperation addRole(String role)
-   {
-      for ( Group sg : getSubject().getPrincipals(Group.class) )      
-      {
-         if ( Identity.ROLES_GROUP.equals( sg.getName() ) )
-         {
-            sg.addMember(new SimplePrincipal(role));
-            break;
-         }
-      }
-               
-      SimpleGroup roleGroup = new SimpleGroup(Identity.ROLES_GROUP);
-      roleGroup.addMember(new SimplePrincipal(role));
-      getSubject().getPrincipals().add(roleGroup); 
-      
-      return this;
-   }
-   
-   public boolean isSystemOperation()
-   {
-      return systemOp;
-   }
-   
-   public void run()
-   {      
-      Identity.instance().runAs(this);
-   }
-}

Deleted: trunk/src/main/org/jboss/seam/security/SecurityFunctions.java
===================================================================
--- trunk/src/main/org/jboss/seam/security/SecurityFunctions.java	2009-04-19 09:32:07 UTC (rev 10475)
+++ trunk/src/main/org/jboss/seam/security/SecurityFunctions.java	2009-04-19 09:44:29 UTC (rev 10476)
@@ -1,31 +0,0 @@
-package org.jboss.seam.security;
-
-/**
- * Delegating wrapper for EL security functions.
- * 
- * @author Shane Bryzak
- */
-public class SecurityFunctions
-{
-   public static boolean hasRole(String name)
-   {
-      return Identity.instance().hasRole(name);
-   }
-   
-   public static boolean hasPermission(String name, String action, Object arg)
-   {
-      if (arg != null)
-      {
-         return Identity.instance().hasPermission(name, action, arg);
-      }
-      else
-      {
-         return Identity.instance().hasPermission(name, action);
-      }
-   }
-   
-   public static boolean hasPermission(Object target, String action)
-   {
-      return Identity.instance().hasPermission(target, action);
-   }
-}

Deleted: trunk/src/main/org/jboss/seam/security/SecurityInterceptor.java
===================================================================
--- trunk/src/main/org/jboss/seam/security/SecurityInterceptor.java	2009-04-19 09:32:07 UTC (rev 10475)
+++ trunk/src/main/org/jboss/seam/security/SecurityInterceptor.java	2009-04-19 09:44:29 UTC (rev 10476)
@@ -1,301 +0,0 @@
-package org.jboss.seam.security;
-
-import java.io.Serializable;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Method;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import org.jboss.seam.annotations.intercept.AroundInvoke;
-import org.jboss.seam.annotations.intercept.Interceptor;
-import org.jboss.seam.annotations.intercept.InterceptorType;
-import org.jboss.seam.annotations.security.PermissionCheck;
-import org.jboss.seam.annotations.security.Restrict;
-import org.jboss.seam.annotations.security.RoleCheck;
-import org.jboss.seam.async.AsynchronousInterceptor;
-import org.jboss.seam.intercept.AbstractInterceptor;
-import org.jboss.seam.intercept.InvocationContext;
-import org.jboss.seam.transaction.RollbackInterceptor;
-import org.jboss.seam.util.Strings;
-
-/**
- * Provides authorization services for component invocations.
- * 
- * @author Shane Bryzak
- */
- at Interceptor(type=InterceptorType.CLIENT, 
-         around=AsynchronousInterceptor.class, within = RollbackInterceptor.class)
-public class SecurityInterceptor extends AbstractInterceptor implements Serializable
-{
-   private static final long serialVersionUID = -6567750187000766925L;
-   
-   /**
-    * You may encounter a JVM bug where the field initializer is not evaluated for a transient field after deserialization.
-    * @see "http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6252102"
-    */
-   private transient volatile Map<Method,Restriction> restrictions = new HashMap<Method,Restriction>();
-   
-   private class Restriction
-   {
-      private String expression;
-      
-      private String permissionTarget;
-      private String permissionAction;
-      
-      private Map<String, Object> methodRestrictions;
-      private Map<Integer,Set<String>> paramRestrictions;
-      private Set<String> roleRestrictions;
-            
-      public void setExpression(String expression)
-      {
-         this.expression = expression;
-      }
-      
-      public void setPermissionTarget(String target)
-      {
-         this.permissionTarget = target;
-      }
-      
-      public void setPermissionAction(String action)
-      {
-         this.permissionAction = action;
-      }
-      
-      public void addMethodRestriction(Object target, String action)
-      {
-         if (methodRestrictions == null)
-         {
-            methodRestrictions = new HashMap<String, Object>();
-         }
-         
-         methodRestrictions.put(action, target);
-      }
-      
-      public void addRoleRestriction(String role)
-      {
-         if (roleRestrictions == null)
-         {
-            roleRestrictions = new HashSet<String>();
-         }
-         
-         roleRestrictions.add(role);
-      }
-      
-      public void addParameterRestriction(int index, String action)
-      {
-         Set<String> actions = null;
-         
-         if (paramRestrictions == null)
-         {
-            paramRestrictions = new HashMap<Integer,Set<String>>();
-         }
-         
-         if (!paramRestrictions.containsKey(index))
-         {
-            actions = new HashSet<String>();
-            paramRestrictions.put(index, actions);
-         }
-         else
-         {
-            actions = paramRestrictions.get(index);
-         }
-         
-         actions.add(action);
-      }
-      
-      public void check(Object[] parameters)
-      {
-         if (Identity.isSecurityEnabled())
-         {
-            if (expression != null)
-            {
-               Identity.instance().checkRestriction(expression);
-            }
-            
-            if (methodRestrictions != null)
-            {
-               for (String action : methodRestrictions.keySet())
-               {
-                  Identity.instance().checkPermission(methodRestrictions.get(action), action);
-               }
-            }
-            
-            if (paramRestrictions != null)
-            {
-               for (Integer idx : paramRestrictions.keySet())
-               {
-                  Set<String> actions = paramRestrictions.get(idx);
-                  for (String action : actions) 
-                  {
-                     Identity.instance().checkPermission(parameters[idx], action);
-                  }
-               }
-            }
-            
-            if (roleRestrictions != null)
-            {
-               for (String role : roleRestrictions)
-               {
-                  Identity.instance().checkRole(role);
-               }
-            }
-            
-            if (permissionTarget != null && permissionAction != null)
-            {
-               Identity.instance().checkPermission(permissionTarget, permissionAction);
-            }
-         }
-      }
-   }
-
-   @AroundInvoke
-   public Object aroundInvoke(InvocationContext invocation) throws Exception
-   {
-      Method interfaceMethod = invocation.getMethod();
-      
-      if (!"hashCode".equals(interfaceMethod.getName()))
-      {
-         Restriction restriction = getRestriction(interfaceMethod);      
-         if ( restriction != null ) restriction.check(invocation.getParameters());
-      }
-
-      return invocation.proceed();
-   }
-
-   private Restriction getRestriction(Method interfaceMethod) throws Exception
-   {
-      // see field declaration as to why this is done
-      if (restrictions == null)
-      {
-         synchronized(this)
-         {
-            restrictions = new HashMap<Method, Restriction>();
-         }
-      }
-      
-      if (!restrictions.containsKey(interfaceMethod))
-      {
-         synchronized(restrictions)
-         {
-            // FIXME this logic should be abstracted rather than sitting in the middle of this interceptor
-            if (!restrictions.containsKey(interfaceMethod))
-            {  
-               Restriction restriction = null;
-               
-               Method method = getComponent().getBeanClass().getMethod( 
-                     interfaceMethod.getName(), interfaceMethod.getParameterTypes() );      
-               
-               Restrict restrict = null;
-               
-               if ( method.isAnnotationPresent(Restrict.class) )
-               {
-                  restrict = method.getAnnotation(Restrict.class);
-               }
-               else if ( getComponent().getBeanClass().isAnnotationPresent(Restrict.class) )
-               {
-                  if ( !getComponent().isLifecycleMethod(method) )
-                  {
-                     restrict = getComponent().getBeanClass().getAnnotation(Restrict.class); 
-                  }
-               }
-               
-               if (restrict != null)
-               {
-                  if (restriction == null) restriction = new Restriction();
-                  
-                  if ( Strings.isEmpty(restrict.value()) )
-                  {
-                     restriction.setPermissionTarget(getComponent().getName());
-                     restriction.setPermissionAction(method.getName());
-                  }
-                  else
-                  {
-                     restriction.setExpression(restrict.value());
-                  }
-               }
-               
-               for (Annotation annotation : method.getDeclaringClass().getAnnotations())
-               {
-                  if (annotation.annotationType().isAnnotationPresent(RoleCheck.class))
-                  {
-                     if (restriction == null) restriction = new Restriction();
-                     restriction.addRoleRestriction(annotation.annotationType().getSimpleName().toLowerCase());
-                  }
-               }
-               
-               for (Annotation annotation : method.getAnnotations())
-               {
-                  if (annotation.annotationType().isAnnotationPresent(PermissionCheck.class))
-                  {
-                     PermissionCheck permissionCheck = annotation.annotationType().getAnnotation(
-                           PermissionCheck.class);
-                     
-                     Method valueMethod = null;
-                     for (Method m : annotation.annotationType().getDeclaredMethods())
-                     {
-                        valueMethod = m;
-                        break;
-                     }
-                     
-                     if (valueMethod != null)
-                     {                        
-                        if (restriction == null) restriction = new Restriction();
-                        Object target = valueMethod.invoke(annotation);
-                        if (!target.equals(void.class))
-                        {
-                           if (restriction == null) restriction = new Restriction();
-                           restriction.addMethodRestriction(target, 
-                                 getPermissionAction(permissionCheck, annotation));
-                        }
-                     }
-                  }
-                  if (annotation.annotationType().isAnnotationPresent(RoleCheck.class))
-                  {
-                     if (restriction == null) restriction = new Restriction();
-                     restriction.addRoleRestriction(annotation.annotationType().getSimpleName().toLowerCase());
-                  }
-               }               
-               
-               for (int i = 0; i < method.getParameterAnnotations().length; i++)
-               {
-                  Annotation[] annotations = method.getParameterAnnotations()[i]; 
-                  for (Annotation annotation : annotations)
-                  {
-                     if (annotation.annotationType().isAnnotationPresent(PermissionCheck.class))
-                     {                        
-                        PermissionCheck permissionCheck = annotation.annotationType().getAnnotation(
-                              PermissionCheck.class);
-                        if (restriction == null) restriction = new Restriction();
-                        restriction.addParameterRestriction(i, 
-                              getPermissionAction(permissionCheck, annotation));                        
-                     }
-                  }
-               }                             
-               
-               restrictions.put(interfaceMethod, restriction);
-               return restriction;
-            }
-         }
-      }
-      return restrictions.get(interfaceMethod);      
-   }
-   
-   private String getPermissionAction(PermissionCheck check, Annotation annotation)
-   {
-      if (!"".equals(check.value()))
-      {
-         return check.value();
-      }
-      else
-      {
-         return annotation.annotationType().getSimpleName().toLowerCase();
-      }
-   }
-   
-   public boolean isInterceptorEnabled()
-   {
-      return getComponent().isSecure() && !getComponent().beanClassHasAnnotation("javax.jws.WebService");
-   }
-}

Deleted: trunk/src/main/org/jboss/seam/security/SimpleGroup.java
===================================================================
--- trunk/src/main/org/jboss/seam/security/SimpleGroup.java	2009-04-19 09:32:07 UTC (rev 10475)
+++ trunk/src/main/org/jboss/seam/security/SimpleGroup.java	2009-04-19 09:44:29 UTC (rev 10476)
@@ -1,93 +0,0 @@
-package org.jboss.seam.security;
-
-import java.io.Serializable;
-import java.security.Principal;
-import java.security.acl.Group;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Implementation of the Group interface, used for holding roles etc.
- * 
- * @author Shane Bryzak
- */
-public class SimpleGroup implements Group, Serializable
-{
-   private static final long serialVersionUID = 5766373925836425908L;
-
-   /**
-    * The name of the group
-    */
-   private String name;
-
-   /**
-    * The members of this group
-    */
-   private Set<Principal> members = new HashSet<Principal>();
-
-   public SimpleGroup(String name)
-   {
-      this.name = name;
-   }
-
-   public boolean addMember(Principal user)
-   {
-      return members.add(user);
-   }
-
-   public boolean isMember(Principal member)
-   {
-      if ( members.contains(member) )
-      {
-         return true;
-      }
-      else
-      {
-         for (Principal m : members)
-         {
-            if (m instanceof Group && ((Group) m).isMember(member))
-            {
-               return true;
-            }
-         }
-      }
-      return false;
-   }
-
-   public Enumeration<? extends Principal> members()
-   {
-      return Collections.enumeration(members);
-   }
-
-   public boolean removeMember(Principal user)
-   {
-      return members.remove(user);
-   }
-
-   public String getName()
-   {
-      return name;
-   }
-
-   @Override
-   public boolean equals(Object obj)
-   {
-      if (obj instanceof SimpleGroup)
-      {
-         SimpleGroup other = (SimpleGroup) obj;
-         return other.name.equals(name);
-      }
-      else
-      {
-         return false;
-      }
-   }
-
-   @Override
-   public int hashCode()
-   {
-      return name.hashCode();
-   }
-}

Deleted: trunk/src/main/org/jboss/seam/security/SimplePrincipal.java
===================================================================
--- trunk/src/main/org/jboss/seam/security/SimplePrincipal.java	2009-04-19 09:32:07 UTC (rev 10475)
+++ trunk/src/main/org/jboss/seam/security/SimplePrincipal.java	2009-04-19 09:44:29 UTC (rev 10476)
@@ -1,54 +0,0 @@
-package org.jboss.seam.security;
-
-import java.io.Serializable;
-import java.security.Principal;
-
-/**
- * Simple implementation of the Principal interface, supporting a named user.
- * 
- * @author Shane Bryzak
- */
-public class SimplePrincipal implements Principal, Serializable
-{
-   private static final long serialVersionUID = 5609375932836425908L;   
-   
-   private String name;
-   
-   public SimplePrincipal(String name)
-   {
-      this.name = name;
-   }
-   
-   public String getName()
-   {
-      return name;
-   }
-
-   @Override
-   public boolean equals(Object obj)
-   {
-      if (obj instanceof Principal)
-      {
-         Principal other = (Principal) obj;
-         return name == null ?
-                  other.getName() == null :
-                  name.equals( other.getName() );
-      }
-      else
-      {
-         return false;
-      }
-   }
-
-   @Override
-   public int hashCode()
-   {
-      return name != null ? name.hashCode() : super.hashCode();
-   }
-
-   @Override
-   public String toString()
-   {
-      return name;
-   }   
-}

Deleted: trunk/src/main/org/jboss/seam/security/TokenStore.java
===================================================================
--- trunk/src/main/org/jboss/seam/security/TokenStore.java	2009-04-19 09:32:07 UTC (rev 10475)
+++ trunk/src/main/org/jboss/seam/security/TokenStore.java	2009-04-19 09:44:29 UTC (rev 10476)
@@ -1,15 +0,0 @@
-package org.jboss.seam.security;
-
-/**
- * A store containing user authentication tokens.  Used in conjunction with the RememberMe
- * component to auto-login users that present a valid cookie-based token.
- * 
- * @author Shane Bryzak
- */
-public interface TokenStore
-{
-   void createToken(String username, String value);
-   boolean validateToken(String username, String value);
-   void invalidateToken(String username, String value);
-   void invalidateAll(String username);
-}

Deleted: trunk/src/main/org/jboss/seam/security/package-info.java
===================================================================
--- trunk/src/main/org/jboss/seam/security/package-info.java	2009-04-19 09:32:07 UTC (rev 10475)
+++ trunk/src/main/org/jboss/seam/security/package-info.java	2009-04-19 09:44:29 UTC (rev 10476)
@@ -1,12 +0,0 @@
-/**
- * Seam Security
- * 
- * @see org.jboss.seam.security.Identity
- * @see org.jboss.seam.annotations.security.Restrict
- */
- at Namespace(value="http://jboss.com/products/seam/security", prefix="org.jboss.seam.security")
- at AutoCreate
-package org.jboss.seam.security;
-
-import org.jboss.seam.annotations.AutoCreate;
-import org.jboss.seam.annotations.Namespace;




More information about the seam-commits mailing list