Open grtjn opened 7 years ago
I've done things like this in app_specific, but we need a better way of feeding relevant roles and paths to protect:
alias_method :original_bootstrap, :bootstrap
def bootstrap
original_bootstrap
bootstrap_els
end
def bootstrap_els
logger.info "Bootstrapping Element Level Security.."
r = execute_query(
%Q{
xquery version "1.0-ml";
import module namespace sec = "http://marklogic.com/xdmp/security" at "/MarkLogic/security.xqy";
let $app-name := "#{@properties['ml.app-name']}"
let $role-names := (
$app-name || "-power-role",
$app-name || "-customer-A-role",
$app-name || "-customer-B-role"
)
let $role-ids :=
for $r in $role-names
return
xdmp:role($r)
return (
let $existing-rolesets :=
collection(sec:query-rolesets-collection())
//sec:query-roleset
[count(sec:role-id[. = $role-ids]) eq count($role-ids)]
where empty($existing-rolesets)
return
let $_ := sec:add-query-rolesets(sec:query-rolesets(sec:query-roleset($role-names)))
return "Added roleset: ((" || string-join($role-names, ",") || "))",
let $permissions :=
for $role-name in $role-names
return
xdmp:permission($role-name, "read")
let $protected-paths := (
"//ip",
"//City",
"//Gender",
"//TwitterID",
"//FacebookID",
"//InstagramID",
"//WeiboID",
"//EmailAddress",
"//StreetAddress",
"//ZipCode",
"//TelephoneNumber",
"//Birthday",
"//NbOfChilds",
"//Invoice"
)
for $path in $protected-paths
let $existing-path :=
collection(sec:protected-paths-collection())
[.//sec:path-expression eq $path]
return
if (empty($existing-path)) then
let $_ := sec:protect-path($path, (), $permissions)
return "Protected path: " || $path
else
let $existing-permissions := sec:path-get-permissions($path, ())
where count($existing-permissions[string(.) = $permissions/string()]) ne count($permissions)
return
let $_ := sec:path-add-permissions($path, (), $permissions)
return "Updated path: " || $path
)
},
{ :db_name => "Security" }
)
r.body = parse_body r.body
logger.info ""
logger.info r.body
logger.info ""
end
Corresponding wipe:
alias_method :original_wipe, :wipe
def wipe_els
logger.info "Wiping Element Level Security.."
r = execute_query(
%Q{
xquery version "1.0-ml";
import module namespace sec = "http://marklogic.com/xdmp/security" at "/MarkLogic/security.xqy";
let $app-name := "#{@properties['ml.app-name']}"
let $role-names := (
$app-name || "-power-role",
$app-name || "-customer-A-role",
$app-name || "-customer-B-role"
)
let $role-ids :=
for $r in $role-names
return
xdmp:role($r)
return (
for $existing-roleset in
collection(sec:query-rolesets-collection())
/sec:query-rolesets
[sec:role-id = $role-ids]
return
let $_ := sec:remove-query-rolesets($existing-roleset)
return ("Removed roleset: ((" || string-join($existing-roleset/sec:role-id/string(), ",") || "))"),
let $permissions :=
for $role-name in $role-names
return
xdmp:permission($role-name, "read")
let $protected-paths := (
"//ip",
"//City",
"//Gender",
"//TwitterID",
"//FacebookID",
"//InstagramID",
"//WeiboID",
"//EmailAddress",
"//StreetAddress",
"//ZipCode",
"//TelephoneNumber",
"//Birthday",
"//NbOfChilds",
"//Invoice"
)
for $path in $protected-paths
let $existing-path :=
collection(sec:protected-paths-collection())
[//sec:path-expression eq $path]
return
if (exists($existing-path)) then
let $existing-permissions := sec:path-get-permissions($path, ())
return
if (count($existing-permissions[string(.) = $permissions/string()]) eq count($permissions)) then
let $_ := sec:unprotect-path($path, ())
return
"Unprotecting path: " || $path (:sec:remove-path($path, ()):)
else if ($existing-permissions) then
let $_ := sec:path-remove-permissions($path, (), $permissions)
return
"Unprotecting path: " || $path
else ()
else ()
);
xquery version "1.0-ml";
import module namespace sec = "http://marklogic.com/xdmp/security" at "/MarkLogic/security.xqy";
for $path in collection(sec:protected-paths-collection())//sec:path-expression
let $existing-permissions := sec:path-get-permissions($path, ())
where empty($existing-permissions)
return
let $_ := sec:remove-path($path, ())
return
"Removing path: " || $path
},
{ :db_name => "Security" }
)
r.body = parse_body r.body
logger.info ""
logger.info r.body
logger.info ""
end
def wipe
wipe_els
original_wipe
end
Involves creating query rolesets, and protected paths