package org.jboss.seam.security.permission;
import static org.jboss.seam.ScopeType.APPLICATION;
import static org.jboss.seam.annotations.Install.BUILT_IN;
import java.io.Serializable;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.jboss.seam.Component;
import org.jboss.seam.Seam;
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.log.LogProvider;
import org.jboss.seam.log.Logging;
import org.jboss.seam.security.Identity;
import org.jboss.seam.security.Role;
import org.jboss.seam.security.SimplePrincipal;
/**
* Resolves dynamically-assigned permissions, mapped to a user or a role, and kept in persistent
* storage, such as a relational database.
*
* @author Shane Bryzak
*/
@Name("org.jboss.seam.security.persistentPermissionResolver")
@Scope(APPLICATION)
@BypassInterceptors
@Install(precedence=BUILT_IN)
@Startup
public class PersistentPermissionResolver implements PermissionResolver, Serializable
{
private PermissionStore permissionStore;
private static final LogProvider log = Logging.getLogProvider(PersistentPermissionResolver.class);
@Create
public void create()
{
initPermissionStore();
}
protected void initPermissionStore()
{
if (permissionStore == null)
{
permissionStore = (PermissionStore) Component.getInstance(JpaPermissionStore.class, true);
}
if (permissionStore == null)
{
log.warn("no permission store available - please install a PermissionStore with the name '" +
Seam.getComponentName(JpaPermissionStore.class) + "' if persistent permissions are required.");
}
}
public PermissionStore getPermissionStore()
{
return permissionStore;
}
public void setPermissionStore(PermissionStore permissionStore)
{
this.permissionStore = permissionStore;
}
public boolean hasPermission(Object target, String action)
{
if (permissionStore == null) return false;
Identity identity = Identity.instance();
if (!identity.isLoggedIn()) return false;
List<Permission> permissions = permissionStore.listPermissions(target, action);
String username = identity.getPrincipal() != null ? identity.getPrincipal().getName() : null;
for (Permission permission : permissions)
{
if (username != null && permission.getRecipient() instanceof SimplePrincipal &&
username.equals(permission.getRecipient().getName()))
{
return true;
}
if (permission.getRecipient() instanceof Role)
{
Role role = (Role) permission.getRecipient();
if (role.isConditional())
{
RuleBasedPermissionResolver resolver = RuleBasedPermissionResolver.instance();
if (resolver.checkConditionalRole(role.getName(), target, action)) return true;
}
else if (identity.hasRole(role.getName()))
{
return true;
}
}
}
return false;
}
public void filterSetByAction(Set<Object> targets, String action)
{
if (permissionStore == null) return;
Identity identity = Identity.instance();
if (!identity.isLoggedIn()) return;
List<Permission> permissions = permissionStore.listPermissions(targets, action);
String username = identity.getPrincipal().getName();
Iterator iter = targets.iterator();
while (iter.hasNext())
{
Object target = iter.next();
for (Permission permission : permissions)
{
if (permission.getTarget().equals(target))
{
if (permission.getRecipient() instanceof SimplePrincipal &&
username.equals(permission.getRecipient().getName()))
{
iter.remove();
break;
}
if (permission.getRecipient() instanceof Role)
{
Role role = (Role) permission.getRecipient();
if (role.isConditional())
{
RuleBasedPermissionResolver resolver = RuleBasedPermissionResolver.instance();
if (resolver.checkConditionalRole(role.getName(), target, action))
{
iter.remove();
break;
}
}
else if (identity.hasRole(role.getName()))
{
iter.remove();
break;
}
}
}
}
}
}
}