Skip to content

Instantly share code, notes, and snippets.

@bryfox
Created June 4, 2018 17:42
Show Gist options
  • Save bryfox/56093cfec319440359b821b2df52f789 to your computer and use it in GitHub Desktop.
Save bryfox/56093cfec319440359b821b2df52f789 to your computer and use it in GitHub Desktop.
Example device API spec for Network Canvas Server
{
"host": "localhost:51001",
"basePath": "/",
"schemes": [
"http"
],
"info": {
"title": "Network Canvas Devices API",
"description": "REST API for paired tablet & desktop clients",
"version": "0.0.0"
},
"swagger": "2.0",
"paths": {
"/devices/new": {
"get": {
"summary": "Pairing Request",
"description": "Pairing Step 1. Generate a new pairing request. Responds with the request ID, and presents a pairing passcode to user (out of band). This information can be used to complete the pairing (create a device).\nA response is not sent until the user takes action (via the GUI), or the request times out; the connection is intended to be open for an extended period of time.",
"responses": {
"200": {
"description": "Information needed to complete the pairing request",
"schema": {
"type": "object",
"properties": {
"status": {
"type": "string",
"example": "ok"
},
"data": {
"type": "object",
"properties": {
"pairingRequestId": {
"type": "string",
"format": "uuid",
"description": "UUIDv4",
"example": "b0a17a58-dc13-4270-998f-ec46a7d8edb2"
},
"salt": {
"type": "string",
"format": "hexadecimal",
"example": "a866b6e85b17caa294093ef3454da1b0",
"description": "32-byte hex"
}
}
}
}
}
},
"400": {
"description": "request error",
"schema": {
"$ref": "#/definitions/Error"
}
}
}
}
},
"/devices": {
"post": {
"summary": "Pairing Confirmation",
"description": "Pairing Step 2. User has entered pairing code.",
"parameters": [
{
"in": "body",
"schema": {
"type": "object",
"properties": {
"message": {
"required": true,
"type": "string",
"format": "hexadecimal",
"description": "The nonce + message payload, encrypted with a client-generated secret.\n\nThis message is a hex encoding of the concatenation of two byte arrays:\n1. Nonce: a 24-byte nonce (not re-used) chosen by the client\n2. Ciphertext: the message, encrypted with secret key and nonce.\n\nFor the message format before encryption, see\n[DecryptedPairingConfirmationRequest](#/definitions/DecryptedPairingConfirmationRequest).\n\nTo encrypt the JSON payload above, use [libsodium](https://download.libsodium.org/doc/):\n1. Derive a secret key from (1) the out-of-band pairing code, and (2) the salt returned from `/devices/new`\n2. Generate a nonce\n3. Use the [secretbox_easy API](https://download.libsodium.org/doc/secret-key_cryptography/authenticated_encryption.html) for authenticated encryption\n\nThe nonce must be additionally sent in plaintext in order to decrypt the message. The server can reconstruct the secret from previous knowledge about the salt and pairing code.\n"
}
}
}
}
],
"responses": {
"200": {
"description": "new Device information (encrypted)",
"schema": {
"type": "object",
"properties": {
"status": {
"type": "string",
"example": "ok"
},
"message": {
"required": true,
"type": "string",
"format": "hexadecimal",
"description": "The nonce + message payload.\n\nAs in the request, the message is a hex encoding of nonce + ciphertext.\n\nFor the message format after decryption, see [Device](#/definitions/Device).\n"
}
}
}
},
"400": {
"description": "request error",
"schema": {
"$ref": "#/definitions/Error"
}
}
}
}
},
"/protocols": {
"get": {
"summary": "Protocol list",
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "all protocols available",
"schema": {
"type": "object",
"properties": {
"status": {
"type": "string",
"example": "ok"
},
"data": {
"type": "array",
"items": {
"$ref": "#/definitions/Protocol"
}
}
}
}
},
"400": {
"description": "request error",
"schema": {
"$ref": "#/definitions/Error"
}
}
}
}
},
"/protocols/{filename}": {
"get": {
"summary": "Protocol download",
"description": "Direct download of a zipped protocol package",
"produces": [
"application/zip",
"application/json"
],
"responses": {
"200": {
"description": "zipped protocol (binary data). Checksum available from /protocols endpoint",
"schema": {
"type": "file",
"example": "[raw data buffer]"
}
},
"400": {
"description": "request error",
"schema": {
"$ref": "#/definitions/Error"
}
}
}
}
}
},
"definitions": {
"Device": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "UUIDv4",
"example": "a692d57c-ab0f-4aa4-8e52-565a585990da"
},
"salt": {
"type": "string",
"description": "32-byte hex",
"example": "a866b6e85b17caa294093ef3454da1b0"
},
"name": {
"type": "string",
"description": "Name provided by the device during pairing confirmation",
"example": "Nexus 7 Tablet"
}
}
},
"Protocol": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"version": {
"type": "string"
},
"networkCanvasVersion": {
"type": "string"
},
"downloadUrl": {
"type": "string"
},
"sha256": {
"type": "string"
}
}
},
"DecryptedPairingConfirmationRequest": {
"type": "object",
"properties": {
"pairingRequestId": {
"required": true,
"type": "string",
"description": "available from the 'Pairing Request' response",
"example": "b0a17a58-dc13-4270-998f-ec46a7d8edb2"
},
"pairingCode": {
"required": true,
"type": "string",
"description": "alphanumeric code entered by the user",
"example": "u8jz1M85JRAB"
},
"deviceName": {
"required": false,
"type": "string",
"description": "A short, user-friendly description of the client device",
"example": "Nexus 7 Tablet"
}
}
},
"Error": {
"type": "object",
"properties": {
"message": {
"type": "string",
"example": "error"
},
"status": {
"type": "string",
"example": "Human-readable description of error"
}
}
}
},
"responses": {},
"parameters": {},
"securityDefinitions": {},
"tags": []
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment