Unverified Commit 1fecff3c authored by Dan Jones's avatar Dan Jones
Browse files

refactor: use constructor config in adapter auth

Commit built dist files for now
We can remove these if we publish to npm
parent 3a67cd1d
......@@ -26,9 +26,6 @@ coverage
# Dependency directories
node_modules/
# Build files
dist/
# Optional npm cache directory
.npm
......
import Validator from 'swagger-model-validator';
import axios from 'axios';
/**
* Handle authentication and send/receive with the backbone
*/
class Adapter {
constructor(protocol, config) {
this.config = config;
this.protocol = protocol;
this.axios = axios;
this.validator = new Validator(protocol.schema);
this.auth();
}
/**
* Test parsing the message based on the provided protocol schema
*
* The message must be successfully json decoded into an object
* prior to validation
*
* At present this returns the validation result which is an
* object containing a boolean valid field as well as details
* of any errors.
* @param {object} message
* @returns {object}
*/
validate(message) {
return this.validator.validate(
message,
this.protocol.schema.definitions.Message
);
}
/**
* Ensure the token in this.credentials is still valid
* @returns {boolean}
*/
tokenValid() {
let valid = false;
if (this.credentials) {
const now = new Date().toISOString();
valid = this.credentials.expiry > now;
}
return valid;
}
/**
* Return an http headers object containing a bearer token authorisation header
* @returns {object}
*/
getAuthorizationHeader() {
if (!this.tokenValid())
return this.auth().then((response) => {
return {
Authorization: `Bearer ${this.credentials.token}`,
};
});
else {
return Promise.resolve({
Authorization: `Bearer ${this.credentials.token}`,
});
}
}
/**
* Do a client credentials grant and store in this.credentials
* @returns {object}
*/
auth() {
return this.axios
.get(`{this.config.api}/token`, {
params: {
client_id: this.config.client_id,
secret: this.config.secret,
},
})
.then((response) => {
this.credentials = response.data;
return response;
});
}
/**
* Call the GET /receive endpoint and process the messages with decode
*
* Returns the response
* @returns {object}
*/
poll() {
return this.getAuthorizationHeader()
.then((headers) => {
return this.axios.get(`{this.config.api}/receive`, {
headers,
});
})
.then((response) => {
response.data.forEach((message) => {
const parsed = JSON.parse(message.message);
const validation = this.validate(parsed);
if (validation.valid) {
const type = this.protocol.getType(parsed);
this.protocol.decode(type, parsed);
}
});
return response;
});
}
/**
* Publish a message to the backbone with the specified topic
*
* Messages should be passed through encode before sending
* @param {string} topic
* @param {string} body
* @returns
*/
publish(topic, body) {
return this.getAuthorizationHeader()
.then((headers) => {
return this.axios.post(
`{this.config.api}/send`,
{
topic,
body,
},
{
headers,
}
);
})
.then((response) => {
return response;
});
}
/**
* Broadcast the message on the backbone
*
* Broadcast messages bypass the normal publisher queues
* this means they can be used to deliver messages more
* quickly in an emergency scenario.
*
* Messages should be passed through encode before sending
* @param {*} body
* @returns
*/
broadcast(body) {
return this.getAuthorizationHeader()
.then((headers) => {
return this.axios.post(
`{this.config.api}/notify`,
{
body,
},
{
headers,
}
);
})
.then((response) => {
return response;
});
}
}
export { Adapter };
'use strict';
var Validator = require('swagger-model-validator');
var axios = require('axios');
/**
* Handle authentication and send/receive with the backbone
*/
class Adapter {
constructor(protocol, config) {
this.config = config;
this.protocol = protocol;
this.axios = axios;
this.validator = new Validator(protocol.schema);
this.auth();
}
/**
* Test parsing the message based on the provided protocol schema
*
* The message must be successfully json decoded into an object
* prior to validation
*
* At present this returns the validation result which is an
* object containing a boolean valid field as well as details
* of any errors.
* @param {object} message
* @returns {object}
*/
validate(message) {
return this.validator.validate(
message,
this.protocol.schema.definitions.Message
);
}
/**
* Ensure the token in this.credentials is still valid
* @returns {boolean}
*/
tokenValid() {
let valid = false;
if (this.credentials) {
const now = new Date().toISOString();
valid = this.credentials.expiry > now;
}
return valid;
}
/**
* Return an http headers object containing a bearer token authorisation header
* @returns {object}
*/
getAuthorizationHeader() {
if (!this.tokenValid())
return this.auth().then((response) => {
return {
Authorization: `Bearer ${this.credentials.token}`,
};
});
else {
return Promise.resolve({
Authorization: `Bearer ${this.credentials.token}`,
});
}
}
/**
* Do a client credentials grant and store in this.credentials
* @returns {object}
*/
auth() {
return this.axios
.get(`{this.config.api}/token`, {
params: {
client_id: this.config.client_id,
secret: this.config.secret,
},
})
.then((response) => {
this.credentials = response.data;
return response;
});
}
/**
* Call the GET /receive endpoint and process the messages with decode
*
* Returns the response
* @returns {object}
*/
poll() {
return this.getAuthorizationHeader()
.then((headers) => {
return this.axios.get(`{this.config.api}/receive`, {
headers,
});
})
.then((response) => {
response.data.forEach((message) => {
const parsed = JSON.parse(message.message);
const validation = this.validate(parsed);
if (validation.valid) {
const type = this.protocol.getType(parsed);
this.protocol.decode(type, parsed);
}
});
return response;
});
}
/**
* Publish a message to the backbone with the specified topic
*
* Messages should be passed through encode before sending
* @param {string} topic
* @param {string} body
* @returns
*/
publish(topic, body) {
return this.getAuthorizationHeader()
.then((headers) => {
return this.axios.post(
`{this.config.api}/send`,
{
topic,
body,
},
{
headers,
}
);
})
.then((response) => {
return response;
});
}
/**
* Broadcast the message on the backbone
*
* Broadcast messages bypass the normal publisher queues
* this means they can be used to deliver messages more
* quickly in an emergency scenario.
*
* Messages should be passed through encode before sending
* @param {*} body
* @returns
*/
broadcast(body) {
return this.getAuthorizationHeader()
.then((headers) => {
return this.axios.post(
`{this.config.api}/notify`,
{
body,
},
{
headers,
}
);
})
.then((response) => {
return response;
});
}
}
exports.Adapter = Adapter;
import Validator from 'swagger-model-validator';
/**
* GenericProtocol defines a simple passthru handler for messages
* This can be extended to handle different schemas
*
* The assunption is that all messages conform to a single
* wrapper schema definition. Different payloads are handled
* by a oneOf definitions within the schema determined by a
* field value.
*
* This class can be extended and overridden to handle
* different schemas and to implement the client specific
* logic related to be executed when invoked for a given
* message type.
*
* By default encode and decode are just passthru stubs
*
* decode is invoked when receiving a message from the backbone
* encode is invoked before delivering a message to the backbone
*
* The intention is that these allow you to transform the message
* and call invoke internal functions and services as required
*/
class GenericProtocol {
constructor(schema, services) {
this.schema = schema;
this.validator = new Validator(schema);
this.services = services;
}
/**
* Validate that a message meets the reqiured schema
* @param {object} message
* @returns {object}
*/
validate(message) {
return this.validator.validate(message, this.schema.definitions.Message);
}
/**
* Identify the payload type from the message content
* @param {object} message
* @returns {string}
*/
getType(message) {
return message.message_type;
}
/**
* Invoked on receiving a message from the backbone
* @param {string} type
* @param {object} message
* @returns {*}
*/
decode(type, message) {
return message;
}
/**
* Optionally invoked before delivering a message to the backbone
* @param {string} type
* @param {*} message
* @returns {object}
*/
encode(type, message) {
return message;
}
}
export { GenericProtocol };
'use strict';
var Validator = require('swagger-model-validator');
/**
* GenericProtocol defines a simple passthru handler for messages
* This can be extended to handle different schemas
*
* The assunption is that all messages conform to a single
* wrapper schema definition. Different payloads are handled
* by a oneOf definitions within the schema determined by a
* field value.
*
* This class can be extended and overridden to handle
* different schemas and to implement the client specific
* logic related to be executed when invoked for a given
* message type.
*
* By default encode and decode are just passthru stubs
*
* decode is invoked when receiving a message from the backbone
* encode is invoked before delivering a message to the backbone
*
* The intention is that these allow you to transform the message
* and call invoke internal functions and services as required
*/
class GenericProtocol {
constructor(schema, services) {
this.schema = schema;
this.validator = new Validator(schema);
this.services = services;
}
/**
* Validate that a message meets the reqiured schema
* @param {object} message
* @returns {object}
*/
validate(message) {
return this.validator.validate(message, this.schema.definitions.Message);
}
/**
* Identify the payload type from the message content
* @param {object} message
* @returns {string}
*/
getType(message) {
return message.message_type;
}
/**
* Invoked on receiving a message from the backbone
* @param {string} type
* @param {object} message
* @returns {*}
*/
decode(type, message) {
return message;
}
/**
* Optionally invoked before delivering a message to the backbone
* @param {string} type
* @param {*} message
* @returns {object}
*/
encode(type, message) {
return message;
}
}
exports.GenericProtocol = GenericProtocol;
......@@ -24,8 +24,7 @@
"lintfix": "prettier --write --list-different . && yarn lint:js --fix",
"prepare": "husky install",
"test": "jest",
"build": "cross-env NODE_ENV=production rollup -c",
"install": "yarn build"
"build": "cross-env NODE_ENV=production rollup -c"
},
"lint-staged": {
"*.{js,vue}": "eslint --cache",
......
......@@ -5,8 +5,8 @@ import axios from 'axios';
* Handle authentication and send/receive with the backbone
*/
export class Adapter {
constructor(protocol, soarConfig) {
this.apiRoot = soarConfig.api;
constructor(protocol, config) {
this.config = config;
this.protocol = protocol;
this.axios = axios;
this.validator = new Validator(protocol.schema);
......@@ -69,10 +69,10 @@ export class Adapter {
*/
auth() {
return this.axios
.get(`{this.apiRoot}/token`, {
.get(`{this.config.api}/token`, {
params: {
client_id: soarConfig.client_id,
secret: soarConfig.secret,
client_id: this.config.client_id,
secret: this.config.secret,
},
})
.then((response) => {
......@@ -90,7 +90,7 @@ export class Adapter {
poll() {
return this.getAuthorizationHeader()
.then((headers) => {
return this.axios.get(`{this.apiRoot}/receive`, {
return this.axios.get(`{this.config.api}/receive`, {
headers,
});
})
......@@ -119,7 +119,7 @@ export class Adapter {
return this.getAuthorizationHeader()
.then((headers) => {
return this.axios.post(
`{this.apiRoot}/send`,
`{this.config.api}/send`,
{
topic,
body,
......@@ -149,7 +149,7 @@ export class Adapter {
return this.getAuthorizationHeader()
.then((headers) => {
return this.axios.post(
`{this.apiRoot}/notify`,
`{this.config.api}/notify`,
{
body,
},
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment