How can I restrict a user's access to just a single node of an AEM website? - aem

I'd like to restrict a user's access to just a specific node within an AEM website. I want them to be able to manage a blog; they should be able to view the blog (of course), add/edit/delete entries/comments, upload photos, add/remove other collaborators, etc. However, I don't want them to have access to or even see anything else within AEM.
I have tried giving access to just the blog node under the content path (/content/geometrixx/en/blog), but when I try to log into AEM as this user and edit the blog (localhost:4502/cf#/content/geometrixx/en/blog.html), I get the following error:
No resource found
Cannot serve request to /cf in /libs/sling/servlet/errorhandler/404.jsp
I've tried giving write access to the /content/geometrixx/en/blog node and read access to everything else, and it seems to work, but of course, the user is able to see way too much. It would seem there is some particular node that a user must have read access to in order to edit content nodes, but I'm not sure what that is. Any ideas?

I would go to the /useradmin, chose the user, and in the Permissions tab I would allow access to the below and its child pages:
/content/geometrixx/en/blog - allow read modify create delete replicate
/apps/geometrixx/ - allow read only
/etc/designs/geometrixx - allow read only
/libs - allow read only
/etc/clientlibs - allow read only (optional)
/etc/workflow - allow read only (optional)
This is roughly the solution I use in our setup. As you are aware, you need to give at least read-only to the directories where cq components sit, as well as the components from your application, in this case geometrixx.
edit: Also useful to read: https://helpx.adobe.com/experience-manager/kb/CQ53ACLsMappingToCRX2.html

Most importantly you really need to understand the different pieces of functionality of cq, where they reside (/libs, /apps/, /etc/, etc...) and what is required to have a page properly rendered.
Is it a requirement you have for both author and publisher?
Reading https://jackrabbit.apache.org/api/2.2/org/apache/jackrabbit/core/security/authorization/GlobPattern.html can also help you set ACLs.
I suggest you create a custom group with deny jcr:all on /, and then set the ACL as described by dex and test to see if it helps.

can you try to give the modified access instead of read access,
/content/geometrixx/en/blog - allow read modify
As you need access to single blog node and its jcr:content

Related

How can I check if current user has write access to a specific field in TYPO3

I would like to check if the current BE user has access to a specific field, e.g. pages.canonical_link or tt_content.header_link.
I can see how this can be done by checking for the permissions of current user to edit the page or content by using e.g. $GLOBALS['BE_USER']->getPagePermsClause(Permission::CONTENT_EDIT). Also it can be checked if user has write access to table by accessing via $GLOBALS['BE_USER']->groupData['tables_modify'] or to the field by checking if the field is an exclude field and checking groupData['non_exclude_fields'].
But groupData is public but internal (so this generates warnings) and I am wondering if maybe I am missing some more general public API to do this. Also, I am not sure if I am missing some things: There are a lot of ways you can configure the access, such as editlock for the page, you can restrict access to edit fields for specific language, etc. etc.

Downloading and Moving OneDrive files from shared link directory

I am looking for assistance to find out how I can download and move a OneDrive file that is accessed through a shared directory, via the shared link method of sharing.
I have two users:
user 'A' who is a Microsoft Consumer and has a regular OneDrive account and will host a csv file 'test.csv' in a folder 'toshare'
and user 'B' who is also a regular Microsoft Consumer who should use the graph API to download test.csv and then move the file to a subdirectory /toshare/archive
Aside: I am currently using the chrome app "advanced REST client" to manually make the REST calls, and am getting Authenticated OAuth BEARER tokens by inspecting network traffic from Microsoft's online "Graph Explorer" tool. After we understand the calls, we'll integrate it into our Java app.
I have succesfully followed the instructions here:
https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/api/shares_get
to view the folder contents.
To be more explicit, user 'A' has went into OneDrive and has right clicked the folder 'toshare' and selected shareLink. I have converted the shareLink to a share token and then used the following API call with the Graph API as user 'B':
GET https://graph.microsoft.com/v1.0/shares/<share-token>/root?$expand=children
this shows me all the files in the directory, which includes 'test.csv'
Now, using this information, how can I download test.csv? Assuming user 'B' doesn't know the name of the file, but can identify it by being a .csv file (we can do this in code). There does not appear to be much documentation on how to download the files through a share.
The closest I've gotten was to take the "webUrl" attribute of the children object for my file, and then turn that into a share token and call
GET https://graph.microsoft.com/v1.0/shares/<child-share-token>/root
This will show me the file meta-data. and then I try to download it by roughly following the api documentation to download https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/api/item_downloadcontent
GET https://graph.microsoft.com/v1.0/shares/<child-share-token>/root/content
This is interesting because this works if I make the call with user 'A' but does not work for user 'B' who instead gets a 403 in advanced REST client. (If I run it in Graph Explorer, I get "The site in the encoded share URI is invalid." instead, which I've discovered with other experimentation, really means there's an authorization issue.)
GET https://graph.microsoft.com/v1.0/shares/<share-token>/root:/test.csv:/content
Also does not work, it returns: "400 Bad Request" with message: "Resource not found for the segment 'root:'." It seems like the path style file navigation does not work for shared directories?
At this point I'm rather stuck. After downloading the file, I also would like to move it into a subdirectory, denoting that it has already been read in. I'd also like to get this working for OneDrive for Business, but that seems to be another set of challenges that I'll leave for another day.
Any insight would be great thanks,
Jeremy
It's best to consider the shares/{id} segments to be similar to drives/{id}, at which point all of the previous documentation around children access is applicable. Given your scenario I'd use the path syntax:
https://graph.microsoft.com/v1.0/shares/<share-token>/root/children/test.csv
This obviously necessitates knowing the file name, but it sounds like you already have an algorithm to do that.
Theoretically your approach for creating a child-share-token would work, but it would now require that User B both provide authentication as well as to have explicit permissions. Since your share-token was a sharing link User B is most likely getting permission by virtue of the fact that they have the URL, in which case generating a new one is probably removing the special token that allows this to work. That's why it's best to always use the original share-token where possible.
Similar rules will apply to move the file. First off, we'll assume that the sharing link provides the ability to "Edit" otherwise none of this will work :). Second, we'll assume that the archive folder already exists (if it doesn't you'd need to create it using a POST to https://graph.microsoft.com/v1.0/shares/<share-token>/root/children that looks like what we've documented here).
To move the file you'd want to PATCH to https://graph.microsoft.com/v1.0/shares/<share-token>/root/children/test.csv and provide a new parentReference as documented here. It's always best to use id values if you have them, but you should also be able to provide the path to the parent in the form of /shares/<share-token>/root/children/archive.

Drupal - need redirect to specified page when node is deleted

I'm using the pathologic module, and currently when a node is deleted users will get a 404 error. I want to set up a Rule such that when ANY node is deleted, a redirect is put in place to send users looking for that path to the HOME page.
Do I need Rules for this, and if so, what is the best method? I haven't been able to successfully get this to work so far because of the interaction between the nid and the pathologic-created redirect. Many of my users have been sent URLs in email, etc. and I don't want them to get a 404.
Thanks in advance!
One soulition could be for you:
install https://www.drupal.org/project/hook_post_action module
write your own module in which you implement hook_node_postdelete($node) in which you set a drupal_goto()

GWT RequestFactory: check if members have been set without permission

I am working with GWT / RequestFactory and a set of customer requirements regarding permissions. Let me explain a basic example:
Every user is assigned to a company. Every user should be able to edit company's core data - but only e.g contact information, website etc. Security-relevant ones like BIC/SWIFT, IBAN, Company name and so on can only be changed if the user has a certain permission XY.
So far so good, on the client side I can check the permissions and disable those fields the user is not allowed to edit. But what would be the most elegant way to ensure on the server side that those fields have not been set without permission?
My problem is that I cannot track changes on the server side. Having #PreAuthorize on every setter is not an option too, because it would end in an authorization-massacre in each and every entity.
At the moment I am following a workaround: every field that is secured / depends on a given permission is passed as an argument to the entity-method and is excluded from the proxy. That way, values cannot be set using the proxy and I can check in my server code if the user has permissions. If not, nothing happens. If user has permissions, I set the values manually. But that produces a lot of boilerplate-code and ugly method signatures because the number of values passed to the method could get large.
I hope you understand my issue. I'm looking forward for your opinions and tips. Thank you in advance.
Well, you can receive many answers (different each other), and all of them could be right, so, at the end is your call. Wait for others answers. I am going to give you the approach that I followed (and it worked pretty well). :D.
Under my opinion, the server should do less as possible, so keep the logic for allowing modify each param on the server I think it is not a scalable solution (if your system has 1M users modifying everything at the same time, will your server work fluent?). I prefer let the client do the job (like Roomba :D).
For solving that problem, in our system we implemented an Access Control List solution. You can store in your db, on each user entity, a list with granted permissions. So, when that information arrives to the client (after user's log in, for example), you can get them, and show the fields that he/she is allow to modify.
Something like:
if (canModifyPersonalDetails(user.getAcls(), ...) ) {
//show labels ...
}
if (canModifyBankDetails(user.getAcls(), ...) ) {
//show labels
}
You can not avoid server call for log in, so it is not a big deal send the extra information (think about the ACLs could be simple list of integers 0 means personal details, 1 bank details....).
If you are dealing with very compromised information and you prefer do some stuff on the server, in that case probably I'd set up a security level, when you are persisting/updating your proxy, I'd do something like:
if (isAllowForPersonalDetails(user.getSecurityCode()) {
//update the modified personal details
}
if (isAllowForBankDetails(user.getSecurityCode()) {
//update the modified bank details
}
user.update();
I am a big fan of clear User GUI's, and a very big fan of let the server free as much as possible, so I prefer the first option. But if you have constraints for modifying user entity in db, or you prefer do not modify your views, or any constraint with security, maybe the second option is the best one for you.
Hope that helps!

How is ACL implemented

i am using Zend_Acl, PHP and is wondering how shld ACLs be implemented.
shld every page be a resource and i always query the acl to see if a user is authorized? i guess i must use this if i want to use a controller plugin (can be setup to run on every request) to check if a user is allowed?
or do i just put the query code where i need it? eg. at the top of pages i need to query the acl? then in pages publicly available, i just skip it? may get troublesome if the application gets big?
ok, i just answer this question then close it
what i did now was have a controller plugin that sets its resource based on controller name and privilege based on action name. then query the acl based on that
still under development, but what i currently have look like http://pastebin.com/9BYzms7W