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=read
domain-management=update
trigger-management=read
trigger-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!