arobson / rabbot

Deprecated: Please see https://github.com/Foo-Foo-MQ/foo-foo-mq
MIT License
277 stars 129 forks source link

Clients with limited permission, that are not allowed to create exchanges on a vhost, are not able to publish to an existing exchange. #99

Closed stheuer closed 7 years ago

stheuer commented 7 years ago

If an amqp server is configured to not permit creation of an exchange by a dedicated user, this user is not able to publish a message to an exchange that exists on the server when using rabbot. Similar issue when calling rabbot.request. These are valid usecases.

We are able to get rid of the exceptions by a dirty hack:

edit lines 44 and 45 of file rabbot/src/exchangeFSM.js

44         //this.failedWith = err;
45         this.transition( stateOnDefined ); // this.transition( "failed" );

Without that workaround we tested three ways.

1) Run demo/topic/publisher-topic.js with a preconfigured 'topic-example-x' exchange on the server when the user has no permission to create exchanges.

λ node publisher-topic.js Could not connect or configure: [Error: Failed to create exchange 'topic-example-x' on connection 'default' with 'Error: Operation failed: ExchangeDeclare; 403 (ACCESS-REFUSED) with message "ACCESS_REFUSED - access to exchange 'topic-example-x' in vhost 'restrictedVhost' refused for user 'rabbit_test'" at reply (C:\workspace\playgound\rabbot_test\node_modules\rabbot\node_modules\amqplib\lib\channel.js:127:17) at ConfirmChannel.C.accept (C:\workspace\playgound\rabbot_test\node_modules\rabbot\node_modules\amqplib\lib\channel.js:401:7) at Connection.mainAccept [as accept] (C:\workspace\playgound\rabbot_test\node_modules\rabbot\node_modules\amqplib\lib\connection.js:63:33) at Socket.go (C:\workspace\playgound\rabbot_test\node_modules\rabbot\nodemodules\amqplib\lib\connection.js:476:48) at emitNone (events.js:67:13) at Socket.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) at Socket.Readable.push (_stream_readable.js:111:10) at TCP.onread (net.js:531:20)'] EVERYTHING IS PEACHY Potentially unhandled rejection [9] Error: Publish failed - no exchange topic-example-x on connection default is defined at null. (C:\workspace\playgound\rabbot_test\node_modules\rabbot\src\index.js:313:25) at tryCatchReject (C:\workspace\playgound\rabbot_test\node_modules\rabbot\node_modules\when\lib\makePromise.js:845:30) at runContinuation1 (C:\workspace\playgound\rabbot_test\node_modules\rabbot\node_modules\when\lib\makePromise.js:804:4) at Fulfilled.when (C:\workspace\playgound\rabbot_test\node_modules\rabbot\node_modules\when\lib\makePromise.js:592:4) at ContinuationTask.run (C:\workspace\playgound\rabbot_test\node_modules\rabbot\node_modules\when\lib\makePromise.js:702:24) at Scheduler._drain (C:\workspace\playgound\rabbot_test\node_modules\rabbot\node_modules\when\lib\Scheduler.js:62:19) at Scheduler.drain (C:\workspace\playgound\rabbot_test\node_modules\rabbot\node_modules\when\lib\Scheduler.js:27:9) at nextTickCallbackWith0Args (node.js:420:9) at process._tickCallback (node.js:349:13)

2) Publish: Run following script with a preconfigured 'topic-example-x' exchange on the server when the user has no permission to create exchanges.

const rabbit = require('rabbot');
const exchangeName = 'topic-example-x';

const connectionSettings = {
  user: 'guest',
  pass: 'guest',
  host: ['127.0.1'],
  port: [5672],
  vhost: 'restrictedVhost',
}

return rabbit.addConnection(connectionSettings)
  .then((con) => {
    console.log(`added connection ${con.name}`);
    const options = {}
    const exchangeType = 'topic';
    return rabbit.addExchange(exchangeName, exchangeType, options)
      .catch((e) => {
        console.log(`Warning: ${e.message}`)
      });
  })
  .then(() => {
    const pubOptons = {
      body: {
        routingKey: "hi",
        foo: 'bar'
      }
    }
    return rabbit.publish(exchangeName, pubOptons)
  });

node publish.js λ node publish.js added connection default Warning: Failed to create exchange 'topic-example-x' on connection 'default' with 'Error: Operation failed: ExchangeDeclare; 403 (ACCESS-REFUSED) with message "ACCESS_REFUSED - access to exchange 'topic-example-x' in vhost 'restrictedVhost' refused for user 'rabbit_test'" at reply (C:\workspace\playgound\rabbot_test\node_modules\rabbot\node_modules\amqplib\lib\channel.js:127:17) at ConfirmChannel.C.accept (C:\workspace\playgound\rabbot_test\node_modules\rabbot\node_modules\amqplib\lib\channel.js:401:7) at Connection.mainAccept [as accept] (C:\workspace\playgound\rabbot_test\node_modules\rabbot\node_modules\amqplib\lib\connection.js:63:33) at Socket.go (C:\workspace\playgound\rabbot_test\node_modules\rabbot\nodemodules\amqplib\lib\connection.js:476:48) at emitNone (events.js:67:13) at Socket.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) at Socket.Readable.push (_stream_readable.js:111:10) at TCP.onread (net.js:531:20)' Potentially unhandled rejection [7] Error: Publish failed - no exchange topic-example-x on connection default is defined at null. (C:\workspace\playgound\rabbot_test\node_modules\rabbot\src\index.js:313:25) at tryCatchReject (C:\workspace\playgound\rabbot_test\node_modules\rabbot\node_modules\when\lib\makePromise.js:845:30) at runContinuation1 (C:\workspace\playgound\rabbot_test\node_modules\rabbot\node_modules\when\lib\makePromise.js:804:4) at Fulfilled.when (C:\workspace\playgound\rabbot_test\node_modules\rabbot\node_modules\when\lib\makePromise.js:592:4) at ContinuationTask.run (C:\workspace\playgound\rabbot_test\node_modules\rabbot\node_modules\when\lib\makePromise.js:702:24) at Scheduler._drain (C:\workspace\playgound\rabbot_test\node_modules\rabbot\node_modules\when\lib\Scheduler.js:62:19) at Scheduler.drain (C:\workspace\playgound\rabbot_test\node_modules\rabbot\node_modules\when\lib\Scheduler.js:27:9) at nextTickCallbackWith0Args (node.js:420:9) at process._tickCallback (node.js:349:13)

3) Request: Run following script with a preconfigured 'topic-example-x' exchange on the server when the user has no permission to create exchanges.

const rabbit = require('rabbot');

const exchangeName = 'topic-example-x';

const connectionSettings = {
  user: 'guest',
  pass: 'guest',
  host: ['127.0.0.1'],
  port: [5672],
  vhost: 'restrictedVhost',
}

return rabbit.addConnection(connectionSettings)
  .then((con) => {
    console.log(`added connection ${con.name}`);
    const options = {}
    const exchangeType = 'topic';
    return rabbit.addExchange(exchangeName, exchangeType, options)
      .catch((e) => {
        console.log(`Warning: ${e.message}`)
      });
  })
  .then(() => {
    const pubOptons = {
      body: {
        routingKey: "hi",
        foo: 'bar'
      }
    }
    return rabbit.request(exchangeName, pubOptons)
  })
  .then((answer) => {
    console.log('Done');
  });

λ node request.js added connection default Warning: Failed to create exchange 'topic-example-x' on connection 'default' with 'Error: Operation failed: ExchangeDeclare; 403 (ACCESS-REFUSED) with message "ACCESS_REFUSED - access to exchange 'topic-example-x' in vhost 'restrictedVhost' refused for user 'rabbit_test'" at reply (C:\workspace\playgound\rabbot_test\node_modules\rabbot\node_modules\amqplib\lib\channel.js:127:17) at ConfirmChannel.C.accept (C:\workspace\playgound\rabbot_test\node_modules\rabbot\node_modules\amqplib\lib\channel.js:401:7) at Connection.mainAccept [as accept] (C:\workspace\playgound\rabbot_test\node_modules\rabbot\node_modules\amqplib\lib\connection.js:63:33) at Socket.go (C:\workspace\playgound\rabbot_test\node_modules\rabbot\nodemodules\amqplib\lib\connection.js:476:48) at emitNone (events.js:67:13) at Socket.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) at Socket.Readable.push (_stream_readable.js:111:10) at TCP.onread (net.js:531:20)' Potentially unhandled rejection [7] TypeError: Cannot read property 'publishTimeout' of undefined at Broker.request (C:\workspace\playgound\rabbot_test\node_modules\rabbot\src\index.js:329:50) at C:\workspace\playgound\rabbot_test\request.js:30:19 at tryCatchReject (C:\workspace\playgound\rabbot_test\node_modules\rabbot\node_modules\when\lib\makePromise.js:845:30) at runContinuation1 (C:\workspace\playgound\rabbot_test\node_modules\rabbot\node_modules\when\lib\makePromise.js:804:4) at Fulfilled.when (C:\workspace\playgound\rabbot_test\node_modules\rabbot\node_modules\when\lib\makePromise.js:592:4) at Pending.run (C:\workspace\playgound\rabbot_test\node_modules\rabbot\node_modules\when\lib\makePromise.js:483:13) at Scheduler._drain (C:\workspace\playgound\rabbot_test\node_modules\rabbot\node_modules\when\lib\Scheduler.js:62:19) at Scheduler.drain (C:\workspace\playgound\rabbot_test\node_modules\rabbot\node_modules\when\lib\Scheduler.js:27:9) at nextTickCallbackWith0Args (node.js:420:9) at process._tickCallback (node.js:349:13)

stheuer commented 7 years ago

When setting undocumented exchange option "passive" to true, the usecase is supported.