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 */ @Name("org.jboss.seam.security.tokenStore") @Install(precedence = BUILT_IN, value=false) @Scope(APPLICATION) @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; } }