Commit 78146367 by Chavee Issariyapat

Merge branch 'alpha-test' into 'master'

merge request from alpha test

See merge request !2
parents 00bd19a8 80fff711
...@@ -7,9 +7,9 @@ var LRU = require("lru-cache"), ...@@ -7,9 +7,9 @@ var LRU = require("lru-cache"),
}); });
// for testing // for testing
function authCheck(client_id, username, topic, callback) { // function authCheck(client_id, username, topic, callback) {
callback(true); // callback(true);
} // }
module.exports = function (options = {}) { module.exports = function (options = {}) {
return function (req, res, next) { return function (req, res, next) {
...@@ -25,13 +25,24 @@ module.exports = function (options = {}) { ...@@ -25,13 +25,24 @@ module.exports = function (options = {}) {
var cachekey = 'pub:' + req.body.client_id + ':' + req.body.username + ':' + topic; var cachekey = 'pub:' + req.body.client_id + ':' + req.body.username + ':' + topic;
var authstatus = cache.get(cachekey); var authstatus = cache.get(cachekey);
if (typeof (authstatus) === 'undefined') {
cache.set(cachekey, true); // cache missed
}
// Set Response var response
var getGroupID = require('./utils/getGroupID').getGroupID
getGroupID(req.body.username, req.body.client_id, (_id) => { // get groupID var decoded = require('./checkClientRole').checkRealDB(req.body.username)
// console.log(_id) if (decoded) {
var _ftopic = require('./utils/getTopic').getTopic(topic, _id) // get topic where concat with groupID if (decoded.role === 'realtimedb') response = { 'result': 'ok' }
var response = { else response = { 'result': 'no' }
res.send(response);
next();
}
else {
var output = {};
var _id = require('./utils/getGroupID').getGroupID(req.body.username, req.body.client_id)
var _ftopic = require('./utils/getTopic').rewriteTopic(topic, 'pub', _id, req.body.client_id, output); // get topic where concat with groupID
response = {
'result': 'ok', 'result': 'ok',
'modifiers': { 'modifiers': {
'topic': _ftopic, 'topic': _ftopic,
...@@ -39,25 +50,15 @@ module.exports = function (options = {}) { ...@@ -39,25 +50,15 @@ module.exports = function (options = {}) {
'retain': false 'retain': false
} }
} }
console.log(response) if (output.verb == 'get' || output.verb == 'read') {
response.modifiers.payload = Buffer.from(req.body.client_id).toString('base64');
if (typeof (authstatus) == 'undefined') {
// cache missed
authCheck(req.body.client_id, req.body.username, topic, function (result) {
cache.set(cachekey, result);
res.send(response);
});
} }
else {
res.send(response); res.send(response);
}
next(); next();
}) }
} }
else { else {
res.send({ res.send({ "result": "no" });
"result": "no"
});
next(); next();
} }
} }
......
var config = require('config'); var config = require('config');
var checkRealDB = require('./checkClientRole').checkRealDB
var getRole = require('./checkClientRole').getRole
// https://github.com/isaacs/node-lru-cache // https://github.com/isaacs/node-lru-cache
var LRU = require("lru-cache"), var LRU = require("lru-cache"),
...@@ -10,23 +8,18 @@ var LRU = require("lru-cache"), ...@@ -10,23 +8,18 @@ var LRU = require("lru-cache"),
}); });
var debug = false; var debug = false;
var authclient = require('seneca')({log: 'silent'}) var authclient = require('seneca')({ log: 'silent' })
.client({port: config.get('authserv_port'), host: config.get('authserv_host')}); .client({ port: config.get('authserv_port'), host: config.get('authserv_host') });
function authCheck(client_id, token, password, callback) { function authCheck(client_id, token, password, callback) {
checkRealDB(token, (err, decoded) => { if (require('./checkClientRole').checkRealDB(token)) { // auth realtimedb by token
/* callback(true)
* decode.scope }
* decode.iat else {
* decode.exp if (require('./checkClientRole').getRole(token)) callback(true) // auth client device by token
*/ else {
if (err) { authclient.act({ role: 'auth', cmd: 'token', action: 'info', token: token }, function (err, res) { // auth client device by query from db
getRole(token, (role) => {
if (role === false) {
authclient.act({role:'auth',cmd:'token',action:'info',token: token}, function(err, res) {
if (debug) { if (debug) {
console.log("res ------>\n"); console.log("res ------>\n");
console.log(res); console.log(res);
...@@ -48,16 +41,8 @@ function authCheck(client_id, token, password, callback) { ...@@ -48,16 +41,8 @@ function authCheck(client_id, token, password, callback) {
callback(false); callback(false);
} }
}); });
} }
else callback(true)
})
} }
else {
callback(true)
}
})
} }
module.exports = function (options = {}) { module.exports = function (options = {}) {
......
...@@ -9,9 +9,9 @@ var LRU = require("lru-cache"), ...@@ -9,9 +9,9 @@ var LRU = require("lru-cache"),
var debug = false; var debug = false;
// for testing // for testing
function authCheck(client_id, token, topic, callback) { // function authCheck(client_id, token, topic, callback) {
callback(true); // callback(true);
} // }
module.exports = function (options = {}) { module.exports = function (options = {}) {
...@@ -30,42 +30,36 @@ module.exports = function (options = {}) { ...@@ -30,42 +30,36 @@ module.exports = function (options = {}) {
var cachekey = 'sub:' + req.body.client_id + ':' + req.body.username + ':' + topic; var cachekey = 'sub:' + req.body.client_id + ':' + req.body.username + ':' + topic;
var authstatus = cache.get(cachekey); var authstatus = cache.get(cachekey);
if (typeof (authstatus) == 'undefined') {
cache.set(cachekey, true); // cache missed
}
var response
var decoded = require('./checkClientRole').checkRealDB(req.body.username)
// checkRole if (decoded) {
var role = require('./checkClientRole') if (decoded.role === 'realtimedb') response = { 'result': 'ok' }
// Set Response else response = { 'result': 'no' }
var getGroupID = require('./utils/getGroupID').getGroupID res.send(response);
getGroupID(req.body.username, req.body.client_id, (_id) => { // get groupID next();
// console.log(_id) }
var _ftopic = require('./utils/getTopic').getTopic(topic, _id) // get topic where concat with groupID else {
var _id = require('./utils/getGroupID').getGroupID(req.body.username, req.body.client_id)
var _ftopic = require('./utils/getTopic').rewriteTopic(topic, 'sub', _id, req.body.client_id) // get topic where concat with groupID
var _topic = [{ // setTopic for response var _topic = [{ // setTopic for response
'topic': _ftopic, 'topic': _ftopic,
'qos': 0 'qos': 0
}] }]
var response = { response = {
'result': 'ok', 'result': 'ok',
'topics': _topic 'topics': _topic
} }
if (typeof (authstatus) == 'undefined') {
// cache missed
authCheck(req.body.client_id, req.body.username, topic, function (result) {
cache.set(cachekey, result);
res.send(response); res.send(response);
});
}
else {
res.send(response);
}
next(); next();
}) }
} }
else { else {
res.send({ res.send({ "result": "no" });
"result": "no"
});
next(); next();
} }
} }
} }
var jwt = require('jsonwebtoken') var jwt = require('jsonwebtoken')
var config = require('config') var config = require('config')
var getExp = require('./utils/getDates').getExp
function checkRealDB(token, cb) { module.exports.checkRealDB = checkRealDB
module.exports.getRole = getRole
module.exports.signRole = signRole
function checkRealDB(token) {
const verifyOptions = { const verifyOptions = {
algorithms: ['RS256'] algorithms: ['RS256']
}; };
jwt.verify(token, config.get('pubca'), verifyOptions, (err, decoded) => { try {
cb(err, decoded) return jwt.verify(token, config.get('pubca'), verifyOptions)
}) }
catch(e) {
return false
}
} }
module.exports.checkRealDB = checkRealDB
function getRole(token, cb) { function getRole(token) {
var secret = 'nexpie' var secret = 'nexpie'
jwt.verify(token, secret, (err, decoded) => { try {
if (err) { return jwt.verify(token, secret)
// console.log(err)
cb(false)
} }
else { catch(e) {
// console.log(decoded) return false
cb(decoded)
} }
})
} }
module.exports.getRole = getRole
function signRole(req, res) { function signRole(req, res) {
var secret = 'nexpie' var secret = 'nexpie'
...@@ -40,44 +42,3 @@ function signRole(req, res) { ...@@ -40,44 +42,3 @@ function signRole(req, res) {
res.send('role not complete') res.send('role not complete')
} }
} }
\ No newline at end of file
module.exports.signRole = signRole
function getExp(expires) {
var exp
if (expires.endsWith('y')) {
exp = getYears(expires.split('y')[0])
}
else if (expires.endsWith('m')) {
exp = getMonths(expires.split('m')[0])
}
else if (expires.endsWith('d')) {
exp = expires.split('d')[0] + 'd'
}
else if (expires.endsWith('h')) {
exp = expires.split('h')[0] + 'h'
}
else if (expires.endsWith('mi')) {
exp = getMinutes(expires.split('mi')[0])
}
else if (expires.endsWith('s')) {
exp = getSeconds(expires.split('s')[0])
}
else exp = getYears(10)
return exp
}
function getMonths(d) {
return (d * 30) + 'd'
}
function getYears(m) {
return (m * 30 * 12) + 'd'
}
function getMinutes(mi) {
return (mi * 1000 * 60) + 'ms'
}
function getSeconds(ms) {
return (ms * 1000) + 'ms'
}
\ No newline at end of file
...@@ -2,9 +2,9 @@ process.env["NODE_ENV"] = "development"; ...@@ -2,9 +2,9 @@ process.env["NODE_ENV"] = "development";
process.env["NODE_CONFIG_DIR"] = __dirname + "/config/"; process.env["NODE_CONFIG_DIR"] = __dirname + "/config/";
var auth_on_register_debug = process.env["AUTH_ON_REGISTER_DEBUG"] || false; var auth_on_register_debug = process.env["AUTH_ON_REGISTER_DEBUG"] || false;
var auth_on_publish_debug = process.env["AUTH_ON_PUBLISH_DEBUG"] || false; var auth_on_publish_debug = process.env["AUTH_ON_PUBLISH_DEBUG"] || true;
var auth_on_subscribe_debug = process.env["AUTH_ON_SUBSCRIBE_DEBUG"] || false; var auth_on_subscribe_debug = process.env["AUTH_ON_SUBSCRIBE_DEBUG"] || true;
var on_publish_debug = process.env["ON_PUBLISH_DEBUG"] || false; var on_publish_debug = process.env["ON_PUBLISH_DEBUG"] || true;
var restify = require('restify'); var restify = require('restify');
var auth_on_register = require('./auth_on_register')({ debug: auth_on_register_debug }); var auth_on_register = require('./auth_on_register')({ debug: auth_on_register_debug });
...@@ -13,6 +13,7 @@ var auth_on_subscribe = require('./auth_on_subscribe')({ debug: auth_on_subscrib ...@@ -13,6 +13,7 @@ var auth_on_subscribe = require('./auth_on_subscribe')({ debug: auth_on_subscrib
var on_publish = require('./on_publish')({ debug: on_publish_debug }); var on_publish = require('./on_publish')({ debug: on_publish_debug });
var on_deliver = require('./on_deliver').on_deliver var on_deliver = require('./on_deliver').on_deliver
var signRole = require('./checkClientRole').signRole var signRole = require('./checkClientRole').signRole
var on_unsubscribe = require('./on_unsubscribe').on_unsubscribe
const server = restify.createServer({ const server = restify.createServer({
name: 'authhook', name: 'authhook',
...@@ -35,6 +36,11 @@ server.get('/about', function (req, res, next) { ...@@ -35,6 +36,11 @@ server.get('/about', function (req, res, next) {
server.post('/authreg', auth_on_register); server.post('/authreg', auth_on_register);
server.post('/authpub', auth_on_publish); server.post('/authpub', auth_on_publish);
server.post('/authsub', auth_on_subscribe); server.post('/authsub', auth_on_subscribe);
server.post('/onsub', (req,res,next) => {
console.log(req.body)
res.send('')
})
server.post('/onunsub', on_unsubscribe)
server.post('/ondeliver', on_deliver) server.post('/ondeliver', on_deliver)
server.post('/onpub', on_publish) server.post('/onpub', on_publish)
server.post('/signRole', signRole) server.post('/signRole', signRole)
......
var modify = require('./utils/modify');
function on_deliver(req, res, next) { function on_deliver(req, res, next) {
var topics = beDesireTopic(req.body.topic) console.log('----on_deliver-----')
var topics = modify.removeTempWordInTopic(req.body.topic)
console.log(req.body)
// console.log(topics)
var response = { var response = {
'result': 'ok', 'result': 'ok',
'modifiers': { 'modifiers': {
"topic": topics "topic": topics
} }
} }
console.log(response);
res.send(response) res.send(response)
} }
module.exports.on_deliver = on_deliver module.exports.on_deliver = on_deliver
function hasGroup(topics) {
if (topics.indexOf('!') > -1) {
return true
}
else return false
}
function beDesireTopic(topics) {
if (hasGroup(topics)) {
return joinTopic(topics)
}
else return topics
}
function joinTopic(topics) { function joinTopic(topics) {
var topic = topics.split('/!')[1] var topic = topics.split('/!')[1]
return topics.split('/!')[0] + topic.substring(topic.indexOf('/'), topic.length) return topics.split('/!')[0] + topic.substring(topic.indexOf('/'), topic.length)
} }
module.exports.joinTopic = joinTopic
\ No newline at end of file
...@@ -14,7 +14,7 @@ module.exports = function(options={}) { ...@@ -14,7 +14,7 @@ module.exports = function(options={}) {
console.log('on_publish-------------'); console.log('on_publish-------------');
console.log(req.body); console.log(req.body);
} }
console.log(req.body)
var topic = req.body.topic; var topic = req.body.topic;
var cachekey = 'pub:'+req.body.client_id +':'+ req.body.username+':'+topic; var cachekey = 'pub:'+req.body.client_id +':'+ req.body.username+':'+topic;
......
function on_unsubscribe(req, res, next) {
console.log('------on unsubscribe-------')
console.log(req.body)
var topic = req.body.topics[0];
var token = req.body.username
var client_id = req.body.client_id
var response
var decoded = require('./checkClientRole').checkRealDB(token)
if (decoded) {
if (decoded.role === 'realtimedb') {
response = { 'result': 'ok' }
}
else response = { 'result': 'no' }
res.send(response);
next()
}
else {
var _id = require('./utils/getGroupID').getGroupID(token, client_id)
if (_id) {
var _ftopic = require('./utils/getTopic').rewriteTopic(topic, 'unsub', _id, client_id)
response = {
"result": "ok",
"topics": [_ftopic]
}
}
else response = { 'result': 'no' }
res.send(response);
next()
}
}
module.exports.on_unsubscribe = on_unsubscribe
\ No newline at end of file
module.exports.getExp = getExp
function getExp(expires) {
var exp
if (expires.endsWith('y')) {
exp = getYears(expires.split('y')[0])
}
else if (expires.endsWith('m')) {
exp = getMonths(expires.split('m')[0])
}
else if (expires.endsWith('d')) {
exp = expires.split('d')[0] + 'd'
}
else if (expires.endsWith('h')) {
exp = expires.split('h')[0] + 'h'
}
else if (expires.endsWith('mi')) {
exp = getMinutes(expires.split('mi')[0])
}
else if (expires.endsWith('s')) {
exp = getSeconds(expires.split('s')[0])
}
else exp = getYears(10)
return exp
}
function getMonths(d) {
return (d * 30) + 'd'
}
function getYears(m) {
return (m * 30 * 12) + 'd'
}
function getMinutes(mi) {
return (mi * 1000 * 60) + 'ms'
}
function getSeconds(ms) {
return (ms * 1000) + 'ms'
}
\ No newline at end of file
var getRole = require('../checkClientRole').getRole var getRole = require('../checkClientRole').getRole
function getGroupID(token, id, cb) { function getGroupID(token, client_id) {
checkID(token, id, (groupId) => { var role = getRole(token)
// console.log(groupId) if (role) {
cb(groupId)
})
}
module.exports.getGroupID = getGroupID
function checkID(token, id, cb) {
// console.log(token)
getRole(token, (role) => {
// console.log(role)
if (role.hasOwnProperty('groupId')) { if (role.hasOwnProperty('groupId')) {
cb(role.groupId) return role.groupId
} }
else { else {
doDB(id, (groupId) => { return doDB(client_id)
// console.log(groupId)
cb(groupId)
})
} }
}) }
else return role
} }
module.exports.getGroupID = getGroupID
function doDB(id, cb) { function doDB(client_id) {
var groupId = 'test' var groupId = 'test'
cb(groupId) return groupId
} }
\ No newline at end of file
function getTopic(topic, id) { var modify = require('./modify');
var _topic = classifiedTopic(topic) + '/!' + id + topic.split(classifiedTopic(topic))[1]
return _topic function rewriteTopic(topic, op, groupid, clientid, output) {
} var chunk = topic.split('/');
module.exports.getTopic = getTopic
switch (chunk[0]) {
function classifiedTopic(topic) { case '@msg' :
if (topic.indexOf('@msg') !== -1) { return modify.insertWordIntoTopic(topic, '!'+clientid, 1);
return '@msg'
} else if (topic.indexOf('@shadow/updated') !== -1) { case '@shadow' :
return '@shadow/updated' if (chunk[1] == 'write' || chunk[1] == 'read') {
} else if (topic.indexOf('@shadow/update') !== -1) { output.verb = chunk[1];
return '@shadow/update' return modify.insertWordIntoTopic(topic, ''+clientid, 2);
} else if (topic.indexOf('@shadow/get') !== -1) { }
return '@shadow/get' else if (chunk[1] == 'set' || chunk[1] == 'get') {
} else if (topic.indexOf('@client') !== -1) { output.verb = chunk[1];
return '@client' return modify.insertWordIntoTopic(topic, groupid, 2);
}
else if (chunk[1] == 'changed') {
if (op == 'pub') {
if ( chunk.length > 2 )
return modify.insertWordIntoTopic(topic, '!'+groupid, 2);
else if ( chunk.length == 2 )
return modify.insertWordIntoTopic(topic, '!'+clientid, 2);
else return "";
}
else {
if ( chunk.length > 2 )
return modify.insertWordIntoTopic(topic, '!'+groupid, 2);
else if ( chunk.length == 2 )
return modify.insertWordIntoTopic(topic, '!'+clientid, 2);
else return "";
}
}
else return "";
case '@private' :
return modify.insertWordIntoTopic(topic, '!'+clientid, 1);
} }
} }
module.exports.rewriteTopic = rewriteTopic
\ No newline at end of file
module.exports.insertWordIntoTopic = insertWordIntoTopic
module.exports.removeTempWordInTopic = removeTempWordInTopic
module.exports.replaceWords = replaceWords
module.exports.cleanUpTopic = cleanUpTopic
/*
Ex: insertWordIntoTopic('@shadow/home/temp', '!GROUP', 1)
expected return : "@shadow/!GROUP/home/temp"
*/
function insertWordIntoTopic(topic, word, pos) {
var a = topic.split('/');
a.splice(pos, 0, word);
// console.log('>>> insertWordIntoTopic('+topic +','+ word +','+ pos +');');
// console.log(a.join('/'));
return a.join('/');
}
/*
Ex : removeTempWordInTopic('@shadow/!GROUP/home/temp')
expected return : "@shadowhome/temp"
*/
function removeTempWordInTopic(topic) {
var a = topic.split('/');
var k=0, l=a.length;
while (k<l) {
if (a[k].substr(0,1)=='!') {
a.splice(k,1);
l--;
}
else k++;
}
return a.join('/');
}
function replaceWords(topic, word, from, to) {
var a = topic.split('/');
a.splice(from,to-from+1);
if (word != null) a.splice(from, 0, word);
return a.join('/');
}
// Sample
// var str = insertWordIntoTopic('@shadow/home/temp', '!GROUP', 0);
// console.log(str);
// console.log(removeTempWordInTopic(str));
//console.log(replaceWords('@shadow/set/home/bob/bedroom/temp', 'CLIENTID-XXXXX', 2, 3));
function cleanUpTopic(topic) {
topic = topic.trim();
if (topic.substr(-1)=='/') return topic.slice(-1);
}
...@@ -811,12 +811,15 @@ vmq_webhooks.webhook2.endpoint = http://localhost:40000/authsub ...@@ -811,12 +811,15 @@ vmq_webhooks.webhook2.endpoint = http://localhost:40000/authsub
vmq_webhooks.webhook3.hook = auth_on_publish vmq_webhooks.webhook3.hook = auth_on_publish
vmq_webhooks.webhook3.endpoint = http://localhost:40000/authpub vmq_webhooks.webhook3.endpoint = http://localhost:40000/authpub
vmq_webhooks.webhook4.hook = on_publish #vmq_webhooks.webhook4.hook = on_publish
vmq_webhooks.webhook4.endpoint = http://localhost:41000/onpub #vmq_webhooks.webhook4.endpoint = http://localhost:41000/onpub
vmq_webhooks.webhook5.hook = on_deliver vmq_webhooks.webhook5.hook = on_deliver
vmq_webhooks.webhook5.endpoint = http://localhost:40000/ondeliver vmq_webhooks.webhook5.endpoint = http://localhost:40000/ondeliver
vmq_webhooks.webhook6.hook = on_unsubscribe
vmq_webhooks.webhook6.endpoint = http://localhost:40000/onunsub
## Specify the address and port of the bridge to connect to. Several ## Specify the address and port of the bridge to connect to. Several
## bridges can configured by using different bridge names (e.g. br0). If the ## bridges can configured by using different bridge names (e.g. br0). If the
## connection supports SSL encryption bridge.ssl.<name> can be used. ## connection supports SSL encryption bridge.ssl.<name> can be used.
......
node_modules
.DS_Store
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