Mads Hansen gave a great example to demonstrate the user permissions and a test to ensure that you can see how a user can be given limited access to read documents AND also use the query console - an important set of permissions for users to explore the data. However, based on your reply to my original comments, I think an exercise in understanding how to find the access to the documents and user is important in troubleshooting.
Please see the following script. It must be run as an admin user or one that has the execute privilege 'user-get-roles' and likely 'xdmp-invoke-function'
xquery version "1.0-ml";
import module namespace sec="http://marklogic.com/xdmp/security" at
"/MarkLogic/security.xqy";
let $sec-db := xdmp:security-database()
let $uris := cts:uri-match('*')[1 to 20]
let $user := 'test-a-user'
(: run on the security database :)
let $role-report := xdmp:invoke-function(function(){
let $direct-roles := xdmp:role(sec:user-get-roles($user))
let $roles := (xdmp:role-roles(sec:user-get-roles($user)), $direct-roles)
return <roles>{
for $role-id in $roles
return element {'role'} {
attribute {'id'} {$role-id},
attribute {'directly-attached'} {if ($direct-roles = $role-id) then '1' else '0'},
xdmp:role-name($role-id)
}
}
</roles>
}, <options xmlns="xdmp:eval">
<database>{$sec-db}</database>
</options>
)
let $doc-report := <doc-access>
{
for $uri in $uris
return for $permission in xdmp:document-get-permissions($uri)
where $permission/*:capability = 'update' and $role-report//role/@id = $permission/*:role-id
return <match uri='{$uri}' capability='update'>{xdmp:role-name($permission/*:role-id)}</match>
}
</doc-access>
return element {'report'} {
if($role-report//role/text() = 'admin')
then element {'attention'} {'Admin role found - access to all documents'}
else (
$role-report,
$doc-report
)
}
Fill in the user name in question and a sequence of URIs (I just grabbed 20 in my sample)
If any direct or inherited role of admin will cause the following report:
<report>
<attention>Admin role found - access to all documents</attention>
</report>
Otherwise, you get back a report of all roles for that user (direct or inherited) and all uris with update access (and the matching role). This should be enough for troubleshooting permissions - especially on inherited permissions. It is not production code. You can also modify it to look for read or execute if needed. It also is an example of using some items from the sec namespaced functions.
<report>
<roles>
<role id="15240420431168313686" directly-attached="0">test-b</role>
<role id="7089338530631756591" directly-attached="0">rest-reader</role>
<role id="13041542794130379697" directly-attached="0">rest-extension-user</role>
<role id="15520654661378671735" directly-attached="0">rest-writer</role>
<role id="15240420431090884371" directly-attached="1">test-a</role>
</roles>
<doc-access>
<match uri="/foo/bar.xml" capability="update">test-b</match>
</doc-access>
</report>