January 2, 2021
Estimated Post Reading Time ~

Creating a Custom YAML file for the Access Control Tool

There may be many reasons to create a custom file, the reason I did it was to include my groups’ members in the YAML output so that I can manage group memberships (whenever I choose to).

What is a YAML File
YAML files aren’t as common in JAVA projects. So, for many of us, we just haven’t had much need to use them. Put simply, a YAML file is just a text-indent formatted file. The amount of indention on an entry dictates its placement in the hierarchy.

My Disclaimer
Before you use anything you create, please test thoroughly. A bad YAML file into the AC Tool can break a lot of things. Please make sure that doesn’t happen to you and keep this in mind when you’re creating your files:

Any users or groups you manage in your configuration file (group_config and user_config sections) must have their ACLs in the same YAML file. If you try to deploy users and groups without their permissions, you may (and probably will) lose the ACLs.

This is documented here:

https://github.com/Netcentric/accesscontroltool/blob/develop/docs/AdvancedFeatures.md

Custom YAML Servlet
You can choose to implement this in many different ways. Since I wrote this code, I actually implemented a custom dashboard. But a servlet is great to start with because you can link to it but you can also use it from other areas within your code, as well as just hitting the URL directly (GET).

The main thing when writing your servlet is really to get the formatting right.

1.) You will likely have three config areas (group_config, user_config, and ac_config). It is possible to not include user_config, but make sure you also don’t generate any ACLs for those users in your YAML.

2.) You will need to indent based on hierarchy. Here are some constants (the netcentric code also uses these)
public static final int DUMP_INDENTATION_KEY = 4;
public static final int DUMP_INDENTATION_FIRST_PROPERTY = 7;
public static final int DUMP_INDENTATION_PROPERTY = 9;
public static final int DUMP_INDENTATION_PROPERTY_SUB = 11;
public static final String YAML_STRUCTURAL_ELEMENT_PREFIX = "- ";


Top-level items do not need an indention (group_config, user_config and ace_config)

Writing the Code
Again, I chose a Servlet because it’s an easy way to get this done, but you can use other methods.

All of the data we need for our files is readily available in AEM.

1.) Generate your group_config section. (I chose to use queries but you can also use the UserManagement API)

Iterator<Resource> groups = resolver.findResources("SELECT * FROM [rep:Group] AS nodes WHERE ISDESCENDANTNODE([/home/groups]) ORDER BY nodes.[rep:principalName]", Query.JCR_SQL2);

Once you have your group Resources you can iterate them and add them to a list. At this point, you can either add the group object or create a custom object told the attributes you plan to use. At the very least you will need the groupID, path,memberOf. As I mentioned before I was doing this to get the members, if you plan to add members also collect the declaredMembers of the group.

This list will later be used to pull the necessary ACL information because remember they should match.

while (groups.hasNext()) {
    <do stuff and add to list>
}


2.) If you’re including System Users, follow the same process and add them to a new List.

Iterator<Resource> userResources = resolver.findResources("SELECT * FROM [rep:SystemUser] AS nodes WHERE ISDESCENDANTNODE([/home/users]) ORDER BY nodes.[rep:principalName]", Query.JCR_SQL2);

You may need to use different paths here, depending on which System Users you plan to include.

3.) Collect the data for your ACLs.
Use the lists you created above to iterate all of the ACLS related to the group and user principles. Do this for each user and group.

Iterator<Resource> repResources = resolver.findResources("SELECT * FROM [rep:ACE] WHERE [rep:principalName]='"+principal+"'", Query.JCR_SQL2);

We use rep: ACE so that we can get all of them at once, but you will need to distinguish between allowing and deny policies. So when you store your data in a LIST, be sure to know how to tell them apart. You can create a custom object and store the information, then add that object to the list.

if(vm.get("jcr:primaryType").toString().equalsIgnoreCase("rep:GrantACE")) {
    type="allow";
}


At the least, you will need the Principle name, type (allow or deny), path, privileges, and restrictions.

Once you have collected all of the data it’s time to write it out.

For each of the above:
1.) Write out the heading and a configuration for each list.
2.) Remember to indent properly.
3.) Test on a local that you’re not too attached to in case of issues.



By aem4beginner

No comments:

Post a Comment

If you have any doubts or questions, please let us know.