Search code examples
marklogic

Which characters are allowed in MarkLogic 8 usernames and roles?


I try to setup a user in MarkLogic with a username equal to an email adres("[email protected]"), seems I can create the user but not the corresponding role.

I created the user but when I want to add a role to it like so:

sec.userAddRoles(user,role)

this gives an error like:

2016-03-11 20:00:48.820 Notice: api-cluey-app: in /v1/projects.sjs, at 182:26, in projPost() [javascript]
2016-03-11 20:00:48.820 Notice: api-cluey-app: in [anonymous], at 1:67,
2016-03-11 20:00:48.820 Notice: api-cluey-app: in xdmp:eval("declareUpdate(); var sec = require('/MarkLogic/security.xqy'); s...", {role:"scc-proj-8327360-owner", user:"[email protected]"}, {isolation:"different-transaction", userId:"11821709629759202109", database:"17312114676051821586"}) [javascript]
2016-03-11 20:00:48.820 Notice: api-cluey-app: in /v1/projects.sjs [javascript]
2016-03-11 20:00:48.820 Notice: api-cluey-app: in /v1/projects.sjs [javascript]
2016-03-11 20:00:49.416 Info: api-cluey-app: Status 500: XDMP-LEXVAL: sec:role-name("[email protected]") -- Invalid lexical value "[email protected]"

And if I try to look into the admin security db it gets worse:

You've encountered an error in the server. If you have a maintenance contract, you can open a support ticket by copying the text below and emailing [email protected]. Otherwise, please see our community Q & A resources for help with this issue:
500: Internal Server Error
XDMP-LEXVAL: sec:role-name("[email protected]") -- Invalid lexical value "[email protected]"
In /MarkLogic/Admin/lib/session.xqy on line 595
In get-session-role()
$role = ()
$u = fn:doc("http://marklogic.com/xdmp/roles/6750406636815962640")/sec:role
In /MarkLogic/Admin/lib/nav-format.xqy on line 2486
In role-nav("security", "summary", "role", "")
$section = "security"
$panel = "summary"
$param = "role"
$icon = ""
$t = "section=security"
$npan = "summary"
$u = fn:doc("http://marklogic.com/xdmp/roles/6966198486234205304")/sec:role
$uid = fn:doc("http://marklogic.com/xdmp/roles/6966198486234205304")/sec:role/sec:role-id
$args = "section=security&role=6966198486234205304"
$uname = sec:role-name("davida")
In /MarkLogic/Admin/lib/nav-format.xqy on line 2392
In security-nav("security", "summary", "role", "")
$section = "security"
$panel = "summary"
$param = "role"
$icon = ""
$panel = "summary"
In /MarkLogic/Admin/lib/nav-format.xqy on line 2358
In printNav("security", "summary", "role", "")
$section = "security"
$panel = "summary"
$param = "role"
$icon = ""
$sec = "security"
$start-time = xs:dayTimeDuration("PT0.001403S")
In /MarkLogic/Admin/lib/role-summary-form.xqy on line 87
In roleSummaryPage()
In /role-summary.xqy on line 16

So my question: What characters are allowed in valid MarkLogic usernames and role? Can't seem to find any documentation on that?


Solution

  • You can find type definitions in the schemas that are shipped with MarkLogic. On a Mac, they're in ~/Library/MarkLogic/Config; on Linux, /opt/MarkLogic/Config/. The schema in question is security.xsd, which has the following type definition for role-name:

    <xs:simpleType name="role-name">
      <xs:annotation>
        <xs:documentation>
        </xs:documentation>
        <xs:appinfo>
        </xs:appinfo>
      </xs:annotation>
      <xs:restriction base="xs:NMTOKEN">
        <xs:minLength value="1"/>
      </xs:restriction>
    </xs:simpleType>
    

    xs:NMTOKEN is defined here: https://www.w3.org/TR/xml11/#NT-Nmtoken. It's a valid NameStartChar followed by any number of NameChar. In other words, it's a valid XML local name. (Update: this is incorrect; an XML local-name is more restrictive than an NMTOKEN.)

    In XQuery, you could check for valid names like this:

    "[email protected]" castable as xs:NMTOKEN
    

    which returns false.

    Update:

    Sorry I missed the follow-up question.

    All XML Schema types have built-in constructor/conversion functions, which work by applying a type-cast to their arguments. Those type constuctors are available in server-side JS, under the global xs object:

    var isValid
    try {
      isValid = !!xs.NMTOKEN("test%")
    } catch(err) {
      isValid = false
    }