diff --git a/src/adapter.coffee b/src/adapter.coffee index d1a9734..d426d29 100644 --- a/src/adapter.coffee +++ b/src/adapter.coffee @@ -12,7 +12,6 @@ Util = require 'util' Timers = require 'timers' BotBuilder = require 'botbuilder' -BotBuilderTeams = require 'botbuilder-teams' { Robot, Adapter, TextMessage, User } = require 'hubot' Middleware = require './adapter-middleware' MicrosoftTeamsMiddleware = require './msteams-middleware' @@ -89,7 +88,8 @@ class BotFrameworkAdapter extends Adapter # Return an error to the user if the message channel doesn't support authorization # and authorization is enabled if @enableAuth - @robot.logger.info "#{LogPrefix} Authorization isn\'t supported for the channel error" + @robot.logger.info "#{LogPrefix} Authorization isn\'t supported + for the channel error" text = "Authorization isn't supported for this channel" payload = middleware.constructErrorResponse(activity, text) @sendPayload(@robot, payload) @@ -99,11 +99,7 @@ class BotFrameworkAdapter extends Adapter if event? @robot.receive event else - teamsConnector = new BotBuilderTeams.TeamsChatConnector { - appId: @robot.adapter.appId - appPassword: @robot.adapter.appPassword - } - middleware.toReceivable activity, teamsConnector, @enableAuth, \ + middleware.toReceivable activity, @enableAuth, @appId, @appPassword, \ (event, response) => if response? @sendPayload(@robot, response) diff --git a/src/msteams-middleware.coffee b/src/msteams-middleware.coffee index f6c22d3..11eb6a9 100644 --- a/src/msteams-middleware.coffee +++ b/src/msteams-middleware.coffee @@ -24,7 +24,7 @@ # billbliss # -BotBuilder = require 'botbuilder' +BotBuilderTeams = require 'botbuilder-teams' HubotResponseCards = require './hubot-response-cards' HubotQueryParts = require './hubot-query-parts' { Robot, TextMessage, Message, User } = require 'hubot' @@ -42,7 +42,7 @@ class MicrosoftTeamsMiddleware extends BaseMiddleware @robot.logger.info("#{LogPrefix} Restricting tenants to \ #{JSON.stringify(@allowedTenants)}") - toReceivable: (activity, teamsConnector, authEnabled, cb) -> + toReceivable: (activity, authEnabled, appId, appPassword, cb) -> @robot.logger.info "#{LogPrefix} toReceivable" # Drop the activity if it came from an unauthorized tenant @@ -60,6 +60,10 @@ class MicrosoftTeamsMiddleware extends BaseMiddleware user.room = getRoomId(activity) # Fetch the roster of members to do authorization based on UPN + teamsConnector = new BotBuilderTeams.TeamsChatConnector { + appId: appId + appPassword: appPassword + } teamsConnector.fetchMembers activity?.address?.serviceUrl, \ activity?.address?.conversation?.id, (err, chatMembers) => if err diff --git a/test/mock-teamschatconnector.coffee b/test/mock-teamschatconnector.coffee index eafce1c..de225fe 100644 --- a/test/mock-teamschatconnector.coffee +++ b/test/mock-teamschatconnector.coffee @@ -1,4 +1,4 @@ -class MockTeamsChatConnector +class TeamsChatConnector constructor: (options) -> @appId = options.appId @appPassword = options.appPassword @@ -30,4 +30,9 @@ class MockTeamsChatConnector send: (payload) -> robot.brain.set("payload", payload) -module.exports = MockTeamsChatConnector +BotBuilderTeams = { + TeamsChatConnector: TeamsChatConnector +} + +# module.exports = TeamsChatConnector +module.exports = BotBuilderTeams diff --git a/test/msteams-middleware.test.coffee b/test/msteams-middleware.test.coffee index 71f4872..5c25feb 100644 --- a/test/msteams-middleware.test.coffee +++ b/test/msteams-middleware.test.coffee @@ -1,28 +1,37 @@ chai = require 'chai' expect = chai.expect { TextMessage, Message, User } = require 'hubot' +rewiremock = require('rewiremock/node').default MockRobot = require './mock-robot' -MockTeamsChatConnector = require './mock-teamschatconnector' -MicrosoftTeamsMiddleware = require '../src/msteams-middleware' BotFrameworkAdapter = require '../src/adapter' +MicrosoftTeamsMiddleware = require '../src/msteams-middleware' describe 'MicrosoftTeamsMiddleware', -> describe 'toReceivable', -> + rewiremock('botbuilder-teams').with(require('./mock-teamschatconnector')) + BotBuilderTeams = null + MicrosoftTeamsMiddleware = null + robot = null event = null + options = null teamsChatConnector = null authEnabled = false cb = null beforeEach -> + rewiremock.enable() + MicrosoftTeamsMiddleware = require '../src/msteams-middleware' + BotBuilderTeams = require 'botbuilder-teams' + delete process.env.HUBOT_OFFICE365_TENANT_FILTER robot = new MockRobot options = { appId: 'botframework-app-id' appPassword: 'botframework-app-password' } - teamsChatConnector = new MockTeamsChatConnector(options) + teamsChatConnector = new BotBuilderTeams.TeamsChatConnector(options) cb = (event, response) -> robot.brain.data["errorResponse"] = response @@ -63,6 +72,9 @@ describe 'MicrosoftTeamsMiddleware', -> name: "user-name" aadObjectId: 'eight888-four-4444-fore-twelve121212' userPrincipalName: 'em@ai.l' + + afterEach -> + rewiremock.disable() it 'should allow messages when auth is not enabled', -> # Setup @@ -71,7 +83,8 @@ describe 'MicrosoftTeamsMiddleware', -> # Action expect(() -> - teamsMiddleware.toReceivable(event, teamsChatConnector, authEnabled, cb) + teamsMiddleware.toReceivable(event, authEnabled, options.appId, \ + options.appPassword, cb) ).to.not.throw() # Assert @@ -80,7 +93,7 @@ describe 'MicrosoftTeamsMiddleware', -> it 'should allow messages when auth is enabled and user is authorized', -> # Setup - robot.brain.data["authorizedUsers"] = + robot.brain.data["authorizedUsers"] = 'an-1_20@em.ail': true 'em@ai.l': false 'user-UPN': true @@ -89,16 +102,18 @@ describe 'MicrosoftTeamsMiddleware', -> # Action expect(() -> - teamsMiddleware.toReceivable(event, teamsChatConnector, authEnabled, cb) + teamsMiddleware.toReceivable(event, authEnabled, options.appId, \ + options.appPassword, cb) ).to.not.throw() # Assert expect(robot.brain.get("errorResponse")).to.be.null expect(robot.brain.get("event")).to.be.a('Object') - it 'should return unauthorized error for message when auth is enabled and user isn\'t authorized', -> + it 'should return unauthorized error for message when auth is enabled and \ + user isn\'t authorized', -> # Setup - robot.brain.data["authorizedUsers"] = + robot.brain.data["authorizedUsers"] = 'an-1_20@em.ail': true 'authorized_user@email.la': false event.address.user.userPrincipalName = 'not@author.ized' @@ -143,7 +158,8 @@ describe 'MicrosoftTeamsMiddleware', -> # Action expect(() -> - teamsMiddleware.toReceivable(event, teamsChatConnector, authEnabled, cb) + teamsMiddleware.toReceivable(event, authEnabled, options.appId, \ + options.appPassword, cb) ).to.not.throw() # Assert @@ -157,7 +173,8 @@ describe 'MicrosoftTeamsMiddleware', -> # Action expect(() -> - teamsMiddleware.toReceivable(event, teamsChatConnector, authEnabled, cb) + teamsMiddleware.toReceivable(event, authEnabled, options.appId, \ + options.appPassword, cb) ).to.not.throw() # Assert @@ -170,7 +187,8 @@ describe 'MicrosoftTeamsMiddleware', -> # Action expect(() -> - teamsMiddleware.toReceivable(event, teamsChatConnector, authEnabled, cb) + teamsMiddleware.toReceivable(event, authEnabled, options.appId, \ + options.appPassword, cb) ).to.not.throw() # Assert @@ -184,7 +202,8 @@ describe 'MicrosoftTeamsMiddleware', -> # Action expect(() -> - teamsMiddleware.toReceivable(event, teamsChatConnector, authEnabled, cb) + teamsMiddleware.toReceivable(event, authEnabled, options.appId, \ + options.appPassword, cb) ).to.not.throw() # Assert @@ -199,7 +218,8 @@ describe 'MicrosoftTeamsMiddleware', -> # Action expect(() -> - teamsMiddleware.toReceivable(event, teamsChatConnector, authEnabled, cb) + teamsMiddleware.toReceivable(event, authEnabled, options.appId, \ + options.appPassword, cb) ).to.not.throw() # Assert @@ -213,7 +233,8 @@ describe 'MicrosoftTeamsMiddleware', -> # Action expect(() -> - teamsMiddleware.toReceivable(event, teamsChatConnector, authEnabled, cb) + teamsMiddleware.toReceivable(event, authEnabled, options.appId, \ + options.appPassword, cb) ).to.not.throw() # Assert @@ -238,7 +259,8 @@ describe 'MicrosoftTeamsMiddleware', -> # Action expect(() -> - teamsMiddleware.toReceivable(event, teamsChatConnector, authEnabled, cb) + teamsMiddleware.toReceivable(event, authEnabled, options.appId, \ + options.appPassword, cb) ).to.not.throw() # Assert @@ -253,7 +275,8 @@ describe 'MicrosoftTeamsMiddleware', -> # Action expect(() -> - teamsMiddleware.toReceivable(event, teamsChatConnector, authEnabled, cb) + teamsMiddleware.toReceivable(event, authEnabled, options.appId, \ + options.appPassword, cb) ).to.not.throw() # Assert @@ -267,7 +290,8 @@ describe 'MicrosoftTeamsMiddleware', -> # Action expect(() -> - teamsMiddleware.toReceivable(event, teamsChatConnector, authEnabled, cb) + teamsMiddleware.toReceivable(event, authEnabled, options.appId, \ + options.appPassword, cb) ).to.not.throw() # Assert @@ -280,18 +304,21 @@ describe 'MicrosoftTeamsMiddleware', -> # Action expect(() -> - teamsMiddleware.toReceivable(event, teamsChatConnector, authEnabled, cb) + teamsMiddleware.toReceivable(event, authEnabled, options.appId, \ + options.appPassword, cb) ).to.not.throw() # Assert result = robot.brain.get("event") - expected = "#{robot.name} do something #{robot.name} and tell #{event.address.user.userPrincipalName} about it" + expected = "#{robot.name} do something #{robot.name} and tell \ + #{event.address.user.userPrincipalName} about it" expect(result.text).to.equal(expected) it 'should replace all @ mentions to chat users with their user principal name', -> # Setup teamsMiddleware = new MicrosoftTeamsMiddleware(robot) - event.text = 'Bot do something Bot and tell User and User2 about it' + event.text = 'Bot do something Bot and tell User \ + and User2 about it' event.entities.push( type: "mention" text: "User2" @@ -302,12 +329,14 @@ describe 'MicrosoftTeamsMiddleware', -> # Action expect(() -> - teamsMiddleware.toReceivable(event, teamsChatConnector, authEnabled, cb) + teamsMiddleware.toReceivable(event, authEnabled, options.appId, \ + options.appPassword, cb) ).to.not.throw() # Assert result = robot.brain.get("event") - expected = "#{robot.name} do something #{robot.name} and tell #{event.address.user.userPrincipalName} and em@ai.l2 about it" + expected = "#{robot.name} do something #{robot.name} and tell \ + #{event.address.user.userPrincipalName} and em@ai.l2 about it" expect(result.text).to.equal(expected) it 'should replace @ mentions even when entities is not an array', -> @@ -318,7 +347,8 @@ describe 'MicrosoftTeamsMiddleware', -> # Action expect(() -> - teamsMiddleware.toReceivable(event, teamsChatConnector, authEnabled, cb) + teamsMiddleware.toReceivable(event, authEnabled, options.appId, \ + options.appPassword, cb) ).to.not.throw() # Assert @@ -338,28 +368,31 @@ describe 'MicrosoftTeamsMiddleware', -> # Action expect(() -> - teamsMiddleware.toReceivable(event, teamsChatConnector, authEnabled, cb) + teamsMiddleware.toReceivable(event, authEnabled, options.appId, \ + options.appPassword, cb) ).to.not.throw() # Assert result = robot.brain.get("event") - expected = "#{robot.name} do something #{robot.name} and tell #{event.entities[1].mentioned.name} about it" + expected = "#{robot.name} do something #{robot.name} and tell \ + #{event.entities[1].mentioned.name} about it" expect(result.text).to.equal(expected) it 'should trim whitespace before and after text', -> # Setup teamsMiddleware = new MicrosoftTeamsMiddleware(robot) - event.text = """ - #{event.text} \n """ + event.text = " #{event.text} \n " # Action expect(() -> - teamsMiddleware.toReceivable(event, teamsChatConnector, authEnabled, cb) + teamsMiddleware.toReceivable(event, authEnabled, options.appId, \ + options.appPassword, cb) ).to.not.throw() # Assert result = robot.brain.get("event") - expected = "#{robot.name} do something #{robot.name} and tell #{event.address.user.userPrincipalName} about it" + expected = "#{robot.name} do something #{robot.name} and tell \ + #{event.address.user.userPrincipalName} about it" expect(result.text).to.equal(expected) it 'should prepend bot name in 1:1 chats when name is not there', -> @@ -371,12 +404,14 @@ describe 'MicrosoftTeamsMiddleware', -> # Action expect(() -> - teamsMiddleware.toReceivable(event, teamsChatConnector, authEnabled, cb) + teamsMiddleware.toReceivable(event, authEnabled, options.appId, \ + options.appPassword, cb) ).to.not.throw() # Assert result = robot.brain.get("event") - expected = "#{robot.name} do something #{robot.name} and tell #{event.address.user.userPrincipalName} about it" + expected = "#{robot.name} do something #{robot.name} and tell \ + #{event.address.user.userPrincipalName} about it" expect(result.text).to.equal(expected) describe 'toSendable', ->