Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
050cbf6
feature: provide a way for devices to obtain a security token and new…
sbender9 Sep 14, 2018
2f16f92
feature: add ability for ws clients that handle put to respond
sbender9 Sep 30, 2018
a1624b0
feature: add support for put via Web Sockets
sbender9 Oct 1, 2018
7906612
fix: remove href as it's handled by requestResponse code
sbender9 Oct 1, 2018
d85eccd
fix: prune old requst data
sbender9 Oct 1, 2018
6d8efaa
fix: don't send context in request reponses
sbender9 Oct 2, 2018
c9ed790
fix: ensure result 202 on PENDING put reponses
sbender9 Oct 2, 2018
8b350fc
tests: add put tests
sbender9 Oct 2, 2018
e26382f
test: complete WS put tests
sbender9 Oct 2, 2018
9160171
docs: update plugin documentation about Put requests
sbender9 Oct 2, 2018
0845767
refactor: rename plugin api registerActionHandler to registerPutHandler
sbender9 Oct 2, 2018
402c4db
fix: revert testing settings for pruning requests
sbender9 Oct 2, 2018
10322e8
fix: make put test stop the server when done
sbender9 Oct 2, 2018
7e75765
refactor: rename `result` to `statusCode`
sbender9 Oct 5, 2018
12c6a53
feature: add `authenticationRequired` to ws hello and `/signalk`
sbender9 Oct 5, 2018
98c83ab
fix: exception when throwing InvalidTokenError
sbender9 Oct 5, 2018
8888172
tests: reflect rename to `statusCode`
sbender9 Oct 5, 2018
801ba47
docs: rename `result` to `statusCode`
sbender9 Oct 5, 2018
5693835
fix: exception when configuration is not allowed
sbender9 Oct 17, 2018
d20ed9e
fix: exception if incoming request does not have a query
sbender9 Oct 17, 2018
f206bb1
refactor: remove authenticationRequired since it did not make it into…
sbender9 Oct 29, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions SERVERPLUGINS.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,17 +124,20 @@ If the plugin needs to make and save changes to its options

If the plugin needs to read plugin options from disk

### app.registerActionHandler (context, path, source, callback)
### app.registerPutHandler (context, path, source, callback)

If the plugin wants to respond to actions, which are PUT requests for a specific path, it should register an action handler.
If the plugin wants to respond to PUT requests for a specific path, it should register an action handler.

The action handler can handle the request synchronously or asynchronously.
For synchronous actions the handler must return a value describing the result of the action: either `{ state: 'SUCCESS' }` or `{ state:'FAILURE', message:'Some Error Message' }`.

The passed callback should be a funtion taking the following arguments: (context, path, value, callback)

For synchronous actions the handler must return a value describing the response of the request: for example `{ state: 'COMPLETED', result:200 }` or `{ state:'COMPLETED', result:400, message:'Some Error Message' }`. The result value can be any valid http response code.

For asynchronous actions that may take considerable time and the requester should not be kept waiting for the result
the handler must return `{ state: 'PENDING' }`. When the action is finished the handler
should call the `callback` function with the result with `callback({ state: 'SUCCESS' })` or
`callback({ state:'FAILURE', message:'Some Error Message' })`.
should call the `callback` function with the result with `callback({ state: 'COMPLETED', statusCode:200 })` or
`callback({ state:'COMPLETED', statusCode:400, message:'Some Error Message' })`.

### app.registerDeltaInputHandler ((delta, next) => ...)

Expand Down
9 changes: 4 additions & 5 deletions lib/deltacache.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,11 +152,10 @@ DeltaCache.prototype.getCachedDeltas = function (user, contextFilter, key) {

deltas = deltas.map(toDelta)

if (this.app.securityStrategy.shouldFilterDeltas()) {
deltas = deltas.filter(delta => {
return this.app.securityStrategy.filterReadDelta(user, delta)
})
}
deltas = deltas.filter(delta => {
return this.app.securityStrategy.filterReadDelta(user, delta)
})

return deltas
}

Expand Down
50 changes: 30 additions & 20 deletions lib/dummysecurity.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,36 +14,36 @@
* limitations under the License.
*/

module.exports = function(app, config) {
module.exports = function (app, config) {
return {
getConfiguration: () => {
return {};
return {}
},

allowRestart: req => {
return false;
return false
},

allowConfigure: req => {
return false;
return false
},

getLoginStatus: req => {
return {
status: "notLoggedIn",
status: 'notLoggedIn',
readOnlyAccess: false,
authenticationRequired: false
};
}
},

getConfig: config => {
return config;
return config
},

setConfig: (config, newConfig) => {},

getUsers: config => {
return [];
return []
},

updateUser: (config, username, updates, callback) => {},
Expand All @@ -54,38 +54,48 @@ module.exports = function(app, config) {

deleteUser: (config, username, callback) => {},

shouldAllowWrite: function(req, delta) {
return true;
shouldAllowWrite: function (req, delta) {
return true
},

shouldAllowPut: function(req, context, source, path) {
return true;
shouldAllowPut: function (req, context, source, path) {
return true
},

filterReadDelta: (user, delta) => {
return delta;
return delta
},

verifyWS: spark => {},

authorizeWS: req => {},

checkACL: (id, context, path, source, operation) => {
return true;
return true
},

isDummy: () => {
return true;
return true
},

canAuthorizeWS: () => {
return false;
return false
},

shouldFilterDeltas: () => {
return false;
return false
},

addAdminMiddleware: () => {}
};
};
addAdminMiddleware: () => {},

allowReadOnly: () => {
return true
},

supportsLogin: () => false,

getAuthRequiredString: () => {
return 'never'
}
}
}
38 changes: 6 additions & 32 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,12 @@ const express = require('express'),
getPrimaryPort = ports.getPrimaryPort,
getSecondaryPort = ports.getSecondaryPort,
getExternalPort = ports.getExternalPort,
{ startSecurity, getCertificateOptions } = require('./security.js'),
{
startSecurity,
getCertificateOptions,
getSecurityConfig,
saveSecurityConfig
} = require('./security.js'),
{ startDeltaStatistics, incDeltaStatistics } = require('./deltastats'),
DeltaChain = require('./deltachain')

Expand Down Expand Up @@ -415,34 +420,3 @@ Server.prototype.stop = function(cb) {
}
})
}

function pathForSecurityConfig(app) {
return path.join(app.config.configPath, 'security.json')
}

function saveSecurityConfig(app, data, callback) {
const config = JSON.parse(JSON.stringify(data))
const path = pathForSecurityConfig(app)
fs.writeFile(path, JSON.stringify(data, null, 2), err => {
if (!err) {
fs.chmodSync(path, '600')
}
if (callback) {
callback(err)
}
})
}

function getSecurityConfig(app) {
try {
const optionsAsString = fs.readFileSync(pathForSecurityConfig(app), 'utf8')
try {
return JSON.parse(optionsAsString)
} catch (e) {
console.error('Could not parse security config')
return {}
}
} catch (e) {
return {}
}
}
36 changes: 31 additions & 5 deletions lib/interfaces/plugins.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const modulesWithKeyword = require('../modules').modulesWithKeyword
const getLogger = require('../logging').getLogger
const _putPath = require('../put').putPath
const { getModulePublic } = require('../config/get')
const { queryRequest } = require('../requestResponse')

// #521 Returns path to load plugin-config assets.
const getPluginConfigPublic = getModulePublic('@signalk/plugin-config')
Expand Down Expand Up @@ -177,12 +178,35 @@ module.exports = function (app) {
return _.get(app.signalk.retrieve(), path)
}

function putSelfPath (path, value) {
return _putPath(app, `vessels.self.${path}`, { value: value })
function putSelfPath (path, value, updateCb) {
return _putPath(
app,
'vessels.self',
path,
{ value: value },
null,
null,
updateCb
)
}

function putPath (path, value) {
return _putPath(app, path, { value: value })
function putPath (path, value, updateCb) {
var parts = path.length > 0 ? path.split('.') : []

if (parts.length > 2) {
var context = `${parts[0]}.${parts[1]}`
var skpath = parts.slice(2).join('.')
}

return _putPath(
app,
context,
skpath,
{ value: value },
null,
null,
updateCb
)
}

function registerPlugin (app, pluginName, metadata, location) {
Expand Down Expand Up @@ -242,6 +266,7 @@ module.exports = function (app) {
getPath,
putSelfPath,
putPath,
queryRequest,
error: msg => {
console.error(`${packageName}:${msg}`)
},
Expand Down Expand Up @@ -287,11 +312,12 @@ module.exports = function (app) {
appCopy.readPluginOptions = () => {
return getPluginOptions(plugin.id)
}
appCopy.registerActionHandler = (context, path, callback) => {
appCopy.registerPutHandler = (context, path, callback) => {
onStopHandlers[plugin.id].push(
app.registerActionHandler(context, path, plugin.id, callback)
)
}
appCopy.registerActionHandler = appCopy.registerPutHandler

appCopy.registerHistoryProvider = provider => {
app.registerHistoryProvider(provider)
Expand Down
4 changes: 2 additions & 2 deletions lib/interfaces/rest.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,15 +106,15 @@ module.exports = function (app) {
return
}
var last = app.deltaCache.buildFullFromDeltas(
req.skUser,
req.skPrincipal,
deltas
)
sendResult(last, path)
}
)
}
} else {
var last = app.deltaCache.buildFull(req.skUser, path)
var last = app.deltaCache.buildFull(req.skPrincipal, path)
sendResult(last, path)
}
})
Expand Down
Loading