Expand my Community achievements bar.

SOLVED

Set Access Control Policy programmatically

Avatar

Former Community Member

I'm trying to make use of AccessControlManager to programmatically set some AccessControlPolcy (ACP) onto a node. So basically what want to do is copy the ACP of one node and set it to another node. My code looks like below

Session userSession = request.getResourceResolver().adaptTo(Session.class); AccessControlManager acm = userSession.getAccessControlManager(); AccessControlPolicy[] acpArr = acm.getPolicies(sourceNode.getPath()); for(AccessControlPolicy acp : acpArr) acm.setPolicy(targetNode.getPath(), acp); userSession.save();

When i execute this i get the error that 

Policy org.apache.jackrabbit.core.security.authorization.acl.ACLTemplate@0 cannot be applied/removed from the node at <nodePath>

I looked at the source code of ACLEditor @  https://svn.apache.org/repos/asf/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbi... and in the method checkValidityPolicy, a check if being done to match the nodepath of the ACL and the targetNode, which fails in my case.

Is there any other way i can replicate the ACP of one node to another??

Thanks.

1 Accepted Solution

Avatar

Correct answer by
Level 1

Hi. Nitin,

Rather than setting source acp to target directly, you can try copying the aces and creating acl and setting to target path as follows:

{code}
 
JackrabbitAccessControlList sourceAcl = getAcl(acm, sourcePath);
JackrabbitAccessControlList targetAcl = getAcl(acm, targetPath); 
AccessControlPolicies []sourcePols = sourceAcl.getAccessControlEntries();
 
for (AccessControlEntry ace: accessControlEntries) {
   Principal principal = ace.getPrincipal();
   Privilege [] privileges = ace.getPrivileges();
   targetAcl.addEntry(principal, privileges, true, null);//true for allow entry, false for deny entry
}
acm.setPolicy(targetPath, targetAcl);
session.save();
{code}

{code}

 
JackrabbitAccessControlList getAcl(AccessControlManager acm,
String path) {
try {
AccessControlPolicyIterator app = acm.getApplicablePolicies(path);
while (app.hasNext()) {
AccessControlPolicy pol = app.nextAccessControlPolicy();
if (pol instanceof JackrabbitAccessControlPolicy) {
return (JackrabbitAccessControlList) pol;
}
}
// no found...check if present
for (AccessControlPolicy pol : acm.getPolicies(path)) {
if (pol instanceof JackrabbitAccessControlPolicy) {
return (JackrabbitAccessControlList) pol;
}
}
} catch (RepositoryException e) {
log.warn("Error while retrieving ACL for {}: {}", path,
e.toString());
}
return null;
}

{code}

 

Hope that helps.

Thanks,

Ravi

View solution in original post

5 Replies

Avatar

Level 6

I think that the problem is that when you retrieve a policy from one node and tries to apply it to another. What you should do is get it from one, then clone it and apply to the other. It might be that the target node already has a set of policies that you need to retrieve to and then copy the settings.

I will take a little deeper look into this during the weekend. Interesting question. :D

/Ove

Avatar

Correct answer by
Level 1

Hi. Nitin,

Rather than setting source acp to target directly, you can try copying the aces and creating acl and setting to target path as follows:

{code}
 
JackrabbitAccessControlList sourceAcl = getAcl(acm, sourcePath);
JackrabbitAccessControlList targetAcl = getAcl(acm, targetPath); 
AccessControlPolicies []sourcePols = sourceAcl.getAccessControlEntries();
 
for (AccessControlEntry ace: accessControlEntries) {
   Principal principal = ace.getPrincipal();
   Privilege [] privileges = ace.getPrivileges();
   targetAcl.addEntry(principal, privileges, true, null);//true for allow entry, false for deny entry
}
acm.setPolicy(targetPath, targetAcl);
session.save();
{code}

{code}

 
JackrabbitAccessControlList getAcl(AccessControlManager acm,
String path) {
try {
AccessControlPolicyIterator app = acm.getApplicablePolicies(path);
while (app.hasNext()) {
AccessControlPolicy pol = app.nextAccessControlPolicy();
if (pol instanceof JackrabbitAccessControlPolicy) {
return (JackrabbitAccessControlList) pol;
}
}
// no found...check if present
for (AccessControlPolicy pol : acm.getPolicies(path)) {
if (pol instanceof JackrabbitAccessControlPolicy) {
return (JackrabbitAccessControlList) pol;
}
}
} catch (RepositoryException e) {
log.warn("Error while retrieving ACL for {}: {}", path,
e.toString());
}
return null;
}

{code}

 

Hope that helps.

Thanks,

Ravi

Avatar

Former Community Member

Ove, Did you get a chance to have look at this.

Avatar

Former Community Member

Thanks for you reply.

Are you suggesting to clone the node or the ACP's? I did try copying the source node but that didnt carry over the ACP's. Basically they sit under the node rep:policy and while debugging those nodes were protected i think (sourceNode.getDefinition().isProtected()) and hence dont copy over

Is there a way i can create freshly create the policies, i basically want to give READ, WRITE, MODIFY, CREATE to the specific targetNode, this needs to be give to all the groups the user belongs to. I can live with this at the moment, though the ideal thing would be to get the ACP's from my source node.

Thanks.