Skip to content

Commit

Permalink
feat(keychain): implement OpenAPI endpoints
Browse files Browse the repository at this point in the history
Specifically for the in-memory and the vault
plugin implementations.

Signed-off-by: Peter Somogyvari <peter.somogyvari@accenture.com>
petermetz committed Jan 14, 2021

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent f4d51da commit 3a0acf4
Showing 24 changed files with 1,731 additions and 0 deletions.
143 changes: 143 additions & 0 deletions packages/cactus-core-api/src/main/json/openapi.json
Original file line number Diff line number Diff line change
@@ -393,6 +393,149 @@
}
}
}
},
"GetKeychainEntryRequest": {
"type": "object",
"required": [
"key"
],
"properties": {
"key": {
"type": "string",
"description": "The key for the entry to get from the keychain.",
"minLength": 1,
"maxLength": 1024,
"nullable": false
}
}
},
"GetKeychainEntryResponse": {
"type": "object",
"required": [
"key",
"value"
],
"properties": {
"key": {
"type": "string",
"description": "The key that was used to retrieve the value from the keychain.",
"minLength": 1,
"maxLength": 1024,
"nullable": false
},
"value": {
"type": "string",
"description": "The value associated with the requested key on the keychain.",
"minLength": 0,
"maxLength": 10485760,
"nullable": false
}
}
},
"SetKeychainEntryRequest": {
"type": "object",
"required": [
"key",
"value"
],
"properties": {
"key": {
"type": "string",
"description": "The key for the entry to set on the keychain.",
"minLength": 1,
"maxLength": 1024,
"nullable": false
},
"value": {
"type": "string",
"description": "The value that will be associated with the key on the keychain.",
"minLength": 0,
"maxLength": 10485760,
"nullable": false
}
}
},
"SetKeychainEntryResponse": {
"type": "object",
"required": [
"key"
],
"properties": {
"key": {
"type": "string",
"description": "The key that was used to set the value on the keychain.",
"minLength": 1,
"maxLength": 1024,
"nullable": false
}
}
}
},
"requestBodies": {
"keychain_get_entry_request_body": {
"description": "Requst body to obtain a keychain entry via its key",
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/GetKeychainEntryRequest"
}
}
}
},
"keychain_set_entry_request_body": {
"description": "Requst body to write/update a keychain entry via its key",
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SetKeychainEntryRequest"
}
}
}
}
},
"responses": {
"keychain_get_entry_200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/GetKeychainEntryResponse"
}
}
}
},
"keychain_get_entry_400": {
"description": "Bad request. Key must be a string and longer than 0, shorter than 1024 characters."
},
"keychain_get_entry_401": {
"description": "Authorization information is missing or invalid."
},
"keychain_get_entry_404": {
"description": "A keychain item with the specified key was not found."
},
"keychain_get_entry_500": {
"description": "Unexpected error."
},
"keychain_set_entry_200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SetKeychainEntryResponse"
}
}
}
},
"keychain_set_entry_400": {
"description": "Bad request. Key must be a string and longer than 0, shorter than 1024 characters."
},
"keychain_set_entry_401": {
"description": "Authorization information is missing or invalid."
},
"keychain_set_entry_500": {
"description": "Unexpected error."
}
}
},
Original file line number Diff line number Diff line change
@@ -228,6 +228,38 @@ export interface ConsortiumMember {
*/
nodeIds: Array<string>;
}
/**
*
* @export
* @interface GetKeychainEntryRequest
*/
export interface GetKeychainEntryRequest {
/**
* The key for the entry to get from the keychain.
* @type {string}
* @memberof GetKeychainEntryRequest
*/
key: string;
}
/**
*
* @export
* @interface GetKeychainEntryResponse
*/
export interface GetKeychainEntryResponse {
/**
* The key that was used to retrieve the value from the keychain.
* @type {string}
* @memberof GetKeychainEntryResponse
*/
key: string;
/**
* The value associated with the requested key on the keychain.
* @type {string}
* @memberof GetKeychainEntryResponse
*/
value: string;
}
/**
*
* @export
@@ -367,4 +399,36 @@ export interface PluginInstance {
*/
packageName: string;
}
/**
*
* @export
* @interface SetKeychainEntryRequest
*/
export interface SetKeychainEntryRequest {
/**
* The key for the entry to set on the keychain.
* @type {string}
* @memberof SetKeychainEntryRequest
*/
key: string;
/**
* The value that will be associated with the key on the keychain.
* @type {string}
* @memberof SetKeychainEntryRequest
*/
value: string;
}
/**
*
* @export
* @interface SetKeychainEntryResponse
*/
export interface SetKeychainEntryResponse {
/**
* The key that was used to set the value on the keychain.
* @type {string}
* @memberof SetKeychainEntryResponse
*/
key: string;
}

9 changes: 9 additions & 0 deletions packages/cactus-plugin-keychain-vault/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# `@hyperledger/cactus-plugin-keychain-vault`

> TODO: description
## Usage

```
// TODO: DEMONSTRATE API
```
474 changes: 474 additions & 0 deletions packages/cactus-plugin-keychain-vault/package-lock.json

Large diffs are not rendered by default.

79 changes: 79 additions & 0 deletions packages/cactus-plugin-keychain-vault/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
{
"name": "@hyperledger/cactus-plugin-keychain-vault",
"version": "0.3.0",
"description": "A keychain implementation storing its entries in Hashicorp Vault. Actual logic is implemented in Rust.",
"main": "dist/lib/main/typescript/index.js",
"mainMinified": "dist/cactus-plugin-keychain-vault.node.umd.min.js",
"browser": "dist/cactus-plugin-keychain-vault.web.umd.js",
"browserMinified": "dist/cactus-plugin-keychain-vault.web.umd.min.js",
"module": "dist/lib/main/typescript/index.js",
"types": "dist/types/main/typescript/index.d.ts",
"files": [
"dist/*"
],
"scripts": {
"generate-sdk": "openapi-generator generate --input-spec src/main/json/openapi.json -g typescript-axios -o ./src/main/typescript/generated/openapi/typescript-axios/",
"tsc": "tsc --project ./tsconfig.json",
"pretsc": "npm run generate-sdk",
"webpack": "npm-run-all webpack:dev webpack:prod",
"webpack:dev": "npm-run-all webpack:dev:node webpack:dev:web",
"webpack:dev:web": "webpack --env=dev --target=web --config ../../webpack.config.js",
"webpack:dev:node": "webpack --env=dev --target=node --config ../../webpack.config.js",
"webpack:prod": "npm-run-all webpack:prod:node webpack:prod:web",
"webpack:prod:web": "webpack --env=prod --target=web --config ../../webpack.config.js",
"webpack:prod:node": "webpack --env=prod --target=node --config ../../webpack.config.js"
},
"publishConfig": {
"access": "public"
},
"engines": {
"node": ">=10",
"npm": ">=6"
},
"repository": {
"type": "git",
"url": "git+https://github.com/hyperledger/cactus.git"
},
"keywords": [
"Hyperledger",
"Cactus",
"Integration",
"Blockchain",
"Distributed Ledger Technology"
],
"author": {
"name": "Hyperledger Cactus Contributors",
"email": "cactus@lists.hyperledger.org",
"url": "https://www.hyperledger.org/use/cactus"
},
"contributors": [
{
"name": "Please add yourself to the list of contributors",
"email": "your.name@example.com",
"url": "https://example.com"
},
{
"name": "Peter Somogyvari",
"email": "peter.somogyvari@accenture.com",
"url": "https://accenture.com"
}
],
"license": "Apache-2.0",
"bugs": {
"url": "https://github.com/hyperledger/cactus/issues"
},
"homepage": "https://github.com/hyperledger/cactus#readme",
"dependencies": {
"@hyperledger/cactus-common": "0.3.0",
"@hyperledger/cactus-core": "0.3.0",
"@hyperledger/cactus-core-api": "0.3.0",
"axios": "0.21.1",
"express": "4.17.1",
"typescript-optional": "2.0.1"
},
"devDependencies": {
"@types/express": "4.17.8",
"@types/express-serve-static-core": "4.17.17",
"openapi-types": "7.2.2"
}
}
76 changes: 76 additions & 0 deletions packages/cactus-plugin-keychain-vault/src/main/json/openapi.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
{
"openapi": "3.0.3",
"info": {
"title": "Hyperledger Cactus - Keychain API",
"description": "Contains/describes the Keychain API types/paths for Hyperledger Cactus.",
"version": "0.3.0"
},
"components": {
"schemas": {}
},
"paths": {
"/api/v1/plugins/@hyperledger/cactus-plugin-keychain-vault/get-keychain-entry": {
"post": {
"x-hyperledger-cactus": {
"http": {
"path": "/api/v1/plugins/@hyperledger/cactus-plugin-keychain-vault/get-keychain-entry",
"verbLowerCase": "get"
}
},
"operationId": "getKeychainEntry",
"summary": "Retrieves the contents of a keychain entry from the backend.",
"parameters": [],
"requestBody": {
"$ref": "../../../../cactus-core-api/src/main/json/openapi.json#/components/requestBodies/keychain_get_entry_request_body"
},
"responses": {
"200": {
"$ref": "../../../../cactus-core-api/src/main/json/openapi.json#/components/responses/keychain_get_entry_200"
},
"400": {
"$ref": "../../../../cactus-core-api/src/main/json/openapi.json#/components/responses/keychain_get_entry_400"
},
"401": {
"$ref": "../../../../cactus-core-api/src/main/json/openapi.json#/components/responses/keychain_get_entry_401"
},
"404": {
"$ref": "../../../../cactus-core-api/src/main/json/openapi.json#/components/responses/keychain_get_entry_404"
},
"500": {
"$ref": "../../../../cactus-core-api/src/main/json/openapi.json#/components/responses/keychain_get_entry_500"
}
}
}
},
"/api/v1/plugins/@hyperledger/cactus-plugin-keychain-vault/set-keychain-entry": {
"post": {
"x-hyperledger-cactus": {
"http": {
"path": "/api/v1/plugins/@hyperledger/cactus-plugin-keychain-vault/set-keychain-entry",
"verbLowerCase": "post"
}
},
"operationId": "setKeychainEntry",
"summary": "Sets a value under a key on the keychain backend.",
"parameters": [],
"requestBody": {
"$ref": "../../../../cactus-core-api/src/main/json/openapi.json#/components/requestBodies/keychain_set_entry_request_body"
},
"responses": {
"200": {
"$ref": "../../../../cactus-core-api/src/main/json/openapi.json#/components/responses/keychain_set_entry_200"
},
"400": {
"$ref": "../../../../cactus-core-api/src/main/json/openapi.json#/components/responses/keychain_set_entry_400"
},
"401": {
"$ref": "../../../../cactus-core-api/src/main/json/openapi.json#/components/responses/keychain_set_entry_401"
},
"500": {
"$ref": "../../../../cactus-core-api/src/main/json/openapi.json#/components/responses/keychain_set_entry_500"
}
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# OpenAPI Generator Ignore
# Generated by openapi-generator https://github.com/openapitools/openapi-generator

# Use this file to prevent files from being overwritten by the generator.
# The patterns follow closely to .gitignore or .dockerignore.

# As an example, the C# client generator defines ApiClient.cs.
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
#ApiClient.cs

# You can match any string of characters against a directory, file or extension with a single asterisk (*):
#foo/*/qux
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux

# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
#foo/**/qux
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux

# You can also negate patterns with an exclamation (!).
# For example, you can ignore all files in a docs folder with the file extension .md:
#docs/*.md
# Then explicitly reverse the ignore rule for a single file:
#!docs/README.md

.npmignore
.gitignore
git_push.sh

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
api.ts
base.ts
configuration.ts
index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
5.0.0-beta2
Original file line number Diff line number Diff line change
@@ -0,0 +1,252 @@
/* tslint:disable */
/* eslint-disable */
/**
* Hyperledger Cactus - Keychain API
* Contains/describes the Keychain API types/paths for Hyperledger Cactus.
*
* The version of the OpenAPI document: 0.3.0
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/


import { Configuration } from './configuration';
import globalAxios, { AxiosPromise, AxiosInstance } from 'axios';
// Some imports not used depending on template conditions
// @ts-ignore
import { BASE_PATH, COLLECTION_FORMATS, RequestArgs, BaseAPI, RequiredError } from './base';

/**
*
* @export
* @interface GetKeychainEntryRequest
*/
export interface GetKeychainEntryRequest {
/**
* The key for the entry to get from the keychain.
* @type {string}
* @memberof GetKeychainEntryRequest
*/
key: string;
}
/**
*
* @export
* @interface SetKeychainEntryRequest
*/
export interface SetKeychainEntryRequest {
/**
* The key for the entry to set on the keychain.
* @type {string}
* @memberof SetKeychainEntryRequest
*/
key: string;
/**
* The value that will be associated with the key on the keychain.
* @type {string}
* @memberof SetKeychainEntryRequest
*/
value: string;
}

/**
* DefaultApi - axios parameter creator
* @export
*/
export const DefaultApiAxiosParamCreator = function (configuration?: Configuration) {
return {
/**
*
* @summary Retrieves the contents of a keychain entry from the backend.
* @param {GetKeychainEntryRequest} getKeychainEntryRequest Requst body to obtain a keychain entry via its key
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
getKeychainEntry: async (getKeychainEntryRequest: GetKeychainEntryRequest, options: any = {}): Promise<RequestArgs> => {
// verify required parameter 'getKeychainEntryRequest' is not null or undefined
if (getKeychainEntryRequest === null || getKeychainEntryRequest === undefined) {
throw new RequiredError('getKeychainEntryRequest','Required parameter getKeychainEntryRequest was null or undefined when calling getKeychainEntry.');
}
const localVarPath = `/api/v1/plugins/@hyperledger/cactus-plugin-keychain-vault/get-keychain-entry`;
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, 'https://example.com');
let baseOptions;
if (configuration) {
baseOptions = configuration.baseOptions;
}
const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};
const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any;



localVarHeaderParameter['Content-Type'] = 'application/json';

const query = new URLSearchParams(localVarUrlObj.search);
for (const key in localVarQueryParameter) {
query.set(key, localVarQueryParameter[key]);
}
for (const key in options.query) {
query.set(key, options.query[key]);
}
localVarUrlObj.search = (new URLSearchParams(query)).toString();
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
const needsSerialization = (typeof getKeychainEntryRequest !== "string") || localVarRequestOptions.headers['Content-Type'] === 'application/json';
localVarRequestOptions.data = needsSerialization ? JSON.stringify(getKeychainEntryRequest !== undefined ? getKeychainEntryRequest : {}) : (getKeychainEntryRequest || "");

return {
url: localVarUrlObj.pathname + localVarUrlObj.search + localVarUrlObj.hash,
options: localVarRequestOptions,
};
},
/**
*
* @summary Sets a value under a key on the keychain backend.
* @param {SetKeychainEntryRequest} setKeychainEntryRequest Requst body to write/update a keychain entry via its key
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
setKeychainEntry: async (setKeychainEntryRequest: SetKeychainEntryRequest, options: any = {}): Promise<RequestArgs> => {
// verify required parameter 'setKeychainEntryRequest' is not null or undefined
if (setKeychainEntryRequest === null || setKeychainEntryRequest === undefined) {
throw new RequiredError('setKeychainEntryRequest','Required parameter setKeychainEntryRequest was null or undefined when calling setKeychainEntry.');
}
const localVarPath = `/api/v1/plugins/@hyperledger/cactus-plugin-keychain-vault/set-keychain-entry`;
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, 'https://example.com');
let baseOptions;
if (configuration) {
baseOptions = configuration.baseOptions;
}
const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};
const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any;



localVarHeaderParameter['Content-Type'] = 'application/json';

const query = new URLSearchParams(localVarUrlObj.search);
for (const key in localVarQueryParameter) {
query.set(key, localVarQueryParameter[key]);
}
for (const key in options.query) {
query.set(key, options.query[key]);
}
localVarUrlObj.search = (new URLSearchParams(query)).toString();
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
const needsSerialization = (typeof setKeychainEntryRequest !== "string") || localVarRequestOptions.headers['Content-Type'] === 'application/json';
localVarRequestOptions.data = needsSerialization ? JSON.stringify(setKeychainEntryRequest !== undefined ? setKeychainEntryRequest : {}) : (setKeychainEntryRequest || "");

return {
url: localVarUrlObj.pathname + localVarUrlObj.search + localVarUrlObj.hash,
options: localVarRequestOptions,
};
},
}
};

/**
* DefaultApi - functional programming interface
* @export
*/
export const DefaultApiFp = function(configuration?: Configuration) {
return {
/**
*
* @summary Retrieves the contents of a keychain entry from the backend.
* @param {GetKeychainEntryRequest} getKeychainEntryRequest Requst body to obtain a keychain entry via its key
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async getKeychainEntry(getKeychainEntryRequest: GetKeychainEntryRequest, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {
const localVarAxiosArgs = await DefaultApiAxiosParamCreator(configuration).getKeychainEntry(getKeychainEntryRequest, options);
return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
const axiosRequestArgs = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
return axios.request(axiosRequestArgs);
};
},
/**
*
* @summary Sets a value under a key on the keychain backend.
* @param {SetKeychainEntryRequest} setKeychainEntryRequest Requst body to write/update a keychain entry via its key
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async setKeychainEntry(setKeychainEntryRequest: SetKeychainEntryRequest, options?: any): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {
const localVarAxiosArgs = await DefaultApiAxiosParamCreator(configuration).setKeychainEntry(setKeychainEntryRequest, options);
return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
const axiosRequestArgs = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
return axios.request(axiosRequestArgs);
};
},
}
};

/**
* DefaultApi - factory interface
* @export
*/
export const DefaultApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) {
return {
/**
*
* @summary Retrieves the contents of a keychain entry from the backend.
* @param {GetKeychainEntryRequest} getKeychainEntryRequest Requst body to obtain a keychain entry via its key
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
getKeychainEntry(getKeychainEntryRequest: GetKeychainEntryRequest, options?: any): AxiosPromise<void> {
return DefaultApiFp(configuration).getKeychainEntry(getKeychainEntryRequest, options).then((request) => request(axios, basePath));
},
/**
*
* @summary Sets a value under a key on the keychain backend.
* @param {SetKeychainEntryRequest} setKeychainEntryRequest Requst body to write/update a keychain entry via its key
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
setKeychainEntry(setKeychainEntryRequest: SetKeychainEntryRequest, options?: any): AxiosPromise<void> {
return DefaultApiFp(configuration).setKeychainEntry(setKeychainEntryRequest, options).then((request) => request(axios, basePath));
},
};
};

/**
* DefaultApi - object-oriented interface
* @export
* @class DefaultApi
* @extends {BaseAPI}
*/
export class DefaultApi extends BaseAPI {
/**
*
* @summary Retrieves the contents of a keychain entry from the backend.
* @param {GetKeychainEntryRequest} getKeychainEntryRequest Requst body to obtain a keychain entry via its key
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof DefaultApi
*/
public getKeychainEntry(getKeychainEntryRequest: GetKeychainEntryRequest, options?: any) {
return DefaultApiFp(this.configuration).getKeychainEntry(getKeychainEntryRequest, options).then((request) => request(this.axios, this.basePath));
}

/**
*
* @summary Sets a value under a key on the keychain backend.
* @param {SetKeychainEntryRequest} setKeychainEntryRequest Requst body to write/update a keychain entry via its key
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof DefaultApi
*/
public setKeychainEntry(setKeychainEntryRequest: SetKeychainEntryRequest, options?: any) {
return DefaultApiFp(this.configuration).setKeychainEntry(setKeychainEntryRequest, options).then((request) => request(this.axios, this.basePath));
}
}


Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/* tslint:disable */
/* eslint-disable */
/**
* Hyperledger Cactus - Keychain API
* Contains/describes the Keychain API types/paths for Hyperledger Cactus.
*
* The version of the OpenAPI document: 0.3.0
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/


import { Configuration } from "./configuration";
// Some imports not used depending on template conditions
// @ts-ignore
import globalAxios, { AxiosPromise, AxiosInstance } from 'axios';

export const BASE_PATH = "http://localhost".replace(/\/+$/, "");

/**
*
* @export
*/
export const COLLECTION_FORMATS = {
csv: ",",
ssv: " ",
tsv: "\t",
pipes: "|",
};

/**
*
* @export
* @interface RequestArgs
*/
export interface RequestArgs {
url: string;
options: any;
}

/**
*
* @export
* @class BaseAPI
*/
export class BaseAPI {
protected configuration: Configuration | undefined;

constructor(configuration?: Configuration, protected basePath: string = BASE_PATH, protected axios: AxiosInstance = globalAxios) {
if (configuration) {
this.configuration = configuration;
this.basePath = configuration.basePath || this.basePath;
}
}
};

/**
*
* @export
* @class RequiredError
* @extends {Error}
*/
export class RequiredError extends Error {
name: "RequiredError" = "RequiredError";
constructor(public field: string, msg?: string) {
super(msg);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/* tslint:disable */
/* eslint-disable */
/**
* Hyperledger Cactus - Keychain API
* Contains/describes the Keychain API types/paths for Hyperledger Cactus.
*
* The version of the OpenAPI document: 0.3.0
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/


export interface ConfigurationParameters {
apiKey?: string | Promise<string> | ((name: string) => string) | ((name: string) => Promise<string>);
username?: string;
password?: string;
accessToken?: string | Promise<string> | ((name?: string, scopes?: string[]) => string) | ((name?: string, scopes?: string[]) => Promise<string>);
basePath?: string;
baseOptions?: any;
}

export class Configuration {
/**
* parameter for apiKey security
* @param name security name
* @memberof Configuration
*/
apiKey?: string | Promise<string> | ((name: string) => string) | ((name: string) => Promise<string>);
/**
* parameter for basic security
*
* @type {string}
* @memberof Configuration
*/
username?: string;
/**
* parameter for basic security
*
* @type {string}
* @memberof Configuration
*/
password?: string;
/**
* parameter for oauth2 security
* @param name security name
* @param scopes oauth2 scope
* @memberof Configuration
*/
accessToken?: string | Promise<string> | ((name?: string, scopes?: string[]) => string) | ((name?: string, scopes?: string[]) => Promise<string>);
/**
* override base path
*
* @type {string}
* @memberof Configuration
*/
basePath?: string;
/**
* base options for axios calls
*
* @type {any}
* @memberof Configuration
*/
baseOptions?: any;

constructor(param: ConfigurationParameters = {}) {
this.apiKey = param.apiKey;
this.username = param.username;
this.password = param.password;
this.accessToken = param.accessToken;
this.basePath = param.basePath;
this.baseOptions = param.baseOptions;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/* tslint:disable */
/* eslint-disable */
/**
* Hyperledger Cactus - Keychain API
* Contains/describes the Keychain API types/paths for Hyperledger Cactus.
*
* The version of the OpenAPI document: 0.3.0
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/


export * from "./api";
export * from "./configuration";

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./public-api";
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {};
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { v4 as uuidv4 } from "uuid";

import {
IPluginFactoryOptions,
PluginFactory,
} from "@hyperledger/cactus-core-api";
import {
IPluginKeychainVaultOptions,
PluginKeychainVault,
} from "./plugin-keychain-vault";

export class PluginFactoryKeychain extends PluginFactory<
PluginKeychainVault,
IPluginKeychainVaultOptions,
IPluginFactoryOptions
> {
async create(
options: IPluginKeychainVaultOptions = {
backend: new Map(),
instanceId: uuidv4(),
keychainId: uuidv4(),
logLevel: "TRACE",
}
): Promise<PluginKeychainVault> {
return new PluginKeychainVault(options);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
import { Server } from "http";
import { Server as SecureServer } from "https";

import { Express } from "express";
import { Optional } from "typescript-optional";

import {
Logger,
Checks,
LogLevelDesc,
LoggerProvider,
} from "@hyperledger/cactus-common";
import {
ICactusPlugin,
ICactusPluginOptions,
IPluginWebService,
IWebServiceEndpoint,
PluginAspect,
} from "@hyperledger/cactus-core-api";
import { GetKeychainEntryEndpointV1 } from "./web-services/get-keychain-entry-endpoint-v1";
import { SetKeychainEntryEndpointV1 } from "./web-services/set-keychain-entry-endpoint-v1";

export interface IPluginKeychainVaultOptions extends ICactusPluginOptions {
logLevel?: LogLevelDesc;
backend?: Map<string, any>;
keychainId: string;
}

export class PluginKeychainVault implements ICactusPlugin, IPluginWebService {
public static readonly CLASS_NAME = "PluginKeychainVault";

private readonly backend: Map<string, any>;
private readonly log: Logger;
private readonly instanceId: string;

public get className() {
return PluginKeychainVault.CLASS_NAME;
}

constructor(public readonly opts: IPluginKeychainVaultOptions) {
const fnTag = `${this.className}#constructor()`;
Checks.truthy(opts, `${fnTag} arg options`);
Checks.truthy(opts.keychainId, `${fnTag} arg options.keychainId`);
Checks.truthy(opts.instanceId, `${fnTag} options.instanceId`);
Checks.nonBlankString(opts.keychainId, `${fnTag} options.keychainId`);

this.backend = opts.backend || new Map();
Checks.truthy(this.backend, `${fnTag} arg options.backend`);

const level = this.opts.logLevel || "INFO";
const label = this.className;
this.log = LoggerProvider.getOrCreate({ level, label });

this.instanceId = this.opts.instanceId;

this.log.info(`Created ${this.className}. KeychainID=${opts.keychainId}`);
this.log.warn(
`Never use ${this.className} in production. ` +
`It does not support encryption. It stores everything in plain text.`
);
}
public async installWebServices(
expressApp: Express
): Promise<IWebServiceEndpoint[]> {
const endpoints: IWebServiceEndpoint[] = [];

{
const ep = new GetKeychainEntryEndpointV1({
logLevel: this.opts.logLevel,
});
ep.registerExpress(expressApp);
endpoints.push(ep);
}

{
const ep = new SetKeychainEntryEndpointV1({
logLevel: this.opts.logLevel,
});
ep.registerExpress(expressApp);
endpoints.push(ep);
}

return endpoints;
}

public getHttpServer(): Optional<Server | SecureServer> {
return Optional.empty();
}

public async shutdown(): Promise<void> {
throw new Error("Method not implemented.");
}

public getInstanceId(): string {
return this.instanceId;
}

public getKeychainId(): string {
return this.opts.keychainId;
}

public getPackageName(): string {
return `@hyperledger/cactus-plugin-keychain-vault`;
}

public getAspect(): PluginAspect {
return PluginAspect.KEYCHAIN;
}

async rotateEncryptionKeys(): Promise<void> {
throw new Error("Method not implemented.");
}

public getEncryptionAlgorithm(): string {
return null as any;
}

async get<T>(key: string): Promise<T> {
return this.backend.get(key);
}

async has(key: string): Promise<boolean> {
return this.backend.has(key);
}

async set<T>(key: string, value: T): Promise<void> {
this.backend.set(key, value);
}

async delete<T>(key: string): Promise<void> {
this.backend.delete(key);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { IPluginFactoryOptions } from "@hyperledger/cactus-core-api";

import { PluginFactoryKeychain } from "./plugin-factory-keychain";
export { PluginFactoryKeychain } from "./plugin-factory-keychain";
export {
IPluginKeychainVaultOptions,
PluginKeychainVault,
} from "./plugin-keychain-vault";

export async function createPluginFactory(
pluginFactoryOptions: IPluginFactoryOptions
): Promise<PluginFactoryKeychain> {
return new PluginFactoryKeychain(pluginFactoryOptions);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { Express } from "express";

import {
Logger,
Checks,
LogLevelDesc,
LoggerProvider,
} from "@hyperledger/cactus-common";
import {
IExpressRequestHandler,
IWebServiceEndpoint,
} from "@hyperledger/cactus-core-api";
import { registerWebServiceEndpoint } from "@hyperledger/cactus-core";

import OAS from "../../json/openapi.json";

export interface IGetKeychainEntryEndpointV1Options {
logLevel?: LogLevelDesc;
}

export class GetKeychainEntryEndpointV1 implements IWebServiceEndpoint {
public static readonly CLASS_NAME = "GetKeychainEntryEndpointV1";

private readonly log: Logger;

public get className() {
return GetKeychainEntryEndpointV1.CLASS_NAME;
}

constructor(public readonly options: IGetKeychainEntryEndpointV1Options) {
const fnTag = `${this.className}#constructor()`;
Checks.truthy(options, `${fnTag} arg options`);

const level = this.options.logLevel || "INFO";
const label = this.className;
this.log = LoggerProvider.getOrCreate({ level, label });
}

private getOperation() {
return OAS.paths[
"/api/v1/plugins/@hyperledger/cactus-plugin-keychain-vault/get-keychain-entry"
].post;
}

public registerExpress(expressApp: Express): IWebServiceEndpoint {
registerWebServiceEndpoint(expressApp, this);
return this;
}

public getVerbLowerCase(): string {
return this.getOperation()["x-hyperledger-cactus"].http.verbLowerCase;
}

public getPath(): string {
return this.getOperation()["x-hyperledger-cactus"].http.path;
}

public getExpressRequestHandler(): IExpressRequestHandler {
throw new Error("Method not implemented.");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { Express } from "express";

import {
Logger,
Checks,
LogLevelDesc,
LoggerProvider,
} from "@hyperledger/cactus-common";
import {
IExpressRequestHandler,
IWebServiceEndpoint,
} from "@hyperledger/cactus-core-api";
import { registerWebServiceEndpoint } from "@hyperledger/cactus-core";

import OAS from "../../json/openapi.json";

export interface ISetKeychainEntryEndpointV1Options {
logLevel?: LogLevelDesc;
}

export class SetKeychainEntryEndpointV1 implements IWebServiceEndpoint {
public static readonly CLASS_NAME = "SetKeychainEntryEndpointV1";

private readonly log: Logger;

public get className() {
return SetKeychainEntryEndpointV1.CLASS_NAME;
}

constructor(public readonly options: ISetKeychainEntryEndpointV1Options) {
const fnTag = `${this.className}#constructor()`;
Checks.truthy(options, `${fnTag} arg options`);

const level = this.options.logLevel || "INFO";
const label = this.className;
this.log = LoggerProvider.getOrCreate({ level, label });
}

private getOperation() {
return OAS.paths[
"/api/v1/plugins/@hyperledger/cactus-plugin-keychain-vault/set-keychain-entry"
].post;
}

public registerExpress(expressApp: Express): IWebServiceEndpoint {
registerWebServiceEndpoint(expressApp, this);
return this;
}

public getVerbLowerCase(): string {
return this.getOperation()["x-hyperledger-cactus"].http.verbLowerCase;
}

public getPath(): string {
return this.getOperation()["x-hyperledger-cactus"].http.path;
}

public getExpressRequestHandler(): IExpressRequestHandler {
throw new Error("Method not implemented.");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import test, { Test } from "tape-promise/tape";
import { PluginKeychainVault } from "../../../main/typescript/public-api";

test("Library can be loaded", (t: Test) => {
t.ok(PluginKeychainVault);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// tslint:disable-next-line: no-var-requires
const tap = require("tap");
import * as publicApi from "../../../main/typescript/public-api";

tap.pass("Test file can be executed");

tap.test("Library can be loaded", (assert: any) => {
assert.plan(1);
assert.ok(publicApi);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import test, { Test } from "tape-promise/tape";

import { v4 as uuidv4 } from "uuid";
import {
IPluginKeychainVaultOptions,
PluginKeychainVault,
} from "../../../main/typescript/public-api";

test("PluginKeychainVault", (t1: Test) => {
t1.doesNotThrow(
() => new PluginKeychainVault({ instanceId: "a", keychainId: "a" })
);

test("Validates constructor arg instanceId", (t: Test) => {
t.throws(
() =>
new PluginKeychainVault({
instanceId: null as any,
keychainId: "valid-value",
})
);
t.throws(
() =>
new PluginKeychainVault({
instanceId: "",
keychainId: "valid-value",
})
);
t.end();
});

test("Validates constructor arg keychainId", (t: Test) => {
t.throws(
() =>
new PluginKeychainVault({
instanceId: "valid-value",
keychainId: null as any,
})
);
t.throws(
() =>
new PluginKeychainVault({
instanceId: "valid-value",
keychainId: "",
})
);
t.end();
});

test("get,set,has,delete alters state as expected", async (t: Test) => {
const options: IPluginKeychainVaultOptions = {
instanceId: uuidv4(),
keychainId: uuidv4(),
};
const plugin = new PluginKeychainVault(options);
t.equal(plugin.getKeychainId(), options.keychainId, "Keychain ID set OK");
t.equal(plugin.getInstanceId(), options.instanceId, "Instance ID set OK");

const key = uuidv4();
const value = uuidv4();

const hasPrior = await plugin.has(key);
t.false(hasPrior, "hasPrior === false OK");

await plugin.set(key, value);

const hasAfter = await plugin.has(key);
t.true(hasAfter, "hasAfter === true OK");

const valueAfter = await plugin.get(key);
t.ok(valueAfter, "valueAfter truthy OK");
t.equal(valueAfter, value, "valueAfter === value OK");

await plugin.delete(key);

const hasAfterDelete = await plugin.has(key);
t.false(hasAfterDelete, "hasAfterDelete === false OK");

const valueAfterDelete = await plugin.get(key);
t.notok(valueAfterDelete, "valueAfterDelete falsy OK");

t.end();
});

test("rotateEncryptionKeys() fails fast", async (t: Test) => {
const options: IPluginKeychainVaultOptions = {
instanceId: uuidv4(),
keychainId: uuidv4(),
};
const plugin = new PluginKeychainVault(options);

const promise = plugin.rotateEncryptionKeys();
const expected = /not implemented/;
await t.rejects(promise, expected, "rotateEncryptionKeys() rejects OK");

t.end();
});

test("getEncryptionAlgorithm() returns null", (t: Test) => {
const options: IPluginKeychainVaultOptions = {
instanceId: uuidv4(),
keychainId: uuidv4(),
};
const plugin = new PluginKeychainVault(options);

t.notok(plugin.getEncryptionAlgorithm(), "encryption algorithm falsy OK");

t.end();
});

t1.end();
});
10 changes: 10 additions & 0 deletions packages/cactus-plugin-keychain-vault/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist/lib/", /* Redirect output structure to the directory. */
"declarationDir": "dist/types",
},
"include": [
"./src"
]
}

0 comments on commit 3a0acf4

Please sign in to comment.