Create account data xquery

Revision as of 11:02, 24 May 2016 by Admin (talk | contribs)

For importing usergroup information during an eXist-db upgrade this xquery sets all user groups and meta-information for each user.

This xquery will perform the following actions:

  • Create all groups that do not exist yet with descriptions, group managers.
  • Create users with password, primairy group, meta-data and activation status.
  • Set permissions on /db/apps/xis-data/accounts/* recursively: 0770 on collections and 0660 on documents.

To run the xquery below on the server:

  • Open a webbrowser, surf to: http://<server>:8877
  • Click on ‘dashboard’.
  • Log in as ‘admin’.
  • Open eXide.
  • Click: ‘New XQuery’ (paste the xquery in the box below to the browserscreen)
  • Click: ‘eval’ to run the xquery.
xquery version "1.0";

declare namespace cfg = "http://exist-db.org/Configuration";

declare function local:setPermissions($path as xs:string, $user as xs:string, $grp as xs:string, $grpperm as xs:string, $resprm as xs:string) {
   sm:chown(xs:anyURI($path),$user),
   sm:chgrp(xs:anyURI($path),$grp),
   sm:chmod(xs:anyURI($path),sm:octal-to-mode($grpperm)),
   sm:clear-acl(xs:anyURI($path)),
   for $file in xmldb:get-child-resources(xs:anyURI($path))
   return (
      sm:chown(xs:anyURI(concat($path,'/',$file)),$user),
      sm:chgrp(xs:anyURI(concat($path,'/',$file)),$grp),
      sm:chmod(xs:anyURI(concat($path,'/',$file)),sm:octal-to-mode($resprm)),
      sm:clear-acl(xs:anyURI(concat($path,'/',$file)))
   )
   ,
   for $collection in xmldb:get-child-collections($path)
   return
   local:setPermissions(concat($path,'/',$collection),$user,$grp,$grpperm,$resprm)
};

let $excludeaccounts:= ('SYSTEM','admin','guest','xis-webservice')
let $excludegroups  := ('dba','decor','decor-admin','terminology','issues','editor','tools','debug')
let $descriptionkey := 'http://exist-db.org/security/description'
let $account-data   := doc('/db/apps/accounts.xml')/x

let $create-groups  :=
    for $groupaccount in $account-data/groups/cfg:group[not(cfg:name=$excludegroups)][not(cfg:name=$account-data/users/cfg:account/cfg:name)]
    let $groupname          := $groupaccount/cfg:name
    let $groupdesc          := $groupaccount/cfg:metadata[@key=$descriptionkey]
    
    let $group-created      := if (not(sm:group-exists($groupname))) then (sm:create-group($groupname),true()) else (false())
    
    return (
        if ($groupdesc) then sm:set-group-metadata($groupname,$descriptionkey,$groupdesc) else ()
        ,
        <group username="{$groupname}" created="{$group-created}"/>
    )

let $create-users   := 
    for $account in $account-data/users/cfg:account[not(cfg:name=$excludeaccounts)]
    let $username           := $account/cfg:name/string()
    let $password           := $account/cfg:name/string()
    let $primary-group      := $account-data/users/cfg:primary-group[@user=$username]/@primarygroup/string()
    let $account-enabled    := $account/cfg:enabled/string()
    let $groups             := $account/cfg:group/@name/string()
    
    let $pw         :=  $account/cfg:password/string()
    let $digest-pw  :=  $account/cfg:digestPassword/string()
    
    let $user-created       := if (not(sm:user-exists($username))) then sm:create-account($username,$password,$groups) else (false())
    
    return (
        for $group in $groups[not(.=sm:get-user-groups($username))]
        return
            sm:add-group-member($group,$username)
        ,
        sm:set-user-primary-group($username,$primary-group)
        (:,
        sm:set-account-enabled($username,$account-enabled):)
        ,
        for $meta in $account/cfg:metadata
        return
            sm:set-account-metadata($username,xs:anyURI($meta/@key/string()),$meta/string())
        ,
        update value doc(concat('/db/system/security/exist/accounts/',$username,'.xml'))/cfg:account/cfg:password with $pw
        ,
        if (string-length($digest-pw)>0) then (
            if (not(doc(concat('/db/system/security/exist/accounts/',$username,'.xml'))/cfg:account/cfg:digestPassword)) then
                update insert <digestPassword/> following doc(concat('/db/system/security/exist/accounts/',$username,'.xml'))//cfg:account[1]/cfg:password[last()]
            else ()
            ,
            update value doc(concat('/db/system/security/exist/accounts/',$username,'.xml'))/cfg:account/cfg:digestPassword with $digest-pw
        )
        else ()
        ,
        <user username="{$username}" created="{$user-created}"/>
    )
    
let $add-group-managers  :=
    for $groupaccount in $account-data/groups/cfg:group[not(cfg:name=$excludegroups)]
    let $groupname          := $groupaccount/cfg:name
    return (
        for $groupmanager in $groupaccount/cfg:manager[not(@name=sm:get-group-managers($groupname))]
        return
            sm:add-group-manager($groupname,$groupmanager/@name)
    )
    
let $setXisAccountsPermissions  :=
    for $xis-account in xmldb:get-child-collections('/db/apps/xis-data/accounts')
    return
        local:setPermissions(concat('xmldb:exist:///db/apps/xis-data/accounts/',$xis-account),'admin',$xis-account,'0770','0660')
    
return <x>{$create-users,$create-groups}</x>