From aec4b6ffe0dea56606bf35e1969b083d2cfe5ce1 Mon Sep 17 00:00:00 2001 From: Matteo Collina Date: Thu, 18 Apr 2013 23:02:44 +0100 Subject: [PATCH] Load and install the authorization system in the CLI. References #20. --- bin/mosca.js | 5 +++- lib/authorizer.js | 1 + lib/cli.js | 24 +++++++++++++++++- lib/server.js | 3 +-- test/cli_spec.js | 57 +++++++++++++++++++++++++++++++++++++++++++ test/credentials.json | 1 + 6 files changed, 87 insertions(+), 4 deletions(-) create mode 100644 test/credentials.json diff --git a/bin/mosca.js b/bin/mosca.js index a8cc41b..61e78c0 100755 --- a/bin/mosca.js +++ b/bin/mosca.js @@ -1,3 +1,6 @@ #! /usr/bin/env node -require("../lib/cli")(process.argv); +require("../lib/cli")(process.argv, function(err) { + console.log(err); + process.exit(1); +}); diff --git a/lib/authorizer.js b/lib/authorizer.js index fd8a19e..6e57fb9 100644 --- a/lib/authorizer.js +++ b/lib/authorizer.js @@ -2,6 +2,7 @@ var hasher = require("./hasher"); var minimatch = require("minimatch"); +var debug = require("debug"); /** * mosca.Authorizer's responsibility is to give an implementation diff --git a/lib/cli.js b/lib/cli.js index ffa52e2..8cc20be 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -17,6 +17,8 @@ module.exports = function cli(argv, callback) { var server = null; var runned = false; + callback = callback || function() {}; + program .version(pkg.version) .option("-p, --port ", "the port to listen to", parseInt) @@ -24,7 +26,7 @@ module.exports = function cli(argv, callback) { .option("--parent-host ", "the parent host to connect to") .option("--parent-prefix ", "the prefix to use in the parent broker") .option("--credentials ", "the file containing the credentials", null, "./credentials.json") - .option("-c, --config ", "the config file to use (override every other options)") + .option("-c, --config ", "the config file to use (override every other option)") .option("-v, --verbose", "equal to DEBUG=mosca") .option("--very-verbose", "equal to DEBUG=mosca,ascoltatori:*"); @@ -68,6 +70,26 @@ module.exports = function cli(argv, callback) { } server = new Server(opts); + + if (program.credentials) { + fs.readFile(program.credentials, function(err, data) { + if (err) { + cb(err); + return; + } + + var authorizer = new Authorizer(); + authorizer.users = JSON.parse(data); + server.authenticate = authorizer.authenticate; + server.authorizeSubscribe = authorizer.authorizeSubscribe; + server.authorizePublish = authorizer.authorizePublish; + callback(server); + }); + } else { + callback(server); + } + + return server; }; var adduser = function (username, password) { diff --git a/lib/server.js b/lib/server.js index 2f84f6a..00b6899 100644 --- a/lib/server.js +++ b/lib/server.js @@ -254,8 +254,7 @@ Server.prototype.serve = function(client) { client.id = packet.clientId; that.authenticate(client, packet.username, packet.password, - - function(err, verdict) { + function(err, verdict) { if (err) { debug("The authentication errored"); client.stream.end(); diff --git a/test/cli_spec.js b/test/cli_spec.js index f730af2..47f4a5b 100644 --- a/test/cli_spec.js +++ b/test/cli_spec.js @@ -1,6 +1,7 @@ var async = require("async"); var tmp = require('tmp'); var fs = require("fs"); +var mqtt = require("mqtt"); describe("mosca.cli", function() { @@ -174,4 +175,60 @@ describe("mosca.cli", function() { }); }); }); + + it("should support authorizing an authorized client", function(done) { + args.push("--credentials"); + args.push("test/credentials.json"); + async.waterfall([ + function(cb) { + server = mosca.cli(args); + server.on("ready", cb); + }, + function(cb) { + var options = { username: "test", password: "test" }; + var client = mqtt.createClient(1883, "localhost", options); + cb = cb.bind(null, null, client); + client.on("connect", cb); + }, + function(client, cb) { + client.on("close", cb); + client.end(); + } + ], function(err) { + if(err) { + done(err); + return; + } + done(); + }); + }); + + it("should support negating an unauthorized client", function(done) { + args.push("--credentials"); + args.push("test/credentials.json"); + async.waterfall([ + function(cb) { + server = mosca.cli(args); + server.on("ready", cb); + }, + function(cb) { + var options = { username: "bad", password: "bad" }; + var client = mqtt.createClient(1883, "localhost", options); + client.on("error", cb); + client.on("connect", function() { + cb(null, client); + }); + }, + function(client, cb) { + client.once("close", cb); + client.end(); + } + ], function(err) { + if(err) { + done(); + return; + } + done(new Error("No error thrown")); + }); + }); }); diff --git a/test/credentials.json b/test/credentials.json new file mode 100644 index 0000000..db7566a --- /dev/null +++ b/test/credentials.json @@ -0,0 +1 @@ +{"test":{"salt":"RtdMQo57Qj/RHdiKZWlsuCX5++KvucbIOGVN1EXPe5zA8M2n4uHcESEEwP+bhkyjhbU6sRShrPtgi6VKaNHsKA==","hash":"sJDtCL9MqCO2Ln3bDTuy4inhA9ayHxIoSjchXnkhzmT0cuvxTcWhF6q2uiiTBqqOKNp57wWrKKQtFKduR515nw==","authorizePublish":"**","authorizeSubscribe":"**"}} \ No newline at end of file