Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.duracloud.account.security.vote.BaseAccessDecisionVoter Maven / Gradle / Ivy
/*
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://duracloud.org/license/
*/
package org.duracloud.account.security.vote;
import org.aopalliance.intercept.MethodInvocation;
import org.duracloud.account.db.model.AccountRights;
import org.duracloud.account.db.model.DuracloudUser;
import org.duracloud.account.db.model.Role;
import org.duracloud.account.db.repo.DuracloudRepoMgr;
import org.duracloud.account.db.repo.DuracloudRightsRepo;
import org.duracloud.account.security.domain.SecuredRule;
import org.duracloud.common.error.DuraCloudRuntimeException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.AccessDecisionVoter;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
/**
* @author Andrew Woods
* Date: 4/5/11
*/
public abstract class BaseAccessDecisionVoter implements AccessDecisionVoter {
protected Logger log = LoggerFactory.getLogger(BaseAccessDecisionVoter.class);
private DuracloudRepoMgr repoMgr;
public BaseAccessDecisionVoter(DuracloudRepoMgr repoMgr) {
this.repoMgr = repoMgr;
}
/**
* This abstract method returns the class for which this voter has interest.
*
* @return class of target service interface
*/
protected abstract Class> getTargetService();
@Override
public boolean supports(ConfigAttribute attribute) {
log.trace("supports attribute{}", attribute.getAttribute());
return true;
}
@Override
public boolean supports(Class> clazz) {
log.trace("supports {}", clazz.getName());
return MethodInvocation.class.isAssignableFrom(clazz);
}
protected boolean supportsTarget(MethodInvocation invocation) {
Class>[] interfaces = invocation.getThis().getClass().getInterfaces();
if (null == interfaces || interfaces.length == 0) {
return false;
}
for (Class> c : interfaces) {
if (c.equals(getTargetService())) {
return true;
}
}
return false;
}
protected SecuredRule getRule(Collection atts) {
if (null == atts || atts.size() != 1) {
throw new DuraCloudRuntimeException("Invalid security att " + atts);
}
return new SecuredRule(atts.iterator().next().getAttribute());
}
protected Collection getUserRoles(Authentication authentication) {
Set roles = new HashSet();
for (GrantedAuthority authority : authentication.getAuthorities()) {
roles.add(authority.getAuthority());
}
return roles;
}
protected int voteHasRole(String role, Collection userRoles) {
return userRoles.contains(role) ? ACCESS_GRANTED : ACCESS_DENIED;
}
protected int voteUserHasRoleOnAccount(DuracloudUser user,
String role,
Long acctId) {
log.trace("Does user {} have role {} on acct {}?",
new Object[]{user.getId(), role, acctId});
AccountRights rights = getUserRightsForAcct(user.getId(), acctId);
if (null == rights) {
return ACCESS_DENIED;
}
Set acctRoles = rights.getRoles();
log.trace("Roles found: {}", acctRoles);
if (acctRoles != null && acctRoles.size() > 0) {
for (Role acctRole : acctRoles) {
if (role.equals(acctRole.authority().getAuthority())) {
return ACCESS_GRANTED;
}
}
}
return ACCESS_DENIED;
}
protected int voteUserHasRoleOnAcctToUpdateOthersRoles(Long userId,
Long acctId,
Long otherUserId,
Set otherRoles) {
log.trace("Voting if user {} has roles on acct {} to manage {}.",
new Object[]{userId, acctId, otherUserId});
AccountRights rights = getUserRightsForAcct(userId, acctId);
AccountRights other = getUserRightsForAcct(otherUserId, acctId);
if (null == rights || null == other) {
log.warn("No rights found for users {}, {} on acct {}",
new Object[]{userId, otherUserId, acctId});
return ACCESS_DENIED;
}
boolean existing = hasVote(voteRolesAreSufficientToUpdateOther(rights.getRoles(),
other.getRoles()));
boolean updates = hasVote(voteRolesAreSufficientToUpdateOther(rights.getRoles(),
otherRoles));
log.trace("Are {} sufficient to update both {} and {}?",
new Object[]{rights.getRoles(),
other.getRoles(),
otherRoles});
return existing && updates ? ACCESS_GRANTED : ACCESS_DENIED;
}
protected int voteRolesAreSufficientToUpdateOther(Set roles,
Set other) {
if (null == roles || null == other) {
log.warn("Null roles one or more {}, {}", roles, other);
return ACCESS_DENIED;
}
Role otherHighestRole = Role.highestRole(other);
if (null == otherHighestRole) {
log.warn("No highest role found for {}", other);
return ACCESS_DENIED;
}
boolean userHasRole = roles.contains(otherHighestRole);
log.trace("Roles {} has permission to manage other {}",
roles,
otherHighestRole);
return userHasRole ? ACCESS_GRANTED : ACCESS_DENIED;
}
protected boolean hasVote(int vote) {
return vote == ACCESS_GRANTED;
}
protected int numUsersForAccount(Long acctId) {
Set rights =
new HashSet<>(repoMgr.getRightsRepo().findByAccountId(acctId));
return (null != rights) ? rights.size() : 0;
}
protected AccountRights getUserRightsForAcct(Long userId, Long acctId) {
DuracloudRightsRepo rightsRepo = repoMgr.getRightsRepo();
AccountRights rights = rightsRepo.findByAccountIdAndUserId(acctId, userId);
return rights;
}
protected Set getAllUserRightsForAcct(Long acctId) {
DuracloudRightsRepo rightsRepo = repoMgr.getRightsRepo();
Set rights = null;
return new HashSet<>(rightsRepo.findByAccountId(acctId));
}
protected int voteMyUserId(DuracloudUser user, Long userId) {
return user.getId().equals(userId) ? ACCESS_GRANTED : ACCESS_DENIED;
}
protected int voteMyUsername(DuracloudUser user, String username) {
return user.getUsername().equals(username) ? ACCESS_GRANTED : ACCESS_DENIED;
}
protected DuracloudUser getCurrentUser(Authentication authentication) {
Object principal = authentication.getPrincipal();
if (principal instanceof String) {
log.trace("Unknown user {}", principal);
DuracloudUser user = new DuracloudUser();
user.setUsername((String)principal);
return user;
} else {
return (DuracloudUser) principal;
}
}
protected String asString(int decision) {
String s = "unknown";
switch (decision) {
case ACCESS_DENIED:
return "ACCESS_DENIED";
case ACCESS_ABSTAIN:
return "ACCESS_ABSTAIN";
case ACCESS_GRANTED:
return "ACCESS_GRANTED";
}
return s;
}
@Override
public final int vote(Authentication authentication, MethodInvocation invocation,
Collection attributes) {
if (!supportsTarget(invocation)) {
return castVote(ACCESS_ABSTAIN, invocation);
}
// Collect target method arguments
Object[] methodArgs = invocation.getArguments();
// Collect user making the call.
DuracloudUser user = getCurrentUser(authentication);
if(user.isRootUser()){
return ACCESS_GRANTED;
}
// Collect security constraints on method.
SecuredRule securedRule = getRule(attributes);
String role = securedRule.getRole().name();
SecuredRule.Scope scope = securedRule.getScope();
return voteImpl(authentication, invocation, attributes, methodArgs, user, securedRule, role, scope);
}
protected int castVote(int decision, MethodInvocation invocation) {
String methodName = invocation.getMethod().getName();
String className = invocation.getThis().getClass().getSimpleName();
log.trace("{}.{}() = {}", new Object[]{className, methodName, asString(
decision)});
return decision;
}
protected abstract int voteImpl(Authentication authentication,
MethodInvocation invocation,
Collection attributes, Object[] methodArgs,
DuracloudUser user, SecuredRule securedRule, String role,
SecuredRule.Scope scope);
}