ALISE JSON API v2 (Aglaia3)

This version provides functionality to authenticate, manage user data, apps, roles, sile permissions and siles, and ask questions.

Authentication

Requests get authorized via HMAC (hash based message authentication). The authentication header is created like this:


secret // came from Aglaia in login response
method // e.g. GET
path // e.g. /v2/apps
user // e.g. user@email.com
nonce // some number, increased in each request

digest = sha256(secret + method + path + nonce)
authenticationHeader = 'hmac ' + user + ':' + nonce + ':' + digest

The request then contains these headers:


GET /v2/apps HTTP/1.1
Host: appx.alise.systems
Authentication: hmac user@email.com:123456:ob23o4h89fo23u4of9h8324oh8f
Content-Type: application/json
Ontology: http://library.alise.systems/ontology/example#

Aglaia uses this information to do the following:

  • use the user name to get its current secrets from session

  • use the host to reduce the amount of possible secrets (secrets are only valid for one app)

  • check if the nonce is higher than the stored last nonce for the secret

  • build the digest from secret, method, path, date and nonce and compare it to the digest in the request

The “Ontology” parameter can be optionally specified and is only required when multiple ontologies are used in Aglaia. With this parameter, it is possible to switch between different ontologies. If no ontology is specified in the header, the default ontology will be used. After that, the request is either rejected or the session is retrieved successfully.

Auth column marked with “X” means the user has to be logged in to perform the request.

Auth

Method

Path

Request Body

Response Body

Description

POST

/login

{ email, password, ontology[opt]}

{ secret, uri }

If login credentials match a user, create an authentication secret and return also the user URI along with it.

POST

/login/license

{ deviceUri, serial}

{ secret, uri, validFrom, validTo, allowedDevices, registeredDevices }

If device URI and corresponding client serial number match the database entries, create an authentication secret and return also the user URI and license data along with it.

X

GET

/logout

Secret is invalid from now on.

POST

/register

{ email, password, firstname, lastname }

{ email }

Create a new deactivated user and an activation key. Send an activation email.

X

POST

/register/pronto

{ email, password, firstname, lastname }

{ email }

Create a new activated user.

X

POST

/fetch-key/redirect

{ appId }

{ key }

Create and return a redirect key for the given app.

X

POST

/fetch-key/password

{ password }

{ key }

If the password matches the current user, create and return a password key.

POST

/mail-key/password

{ email }

{ email }

Create a password key and send it via email.

X

POST

/mail-key/email

{ email }

{ email }

Create an email key and send it via email.

POST

/use-key/activation

{ key }

If the activation key exists (and is not too old), activate the corresponding user.

POST

/use-key/redirect

{ key }

{ secret, email, uri }

If key is valid, return a new secret along with the user’s email.

POST

/use-key/password

{ key, password }

If key is valid, set password of the user.

POST

/use-key/email

{ key }

If key is valid, set email of the user.

X

PATCH

/user/password

{ password }

Changes the password of the authenticated user.

Ontologies

The OWL-files used for storing data can be retrieved in binary (Base64) form via the API.

Auth

Method

Path

Request Body

Response Body

Description

GET

/ontology/list

[ uri_1, uri_2, … ]

Return all Ontology URIs within a JSON Array.

POST

/ontology/owl

{ uri }

{ uri, owl }

Returns the Ontology URI as well as the Base64-coded owl file.

Ontology Specifications

Auth

Method

Path

Request Body

Response Body

Description

GET

/category/children/{category}

[category1, category2, … ]

Return all subcategories of the provided {category} name

Siles

Siles are objects that are specified by their URI and contain use data, a human-readable (or searchable) label can be specified. Attributes, Categories and Slinks (semantic links) to other objects are called metadata. Additionally, a Sile can contain binary content (e.g. an image).

Sile Query Parameters

The following API calls (except for DELETE) always return a sile (or, by using the filter, multiple siles) where the amount of contained information can be specified by using a query parameter: Just add ?content= and a corresponding value at the end of the API call.

Specifier ID

Returned Content

uri (only multiple siles)

JSON Array with URIs

date (only multiple siles)

JSON Array with JSONObjects containing URI and according update date

label

uri and label

metadata

uri, label, attributes, categories and slinks (default)

binary

uri, label and data

all

complete sile as specified in Sile structure below

Single sile

Method

Path

Body

Description

GET

/sile/{id}

Get sile with this ID

POST

/sile

Sile

Create sile for unspecified ID

PATCH

/sile/{id}

{ …changes }

Change the given values in the sile with this ID

DELETE

/sile/{id}

Delete sile with this ID (or keep but set ‘deleted’ timestamp)

PUT

/sile/{id}

Sile

Replace the sile with this ID with a new sile

Sile structure

{
    "uri": "234r-23s2-234r-df54",
    "label": "Sile Label",
    "binaryArray": "lsadf89a43q4...",
    "attributes": {
        "attributeLabel1": [
            "Value 1",
            "Value 2"
        ]
    },
    "categories": [
        "category1",
        "category2"
    ],
    "slinks": {
        "dependsOn": [
            {
                "uri": "h39k-i9jn-826j-52ee",
                "label": "Linked sile 1"
            }
        ]
    }
}

Multiple siles

Additional query parameters “limit” and “offset” are allowed to avoid big data chunks.

Auth

Method

Path

Request Body

Response Body

Description

X

POST

/sile/filter

{filter}

[siles]

Returns an array of siles that match the specified filter

X

POST

/sile/filter/uris

[“uri_1”, “uri_2”, …]

[siles]

Returns an array of siles that match the specified uris

X

POST

/sile/filter/count

[“uri_1”, “uri_2”, …]

{count}

Returns the count of siles that match the specified uris

Filter structure

[
    {
        "and": [
            {
                "or": [
                    {
                        "type": "category",
                        "label": "Person"
                    },
                    {   
                        "type": "category",
                        "label": "Topic"
                    },
                    {
                        "type": "attributetypevalue",
                        "label": "FirstName",    
                        "value": "Franz"
                    }
                ]
            },
            {
                "type": "attributetyperange",
                "label": "AvgHeartRate",
                "minvalue": "80",
                "maxvalue": "120"
            }
        ]
    },
    {
        "or": [...]
    },
    {
        "not": {
            "type": "category",
            "label": "Company"
        }
    }
]

Atomic Filter types

type

sileuri

label

value

minvalue

maxvalue

description

attributerange

–

–

–

X

X

An attribute range filter selects siles which are annotated with an attribute whose value is within a specific range

attributetype

–

X

–

–

–

An attribute type filter passes all siles that have at least one attribute with the specified attribute type URI

attributetyperange

–

X

–

X

X

An attribute type range filter selects siles with a specific attribute type and a value within a range

attributetypevalue

–

X

X

–

–

Considers both the attribute type and its value

category

–

X

–

–

–

Checks whether a sile is annotated with a specific category

fulltextpattern

–

–

X

–

–

Matches tag annotations based on a regular expression pattern (case-insensitive)

labelvalue

–

–

X

–

–

Matches siles by label value

null

–

–

–

–

–

Matches all siles

sileinoutbound

X

–

–

–

–

Checks for siles that are slinked by, or slink to, the specified sile

sileinbound

X

–

–

–

–

Checks for siles that slink to the searched sile

sileoutbound

X

–

–

–

–

Checks for siles that are slinked by the searched sile

sileslinkinbound

X

X

–

–

–

Checks for siles linked by a specified sile with a specified slink type (inbound)

sileslinkoutbound

X

X

–

–

–

Checks for siles linking to a specified sile with a specified slink type (outbound)

slinkinoutbound

–

X

–

–

–

Searches for siles slinked to/from by a specified slink type

slinkinbound

–

X

–

–

–

Searches for siles slinked to by a specified slink type

slinkoutbound

–

X

–

–

–

Searches for siles that slink to other siles by a specified slink type

Filter query parameters (?key=value)

key

type

required

Default

description

limit

int

no

infinity

How many objects should be retrieved in one call

offset

int

no

0

How many objects should be left out before the first one

Sile Permission Management

These endpoints allow programmatic management of role-based sile permissions via the JSON API. They correspond to the XMLRPC methods getSileRolePermissions, setSileRolePermission, and checkUserSilePermission.

Auth

Method

Path

Request Body

Response Body

Description

X

GET

/sile/{id}/permissions

{ “Editor”: “read,write”, “Viewer”: “read” }

Returns role-based permissions for a sile

X

PUT

/sile/{id}/permissions

{ roleName, canRead, canWrite }

{ success: true }

Sets or clears read/write permissions for a role on a sile

X

GET

/sile/{id}/permissions/check?user={user}&type={type}

{ permitted: true/false }

Checks if a user has a specific permission on a sile

GET /v2/sile/{id}/permissions

Returns the current role-based permissions for a sile as a JSON object.

Response:

{
    "Editor": "read,write",
    "Viewer": "read",
    "Colleague": "read"
}

Each key is a role name, and the value is a comma-separated permission string ("read", "write", or "read,write").

PUT /v2/sile/{id}/permissions

Sets or clears read/write permissions for a specific role on a sile. Internally creates or removes RoleName:read and RoleName:write tags on the sile.

Request body:

{
    "roleName": "Editor",
    "canRead": true,
    "canWrite": true
}

Field

Type

Required

Description

roleName

String

Yes

Name of the role (e.g. “Editor”, “Viewer”)

canRead

boolean

No (default: false)

Whether the role should have READ permission

canWrite

boolean

No (default: false)

Whether the role should have WRITE/DELETE permission

Response:

{
    "success": true
}

Note: The calling user must have write permission on the sile.

GET /v2/sile/{id}/permissions/check?user={user}&type={type}

Checks if a specific user has a specific permission on a sile.

Query parameters:

Parameter

Type

Required

Description

user

String

Yes

Username to check

type

String

Yes

Permission type: "read", "write", or "delete"

Response:

{
    "permitted": true
}

Example: Grant “Colleague” read-only and “Editor” full access

PUT /v2/sile/urn:uuid:1234-5678/permissions HTTP/1.1
Authentication: hmac user@example.com:123456:digest...
Content-Type: application/json

{ "roleName": "Colleague", "canRead": true, "canWrite": false }
PUT /v2/sile/urn:uuid:1234-5678/permissions HTTP/1.1
Authentication: hmac user@example.com:123457:digest...
Content-Type: application/json

{ "roleName": "Editor", "canRead": true, "canWrite": true }

Example: Check if user has read access

GET /v2/sile/urn:uuid:1234-5678/permissions/check?user=john@example.com&type=read HTTP/1.1
Authentication: hmac user@example.com:123458:digest...

Response:

{ "permitted": true }

Role

Auth

Method

Path

Body

Description

X

GET

/role/{id}

Get Role Group with this ID

X

POST

/role

{roleId, readSlinks[opt], writeSlinks[opt], superRoleId[opt]}

Create Role Group

X

PATCH

/role/{id}

{ …changes }

Change the given values in the Role Group with this ID

X

PATCH

/role/add/{id}

{ readSlinks, writeSlinks }

Adds Slinks for read or write to the Role with this ID

X

PATCH

/role/remove/{id}}

{ readSlinks, writeSlinks }

Removes a Slink from the Role for read or write with this ID

Database Maintenance

Auth

Method

Path

Body

Description

X

DELETE

/sile/squeeze

Permanently removes all soft-deleted siles (admin only). Returns { "purged": count }

Source Code References

Component

File

REST API — Sile endpoints

aglaia3/src/main/java/systems/alise/aglaia3/api/v2/Sile.java

REST API — Role endpoints

aglaia3/src/main/java/systems/alise/aglaia3/api/v2/Role.java

Controller interface

aglaia3/src/main/java/systems/alise/aglaia3/controller/ILetoController.java

Controller (Direct/embedded)

aglaia3/src/main/java/systems/alise/aglaia3/controller/DirectLetoController.java

Controller (XMLRPC)

aglaia3/src/main/java/systems/alise/aglaia3/controller/SXmlRpcLetoController.java

Permission tests

aglaia3/src/test/java/systems/alise/aglaia3/api/v2/SilePermissionTest.java

ConnectorUtil (Leto bridge)

leto/src/main/java/systems/alise/leto/utils/ConnectorUtil.java

XMLRPC handlers

leto/src/main/java/systems/alise/leto/connector/HighLevelRepositoryConnector.java

XMLRPC client

shared/sxmlrpc/src/main/java/systems/alise/leto/protocol/sxmlrpc/client/HighLevelConnector.java

Notes

According to the redirect pattern, changing/creating requests would respond with the entity’s URL. In our case though, it is more practical to return the entity directly.

A DELETE request returns the latest representation of the deleted entity, because it can be used by the client to undo the operation by a new PUT request.

Leave a Reply

Your email address will not be published. Required fields are marked *