Setting permissions on a document using MarkLogic's REST API - rest

I'm trying to specify permissions on documents in a MarkLogic 6 database using the rest api.
This is the permissions metadata I'm sending in (permissions.xml):
<rapi:metadata xmlns:rapi="http://marklogic.com/rest-api"
xmlns:prop="http://marklogic.com/xdmp/property">
<rapi:permissions>
<rapi:permission>
<rapi:role-name>arole</rapi:role-name>
<rapi:capability>update</rapi:capability>
</rapi:permission>
<rapi:permission>
<rapi:role-name>brole</rapi:role-name>
<rapi:capability>read</rapi:capability>
</rapi:permission>
</rapi:permissions>
</rapi:metadata>
using this command:
curl --anyauth --user user:pass -X PUT -T permissions.xml \
-H "Content-type: application/xml" \
"http://localhost:8003/v1/documents?uri=/test/test.xml&category=permissions"
When I look at the permissions afterwards, I see:
arole (update)
brole (read)
rest-reader (read)
rest-writer (update)
I expect it to only have the permissions for arole and brole.
The documentation says, "If no permissions are explicitly set, documents you create with the MarkLogic REST API have a read permission for the rest-reader role and an update permission for the rest-writer role." (And yes, I know, this example doesn't create a new document. But it does the same thing if I add a new document and set permissions at the same time using a multipart content+metadata message through the rest api).
Setting permissions via the direct xquery calls (ex. xdmp:document-insert with permissions) using the same user and database works as expected.
How can I keep the rest api from adding these extra permissions?
EDIT:
There's a ticket in with MarkLogic, no target date or version that I know of yet.
In case someone else runs into this, they did give me a workaround: Create new roles (or change existing ones), and give them rest-reader and/or rest-writer 'execute' privileges instead of having them inherit the rest-reader/rest-writer roles, or having a user directly assigned the rest-reader/rest-writer roles.

The internal function docmodupd:write-permissions always combines the input permissions with the output from xdmp:default-permissions. It does that to ensure that rest-reader can read the document, and rest-writer can update it. As far as I can tell there is no API to control this behavior.
If you have a strong use-case for omitting those extra permissions, contact support.

The easiest way to accomplish access via REST but NOT universal access to documents is to create custom roles that you can assign to users in place of the built-in roles. Add default read/write permissions to that role if desired (so that you don't have to specify the permissions on every document insert), along with the REST execute privilege(s) that you want the role to have (http://marklogic.com/xdmp/privileges/rest-writer, http://marklogic.com/xdmp/privileges/rest-reader). Don't assign the rest-reader or rest-writer built-in role to the custom role, just the execute privilege(s).
The custom roles will then be able to use all of the REST endpoints, but will NOT have universal access to all documents created via the REST interface. Searches and document GET requests will return only documents that the custom role has access to, and they won't be able to modify documents that their role does not have update permissions on.

Related

Use token's username in policy path

I have a Vault server where users will log-in using Userpass auth method and making use of kv secret engine.
The structure is like below -
-- user-kv
-- u1
-- u1-secret1
-- u1-secret2
-- u2
-- u2-secret1
-- u2-secret2
-- u3
-- u3-secret1
Here, u1, u2 , u3 are username of the users logged in using Userpass auth.
Now, for each user, I want to allow access to his path only. His path refers to this structure user-kv/<username>/ For example -
u1 --> user-kv/u1/*
u2 --> user-kv/u2/*
u3 --> user-kv/u3/*
and so on....
I am currently doing this by creating a separate policy for each user and and assigning it to him. I believe this is not the right way as when number of users grow, it would be difficult to maintain.
Is there a way to specify the logged-in user's username in the path in a policy. Something like -
path user-kv/{{username}}/* {
capabilities = ["read", "update", "create" ]
}
I have tried with templated policies but it doesn't work.
path user-kv/{{identity.entity.metadata.username}}/*
path user-kv/{{identity.entity.name}}/*
I can do something like user-kv/+/* but that would mean every user would have access to other's path.
Can anyone point out a more elegant way or provide links for further research?
I don't have a Vault running at the moment to check this out, sorry, but I believe that the templated policy you tried should work. The key is to create an identity that is associated (via an alias) with the userpass user. It's been a while since I've done this, so I can't remember the details, but check out the docs: https://www.vaultproject.io/docs/secrets/identity
The basic idea you have is feasible, but it is a lot more complex than that.
First, some background
A user in Vault is called and entity. When you authenticate for the very first time, a Vault entity will be created automatically, unless one already exists.
Obviously, you had to login with some auth backend. Let's say you used LDAP. Whatever you actually used is irrelevant for this discussion.
When you authenticated, an entity alias was created to tie this specific user in that specific auth backend to an entity.
With that background information, here is where it gets complicated.
Vault supports multiple auth backends, and you can tie them all to a single entity. So if our user prefers to login with the Github auth backend, he still keeps his access rights (aka policies). That happens because you would have set the entity alias prior to the user logging in.
Now even if you are using a single auth backend, Vault will still behave like that, because it can't know what the future holds.
Now back to your question.
To allow a path to represent a user, you must use the syntax described here. But to use them, you need to know in advance either:
The name of the entity
The name of the user in the auth backend
Option #2 will also require you to assign multiple policies (one per auth backend). I suggest you go with option 1.
The easiest way to acheive what you want (even if it not that easy) is to provision entities before they log in, and associate metadata to it.
Say you add the metadata kv-user=u3 to the entity that represents the user named u3, Then use {{ identity.entity.metadata.kv-user }} in your policy file.

Deleting bulk users from aem using excel and curl

I there any way to delete multiple users from aem useradmin console.I have the list of users with there userid in excel sheet. Any way to import list of users from excel sheet and can I delete users using curl command?.
You can delete users with curl:
curl -u : -FdeleteAuthorizable= http://localhost:4502/home/users/t/testuser
But to do so, you need to know the path to the user. Since users are nowadays stored in a node with a generic name (rather than with the user id as node name), you might need to search for them before they can be deleted.
If you have lots of users on AEM you might want to think about using ldap or something else for user management.
I don't think there is a direct utility available to do a bulk deletion of users.
CURL commands are easier to execute.
You can use the User Exporter utility in the ACS-Commons (https://adobe-consulting-services.github.io/acs-aem-commons/features/exporters/users/index.html) to download the list of users/groups in the system which will give you the paths of the users/groups.
Once you got the CSV downloaded, you can use the Paths to create CURL commands to delete the list of users.
You can also use applyTo parameter to delete them in a single request https://sling.apache.org/documentation/bundles/manipulating-content-the-slingpostservlet-servlets-post.html#deleting-multiple-items
But as there are more than 500, it is best to divide them into individual/fewer commands which will be easier for tracking

How to manage Azure DevOps group permissions with REST API

I need to set group permissions by inheriting from another already existing group but it has to be coded. I've managed to create a group but I haven't found a way to edit their permissions, is there any way to do it using either Client libraries or the API resources?
I believe it should be possible to do it using SecurityHttpClient's function SetAccessControlListsAsync() or something similar to it but I'm not sure how to implement it.
It seems you are looking for Access Control Entries - Set Access Control Entries API, which is used to add or update ACEs in the ACL for the provided token.
More details, you can refer to the documentation below:
https://learn.microsoft.com/en-us/rest/api/azure/devops/security/?view=azure-devops-rest-5.0
I don't think it is possible for the APIs at the moment. I also can not find APIs which are used to set the permission for the group.
#Cece Dong - MSFT, in your response, the API is for security namespace of the organization, but it is not for a group. In another word, I can not find any relationship with the security namespace and group. I created a group in my project, but when i use this API to query all the security namespaces, i can not get the relative group info.

Role Activity & Access Level

I have developed a web application with following architecture:
Frontend : Angular 6
Backend : Java REST APIs with Springboot
I want to add authentication and authorization to it. For that I'm looking for some open source application (e.g. KeyCloak, Gluu etc.). I would like to know in which tool the below scenarios are supported.
There will be predefined set of Activities on UI (e.g. Add, Edit,
Delete etc)
There will be predefined Access Levels (e.g. Read, Write, No Access)
I should be able to create Roles, then assign activities and access levels to those roles and assign those roles to user.
Can you please help me to find out a tool which supports my above scenario?
I tried something for KeyCloak, but i couldn't find a way to add activities, access levels and map roles to it. I think everything there is governed by Role only.
I just realized that I need Activity based authorization and not Role based authorization. Please help me find some tool for that.
I'm not sure what is meant by activity based authorization but i suspect you actually mean permission based authorization, in example: Grant permissions to users to perform certain actions.
Shiro offers you permissions and role based authorization out of the box.
You can create roles, add permissions to these roles and assign them to a user. Supported are implicit and explicit roles, whereas one role can hold any number of permissions. You can even work with wildcards and group the permissions.
For more information you should take a look at the official Shiro entry and especially the web documentation for your project in particular. Shiro offers full support for Spring-Boot applications, you can find a HowTo here.
Shiro fully supports your described scenario.

Permission control using apache shiro

I am new in apache shiro, and I read almost 60% of tutorials in apache shiro page.
It is a wonderful framework, however I wonder if it can meet my requirements.
I am interested in the permission-based authentication.
For example, to make sure if the user have the permission of delete resources, we can use this:
currentUser.isPermitted( "resource:delete" );
However in our application, even a user have the permission of delete resources, he can only delete some specified resources, not all of them.
For example(just an exmaple), the resource have an filed named createdby to record the one who create this resource.
Now user can only delete the resources created by himself if he have the resouce:delete permission.
In fact, the resources which can be deleted by the user(who have authenticated and have delete permission) will be calculated by more constraints.
Now how to make shiro work in this suitation?
You can do this in Shiro but you will have to write some code. Either create a subclass of Authorizer and inject it into the security manager or create a subclass of one of the realm classes such as JdbcRealm. Then override the isPermitted method. This will need to have access to your permissions model, for example the database table or a document in a NoSQL database.
Your call to isPermitted will need to specify the resource you are deleting so you can look it up in your overridden method.
If you override the isPermitted method in the AuthorizingRealm subclass you will have access to the logged in user's principals and the user's Roles: this gives you quite a bit of flexibility because you can have says: user (principal) Fred with roles: Manager, Administrator. Your permissions model can then decide if Fred, a Manager or and Administrator can perform the task on the specified resource.
Hope that gives you some ideas.
From the extent, I have explored Shiro, I don't think it gives that level of flexibility to have a customized check. It basically functions based on roles and permission defined in the config file.
For this functionality I would suggest that you display only those records the user is allowed to delete, by have this check at query fetch level. (or) add a condition at the UI level not display the delete button if logged in user is same as created by. This is just a suggestion.