10-18-2007 04:13 AM
10-25-2007 07:07 AM
04-01-2009 09:38 AM
public class CompositeVoter implements AccessDecisionVoter, InitializingBean {
List<AccessDecisionVoter> containedVoters;
private int combine(int currentResult, int newResult) {
// Deny always wins
if (currentResult == ACCESS_DENIED || newResult == ACCESS_DENIED) {
return ACCESS_DENIED;
}
// Allow precedes abstain
if (currentResult == ACCESS_GRANTED || newResult == ACCESS_GRANTED) {
return ACCESS_GRANTED;
}
return ACCESS_ABSTAIN;
}
@Override
public boolean supports(ConfigAttribute arg0) {
boolean result = false;
for (AccessDecisionVoter voter : containedVoters) {
result |= voter.supports(arg0);
}
return result;
}
@Override
public boolean supports(Class arg0) {
boolean result = false;
for (AccessDecisionVoter voter : containedVoters) {
result |= voter.supports(arg0);
}
return result;
}
@Override
public int vote(Authentication arg0, Object arg1,
ConfigAttributeDefinition arg2) {
int result = ACCESS_ABSTAIN;
for (AccessDecisionVoter voter : containedVoters) {
// Could be optimized: on a deny, you can give up immediately
result = combine(result, voter.vote(arg0, arg1, arg2));
}
return result;
}
@Override
public void afterPropertiesSet() throws Exception {
assert containedVoters != null;
}
public void setContainedVoters(List<AccessDecisionVoter> containedVoters) {
this.containedVoters = containedVoters;
}
}
And the confidentiality voter:
public class ConfidentialityVoter implements InitializingBean, AccessDecisionVoter {
private Logger logger = Logger.getLogger(ConfidentialityVoter.class);
private static final String ACL_NODE = "ACL_NODE";
private static final String ACL_PARENT = "ACL_PARENT";
private static final String ACL_ALLOW = "ACL_ALLOW";
private static final String ACL_METHOD = "ACL_METHOD";
private static final String TOP_SECRET = "AllowStrengVertraulich";
private static final String RESTRICTED = "AllowVertraulich";
private static final String INTERNAL = "AllowIntern";
private static final QName nameProp = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "name");
private AuthenticationService authenticationService;
private NodeService nodeService;
private NamespacePrefixResolver nspr;
private AuthorityService authorityService;
private PermissionServiceSPI permissionService;
private PermissionReference allowTopSecret = SimplePermissionReference.getPermissionReference(MyModel.QNAME_PROP_INFORMATIONSSCHUTZ, TOP_SECRET);
private PermissionReference allowRestricted = SimplePermissionReference.getPermissionReference(MyModel.QNAME_PROP_INFORMATIONSSCHUTZ, RESTRICTED);
private PermissionReference allowInternal = SimplePermissionReference.getPermissionReference(MyModel.QNAME_PROP_INFORMATIONSSCHUTZ, INTERNAL);
@Override
public void afterPropertiesSet() throws Exception {
logger.debug("Entered afterPropertiesSet");
assert authenticationService != null;
assert nodeService != null;
assert nspr != null;
}
@Override
public boolean supports(ConfigAttribute arg0) {
logger.debug("Entered supports (configAttribute : " + arg0.getAttribute() + ")");
if ((arg0.getAttribute() != null) && (arg0.getAttribute().startsWith(ACL_NODE))) {
return true;
}
else {
return false;
}
}
@Override
public boolean supports(Class arg0) {
logger.debug("Entered supports (class)");
return MethodInvocation.class.isAssignableFrom(arg0);
}
@Override
public int vote(Authentication authentication, Object obj, ConfigAttributeDefinition attributes) {
logger.debug("Entered vote: obj = " + obj.toString() + ", config = " + attributes.toString());
// The system user can do everything
if (authenticationService.isCurrentUserTheSystemUser()) {
logger.debug("system user -> allow");
return ACCESS_GRANTED;
}
// Find the called method and the applicable config attributes
List<ConfigAttributeHelper> supportedDefinitions = this.extractSupportedDefinitions(attributes);
MethodInvocation invocation = (MethodInvocation) obj;
Method method = invocation.getMethod();
Class[] params = method.getParameterTypes();
// Check for the permissions
for (ConfigAttributeHelper attribute : supportedDefinitions) {
logger.debug("Processing attribute " + attribute.toString());
// The parameter needs to be interpreted as a node ref
if (NodeRef.class.isAssignableFrom(params[attribute.parameter])) {
NodeRef node = (NodeRef) invocation.getArguments()[attribute.parameter];
logger.debug("Authorities: " + authorityService.getAuthorities().toString());
// The aspect must be present on the node
//if (nodeService.hasAspect(node, MyModel.QNAME_ASPECT_CONFIDENTIALITY)) {
if (this.hasConfidentialityAspect(node) == Boolean.TRUE) {
String confidentiality = (String) nodeService.getProperty(node, MyModel.QNAME_PROP_INFORMATIONSSCHUTZ);
logger.debug("Found node with confidentiality '" + confidentiality+ "'");
// For unrestricted nodes, access is granted no matter what
if ("unrestricted".contentEquals(confidentiality)) {
return ACCESS_GRANTED;
}
if (INTERNAL.contentEquals(confidentiality)) {
if (permissionService.hasPermission(node, this.allowInternal) != AccessStatus.ALLOWED) {
logger.debug("ACCESS DENIED on node: " + nodeService.getProperty(node, nameProp));
}
return (permissionService.hasPermission(node, this.allowInternal) == AccessStatus.ALLOWED ?
ACCESS_GRANTED : ACCESS_DENIED);
}
// For restricted nodes, the principal must have the restricted allowed permission
if (RESTRICTED.contentEquals(confidentiality)) {
if (permissionService.hasPermission(node, this.allowRestricted) != AccessStatus.ALLOWED) {
logger.debug("ACCESS DENIED on node: " + nodeService.getProperty(node, nameProp));
}
return (permissionService.hasPermission(node, this.allowRestricted) == AccessStatus.ALLOWED ?
ACCESS_GRANTED : ACCESS_DENIED);
}
// For top secret nodes, the principal must have the top secret permission
if (TOP_SECRET.contentEquals(confidentiality)) {
if (permissionService.hasPermission(node, this.allowTopSecret) != AccessStatus.ALLOWED) {
logger.debug("ACCESS DENIED on node: " + nodeService.getProperty(node, nameProp));
}
return (permissionService.hasPermission(node, this.allowTopSecret) == AccessStatus.ALLOWED ?
ACCESS_GRANTED : ACCESS_DENIED);
}
}
}
}
// if no match, then abstain
logger.debug("No match -> abstain");
return ACCESS_ABSTAIN;
}
public void setAuthenticationService(AuthenticationService authenticationService) {
this.authenticationService = authenticationService;
}
public AuthenticationService getAuthenticationService() {
return authenticationService;
}
public void setNodeService(NodeService nodeService) {
this.nodeService = nodeService;
}
public NodeService getNodeService() {
return nodeService;
}
public NamespacePrefixResolver getNamespacePrefixResolver()
{
return nspr;
}
public void setNamespacePrefixResolver(NamespacePrefixResolver nspr)
{
this.nspr = nspr;
}
public void setAuthorityService(AuthorityService authorityService) {
this.authorityService = authorityService;
}
public AuthorityService getAuthorityService() {
return authorityService;
}
public void setPermissionService(PermissionServiceSPI permissionService) {
this.permissionService = permissionService;
}
public PermissionServiceSPI getPermissionService() {
return permissionService;
}
// Private methods
private List<ConfigAttributeHelper> extractSupportedDefinitions(ConfigAttributeDefinition config)
{
List<ConfigAttributeHelper> definitions = new ArrayList<ConfigAttributeHelper>(2);
Iterator iter = config.getConfigAttributes();
while (iter.hasNext()) {
ConfigAttribute attr = (ConfigAttribute) iter.next();
logger.debug("Config attribute: " + attr.getAttribute());
if (this.supports(attr)) {
logger.debug("Matched");
definitions.add(new ConfigAttributeHelper(attr));
}
}
return definitions;
}
private Boolean hasConfidentialityAspect(final NodeRef node) {
//if (nodeService.hasAspect(node, MyModel.QNAME_ASPECT_CONFIDENTIALITY))
return AuthenticationUtil.runAs(
new AuthenticationUtil.RunAsWork<Boolean>() {
@Override
public Boolean doWork() throws Exception {
return nodeService.hasAspect(node, MyModel.QNAME_ASPECT_NEEDED);
}
},
AuthenticationUtil.getSystemUserName());
}
private class ConfigAttributeHelper
{
String attr;
String typeString;
SimplePermissionReference required;
int parameter;
String authority;
public String toString() {
return attr;
}
ConfigAttributeHelper(ConfigAttribute attr)
{
logger.debug("Create ConfigAttributeHelper with attr = " + attr.getAttribute());
this.attr = attr.getAttribute();
StringTokenizer st = new StringTokenizer(attr.getAttribute(), ".", false);
if (st.countTokens() < 1)
{
throw new ACLEntryVoterException("There must be at least one token in a config attribute");
}
typeString = st.nextToken();
if (!(typeString.equals(ACL_NODE) || typeString.equals(ACL_PARENT) || typeString.equals(ACL_ALLOW) || typeString
.equals(ACL_METHOD)))
{
throw new ACLEntryVoterException("Invalid type: must be ACL_NODE, ACL_PARENT or ACL_ALLOW");
}
if (typeString.equals(ACL_NODE) || typeString.equals(ACL_PARENT))
{
if (st.countTokens() != 3)
{
throw new ACLEntryVoterException("There must be four . separated tokens in each config attribute");
}
String numberString = st.nextToken();
String qNameString = st.nextToken();
String permissionString = st.nextToken();
parameter = Integer.parseInt(numberString);
QName qName = QName.createQName(qNameString, nspr);
required = SimplePermissionReference.getPermissionReference(qName, permissionString);
}
else if (typeString.equals(ACL_METHOD))
{
if (st.countTokens() != 1)
{
throw new ACLEntryVoterException(
"There must be two . separated tokens in each group or role config attribute");
}
authority = st.nextToken();
}
}
}
}
04-08-2009 09:48 AM
Tags
Find what you came for
We want to make your experience in Hyland Connect as valuable as possible, so we put together some helpful links.