Skip to content

Commit

Permalink
Merge pull request #178 from StackStorm/fix/exit-on-unauthorized
Browse files Browse the repository at this point in the history
 Exit hubot on Unauthorized errors
  • Loading branch information
armab authored Jun 26, 2019
2 parents 4c69b6c + 8b8504e commit c692c6e
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 5 deletions.
8 changes: 7 additions & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,16 @@ Changelog

in development
--------------
* Exit hubot on unhandled promise rejections and uncaught exceptions, usually caused by unrecoverable errors (bug fix)


0.9.5
-----
* Exit hubot on invalid, expired `ST2_API_KEY` / `ST2_AUTH_TOKEN` or any other Unauthorized response from st2 server (bug fix)
* When st2 username/password is used, re-generate st2 auth token in advance, giving enough time for request to complete, st2client.js (bug fix)

0.9.4
-----
* Exit hubot on unhandled promise rejections and uncaught exceptions, usually caused by unrecoverable errors (bug fix)
* Add pagination support for action aliases - fixes #158 (bug fix)

0.9.3
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "hubot-stackstorm",
"description": "A hubot plugin for integrating with StackStorm event-driven infrastructure automation platform.",
"version": "0.9.4",
"version": "0.9.5",
"author": "StackStorm, Inc. <[email protected]>",
"license": "Apache-2.0",
"keywords": [
Expand All @@ -27,7 +27,7 @@
"coffee-script": "1.12.7",
"lodash": "^4.17.11",
"rsvp": "^4.8.4",
"st2client": "^1.1.2",
"st2client": "^1.1.3",
"truncate": "^2.0.1",
"uuid": "^3.0.0"
},
Expand Down
9 changes: 7 additions & 2 deletions scripts/stackstorm.js
Original file line number Diff line number Diff line change
Expand Up @@ -258,8 +258,10 @@ module.exports = function(robot) {
robot.logger.info(command_factory.st2_hubot_commands.length + ' commands are loaded');
})
.catch(function (err) {
var error_msg = 'Failed to retrieve commands from "%s": %s';
robot.logger.error(util.format(error_msg, env.ST2_API_URL, err.message));
robot.logger.error(util.format('Failed to retrieve commands from "%s": %s', env.ST2_API_URL, err.message));
if (err.status === 401 || err.message.includes('Unauthorized')) {
throw err;
}
});
};

Expand Down Expand Up @@ -397,6 +399,9 @@ module.exports = function(robot) {
source.onerror = function (err) {
// TODO: squeeze a little bit more info out of evensource.js
robot.logger.error('Stream error:', err);
if (err.status === 401) {
throw err;
}
};
source.addEventListener('st2.announcement__chatops', function (e) {
var data;
Expand Down
99 changes: 99 additions & 0 deletions tests/test-st2-unauthorized.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// Copyright 2019 Extreme Networks, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/*jshint quotmark:false*/
/*jshint -W030*/
/*global describe, it, before, after*/
'use strict';

var chai = require('chai'),
expect = chai.expect,
nock = require('nock'),
Robot = require('hubot/src/robot');

describe("auth with invalid st2 API key", function() {
var stop;
var robot = new Robot(null, "mock-adapter", true, "Hubot");
var recordedError = null,
logs = [],
controlledLogger = function(msg) { logs.push(msg); };

robot.logger.error = controlledLogger;
robot.logger.warning = controlledLogger;
robot.logger.info = controlledLogger;
robot.logger.debug = controlledLogger;


before(function(done) {
process.env.ST2_API_KEY = 'aaaa';

// emulate ST2 API response
nock('http://localhost:9101')
.get('/v1/actionalias')
.query({"limit":"-1","offset":"0"})
.reply(401, {"faultstring":"Unauthorized - ApiKey with key_hash=123 not found."});

// emulate ST2 STREAM response
nock('http://localhost:9102')
.get('/v1/stream')
.query({"st2-api-key":"aaa"})
.reply(401, "");

// hack to detect uncaught exceptions
var originalException = process.listeners('uncaughtException').pop();
process.removeListener('uncaughtException', originalException);
process.prependOnceListener('uncaughtException', function (error) {
process.listeners('uncaughtException').push(originalException);
recordedError = error;
//done();
});

var stackstorm = require("../scripts/stackstorm.js");
stackstorm(robot).then(function (result) {
stop = result;
done();
});
robot.run();
});

after(function() {
stop && stop();
robot.server.close();
robot.shutdown();
// Remove stackstorm.js from the require cache
// https://medium.com/@gattermeier/invalidate-node-js-require-cache-c2989af8f8b0
delete require.cache[require.resolve("../scripts/stackstorm.js")];
});


it("is using ST2_API_KEY as authentication", function () {
// debug, if needed
//console.log(logs);
expect(logs).to.contain('Using ST2_API_KEY as authentication. Expiry will lead to bot exit.');
});

it("fails to retrieve the commands from API", function () {
expect(logs).to.include('Failed to retrieve commands from "http://localhost:9101": Unauthorized - ApiKey with key_hash=123 not found.');
});

it("throws an 'Unauthorized' error", function () {
expect(JSON.stringify(recordedError)).to.be.equal(
'{"name":"APIError","status":401,"message":"Unauthorized - ApiKey with key_hash=123 not found."}'
);
});

it("leads to Hubot shutdown", function () {
expect(logs).to.contain('Hubot will shut down ...');
});
});

0 comments on commit c692c6e

Please sign in to comment.