You want to manage a group of users of your web site, validate their roles on the site, and track user-dependent information. This application will manage a list of users, and associate with the users the number of attempted logins, their session timeout interval, and the roles they are assigned. Our application will use Role-Based Access Control (RBAC). We will use several functions to perform user management: xmldb:login($collection, $user, $pass) will log the user into the system and verify they have write access to a collection. Note that to log the user out, we will change the login to the user "guest." xmldb:get-current-user() will return the user-id of the current user. We will also need to add a new function that will check to see if a given user has a role. auth:has-role(xmldb:get-current-user(), $role) as xs:boolean check to see if a user has a given role. This will return a true() if the current user has a given role. The following is an example of a user's information. Note that we do not store the password in this file. The eXist system is used to store the user's password. 47 jdoe John Doe true 5 60  ba ba-admin   In the above example, the user jdoe has the role of ba and ba-admin which means the user is classified as a business analyst and also has the ability to administer the business analyst tools in the system. So the following function: auth:has-role('jdoe', 'ba') will return true() The following is a simplified login form that will allow the user to enter a login and a password and perform an HTTP post operation. Note that this is different from the eXist standard login in that it does not place the password on the URL using an HTTP get. This information is placed in a log file can compromise the security of the system. xquery version "1.0"; import module namespace style ='http://code.google.com/p/xrx/style' at '/db/xrx/modules/style.xqm'; declare option exist:serialize "method=xhtml media-type=text/html indent=yes"; let $user := xmldb:get-current-user() (: this gets the entire input URL :) let $get-query-string := request:get-query-string() (: were are only interested in the portion after the return= :) let $return-uri := substring-after($get-query-string, 'return=') return   Login {style:import-css()}   {style:header()} Login Current User = {$user}    Please Login   Username:    Password:       We will return to the following URI on success: {$return-uri} {style:footer()}   The following script takes incoming login data from an HTTP POST operation and performs a login. HTTP POST data arrives from the request:get-data() format in the following key-value-pair format: user=jdoe&pass=mypass&return=/exist/rest/db/xrx/apps/test/view/view-item.xq&id=47 Note that we assume that the user-id is in the first key-value pair and the pass is in the second. If you want a more general interface you can scan for the correct key in all the incoming form key-value pairs. xquery version "1.0"; import module namespace style ='http://code.google.com/p/xrx/style' at '/db/xrx/modules/style.xqm'; declare option exist:serialize "method=xhtml media-type=text/html indent=yes"; let $data := request:get-data() let $tokens := tokenize($data, '&') let $user := substring-after($tokens[1], 'user=') let $pass := substring-after($tokens[2], 'pass=') let $return := substring-after($tokens[3], 'return=') (: this is required to fix the incomming URI encodings :) let $unescape-uri := request:unescape-uri($return, 'UTF-8') (: this is required to put the first parameter deliminator ? back in place of the ampersand :) let $fix-first-param := replace($unescape-uri, 'xq&', 'xq?') let $login-success-indicator := xmldb:login("/db", $user, $pass) return   Login Result {style:import-css()}   {style:header()} {style:breadcrumb()} Login Status {if ($login-success-indicator) then Your Login Was Successful Return else Login Failed Try Again } You are logged in to the root database collection as {xmldb:get-current-user()}  Logout {style:footer()}   The following script logs you out of the system. Technically, it just logs you in as the user that has read-only access. xquery version "1.0"; import module namespace style='http://mdr.crossflow.com/style' at '/db/crossflo/modules/style.xq'; declare option exist:serialize "method=xhtml media-type=text/html indent=yes"; let $null := xmldb:login("/db", "guest", "guest") let $user := xmldb:get-current-user() return   Logout {style:import-css()} {style:breadcrumb()}   {style:header()} You have been logged out. User = {$user} Login {style:footer()}   Edit Item Delete Item  else User {xmldb:get-current-user()} has no roles with edit privileges Login  } You can also add a function in any page that has sensitive information or functions by checking that the user is logged in. This can be done with a single function called auth:validate-user() request:get-session-attribute("user") - this function will return the user name associated with the login session response:redirect-to($uri as xs:anyURI) - this function will redirect the user to another URI such as a login panel. Note that typically you want to make it easy to allow the user to bounce back to the screen that they were on. To do this you frequently want to add a parameter to the login.xq XQuery that will redirect the user back to where they came from. response:redirect-to('/exist/rest/db/xrx/apps/user-manager/login.xq?return=/exist/rest/db/myapp/edit/edit.xq?id=47') The following is a sample function that can be placed at the top of all pages that require user authentication: declare function auth:validate-user() as xs:string { let $url:= request:get-url() let $param-names := request:parameter-names() let $param-string :=for $count in 1 to count($param-names) let $param := $param-names[$count] let $value := request:get-parameter($param, '') let $return := if ($count=1) then (concat('? ',$param,'=',$value)) else (concat('&',$param,'=',$value)) return $return let $return-param :=fn:string-join($param-string,'') let $get-session-name :=request:get-session-attribute("user") let $login-uri := '/exist/rest/db/xrx/apps/user-manager/login.xq?url=' return if ($get-session-name) then ($get-session-name) else( response:redirect-to(xs:anyURI(concat($string,$url,fn:string-join($param-string,''))))) }; Back: XForms Generator • Next: Content Routing
{'wiki_source': 'wikibooks', 'other_info': "{'content_model': 'wikitext', 'language': 'en', 'title': 'XRX/User Manager', 'type': 'text'}"}