SCIM driver questions

 

Hello,

I am trying to implement my first SCIM driver and am having some issues.  I'm working with atlassian access and the driver will not load if I tell it to update the schema on startup.  It doesn't seem capable of parsing the schema response from atlassian.  I haven't dug into the driver rules to see why at this point.  How standard is SCIM?  Should I be able to expect this to work without customization?

I tried to sync a user with the default schema and got an error back that one email address must be marked primary.  Would the schema update have prevented that if it could parse it?  Should I work on fixing the output manually?

Thanks,
Jeremiah

Top Replies

  • 0  

    I think the schema parsing is built into the shim.  SCIM is SUPPOSED To be pretty standard.  But like everything web based, the best part of the standards is that there are so many of them!

    You can point at a file, you can store local if you need to instead. Not sure how to get the SCIM schema and save as a file in this context for this endpoint though.

  • 0   in reply to Geoffrey Carman

    I pointed the driver to the URL and to a file that I pulled from the schema url using curl and either way it would give a fatal error on startup.  I checked the driverstorage attribute and found that it did import the schema there.  It still isn't working to add the primary email attribute though.  The schema doesn't make it clear to me that it is required so maybe that is the issue.

  • 0   in reply to jrmhscht

    Can you post the schema file?  But I am not suggesting the driver storage attribute.  There is a Driver config setting.  Enable refresh of schema, and new options appear, like this.

    So if you get the JSON, you can store it where the server can get at it, and read it on each restart.

  • 0   in reply to Geoffrey Carman

    Here is the schema file.  I did have it set in the schema settings like in your screenshot.  When that was set to Refresh on startup the driver would fail to start.  It did however store the contents of the file in the dirxml-driverstorage attribute.  

    {
      "totalResults":3,
      "itemsPerPage":10,
      "startIndex":1,
      "schemas":[
        "urn:ietf:params:scim:api:messages:2.0:ListResponse"
      ],
      "Resources":[
        {
          "id" : "urn:ietf:params:scim:schemas:core:2.0:User",
          "name" : "User",
          "description" : "User Account",
          "attributes" : [
            {
              "name" : "userName",
              "type" : "string",
              "multiValued" : false,
              "description" : "Unique identifier for the User, typically used by the user to directly authenticate to the service provider. Each User MUST include a non-empty userName value.  This identifier MUST be unique across the service provider's entire set of Users. REQUIRED.",
              "required" : true,
              "caseExact" : false,
              "mutability" : "readWrite",
              "returned" : "default",
              "uniqueness" : "server"
            },
            {
              "name" : "name",
              "type" : "complex",
              "multiValued" : false,
              "description" : "The components of the user's real name. Providers MAY return just the full name as a single string in the formatted sub-attribute, or they MAY return just the individual component attributes using the other sub-attributes, or they MAY return both.  If both variants are returned, they SHOULD be describing the same name, with the formatted name indicating how the component attributes should be combined.",
              "required" : false,
              "subAttributes" : [
                {
                  "name" : "formatted",
                  "type" : "string",
                  "multiValued" : false,
                  "description" : "The full name, including all middle names, titles, and suffixes as appropriate, formatted for display (e.g., 'Ms. Barbara J Jensen, III').",
                  "required" : false,
                  "caseExact" : false,
                  "mutability" : "readWrite",
                  "returned" : "default",
                  "uniqueness" : "none"
                },
                {
                  "name" : "familyName",
                  "type" : "string",
                  "multiValued" : false,
                  "description" : "The family name of the User, or last name in most Western languages (e.g., 'Jensen' given the full name 'Ms. Barbara J Jensen, III').",
                  "required" : false,
                  "caseExact" : false,
                  "mutability" : "readWrite",
                  "returned" : "default",
                  "uniqueness" : "none"
                },
                {
                  "name" : "givenName",
                  "type" : "string",
                  "multiValued" : false,
                  "description" : "The given name of the User, or first name in most Western languages (e.g., 'Barbara' given the full name 'Ms. Barbara J Jensen, III').",
                  "required" : false,
                  "caseExact" : false,
                  "mutability" : "readWrite",
                  "returned" : "default",
                  "uniqueness" : "none"
                },
                {
                  "name" : "middleName",
                  "type" : "string",
                  "multiValued" : false,
                  "description" : "The middle name(s) of the User (e.g., 'Jane' given the full name 'Ms. Barbara J Jensen, III').",
                  "required" : false,
                  "caseExact" : false,
                  "mutability" : "readWrite",
                  "returned" : "default",
                  "uniqueness" : "none"
                },
                {
                  "name" : "honorificPrefix",
                  "type" : "string",
                  "multiValued" : false,
                  "description" : "The honorific prefix(es) of the User, or title in most Western languages (e.g., 'Ms.' given the full name 'Ms. Barbara J Jensen, III').",
                  "required" : false,
                  "caseExact" : false,
                  "mutability" : "readWrite",
                  "returned" : "default",
                  "uniqueness" : "none"
                },
                {
                  "name" : "honorificSuffix",
                  "type" : "string",
                  "multiValued" : false,
                  "description" : "The honorific suffix(es) of the User, or suffix in most Western languages (e.g., 'III' given the full name 'Ms. Barbara J Jensen, III').",
                  "required" : false,
                  "caseExact" : false,
                  "mutability" : "readWrite",
                  "returned" : "default",
                  "uniqueness" : "none"
                }
              ],
              "mutability" : "readWrite",
              "returned" : "default",
              "uniqueness" : "none"
            },
            {
              "name" : "displayName",
              "type" : "string",
              "multiValued" : false,
              "description" : "The name of the User, suitable for display to end-users.  The name SHOULD be the full name of the User being described, if known.",
              "required" : false,
              "caseExact" : false,
              "mutability" : "readWrite",
              "returned" : "default",
              "uniqueness" : "none"
            },
            {
              "name" : "nickName",
              "type" : "string",
              "multiValued" : false,
              "description" : "The casual way to address the user in real life, e.g., 'Bob' or 'Bobby' instead of 'Robert'.  This attribute SHOULD NOT be used to represent a User's username (e.g., 'bjensen' or 'mpepperidge').",
              "required" : false,
              "caseExact" : false,
              "mutability" : "readWrite",
              "returned" : "default",
              "uniqueness" : "none"
            },
            {
              "name" : "title",
              "type" : "string",
              "multiValued" : false,
              "description" : "The user's title, such as \"Vice President.\"",
              "required" : false,
              "caseExact" : false,
              "mutability" : "readWrite",
              "returned" : "default",
              "uniqueness" : "none"
            },
            {
              "name" : "preferredLanguage",
              "type" : "string",
              "multiValued" : false,
              "description" : "Indicates the User's preferred written or spoken language.  Generally used for selecting a localized user interface; e.g., 'en_US' specifies the language English and country US.",
              "required" : false,
              "caseExact" : false,
              "mutability" : "readWrite",
              "returned" : "default",
              "uniqueness" : "none"
            },
            {
              "name" : "timezone",
              "type" : "string",
              "multiValued" : false,
              "description" : "The User's time zone in the 'Olson' time zone database format, e.g., 'America/Los_Angeles'.",
              "required" : false,
              "caseExact" : false,
              "mutability" : "readWrite",
              "returned" : "default",
              "uniqueness" : "none"
            },
            {
              "name" : "active",
              "type" : "boolean",
              "multiValued" : false,
              "description" : "A Boolean value indicating the User's administrative status.",
              "required" : false,
              "mutability" : "readWrite",
              "returned" : "default"
            },
            {
              "name" : "emails",
              "type" : "complex",
              "multiValued" : true,
              "description" : "Email addresses for the user.  The value SHOULD be canonicalized by the service provider, e.g., 'bjensen@example.com' instead of 'bjensen@EXAMPLE.COM'. Canonical type values of 'work', 'home', and 'other'.",
              "required" : true,
              "subAttributes" : [
                {
                  "name" : "value",
                  "type" : "string",
                  "multiValued" : false,
                  "description" : "Email addresses for the user.  The value SHOULD be canonicalized by the service provider, e.g., 'bjensen@example.com' instead of 'bjensen@EXAMPLE.COM'. Canonical type values of 'work', 'home', and 'other'.",
                  "required" : false,
                  "caseExact" : false,
                  "mutability" : "readWrite",
                  "returned" : "default",
                  "uniqueness" : "none"
                },
                {
                  "name" : "display",
                  "type" : "string",
                  "multiValued" : false,
                  "description" : "A human-readable name, primarily used for display purposes.  READ-ONLY.",
                  "required" : false,
                  "caseExact" : false,
                  "mutability" : "readWrite",
                  "returned" : "default",
                  "uniqueness" : "none"
                },
                {
                  "name" : "type",
                  "type" : "string",
                  "multiValued" : false,
                  "description" : "A label indicating the attribute's function, e.g., 'work' or 'home'.",
                  "required" : false,
                  "caseExact" : false,
                  "canonicalValues" : [
                    "work",
                    "home",
                    "other"
                  ],
                  "mutability" : "readWrite",
                  "returned" : "default",
                  "uniqueness" : "none"
                },
                {
                  "name" : "primary",
                  "type" : "boolean",
                  "multiValued" : false,
                  "description" : "A Boolean value indicating the 'primary'or preferred attribute value for this attribute, e.g., the preferredmailing address or primary email address.  The primary attributevalue 'true' MUST appear no more than once.",
                  "required" : false,
                  "mutability" : "readWrite",
                  "returned" : "default"
                }
              ],
              "mutability" : "readWrite",
              "returned" : "default",
              "uniqueness" : "none"
            },
            {
              "name" : "phoneNumbers",
              "type" : "complex",
              "multiValued" : true,
              "description" : "Phone numbers for the User.  The value SHOULD be canonicalized by the service provider according to the format specified in RFC 3966, e.g., 'tel:+1-201-555-0123'.Canonical type values of 'work', 'home', 'mobile', 'fax', 'pager', and 'other'.",
              "required" : false,
              "subAttributes" : [
                {
                  "name" : "value",
                  "type" : "string",
                  "multiValued" : false,
                  "description" : "Phone number of the User.",
                  "required" : false,
                  "caseExact" : false,
                  "mutability" : "readWrite",
                  "returned" : "default",
                  "uniqueness" : "none"
                },
                {
                  "name" : "display",
                  "type" : "string",
                  "multiValued" : false,
                  "description" : "A human-readable name, primarily used for display purposes.  READ-ONLY.",
                  "required" : false,
                  "caseExact" : false,
                  "mutability" : "readWrite",
                  "returned" : "default",
                  "uniqueness" : "none"
                },
                {
                  "name" : "type",
                  "type" : "string",
                  "multiValued" : false,
                  "description" : "A label indicating the attribute's function, e.g., 'work', 'home', 'mobile'.",
                  "required" : false,
                  "caseExact" : false,
                  "canonicalValues" : [
                    "work",
                    "home",
                    "mobile",
                    "fax",
                    "pager",
                    "other"
                  ],
                  "mutability" : "readWrite",
                  "returned" : "default",
                  "uniqueness" : "none"
                },
                {
                  "name" : "primary",
                  "type" : "boolean",
                  "multiValued" : false,
                  "description" : "A Boolean value indicating the 'primary' or preferred attribute value for this attribute, e.g., the preferred phone number or primary phone number.  The primary attribute value 'true' MUST appear no more than once.",
                  "required" : false,
                  "mutability" : "readWrite",
                  "returned" : "default"
                }
              ],
              "mutability" : "readWrite",
              "returned" : "default"
            },
            {
              "name" : "groups",
              "type" : "complex",
              "multiValued" : true,
              "description" : "A list of groups to which the user belongs, either through direct membership, through nested groups, or dynamically calculated.",
              "required" : false,
              "subAttributes" : [
                {
                  "name" : "value",
                  "type" : "string",
                  "multiValued" : false,
                  "description" : "The identifier of the User's group.",
                  "required" : false,
                  "caseExact" : false,
                  "mutability" : "readOnly",
                  "returned" : "default",
                  "uniqueness" : "none"
                },
                {
                  "name" : "$ref",
                  "type" : "reference",
                  "referenceTypes" : [
                    "User",
                    "Group"
                  ],
                  "multiValued" : false,
                  "description" : "The URI of the corresponding 'Group' resource to which the user belongs.",
                  "required" : false,
                  "caseExact" : false,
                  "mutability" : "readOnly",
                  "returned" : "default",
                  "uniqueness" : "none"
                },
                {
                  "name" : "display",
                  "type" : "string",
                  "multiValued" : false,
                  "description" : "A human-readable name, primarily used for display purposes.  READ-ONLY.",
                  "required" : false,
                  "caseExact" : false,
                  "mutability" : "readOnly",
                  "returned" : "default",
                  "uniqueness" : "none"
                },
                {
                  "name" : "type",
                  "type" : "string",
                  "multiValued" : false,
                  "description" : "A label indicating the attribute's function, e.g., 'direct' or 'indirect'.",
                  "required" : false,
                  "caseExact" : false,
                  "canonicalValues" : [
                    "direct",
                    "indirect"
                  ],
                  "mutability" : "readOnly",
                  "returned" : "default",
                  "uniqueness" : "none"
                }
              ],
              "mutability" : "readOnly",
              "returned" : "default"
            }
          ],
          "meta" : {
            "resourceType" : "Schema",
            "location" :
            "https://api.atlassian.com/scim/directory/62083768-8226-47df-903f-e2680a12ea4f/Schemas/urn:ietf:params:scim:schemas:core:2.0:User"
          }
        },
        {
          "id" : "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User",
          "name" : "EnterpriseUser",
          "description" : "Enterprise User",
          "attributes" : [
            {
              "name" : "organization",
              "type" : "string",
              "multiValued" : false,
              "description" : "Identifies the name of an organization.",
              "required" : false,
              "caseExact" : false,
              "mutability" : "readWrite",
              "returned" : "default",
              "uniqueness" : "none"
            },
            {
              "name" : "department",
              "type" : "string",
              "multiValued" : false,
              "description" : "Identifies the name of a department.",
              "required" : false,
              "caseExact" : false,
              "mutability" : "readWrite",
              "returned" : "default",
              "uniqueness" : "none"
            }
          ],
          "meta" : {
            "resourceType" : "Schema",
            "location" :
            "https://api.atlassian.com/scim/directory/62083768-8226-47df-903f-e2680a12ea4f/Schemas/urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"
          }
        },
        {
          "id" : "urn:ietf:params:scim:schemas:core:2.0:Group",
          "name" : "Group",
          "description" : "Group",
          "attributes" : [
            {
              "name" : "displayName",
              "type" : "string",
              "multiValued" : false,
              "description" : "A human-readable name for the Group. REQUIRED.",
              "required" : true,
              "caseExact" : false,
              "mutability" : "immutable",
              "returned" : "default",
              "uniqueness" : "none"
            },
            {
              "name" : "members",
              "type" : "complex",
              "multiValued" : true,
              "description" : "A list of members of the Group.",
              "required" : false,
              "subAttributes" : [
                {
                  "name" : "value",
                  "type" : "string",
                  "multiValued" : false,
                  "description" : "Identifier of the member of this Group.",
                  "required" : false,
                  "caseExact" : false,
                  "mutability" : "immutable",
                  "returned" : "default",
                  "uniqueness" : "none"
                },
                {
                  "name" : "$ref",
                  "type" : "reference",
                  "referenceTypes" : [
                    "User",
                    "Group"
                  ],
                  "multiValued" : false,
                  "description" : "The URI corresponding to a SCIM resource that is a member of this Group.",
                  "required" : false,
                  "caseExact" : false,
                  "mutability" : "immutable",
                  "returned" : "default",
                  "uniqueness" : "none"
                }
              ],
              "mutability" : "readWrite",
              "returned" : "default"
            }
          ],
          "meta" : {
            "resourceType" : "Schema",
            "location" :
            "https://api.atlassian.com/scim/directory/62083768-8226-47df-903f-e2680a12ea4f/Schemas/urn:ietf:params:scim:schemas:core:2.0:Group"
          }
        }
      ]
    }

  • 0   in reply to jrmhscht

    So reading that JSON, I see the relevant snippet for email is:

    {
      "name" : "emails",
      "type" : "complex",
      "multiValued" : true,
      "description" : "Email addresses for the user.  The value SHOULD be canonicalized by the service provider, e.g., 'bjensen@example.com' instead of 'bjensen@EXAMPLE.COM'. Canonical type values of 'work', 'home', and 'other'.",
      "required" : true,
      "subAttributes" : [
        {
          "name" : "value",
          "type" : "string",
          "multiValued" : false,
          "description" : "Email addresses for the user.  The value SHOULD be canonicalized by the service provider, e.g., 'bjensen@example.com' instead of 'bjensen@EXAMPLE.COM'. Canonical type values of 'work', 'home', and 'other'.",
          "required" : false,
          "caseExact" : false,
          "mutability" : "readWrite",
          "returned" : "default",
          "uniqueness" : "none"
        },
        {
          "name" : "display",
          "type" : "string",
          "multiValued" : false,
          "description" : "A human-readable name, primarily used for display purposes.  READ-ONLY.",
          "required" : false,
          "caseExact" : false,
          "mutability" : "readWrite",
          "returned" : "default",
          "uniqueness" : "none"
        },
        {
          "name" : "type",
          "type" : "string",
          "multiValued" : false,
          "description" : "A label indicating the attribute's function, e.g., 'work' or 'home'.",
          "required" : false,
          "caseExact" : false,
          "canonicalValues" : [
    	"work",
    	"home",
    	"other"
          ],
          "mutability" : "readWrite",
          "returned" : "default",
          "uniqueness" : "none"
        },
        {
          "name" : "primary",
          "type" : "boolean",
          "multiValued" : false,
          "description" : "A Boolean value indicating the 'primary'or preferred attribute value for this attribute, e.g., the preferredmailing address or primary email address.  The primary attributevalue 'true' MUST appear no more than once.",
          "required" : false,
          "mutability" : "readWrite",
          "returned" : "default"
        }
      ],
      "mutability" : "readWrite",
      "returned" : "default",
      "uniqueness" : "none"
    },

    Which I read to suggest that for emails, the JSON should look something like:

    {"emails":["value":"bob@acme.com","diplay":"bob@acme.com","type":"home",primary":"true"]}

    So, now, look at the outgoing event, and show us the <dirver-operation-data> which will have the JSON It sends out.  Lets see how it built the emails node.

    Of course, the shim does not know to set the primary attribute to true or false.

    You could always set it to trrue if you only ever send one.  You could decide which is primary in policy, somehow, and then add in that attribute to the JSON.

  • 0   in reply to jrmhscht

    {
      "name" : "emails",
      "type" : "complex",
      "multiValued" : true,
      "description" : "Email addresses for the user.  The value SHOULD be canonicalized by the service provider, e.g., 'bjensen@example.com' instead of 'bjensen@EXAMPLE.COM'. Canonical type values of 'work', 'home', and 'other'.",
      "required" : true,
      "subAttributes" : [
        {
          "name" : "value",
          "type" : "string",
          "multiValued" : false,
          "description" : "Email addresses for the user.  The value SHOULD be canonicalized by the service provider, e.g., 'bjensen@example.com' instead of 'bjensen@EXAMPLE.COM'. Canonical type values of 'work', 'home', and 'other'.",
          "required" : false,
          "caseExact" : false,
          "mutability" : "readWrite",
          "returned" : "default",
          "uniqueness" : "none"
        },
        {
          "name" : "display",
          "type" : "string",
          "multiValued" : false,
          "description" : "A human-readable name, primarily used for display purposes.  READ-ONLY.",
          "required" : false,
          "caseExact" : false,
          "mutability" : "readWrite",
          "returned" : "default",
          "uniqueness" : "none"
        },
        {
          "name" : "type",
          "type" : "string",
          "multiValued" : false,
          "description" : "A label indicating the attribute's function, e.g., 'work' or 'home'.",
          "required" : false,
          "caseExact" : false,
          "canonicalValues" : [
    	"work",
    	"home",
    	"other"
          ],
          "mutability" : "readWrite",
          "returned" : "default",
          "uniqueness" : "none"
        },
        {
          "name" : "primary",
          "type" : "boolean",
          "multiValued" : false,
          "description" : "A Boolean value indicating the 'primary'or preferred attribute value for this attribute, e.g., the preferredmailing address or primary email address.  The primary attributevalue 'true' MUST appear no more than once.",
          "required" : false,
          "mutability" : "readWrite",
          "returned" : "default"
        }
      ],
      "mutability" : "readWrite",
      "returned" : "default",
      "uniqueness" : "none"
    },

  • 0   in reply to Geoffrey Carman

    It built the email node without the primary attribute.

    "emails":[{"type":"work","value":"xxxx@xxxx.xx"}]

    I tried adding this attribute to the event to mark the work email as primary:

    <add-attr attr-name="emails:work:primary">
    <value type="state">true</value>
    </add-attr>

    This causes the policy NETQSCIMJSON-otp-XDStoJSON to output this error:

    Invalid JSON Payload: Given input value is invalid for the type 'complex' for the attribute 'emails:work:primary'. Check if you have given a list of JSON Values instead of a single JSON Value.

    Is this how it should work?  I tried using a string instead of a state as well and get the same error.

  • 0   in reply to jrmhscht

    So I would try emails:primary and not  with the :work: in the middle.  But show some trace of what comes into that policy, and if there is any useful events inside the trace.

  • 0   in reply to Geoffrey Carman

    I noticed that emails:primary is mapped to scim-PrimaryEmail by default so I tried to set that to "work" and to the work email address and both of those did nothing.  Tracing is disabled in the policy so I will have to edit it and enable tracing to learn what is going on.  I don't really understand why they created the new scim attributes in the schema and I suspect this could be related.  Perhaps some documentation is in order?

    I'll dig around in the policy to see if I can figure anything out and get tracing turned on.

  • 0   in reply to jrmhscht

    All the interesting work is done in java so I just created an ecmascript method to insert primary: true on the work email.  

    I wasn't able to get the shim to output anything for the scim attributes like urn:ietf:params:scim:schemas:extension:enterprise:2.0:User+department, but those aren't a big enough deal for me to spend more time on it.