Sling process child resources - aem

Is there a way to access properties of a child resource using Sling API ? I know with JCR API it is possible to access child nodes. Sling does give a way to list Children. But
Resource pageResource = resolver.getResource("/content/sitename/page/jcr:content");
ModifiableValueMap map = pageResource.adaptTo(ModifiableValueMap.class);
map.put("component01/propertyName","Changed Text");
doesn't work. This throws an 'Invalid Property' SlingException. Any suggestions ?

doesn't work. This throws an 'Invalid Property' SlingException.
The quotes (“”) seem to be little fishy as I mentioned in the comment.
Try the following snippet .
You can fiddle around with these kind of requirements with the beautiful AEM Fiddle by ACS Tools.
Resource pageResource = resourceResolver.getResource("/content/sitename/page/jcr:content");
Iterable<Resource> childrenResources = pageResource.getChildren(); // Gives you all the resources representing direct children of /content/sitename/page/jcr:content
for(Resource childResource : childrenResources){
ModifiableValueMap mValueMap = childResource.adaptTo(ModifiableValueMap.class); // childResource should represent "component01" .
mValueMap.put("someProperty", "Some Value");
}

Related

ABAC with keycloak - Using Resource attributes in policy

What I am trying to achieve
Protect a resource in Keycloak with policy like:
if (resource.status == 'draft') $evaluation.grant();
else $evaluation.deny();
Going by their official documents and mailing list responses, it seems attribute based access control is possible, however, I could not find a way of getting it to work.
What I have tried
Using Authorization Services: I was unable to figure out where and how I can inject the attributes from the resource instance.
Using Authorization Context: I was hoping to get the policies associated with a resource and a scope so that I could evaluate them my self.
So far, I have managed to get no where with both approaches. To be honest, I have been overwhelmed by the terminology used in the Authorization services.
Question
How can I use attributes of a resource instance while defining a policy in keycloak?
I solved this problem in Keycloak 4.3 by creating a JavaScript policy because Attribute policies don't exist (yet). Here is an example of the code I got working (note that the attribute values are a list, so you have to compare against the first item in the list):
var permission = $evaluation.getPermission();
var resource = permission.getResource();
var attributes = resource.getAttributes();
if (attributes.status !== null && attributes.status[0] == "draft") {
$evaluation.grant();
} else {
$evaluation.deny();
}
Currently there is no way to do what you are looking to do. ResourceRepresentation class only has (id, name, uri, type, iconUri, owner) fields. So you can use owner to determine ownership per Keycloak example. I've seen a thread that talks about adding additional resource attributes, but haven't seen a Keycloak JIRA for it.
Perhaps you could use Contextual Attributes in some way by setting what you need at runtime and writing a Policy around it.
var context = $evaluation.getContext();
var attributes = context.getAttributes();
var fooValue = attributes.getValue("fooAttribute");
if (fooValue.equals("something"))
{
$evaluation.grant();
}

Query builder API in Cq5

Hi I am implementing a Java module to fetch the pages which has a particular component.
Below is the code snippet which i use, but when running the module am getting an warning Saying that no PredicateEvaluator found for 'sling:resourceType'.
Kindly suggest me the proper way to give resourceType property as query parameter
Map<String, String> predicateMap = new HashMap<String, String>();
predicateMap.put("path","/content/geometrixx-outdoors/en/men");
predicateMap.put("type", "cq:Page");
predicateMap.put("sling:resourceType", "geometrixx-outdoors/components/title");
predicateMap.put("p.limit", "-1");
QueryBuilder queryBuilder = slingScriptHelper.getService(QueryBuilder.class);
com.day.cq.search.Query queryObj = queryBuilder.createQuery(PredicateGroup.create(predicateMap), session);
sling:resourceType is indeed not a valid predicate evaluator. You need to put it as a property:
predicateMap.put("property", "jcr:content/sling:resourceType");
predicateMap.put("property.value", "geometrixx-outdoors/components/title");
As you alre filtering type=cq:Page you have to also include jcr:content in the path to the property.

CQ - Check whether the resource object is valid

I need to check whether the resource object is valid or not for the below 'resource' object. For example If I pass any url like getResource("some path which is not available in cq") in this case I need to restrict it
Resource resource= resourceResolver.getResource(/content/rc/test/jcr:content");
Node node = resource.adaptTo(Node.class);
String parentPagePath= node.getProperty("someproperty").getValue().getString();
Is there any way to do?
If you are using getResource a null check is sufficient. If you use resolve, then you have to use the !ResourceUtil.isNonExistingResource(resource).
On Node level you can check the existence of a property with hasProperty.
As Thomas said , ResourceResolver.getResource() returns null if the path you provide as argument does not exist. A null check on the resource should get your problem solved .
Resource resource= resourceResolver.getResource("some path which is not available in cq");
if(resource != null){
Node node = resource.adaptTo(Node.class);
String parentPagePath= node.getProperty("someproperty").getValue().getString();
}
Just a side note :
Its mostly better to play around with a wrapper than to work with a lower level API unless there is a compelling reason to do so.
Hence , I would recommend you to deal with ValueMap(Sling API) to retrieve/set properties of Node rather than dealing with the Node (JCR API)
Resource resource= resourceResolver.getResource("some path which is not available in cq");
if(resource != null){
ValueMap mapWithAllTheValues = resource.adaptTo(ValueMap.class);
String parentPagePath= mapWithAllTheValues.get("someproperty", String.class);
}
Ref :
https://docs.adobe.com/docs/en/cq/5-6-1/javadoc/org/apache/sling/api/resource/ResourceResolver.html#getResource(java.lang.String)

Accessing the style properties from an OSGi service

I have an OSGi service that needs to access values stored by a component in it's design dialog.
Since I don't have access to the currentStyle value. I've attempted to access that Style object by instantiating it myself, with little luck.
My current code to access it from the the ServletRequest is
SlingHttpServletRequest resource = (SlingHttpServletRequest)request;
ComponentContext componentContext = WCMUtils.getComponentContext(resource);
Page page = componentContext.getPage();
Design design = page.adaptTo(Design.class);
return design.getStyle(componentContext.getCell())
At this point there is a style object, but no values get returned from it.
I found this code to return the correct Style object
SlingHttpServletRequest request = (SlingHttpServletRequest)adaptable;
Designer designer = (Designer)request.getResourceResolver().adaptTo(Designer.class);
ComponentContext componentContext = WCMUtils.getComponentContext(request);
Page page = componentContext.getPage();
Design design = designer.getDesign(page);
return design.getStyle(componentContext.getCell());

Get a node form currenPage in CQ5

I have a component that needs to fetch properties from another component on the same page.
Is there a way to get a component's NODE object from currentPage ?
I have the name of the node I need to fetch available in the code.
Assuming the node you need is in Page/jcr:content/yournode:
the Page object has a method getContentResource() which returns you the jcr:content resource node by default. You can also use page.getContentResource("yournode") to get a specific node below jcr:content.
If your node, for some reason is sibling to jcr:content (it shouldn't btw), you can your iterate the children of a resource using resource.listChildren().
Remember, this is all Sling API, so you are managing resources, not nodes. You can get a JCR Node from a resource using resource.adaptTo(Node.class)
Usually every Page class has a method for retrieving nodes within jcr:content that’s a little cleaner:
Node node = CurrentPage.getContentResource("COMPONENTNAME").adaptTo(Node.class);
Developers should check for a resource's existence before adapting it to a Node.
Now that we have a node, we can extract properties from that node.
String title = node.getProperty("jcr:title").getString();
This way you can fetch any properties of a component.
I would like to add that this can be solved in more clean way by delegating request to a servlet provided the problem being solved requires separation of concerns - separate the view from the controller logic.
LINK EXPLAINING IN DETAIL HOW VALIDATION IS DONE USING SLING SERVLETS
Adds validator to a form using below logic that calls the sling servlet hosted
var url = CQ.HTTP.addParameter(dialog.path + '.validator.json', 'value', value);
var result = CQ.HTTP.eval(url);
and in the servlet we access the node and its parents using below logic
final Node currentNode = request.getResource().adaptTo(Node.class);
try {
final Node par = currentNode.getParent();
final NodeIterator nodes = par.getNodes();
// get all form names for the current paragraph system
while (nodes.hasNext()) { //and the business logic
See more at: http://www.citytechinc.com/us/en/blog/2012/04/complex_cq5_dialog_validation.html#sthash.wey3cwdI.dpuf