MarkLogic is uber secure. So secure it doesn’t let you see role names when viewing document permissions. This tip shows you how to resolve this foible…
Using xdmp:document-get-permissions($uri) you can fetch a document’s permissions – this lists the role IDs and actions (read, update, execute) that this role has.
Role IDs are unsignedLong’s though – not the human role name. Using the sec:get-role-names() call you can get the role name – but this must be a call against the security database – not the content or other database.
You can get around this though by invoking the sec function against the security database using xdmp:invoke-function. Below is the code:-
xquery version "1.0-ml";
declare namespace l = "local";
import module namespace sec = "http://marklogic.com/xdmp/security" at "/MarkLogic/security.xqy";
declare private function l:getperm($roleid) {
xdmp:invoke-function(
function() {
sec:get-role-names($roleid)
},
<options xmlns="xdmp:eval">
<database>{xdmp:security-database()}</database>
<transaction-mode>update-auto-commit</transaction-mode>
<isolation>different-transaction</isolation>
</options>
)
};
for $perm in xdmp:document-get-permissions("http://marklogic.com/cpf/domains/18444233322793156516.xml")
return
(l:getperm(xs:unsignedLong($perm/sec:role-id)) || "=" || xs:string($perm/sec:capability))
Using the above method you can write XQuery (or indeed Server-side JavaScript) that is executed in the context of another database. Much better and more secure than eval()-ing code – and not prone to XQuery-injection attacks.
The above code returns things like this:-
domain-management=readdomain-management=updatetrigger-management=readtrigger-management=read
Much nicer to read!
In the above example I’m looking at Domain document privileges (I shalln’t bore you with why), but you could look at a normal content document, or indeed anything stored within MarkLogic.
Happy Coding!