Friday, May 29, 2015

JackRabbit Access Control

While researching JackRabbit Access Control I struggled with a lot of new concepts then I found this article is very useful, one thing left for me is to read it patiently

Summary: TBC




The original source: http://wiki.apache.org/jackrabbit/AccessControl

The 'cached' version of source:

Basic privileges:

  • jcr:read The privilege to retrieve a node and get its properties and their values.
  • jcr:modifyProperties The privilege to create, remove and modify the values of the properties of a node.
  • jcr:addChildNodes The privilege to create child nodes of a node.
  • jcr:removeNode The privilege to remove a node.
  • jcr:removeChildNodes The privilege to remove child nodes of a node.
  • jcr:write An aggregate privilege that contains: jcr:readjcr:modifyPropertiesjcr:addChildNodesjcr:removeNodejcr:removeChildNodes
  • jcr:all An aggregate privilege that contains all available permissions, including jcr:readjcr:write and the advanced permssions.

Resource-based ACLs

Advantages:
  • fully supported by the JCR API / specification
  • very widely available ACL model (eg. file systems)
  • simple resource inheritance
  • default mechanism in Jackrabbit, no configuration needed
Disadvantages:
  • cannot assign ACLs to non-existent nodes
  • cumbersome when many users need un-groupable ACLs on a few resources (e.g. "subscriptions"), lots of ACL entries per resource
  • permissions are stored right inside the content (can be cumbersome for backups, etc.)

Resource-based ACLs are stored per resource/node in a special child node rep:policy. This one will have a list of rep:GrantACE child nodes (usually named allowallow0,...) for grant access control entries and rep:DenyACE child nodes (usually named denydeny0,...) for deny access control entries.
Each ACE node has a rep:principalName STRING property pointing to the user or group this ACE belongs to, and a rep:privileges NAME multi-value property, containing all the privileges of this ACE.

Example for your examination (for both cases: Resource-based, and Principal-based)



AccessControlManager aMgr = session.getAccessControlManager();

// create a privilege set with jcr:all
Privilege[] privileges = new Privilege[] { aMgr.privilegeFromName(Privilege.JCR_ALL) };
AccessControlList acl;
try {
    // get first applicable policy (for nodes w/o a policy)
    acl = aMgr.getApplicablePolicies(path).nextAccessControlPolicy();
} catch (NoSuchElementException e) {
    // else node already has a policy, get that one
    acl = aMgr.getPolicies(path)[0];
}
// remove all existing entries
for (AccessControlEntry e : acl.getAccessControlEntries()) {
    acl.removeAccessControlEntry(e);
}
// add a new one for the special "everyone" principal
acl.addAccessControlEntry(EveryonePrincipal.getInstance(), privileges);

// the policy must be re-set
aMgr.setPolicy(path, acl);

// and the session must be saved for the changes to be applied
session.save();


Principal-based ACLs

Advantages:
  • permissions can be assigned to non-existent nodes
  • permissions are stored separately from the content (good for content replication, backup etc.)
  • good for having many users with un-groupable ACLs (e.g. "subscriptions"); resources don't get filled up with ACL entries
Disadvantages:
  • additional Jackrabbit API has to be used for setting ACLs
  • modeling resource inheritance requires more ACLs than resource-based

An access control list (rep:ACL) is stored for each user and group (this is transparent, currently it's mirroring the users's home path at /rep:accesscontrol//rep:policy/). This consists of entries (rep:ACE), which are either allow (rep:GrantACE) or deny (rep:DenyACE) entries.
The rep:ACE nodetype (used by both resource- and principal-based ACLs) defines the following two properties for principal-based usage. These exact same names need to be used as restrictions when using the Jackrabbit API (JackrabbitAccessControlList.addEntry()):
  • rep:nodePath defines the (base) path of a subtree the ACL applies to (mandatory, PATH property)
  • rep:glob defines a glob pattern to restrict the subtree, both child nodes & properties (only a path matching is done) (optional, STRING property)
For the glob pattern, see http://jackrabbit.apache.org/api/2.2/org/apache/jackrabbit/core/security/authorization/GlobPattern.html (NodePath is the rep:nodePath and restriction is the rep:glob).
// usual entry point into the Jackrabbit API
JackrabbitSession js = (JackrabbitSession) session;

// get user/principal for whom to read/set ACLs

// Note: the ACL security API works using Java Principals as high-level abstraction and does not
// assume the users are actually stored in the JCR with the Jackrabbit UserManagement; an example
// are external users provided by a custom LoginModule via LDAP
PrincipalManager pMgr = js.getPrincipalManager();
Principal principal = pMgr.getPrincipal(session.getUserID());

// alternatively: get the current user as Authorizable from the user management
// (there is a one-to-one mapping between Authorizables and Principals)
User user = ((User) js.getUserManager().getAuthorizable(session.getUserID()));
Principal principal = user.getPrincipal();

// get the Jackrabbit access control manager
JackrabbitAccessControlManager acMgr = (JackrabbitAccessControlManager) session.getAccessControlManager();

JackrabbitAccessControlPolicy[] ps = acMgr.getPolicies(principal); // or getApplicablePolicies()
JackrabbitAccessControlList list = (JackrabbitAccessControlList) ps[0];

// list entries
JackrabbitAccessControlEntry[] entries = (JackrabbitAccessControlEntry[]) list.getAccessControlEntries();
JackrabbitAccessControlEntry entry = entries[0];

// remove entry
list.removeAccessControlEntry(entry);

// add entry
Privilege[] privileges = new Privileges[] { acMgr.privilegeFromName(Privilege.JCR_READ) };
Map restrictions = new HashMap();
ValueFactory vf = session.getValueFactory();
restrictions.put("rep:nodePath", vf.createValue("/some/path", PropertyType.PATH));
restrictions.put("rep:glob", vf.createValue("*"));
list.addEntry(principal, privileges, true /* allow or deny */, restrictions);

// reorder entries
list.orderBefore(entry, entry2);

// finally set policy again & save
acMgr.setPolicy(list.getPath(), list);
session.save();
























Thursday, May 28, 2015

How to add Observer to Magnolia CMS

JCR Node Manipulation Observation: When you want to monitor any actions taken on your JCR node, eg: Create, Update, Read, Delete... It's very easy to do it in Magnolia CMS

Magnolia has mechanism to manage observation, it's Observation module. You can find this module in Magnolia\Configuration app

In there, you can add your observer (class), and register any actions as your wish, workspace, node type, path, including sub-nodes? and other options. There are already many built-in observers in there for your reference



And your observation class should extend BaseRepositoryCommand, and look like below


Java Programming: Back to 2005 - Troubleshooting build issues

I didn't build any Java project far far away... from 2005, when I got my first job. Now, I'm coming back managing Java project... it's 2nd Java project that I have ever managed, this is very interesting project, and I decide to... play a role of developer

I try to build the project and I'm struggling with it!! So the motivation for this post is simple... taking notes of what I learn


I built my project, It was successful, without any errors message! I ran it, successful too... perfect! But it's weird, I cannot debug my project! I set the breakpoint, but it was not working!

My colleague, after few minutes troubleshooting, and we found the issues:

1/ The main project dependency pointing to module's version that is different from the current version that I have set in the module. So the main project is always pointing to the old Jar, not module's project

Although, before that we tried to 'MVN Clean', 'Update dependencies' for each project, it's still the same. The only way to solve the problem is going to main project POM and update the correct module's version

2/ I had learnt also that there were a Problem window in the Eclipse IDE, where I can see all the issues and I had to clean it up to make sure my project works correctly

3/ There were also Server window, where I can see my web project instance, and its dependent modules inside. If there were any problem with build, there should be missing modules inside that web instance. So you have to make sure all the dependent modules should be built and present in the web instance

Digital Inspiration Technology Guide

Change the world with your passion