Schemas/Types

Cordra manages information as digital objects. All digital objects must be typed.

Special digital objects called Types can be used to define the structure of the rest of the Cordra objects. Rules to validate and enrich objects during various stages of a digital object lifecycle can also be specified in those Types.

Essentially, Types in Cordra enable you to express:

  • The structure of your information using JSON schemas, and
  • JavaScript rules to apply during various stages.

Cordra is designed to support multiple types of digital objects (additionally allowing links between them).

In spite of the broader scope of these Type digital objects, for historical reasons, the Cordra type of the Type digital object is called Schema.

This section discusses the schema aspect of the Type objects. Refer to Lifecycle Hooks for defining rules that could be applied during various stages of a Cordra object lifecycle.

JSON schemas within those type objects should be defined using the core and validation parts of the JSON schema representation language (http://json-schema.org/latest/json-schema-core.html and http://json-schema.org/latest/json-schema-validation.html). The schemas can additionally leverage Cordra-specific functionality via attributes as defined below. The schemas are used on the server-side to ensure that objects are correctly structured, and on the client-side to automatically generate a user interface for viewing and editing objects. In order to edit the schemas in your instance via the UI, sign in as an administrator and click on the “Admin” dropdown, then “Types”.

The following is a schema for digital objects that correspond to an example Type called Document. In this example, the Document schema defines two properties that are user-managed: a name and a description, which will be part of each digital object of that Type. Each digital object will be allotted an identifier, but that identifier can also be configured to be included in the user-managed portion of the digital object, by including it as a third property as shown in the example schema below with the property name id:

{
    "type": "object",
    "title": "Document",
    "required": [
        "name",
        "description"
    ],
    "properties": {
        "id": {
            "type": "string",
            "cordra": {
                "type": {
                    "autoGeneratedField": "handle"
                }
            }
        },
        "name": {
            "type": "string",
            "maxLength": 128,
            "title": "Name",
            "cordra": {
                "preview": {
                    "showInPreview": true,
                    "isPrimary": true
                }
            }
        },
        "description": {
            "type": "string",
            "format": "textarea",
            "title": "Description",
            "cordra": {
                "preview": {
                    "showInPreview": true,
                    "excludeTitle": true
                }
            }
        }
    }
}

The Cordra software will generate an interface for editing objects based on the schema. The interface that conforms to the above schema is shown in Figure 1.

image1.png

Figure 1: Schema Editing Interface

Keywords and Attributes within the JSON Schema

Format keyword

The Cordra software supports validation of the “format” keyword for all values defined in the JSON Schema v4 draft specification. Additionally, other values for the “format” keyword may be used as UI hints for the automatic UI generation. Notably, arrays can have "format" : "table" to be laid out in a more compact tabular format; strings can have "format" : "textarea" to have a larger HTML textarea input box; and strings can have "format" : "password" to have a password-style hidden data entry input box.

Cordra-specific schema attributes

In addition to the usual JSON schema attributes on properties, properties can be marked with Cordra-specific attributes to indicate that a property should be handled in a particular way. These are all contained within a property cordra.

indexPayloads

In a “cordra” property at the top-level of a schema, "indexPayloads": false can be added to turn off indexing of payloads. This is helpful if payloads are exceptionally large and metadata is sufficient for search.

preview

These properties determine how the object should be displayed in UI previews.

preview.showInPreview

When added to a property the value of this property will be included in any UI previews of this object such as in search results or on nodes in the relationships graph.

Example:

"description": {
    "type": "string",
    "title": "Description",
    "cordra": {
        "preview": {
            "showInPreview": true
        }
    }
}

preview.isPrimary

The value of this property is used as the title of the object in previews. Used in conjunction with showInPreview

Example:

"description": {
    "type": "string",
    "title": "Description",
    "cordra": {
        "preview": {
        "showInPreview": true,
            "isPrimary": true
        }
    }
}

preview.excludeTitle

Used in conjunction with showInPreview. Used to indicate to the UI that only the property value should be shown and not the property title.

Example:

"description": {
    "type": "string",
    "title": "Description",
    "cordra": {
        "preview": {
        "showInPreview": true,
            "excludeTitle": true
        }
    }
}

type

Properties related to the typing and validation of the JSON structure.

type.suggestedVocabulary

This is similar to JSON schema enum keyword, but allows for the user to use an unspecified value. UI provides a combo box. No extra validation is performed; the suggested values are hints only.

Example:

"fruit": {
    "title": "Fruit",
    "type": "string",
    "cordra": {
        "type": {
            "suggestedVocabulary": [
                "Apple",
                "Banana",
                "Orange"
            ]
        }
    }
}

type.autoGeneratedField

If this is a string, it is equivalent to type.autoGeneratedField.type.

type.autoGeneratedField.type

The server will populate this field automatically with the specified type of data. Values can be:

  • handle
  • createdOn (or creationDate)
  • modifiedOn (or modificationDate)
  • createdBy
  • modifiedBy

The UI will display these fields but not allow the user to edit them. If the handle value is used for this property the id of the object will be inserted into the metadata record.

Example:

"id": {
    "type": "string",
    "cordra": {
        "type": {
            "autoGeneratedField": "handle"
        }
    }
}

type.autoGeneratedField.prepend

Indicates the the property is only a textual suffix of the auto-generated data. The full data is the concatenation of prepend with the value which will be stored in the property. This is typically used with type.autoGeneratedField.type = "handle". Here prepend is text which could contain more or less than a handle prefix; if a handle prefix is intended, it should end with a slash. For example, if the desired handle corresponding to value xyz is 20.5555/xyz, the schema should have "prepend" = "20.5555/".

type.autoGeneratedField.prependHandleMintingConfigPrefix

If true, behaves like prepend set to Cordra’s configured handle-minting prefix followed by a slash.

type.handleReference

Properties indicating that the value in the JSON should be a handle referring to another Cordra object.

type.handleReference.types

The value of this property needs to be an array of strings specifying the permitted types this object can reference. The auto generated UI for this field will provide a search input for searching for objects of the specified types. Omitting the types property or setting it to an empty array indicates that this reference can point to an object of any type.

Example:

"reference": {
    "title": "Reference",
    "type": "string",
    "cordra": {
        "type": {
            "handleReference": {
                "types": [
                    "type1",
                    "type2",
                    "type3"
                ]
            }
        }
    }
}

type.handleReference.excludeTypes

The value of this property needs to be an array of strings specifying the types this object may not reference. If this property is used, the type.handleReference.types property should be omitted. This property creates a “every type except these excluded types” semantic.

Example:

"reference": {
    "title": "Reference",
    "type": "string",
    "cordra": {
        "type": {
            "handleReference": {
                "excludeTypes": ["Foo", "Bar"]
            }
        }
    }
}

In the above example the reference can point at an object of any type except Foo or Bar.

type.handleReference.name

Specifies a relative json path to a property that should be used to name this reference in the UI.

Example:

"name": {
    "type": "string",
    "title": "Name"
},
"id": {
    "type": "string",
    "cordra": {
        "type": {
            "handleReference": {
                "types": [ "dataType" ],
                "name": "{{../name}}"
            }
        }
    }
}

In the above example {{../name}} indicates that the value of a sibling property should be used in the UI to name this reference. This is also used in the relationships graph to label the links.

type.handleReference.prepend

Indicates the the property is only a textual suffix of the handle of the referenced object. The full handle is the concatenation of prepend with the value of the property. Here prepend is text which could contain more or less than a handle prefix; if a handle prefix is intended, it should end with a slash. For example, if the desired handle corresponding to value xyz is 20.5555/xyz, the schema should have "prepend" = "20.5555/".

type.handleReference.prependHandleMintingConfigPrefix

If true, behaves like prepend set to Cordra’s configured handle-minting prefix followed by a slash.

auth

A string property indicating a field used to specify information used in authentication and authorization.

“auth”: “usersList”

Indicates that this object contains a list of users. The object can be used as a group in access control lists. The type of the associated property should be an array of strings.

In order to indicate that the elements of the list are suffixes of the full user ids, it is possible to use an expanded form:

"auth": { "type": "usersList", "prepend": "..." }

or:

"auth": { "type": "usersList", "prependHandleMintingConfigPrefix": true }

Example:

"users": {
    "type": "array",
    "format": "table",
    "title": "Users",
    "uniqueItems": true,
    "items": {
        "type": "string",
        "title": "User",
        "cordra": {
            "type": {
                "handleReference": {
                    "types": [ "user" ]
                }
            }
        }
    },
    "cordra": {
        "auth": "usersList"
    }
}

If there are multiple properties with the "auth": "usersList" nested property, only the last of such properties is considered by Cordra for the user list.

“auth”: “username”

Indicates that this object is a user. The associated property should be a string that identifies the user. Any object that has such a username property can be used to log into the system. Cordra ensures uniqueness of usernames.

Example:

"username": {
    "type": "string",
    "title": "Username",
    "cordra": {
        "auth": "username"
    }
}

“auth”: “password”

Used in conjunction with “username” property. Indicates that the associated property is a password. The following steps are taken to ensure the security of the provided password:

The password is not directly stored by the server.

When the object is saved, the password is salted with 16 bytes generated by java.security.SecureRandom, and the result is hashed using the PBKDF2WithHmacSHA1 algorithm for 10K iterations. The final hash is then stored.

Both the hash and the salt are stored in the metadata for this object. This metadata is not part of the content of the object and cannot be retrieved using the APIs.

When a user attempts to authenticate, the password supplied with the authentication request is salted with the stored salt and hashed the same number of times as before with the same algorithm. The resulting hash is compared with the stored hash. If the two hashes match, authentication is deemed successful.

Example:

"password": {
    "type": "string",
    "format": "password",
    "title": "Password",
    "cordra": {
        "auth": "password"
    }
}

“auth”: “requirePasswordChange”

Used in conjunction with “username” and “password” on a boolean property. When that property is set to true, the user must change their password (see Password Change API) before performing any other API call. Password changes will automatically set the property to false.

Example:

"requirePasswordChange": {
    "type": "boolean",
    "title": "Require Password Change",
    "description": "If true a new password must be set on next authentication.",
    "cordra": {
        "auth": "requirePasswordChange"
    }
}

“auth”: “accountActive”

Used in conjunction with “username” and “password” on a boolean property. When that property is set to true, the user account is active and can be used to log in and perform functions. If false, the user account is inactive and will be blocked. User accounts with no accountActive property are treated as active.

Example:

"accountActive": {
    "type": "boolean",
    "title": "Account active",
    "cordra": {
        "auth": "accountActive"
    }
}

“auth”: “publicKey”

Indicates that a public key is stored in the Cordra object for use with key-pair-based authentication (Authentication via Keys). The key should be stored in JSON Web Key (JWK) format.

response.mediaType

This indicates the default Internet media type for the content of the associated property. When a client requests the URI with the jsonPointer argument for this property, and uses the text argument, then the contents of the property will be returned along with a Content-Type: header with this value.

Example:

"xmlschema": {
    "type": "string",
    "format": "textarea",
    "title": "XML Schema",
    "cordra": {
        "response": {
            "mediaType": "application/xml"
        }
    }
}

search.altFieldName

Indicates an alternate field name to be used in searches, in addition to the default field name of the JSON Pointer.

Example:

"abstract": {
    "type": "string",
    "cordra": {
        "search": {
            "altFieldName": "abstract"
        }
    }
}

search.altPayloadFieldNames

On the root of the schema, this indicates a mapping from payload names to alternate field names to be used in searches, in addition to the default field name of the payload name.

Example:

{
    ...
    "cordra": {
        "search": {
            "altPayloadFieldNames": {
                "file": "dataset",
                "documentation": "doc"
            }
        }
    }
}

referrable

Used to indicate that the object contains information that can be referred to. Currently this is used for JavaScript modules to be used with require; see Using External Modules. With "id": true and "payloads": "scripts" this indicates that payloads on the object can be referred to as JavaScript modules, with the field being the directory name and the payload name being the filename.

Example:

{
    "type": "object",
    "properties": {
        "directory": {
            "type": "string",
            "cordra": {
                "referrable": {
                    "id": true,
                    "payloads": "scripts"
                }
            }
        }
    }
}

secureProperty

Used on a string property to indicate that the value should be hashed and salted prior to storage. Properties with this flag set are not stored in plain text, and so can not be retrieved directly. The hashes and salts are never made available to client calls.

Values can be verified against the stored hash using Type methods. See CordraUtil.js Module for details.

Example:

"securityQuestionAnswer": {
    "type": "string",
    "cordra": {
        "secureProperty": true
    }
}