Showing posts with label Permissions. Show all posts
Showing posts with label Permissions. Show all posts

Tuesday, November 5, 2024

Version Issue with Custom AssetMetadataPermissionProvider implementation

While implementing custom metadata based permission provider, you can follow this article to implement it. One issue I faced during this implementation that the version access was not working. To fix this modify below methods:

@Override

public TreePermission getTreePermission(Tree tree, TreePermission parentPermission) {

if (PermissionHelpers.isDamPath(tree) || PermissionHelpers.isDamAncestorPath(tree)) {

if (PermissionHelpers.findAncestorAsset(tree) != null) {

return PermissionHelpers.isAncestorAssetOwner(tree, principalNames) ?

             TreePermission.ALL : parentPermission;

} else {

return new EmptyAssetMetadataTreePermission(tree, TreeType.DEFAULT, this);

}

} else if (tree.getPath().startsWith("/" + JcrConstants.JCR_SYSTEM)) {

      // This condition added to allow version to path access

      // This is just an example code, optimize this condition before you use

return TreePermission.ALL;

}

return TreePermission.NO_RECOURSE;

}

Another method:

@Override

public boolean isGranted(Tree tree, PropertyState property, long permissions) {

TreeType type = treeTypeProvider.getType(tree);

switch (type) {

case HIDDEN:

return true;

case VERSION:

Tree evalTree = getEvaluationTree(tree);

if (evalTree == null) {

return false;

}

if (evalTree.exists()) {

return internalIsGranted(evalTree, property, permissions);

} else {

return false;

}

case INTERNAL:

return false;

default:

return internalIsGranted(tree, property, permissions);

}

} 

Core logic to test metadata conditions to meet business requirement is put in the below private method which is called in the above isGranted method.

private boolean internalIsGranted(@NotNull Tree tree, @Nullable PropertyState property,

   long permissions) {

boolean answer = false;

if (PermissionHelpers.isAncestorAssetOwner(tree, principalNames)) {

answer = true;

}

if (property != null) {

LOG.debug("isGranted: {}@{} ({}) = {}", tree.getPath(), property.getName(),

             permissions, answer);

} else {

LOG.debug("isGranted: {} ({}) = {}", tree.getPath(), permissions, answer);

}

return answer;

}

PermissionHelpers here is a general utility class like below:


Thursday, July 21, 2016

AEM6 | Export Users/ Groups with ACL Permissions

If you need to transfer users and groups in  AEM from one server to another or from one AEM instance to another then you need to create a package of users/groups along with rep:policy nodes. It is important to include rep:policy nodes as the permissions are stored at the individual target nodes instead of group/ user node. We need to Include all individual rep:policy nodes where you have given access to groups.

If users are included in the package then :
Add Exclude rule to users for token: /home/users/.*/.tokens

The Recommended option is to use acs-aem-commons tool to create a separate ACL package to migrate the ACLs. This utility picks the rep:policy nodes automatically so we don't have to worry about it.

Follow the below steps :

1. Create the ACL package as shown below -




2. Configure the ACL package

Once package is created open the ACL package page and configure it for groups and users definition.
While configuring package, it is important that you select all the principles i.e. users or groups which you want to export under "Principal Names". You can keep the "Include Patterns" field blank to ensure that all nodes which have rep:policy node are included automatically. You don't have to include them selectively because doing that may be cucumbersome and  there are chances you may miss few entries.


You need to check "Include principles" option if the selected principals do not exist in target environment otherwise you can keep it unchecked.

Set ACL Handling to overwrite (or Merge**)
**In case the "overwrite" does not work for you, try with "merge" option.

3. Install the package in destination AEM instance

Note :- I suggest to perform/ verify this in a test instance first. Ensure you take back of existing User/group definitions before you upload the package in destination AEM instance.

Troubleshooting: 

Once you have installed the package in destination, cross verify the users, groups and permission. Make changes in your filter definition in Step 1 as required if you see any issues and build/ install again.
In case the permissions does not reflect properly, check if you have given the permission at root level i.e. selecting the check all option at the top. Sometimes this give issue so instead of giving permissions at root level, give permissions at sub root level i.e. /content, /etc, /home, /libs etc.


Sunday, June 19, 2016

Control component rendering in Touch UI Dialogs

RenderCondition comes very handy when you want to control rendering of your dialog. You can restrict display of field, button, tab etc. based on RenderConditions. I am going to take an  example of Carousel component where I will hide a tab panel from dialog to certain users. Consider the component dialog has two tabs- Carousel and List. Now to restrict display of one tab i.e. List to certain users who do not have "Create" access a certain path, perform following steps-

1. Go to cq:dialog component which you want to restrict for rendering, in this case go to - "/apps/myproject/components/carousel/cq:dialog/content/items/list" node

2. Create a new node "granite:rendercondition" of type "nt:unstructured"

3. Add following properties to this new node-
path- Type: String, Value: /content/mysite/en/homepage
privileges- Type: String, Value: jcr:addChildNodes
sling:resourceType-Type: String,Value: granite/ui/components/foundation/renderconditions/privilege

Another resourceType is - granite/ui/components/coral/foundation/renderconditions/simple which supports a expression property like this- 
expression="${param.item == '/content/mysite/en' || param.item == '/content/mysite/es'}" 
OR
expression="${granite:relativeParent(param.item, 1)== '/content/mysite'}" To ensure that just first level pages e.g. /content/mysite/en match the render condition.

Refer the screenshot below-


4. Save your changes. And go to useradmin console and revoke "Create" access on the following path- "/content/mysite/en/homepage". You can use regex also for the path value for pattern based matching as per your specific need.

5. Now go back to the page i.e. /content/mysite/en/homepage.html, Open the carousel component dialog, You should observe that the list tab does not appear to the logged in user as  the RenderCondition rule evaluates to false.

For more rendercondition options refer the link here-
https://developer.adobe.com/experience-manager/reference-materials/6-5/granite-ui/api/jcr_root/libs/granite/ui/docs/server/rendercondition.html

CDN | Clearing Cloudflare cache

In order to clear Cloudflare cache automatically via code, follow below steps: 1. Develop Custom TransportHandler Develop a custom Trans...