mqlobber-access-control
v8.0.5
Published
Access control for mqlobber message queues
Downloads
44
Maintainers
Readme
mqlobber-access-control
Access control for mqlobber message queues. Specify to which topics clients can (and can't) subscribe, publish and receive.
The API is described here.
Example:
Here's a server program which listens on a TCP port specified on the command line. It allows clients to:
- Publish messages to topics matching
foo.bar.#
(i.e. any topic beginning withfoo.bar.
) but not tofoo.bar.reserved
- Subscribe to messages with topics matching
foo.#
(i.e. any topic beginning withfoo.
)
// server.js
var net = require('net'),
QlobberFSQ = require('qlobber-fsq').QlobberFSQ,
MQlobberServer = require('mqlobber').MQlobberServer,
AccessControl = require('mqlobber-access-control').AccessControl,
fsq = new QlobberFSQ();
fsq.on('start', function ()
{
var server = net.createServer().listen(parseInt(process.argv[2]));
server.on('connection', function (c)
{
new AccessControl(
{
publish: { allow: [ 'foo.bar.#' ],
disallow: [ 'foo.bar.reserved' ] },
subscribe: { allow: [ 'foo.#' ] }
}).attach(new MQlobberServer(fsq, c));
});
});
Next, a program which connects to the server and subscribes to messages published to a topic:
// client_subscribe.js
var assert = require('assert'),
MQlobberClient = require('mqlobber').MQlobberClient,
c = require('net').createConnection(parseInt(process.argv[2])),
mq = new MQlobberClient(c),
topic = process.argv[3];
mq.subscribe(topic, function (s, info)
{
var msg = '';
s.on('readable', function ()
{
var data;
while ((data = this.read()) !== null)
{
msg += data.toString();
}
});
s.on('finish', function ()
{
c.end();
});
s.on('end', function ()
{
console.log('received', info.topic, msg);
assert.equal(msg, 'hello');
});
}, assert.ifError);
Finally, a program which connects to the server and publishes a message to a topic:
// client_publish.js
var assert = require('assert'),
MQlobberClient = require('mqlobber').MQlobberClient,
c = require('net').createConnection(parseInt(process.argv[2])),
mq = new MQlobberClient(c);
mq.publish(process.argv[3], function (err)
{
assert.ifError(err);
c.end();
}).end('hello');
Run two servers listening on ports 8600 and 8601:
$ node server.js 8600 &
$ node server.js 8601 &
Try to subscribe to topic test
:
$ node client_subscribe.js 8600 test
[Error: blocked subscribe to topic: test]
assert.js:362
assert.ifError = function(err) { if (err) throw err; };
^
Error: server error
at BPDuplex.<anonymous> (/tmp/wup/node_modules/mqlobber/lib/client.js:423:27)
at emitTwo (events.js:87:13)
at BPDuplex.emit (events.js:172:7)
at BPMux._process_header (/tmp/wup/node_modules/mqlobber/node_modules/bpmux/index.js:652:20)
at null.<anonymous> (/tmp/wup/node_modules/mqlobber/node_modules/bpmux/index.js:514:29)
at emitNone (events.js:67:13)
at emit (events.js:166:7)
at emitReadable_ (_stream_readable.js:419:10)
at emitReadable (_stream_readable.js:413:7)
at readableAddChunk (_stream_readable.js:164:13)
Subscribe to two topics, foo.bar
and wildcard topic foo.*
, one against each
server:
$ node client_subscribe.js 8600 foo.bar &
$ node client_subscribe.js 8601 'foo.*' &
Try to publish to topic foo.bar.reserved
:
$ node client_publish.js 8600 foo.bar.reserved
node client_publish.js 8600 foo.bar.reserved
[Error: blocked publish to topic: foo.bar.reserved]
assert.js:362
assert.ifError = function(err) { if (err) throw err; };
^
Error: server error
at BPDuplex.<anonymous> (/tmp/wup/node_modules/mqlobber/lib/client.js:633:27)
at emitTwo (events.js:87:13)
at BPDuplex.emit (events.js:172:7)
at BPMux._process_header (/tmp/wup/node_modules/mqlobber/node_modules/bpmux/index.js:652:20)
at null.<anonymous> (/tmp/wup/node_modules/mqlobber/node_modules/bpmux/index.js:514:29)
at emitNone (events.js:67:13)
at emit (events.js:166:7)
at emitReadable_ (_stream_readable.js:419:10)
at emitReadable (_stream_readable.js:413:7)
at readableAddChunk (_stream_readable.js:164:13)
Then publish a message to the topic foo.bar
:
$ node client_publish.js 8600 foo.bar
received foo.bar hello
received foo.bar hello
[3]- Done node client_subscribe.js 8600 foo.bar
[4]+ Done node client_subscribe.js 8601 'foo.*'
Only the servers should still be running and you can now terminate them:
$ jobs
[1]- Running node server.js 8600 &
[2]+ Running node server.js 8601 &
$ kill %1 %2
[1]- Terminated node server.js 8600
[2]+ Terminated node server.js 8601
Installation
npm install mqlobber-access-control
Licence
Test
grunt test
Lint
grunt lint
Code Coverage
grunt coverage
Istanbul results are available here.
Coveralls page is here.
API
- AccessControl
- AccessControl.prototype.reset
- AccessControl.prototype.attach
- AccessControl.prototype.detach
- AccessControl.events.subscribe_blocked
- AccessControl.events.publish_blocked
- AccessControl.events.message_blocked
AccessControl(options)
Create a new
AccessControl
object for applying access control on publish and subscribe requests toMQlobberServer
objects and messages delivered to clients.
Calls reset
after creating the object.
Parameters:
{Object} options
Seereset
for valid options.
Go: TOC
AccessControl.prototype.reset(options)
Reset the access control applied by this object to client publish and subscribe requests on attached
MQlobberServer
objects and messages delivered to clients.
Parameters:
{Object} options
Specifies to which topics clients should be allowed and disallowed to publish, subscribe and receive messages. It supports the following properties:{Object} [publish]
Allowed and disallowed topics for publish requests, with the following properties:{Array} [allow]
Clients can publish messages to these topics.{Array} [disallow]
Clients cannot publish messages to these topics.{Integer} [max_data_length]
Maximum number of bytes allowed in a published message.{Integer} [max_publications]
Maximum number of messages each client can publish at any one time.{Boolean} [disallow_single]
Whether to allow messages to be published to a single subscriber.{Boolean} [disallow_multi]
Whether to allow messages to be published to multiple subscribers.
{Object} [subscribe]
Allowed and disallowed topics for subscribe requests, with the following properties:{Array} [allow]
Clients can subscribe to messages published to these topics.{Array} [disallow]
Clients cannot subscribe to messages published to these topics.{Integer} [max_subscriptions]
Maximum number of topics to which each client can be subscribed at any one time.
{Array} [block]
Clients cannot receive messages published to these topics. This is useful ifsubscribe.allow
is a superset ofsubscribe.disallow
but you don't want messages matching (a subset of)subscribe.disallow
sent to clients.{Integer} [max_topic_length]
Maximum topic length for publish, subscribe and unsubscribe requests.
Topics are the same as mqlobber
topics and qlobber-fsq
topics. They're split into words using .
as the separator. You can use *
to match exactly one word in a topic or #
to match zero or more words.
For example, foo.*
would match foo.bar
whereas foo.#
would match foo
,
foo.bar
and foo.bar.wup
.
Note these are the default separator and wildcard characters. They can be
changed when constructing the QlobberFSQ
instance or QlobberPG
instance passed to
MQlobberServer
's constructor. If you do change them, make sure you specify the
changed values in options
too.
There's also a limit on the number of words and #
words, imposed by
Qlobber
. For defaults, see max_words
and max_wildcard_somes
here. You can change
the limits by specifying max_words
and/or max_wildcard_somes
in options
.
Note also that for subscribe requests, AccessControl
matches topics you
specify here against topics in the requests, which can themselves contain
wildcard specifiers.
Disallowed topics take precedence over allowed ones. So if a topic in a publish or subscribe request matches a disallowed topic specifier, it's blocked even if it also matches an allowed topic specifier.
Access control is only applied where topics are specified.
Go: TOC | AccessControl.prototype
AccessControl.prototype.attach(server)
Start applying access control to a
MQlobberServer
object.
Only one AccessControl
object can be attached to a MQlobberServer
object at
a time. Trying to attach more than one will throw an exception.
If a conflict is detected between server
's configuration and the
AccessControl
object's configuration (for example different separators or
different word limit) then an exception will be thrown.
Parameters:
{MQlobberServer} server
Object to which to apply access control.
Go: TOC | AccessControl.prototype
AccessControl.prototype.detach(server)
Stop applying access control to a
MQlobberServer
object.
Parameters:
{MQlobberServer} server
Object to which to stop applying access control.
Go: TOC | AccessControl.prototype
AccessControl.events.subscribe_blocked(topic, server)
subscribe_blocked
event
Emitted by an AccessControl
object after it blocks a subscribe request from a
client.
Parameters:
{String} topic
The topic that was blocked.{MQlobberServer} server
TheMQlobberServer
object which received the subscription request.
Go: TOC | AccessControl.events
AccessControl.events.publish_blocked(topic, server)
publish_blocked
event
Emitted by an AccessControl
object after it blocks a publish request from a
client.
Parameters:
{String} topic
The topic that was blocked.{MQlobberServer} server
TheMQlobberServer
object which received the publication request.
Go: TOC | AccessControl.events
AccessControl.events.message_blocked(topic, server)
message_blocked
event
Emitted by an AccessControl
object after it blocks a message being sent to a
client.
Parameters:
{String} topic
The topic that was blocked.{MQlobberServer} server
TheMQlobberServer
object which was handling the message.
Go: TOC | AccessControl.events
—generated by apidox—