Extending JpaPermissionStore

The existing permission store provides ways to view all permissions available for targets but no methods to see what permissions have been granted to a particular role or user. The following code extends the JpaPermissionStore to include methods for querying user permissions.

/**
 * Copyright Software Factory - 2009
 */
package nz.co.softwarefactory.risingstars.seam;

import static org.jboss.seam.ScopeType.APPLICATION;

import java.security.Principal;
import java.util.LinkedList;
import java.util.List;

import javax.persistence.EntityManager;
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.permission.PermissionAction;
import org.jboss.seam.annotations.security.permission.PermissionDiscriminator;
import org.jboss.seam.annotations.security.permission.PermissionRole;
import org.jboss.seam.annotations.security.permission.PermissionTarget;
import org.jboss.seam.annotations.security.permission.PermissionUser;
import org.jboss.seam.security.Role;
import org.jboss.seam.security.permission.Permission;
import org.jboss.seam.util.AnnotatedBeanProperty;

/**
 * @author craig
 */
@SuppressWarnings("serial")
@Name("org.jboss.seam.security.jpaPermissionStore")
@Install(precedence = Install.APPLICATION, value = false)
@Scope(APPLICATION)
@BypassInterceptors
public class JpaPermissionStore extends org.jboss.seam.security.permission.JpaPermissionStore {

    private AnnotatedBeanProperty<PermissionUser> userProperty;
    private AnnotatedBeanProperty<PermissionRole> roleProperty;
    private AnnotatedBeanProperty<PermissionAction> actionProperty;
    private AnnotatedBeanProperty<PermissionTarget> targetProperty;
    private AnnotatedBeanProperty<PermissionDiscriminator> discriminatorProperty;
    private AnnotatedBeanProperty<PermissionTarget> roleTargetProperty;
    private AnnotatedBeanProperty<PermissionAction> roleActionProperty;

    /*
     * (non-Javadoc)
     *
     * @see org.jboss.seam.security.management.JpaIdentityStore#init()
     */
    @Override
    @Create
    public void init() {
        super.init();

        final Class<?> userPermissionClass = getUserPermissionClass();
        userProperty = new AnnotatedBeanProperty<PermissionUser>(userPermissionClass,                         PermissionUser.class);
        targetProperty = new AnnotatedBeanProperty<PermissionTarget>                 
                        
(userPermissionClass, PermissionTarget.class);

        actionProperty = new AnnotatedBeanProperty<PermissionAction>
                        (userPermissionClass, PermissionAction.class);


        final Class<?> rolePermissionClass = getRolePermissionClass();
        if (rolePermissionClass == null) {
            roleProperty = new AnnotatedBeanProperty<PermissionRole>
                        (userPermissionClass, PermissionRole.class);

            if (roleProperty.isSet()) {
                discriminatorProperty = new
                AnnotatedBeanProperty<PermissionDiscriminator>(userPermissionClass,

                        PermissionDiscriminator.class);
            }
        }
        else {
            roleProperty = new AnnotatedBeanProperty<PermissionRole>
                        (rolePermissionClass, PermissionRole.class);

            if (roleProperty.isSet()) {
                roleTargetProperty = new AnnotatedBeanProperty<PermissionTarget>
                        (rolePermissionClass,

                        PermissionTarget.class);
                roleActionProperty = new AnnotatedBeanProperty<PermissionAction>
                        (rolePermissionClass,

                        PermissionAction.class);
            }
        }

        if (roleProperty.isSet()) {
            discriminatorProperty = new AnnotatedBeanProperty<PermissionDiscriminator>
                        (userPermissionClass,
PermissionDiscriminator.class);
        }
    }

    /**
     *
     * @param recipient
     * @return
     */
    public List<Permission> listPermissions(final Principal recipient) {
        final boolean recipientIsRole = recipient instanceof Role &&              
                        
getRolePermissionClass() != null;


        final StringBuilder q = new StringBuilder();
        q.append("select p from ");
        q.append(recipientIsRole ? getRolePermissionClass().getName() :
                        getUserPermissionClass().getName());

        q.append(" p");

        q.append(" where p.");
        q.append(recipientIsRole ? roleProperty.getName() : userProperty.getName());
        q.append(" = :recipient");

        final Query query = ((EntityManager)
                    getEntityManager().getValue()).createQuery(q.toString());

        query.setParameter("recipient", resolvePrincipalEntity(recipient));

        return convertPermissionObjects(query.getResultList());
    }

    private List<Permission> convertPermissionObjects(final List<?> permissions) {
        final List<Permission> resultingPermissions = new LinkedList<Permission>();

        final boolean useDiscriminator = getRolePermissionClass() == null &&
                                        discriminatorProperty.isSet();

        for (final Object permission : permissions) {

            if (useDiscriminator) {
                boolean isUser = true;
                if (useDiscriminator
                        && discriminatorProperty.getAnnotation().roleValue().equals(
                                discriminatorProperty.getValue(permission))) {
                    isUser = false;
                }
                final Principal recipient = resolvePrincipal(isUser ?
                        userProperty.getValue(permission) : roleProperty

                        .getValue(permission), isUser);
                resultingPermissions.add(new
                        Permission(targetProperty.getValue(permission),
                                    actionProperty.getValue(

                                    permission).toString(), recipient));
            }
            else {
                final Principal recipient =
                resolvePrincipal(roleProperty.getValue(permission), false);

                resultingPermissions.add(new
                        Permission(roleTargetProperty.getValue(permission),
                                    roleActionProperty

                                    .getValue(permission).toString(), recipient));
            }
        }

        return resultingPermissions;
    }
}

After you have created your new class you should configure it in your components.xml like this:

    <security:jpa-permission-store entity-manager="#{unrestrictedEntityManager}"
        class="nz.co.softwarefactory.esafensound.seam.JpaPermissionStore" />


Comments