LCP Status Server API - readium/readium-lcp-server GitHub Wiki

In brief

The License Status Server stores, for each license, its ID, its status, the date of the last update of the license rights (in the case of a loan return or extension), the date of the last status update, and a sequence of past events. Each event is made of an event type, timestamp, originating device identifier, and name.

The License Status server exposes several REST API methods:

Public methods (accessible from the web)

  • Return a license status document
  • Process a device registration
  • Process a lending return
  • Process a lending renewal

Private methods (authentication required)

  • Create a license status document
  • Filter licenses
  • List all registered devices for a given licence
  • Revoke/cancel a license
  • Count licenses

From the user device, the registration workflow is as follows:

  1. The user makes a transaction.
  2. He gets a license.
  3. Each time he opens the publication, if the license contains a link to a status document and the device is online, then the status document is requested.
  4. If the device wasn’t registered before for this license and if the status document contains a registration link, then the device calls the registration link;
  5. As per the specification, if the server rejects the registration, the device must not let the user open the book before a successful attempt is made. It should store a positive result.
  6. If the license was updated (test of a timestamp in the status document), the device downloads the updated license.

API

Notify of a new license

Private method.

The License Server invokes this method after a license has been generated. The complete license is provided as a payload; the Status Server then extracts the necessary information from the license structure.

PUT <LSDbaseURL>/licenses

Payload: {license} (json).

Return:

  • 201: created
  • 400 (bad request) The license structure is malformed.
  • 5xx: internal error

Return a license status document

The method generates and returns a license status document, using a license identifier as key.

GET <LSDbaseURL>/licenses/<license_id>/status

Return:

Process a device registration

Activate a device for a given license.

Any certified device MUST call this method the first time it processes an LCP license, and SHOULD store a positive answer.

POST <LSDbaseURL>/licenses/<license_id>/register{?id, name}

where:

  • id is the device identifier in the form of a URL-encoded string (a UUID is recommended)
  • name is the device name in the form of a URL-encoded string

Return:

  • 200+ the updated license status: ok
  • 400 (bad request) Your device could not be registered correctly. Probable causes are that the license has been revoked, the identifier is poorly formatted, or the name is too long
  • 404 (not found) This license does not exist in the database (type http://readium.org/license-status-document/error/notfound)
  • 5xx (internal error) An unexpected error has occurred.

Process a lending return

The method checks that the calling device is activated and then modifies the end date associated with the given license, setting it to “now”. This method calls the “rights” method of the LCP server.

PUT <LSDbaseURL>/licenses/<license_id>/return{?id, name}

where:

  • id is the device identifier in the form of a URL-encoded string (a UUID is recommended)
  • name is the device name in the form of a URL-encoded string

Return:

  • 200 + the updated license status: ok
  • 400 (bad request) Your publication could not be returned properly.
  • 403 (rejected) Your publication has already been returned before.
  • 403 (rejected) Your publication has already expired.
  • 404 (not found) This license does not exist in the database.
  • 5xx (internal error) An unexpected error has occurred.

Process a lending renewal

The method checks that the calling device is activated, then modifies the end date associated with the license. This method calls the “rights” method of the LCP server.

PUT <LSDbaseURL>/licenses/<license_id>/renew{?end, id, name}

where:

  • end is the requested end date and time, in the form of a W3C date-time (YYYY-MM-DDThh:mm:ssTZD)
  • id is the device identifier in the form of a URL-encoded string (a UUID is recommended)
  • name is the device name in the form of a URL-encoded string

Return:

  • 200+ the updated license status: ok
  • 400 (bad request) Your publication could not be renewed properly.
  • 403 (rejected) Incorrect renewal period; your publication could not be renewed.
  • 404 (not found) This license does not exist in the database.
  • 5xx (internal error) An unexpected error has occurred.

Note 1: in the absence of the end parameter in the request, the default number of additional days (renew_days) found in the configuration file will be used. If there is none, an internal error is sent back with the message “No default renew period (parameter renew-days) found in the configuration file.”.

Note 2: The potential rights end parameter is initialized when the license is added to the LSD server. The corresponding number of days is the maximum value between a/ the value of renting_days in the configuration file and b/ the number of days passed as the "end" parameter of the method. It means that if renting_days is lower than the end date, no renewal is possible (potential_rights_end equals the initial end of the loan).

Check overshared licenses

Private method.

This method returns a sequence of license statuses in the order of their IDs.

GET <LSDbaseURL>/licenses{?devices, page, per_page}

It is used to filter the licenses that many devices have used. The devices parameter represents the minimum number of devices.

The pagination mechanism is based on the Link headers RFC (https://tools.ietf.org/html/rfc5988) and GitHub's pagination syntax (https://developer.github.com/v3/#pagination).

Partial license statuses are returned, e.g.:

{
  "id": "234-5435-3453-345354",
  "status": "active",
  "message": "Your license is currently active and has been used on at least one device.",
  "updated": {
    "license": "2014-08-05T00:00:00Z",
    "status": "2014-08-08T00:00:00Z"
  },
  "device_count": "100"
 }

Return:

  • 200 + the requested array of partial licenses: ok
  • 401: unauthorized
  • 400: bad request; the device boundary or pagination parameters are wrong
  • 5xx: internal error

Example: http://lsdserver.my.org/licenses?devices=100&page=2

List all registered devices for a given license

Private method.

Gives data to the provider (and publisher) about the use of a given license.

GET <LSDbaseURL>/licenses/<license_id>/registered

Return:

Revoke/cancel a license

Private method.

This method revokes (after use) or cancels (before use) a license by sending a partial license status document that contains the new status and a message indicating why the status is being changed.

PATCH <LSDbaseURL>/licenses/<license_id>/status

Payload: {partial license status document} (json)

Cancelling a license is only possible if its status is 'ready'. Revoking a license is only possible if its status is 'active' or 'ready'.

The LSD server internally calls the LCP server and updates the expiration time to “now”.

Return:

Sample partial license status document:

{
  "status": "revoked"
}

Count licenses

Private method.

This method returns the number of LCP licenses generated between two dates.

GET <LSDbaseURL>/licensecount

Query parameters (optional):

  • from: start date (date and time, RFC3339 format). By default, this is one year before the current date and time.
  • to: end date (date and time, RFC3339 format). By default, this is the current date and time.

The Server returns as a JSON structure:

  • total: the total number of LCP licenses
  • ready: the number of LCP licenses in the ready state
  • active: the number of LCP licenses in the active state
  • expired: the number of LCP licenses in the expired state
  • returned: the number of LCP licenses in the returned state
  • revoked: the number of LCP licenses in the revoked state
  • cancelled: the number of LCP licenses in the cancelled state
  • from: the start date and time as processed by the server
  • to: the end date and time as processed by the server

Return:

⚠️ **GitHub.com Fallback** ⚠️