Skip to content
This repository has been archived by the owner on Feb 11, 2020. It is now read-only.

Commit

Permalink
Merge pull request #638 from btsimonh/btsimonh-unauthpub
Browse files Browse the repository at this point in the history
Allow published messages on an unauthorised publish topic to be pubacked
  • Loading branch information
mcollina authored May 19, 2017
2 parents a0d5622 + 880c82e commit c4303c5
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 4 deletions.
13 changes: 11 additions & 2 deletions examples/Server_With_All_Interfaces-Settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,20 @@ var authenticate = function (client, username, password, callback) {
}

var authorizePublish = function (client, topic, payload, callback) {
callback(null, true);
var auth = true;
// set auth to :
// true to allow
// false to deny and disconnect
// 'ignore' to puback but not publish msg.
callback(null, auth);
}

var authorizeSubscribe = function (client, topic, callback) {
callback(null, true);
var auth = true;
// set auth to :
// true to allow
// false to deny
callback(null, auth);
}

var server = new mosca.Server(moscaSetting);
Expand Down
15 changes: 13 additions & 2 deletions lib/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,7 @@ Client.prototype.handleSubscribe = function(packet) {
Client.prototype.handleAuthorizePublish = function(err, success, packet) {
var that = this;

// if err is passed, or success is false or undefined, terminate the connection
if (err || !success) {
if (!this._closed && !this._closing) {
that.close(null, (err && err.message) || "publish not authorized");
Expand All @@ -534,13 +535,23 @@ Client.prototype.handleAuthorizePublish = function(err, success, packet) {
packet.payload = success;
}

that.server.publish(packet, that, function() {
var dopuback = function() {
if (packet.qos === 1 && !(that._closed || that._closing)) {
that.connection.puback({
messageId: packet.messageId
});
}
});
};


// if success is passed as 'ignore', ack but don't publish.
if (success !== 'ignore'){
// publish message
that.server.publish(packet, that, dopuback);
} else {
// ignore but acknowledge message
dopuback();
}
};

/**
Expand Down
104 changes: 104 additions & 0 deletions test/abstract_server.js
Original file line number Diff line number Diff line change
Expand Up @@ -852,6 +852,110 @@ module.exports = function(moscaSettings, createConnection) {
});
});


// tests for local authorizePublish, with 'ignore' return
var authorizePublishIgnore = function(client, topic, payload, callback) {
var auth = true;
if (topic === 'authignore'){
auth = 'ignore';
}
if (topic === 'authfalse'){
auth = false;
}

callback(null, auth);
}

it("should not call onPublished on publish to topic where auth='ignore'", function(done) {
var onPublishedCalled = false;
var clientId;
var count = 0;

instance.authorizePublish = authorizePublishIgnore;
instance.published = function(packet, serverClient, callback) {
onPublishedCalled = true;
expect(packet.topic).to.be.equal("hello");
expect(packet.payload.toString().toString()).to.be.equal("some data");
expect(serverClient.id).to.be.equal(clientId);

callback();
};

buildAndConnect(done, function(client) {
clientId = client.opts.clientId;

client.publish({
messageId: 42,
topic: "authignore",
payload: "some data to ignore",
qos: 1
});
client.publish({
messageId: 43,
topic: "hello",
payload: "some data",
qos: 1
});

// auth='ignore' should puback, but not publish
client.on("puback", function() {
count++
// on second call, onPublished should be true
if(count === 2){
expect(onPublishedCalled).to.eql(true);
client.disconnect();
}
});
});
});

it("should disconnect client on publish to topic where auth=false", function(done) {
var onPublishedCalled = false;
var clientId;
var count = 0;
var timer;

instance.authorizePublish = authorizePublishIgnore;
instance.published = function(packet, serverClient, callback) {
onPublishedCalled = true;
expect(packet.topic).to.be.equal("should not have published");
callback();
};

buildAndConnect(done, function(client) {
clientId = client.opts.clientId;

client.publish({
messageId: 42,
topic: "authfalse",
payload: "some data to cause close",
qos: 1
});

// if after 2 seconds, we've not closed
timer = setTimeout(function(){
var test = false;
expect(count).to.eql(0);
expect(test).to.eql(true);
client.disconnect();
}, 2000);

// auth=false should NOT puback
client.on("puback", function() {
expect(onPublishedCalled).to.eql(false);
count++;
expect(count).to.eql(0);
client.disconnect();
});
client.on("close", function() {
expect(onPublishedCalled).to.eql(false);
expect(count).to.eql(0);
client.disconnect();
clearTimeout(timer);
});
});
});

it("should emit an event when a new client is connected", function(done) {
buildClient(done, function(client) {

Expand Down

0 comments on commit c4303c5

Please sign in to comment.