UNPKG

openhim-core

Version:

The OpenHIM core application that provides logging and routing of http requests

485 lines (427 loc) 17.6 kB
should = require "should" sinon = require "sinon" authorisation = require "../../lib/middleware/authorisation" Channel = require("../../lib/model/channels").Channel describe "Authorisation middleware", -> describe ".authorise(ctx, done)", -> validTestBody = """ <careServicesRequest> <function uuid='4e8bbeb9-f5f5-11e2-b778-0800200c9a66'> <codedType code="2221" codingScheme="ISCO-08" /> <address> <addressLine component='city'>Kigali</addressLine> </address> <max>5</max> </function> </careServicesRequest> """ invalidTestBody = """ <careServicesRequest> <function uuid='invalid'> <codedType code="2221" codingScheme="ISCO-08" /> <address> <addressLine component='city'>Kigali</addressLine> </address> <max>5</max> </function> </careServicesRequest> """ addedChannelNames = [] afterEach -> # remove test channels for channelName in addedChannelNames Channel.remove { name: channelName }, (err) -> addedChannelNames = [] it "should allow a request if the client is authorised to use the channel by role", (done) -> # Setup a channel for the mock endpoint channel = new Channel name: "Authorisation mock channel 1" urlPattern: "test/authorisation" allow: [ "PoC", "Test1", "Test2" ] routes: [ name: "test route" host: "localhost" port: 9876 primary: true ] addedChannelNames.push channel.name channel.save (err) -> if err return done err # Setup test data, will need authentication mechanisms to set ctx.authenticated ctx = {} ctx.authenticated = clientID: "Musha_OpenMRS" domain: "poc1.jembi.org" name: "OpenMRS Musha instance" roles: [ "OpenMRS_PoC", "PoC" ] passwordHash: "" cert: "" ctx.request = {} ctx.request.url = "test/authorisation" ctx.request.path = "test/authorisation" ctx.response = {} authorisation.authorise ctx, -> ctx.authorisedChannel.should.exist done() it "should deny a request if the client is NOT authorised to use the channel by role", (done) -> # Setup a channel for the mock endpoint channel = new Channel name: "Authorisation mock channel 2" urlPattern: "test/authorisation" allow: [ "Something-else" ] routes: [ name: "test route" host: "localhost" port: 9876 primary: true ] addedChannelNames.push channel.name channel.save (err) -> if err return done err # Setup test data, will need authentication mechanisms to set ctx.authenticated ctx = {} ctx.authenticated = clientID: "Musha_OpenMRS" domain: "poc1.jembi.org" name: "OpenMRS Musha instance" roles: [ "OpenMRS_PoC", "PoC" ] passwordHash: "" cert: "" ctx.request = {} ctx.request.url = "test/authorisation" ctx.request.path = "test/authorisation" ctx.response = {} ctx.set = -> authorisation.authorise ctx, -> (ctx.authorisedChannel == undefined).should.be.true ctx.response.status.should.be.exactly 401 done() it "should allow a request if the client is authorised to use the channel by clientID", (done) -> # Setup a channel for the mock endpoint channel = new Channel name: "Authorisation mock channel 3" urlPattern: "test/authorisation" allow: [ "Test1", "Musha_OpenMRS", "Test2" ] routes: [ name: "test route" host: "localhost" port: 9876 primary: true ] addedChannelNames.push channel.name channel.save (err) -> if err return done err # Setup test data, will need authentication mechanisms to set ctx.authenticated ctx = {} ctx.authenticated = clientID: "Musha_OpenMRS" domain: "poc1.jembi.org" name: "OpenMRS Musha instance" roles: [ "OpenMRS_PoC", "PoC" ] passwordHash: "" cert: "" ctx.request = {} ctx.request.url = "test/authorisation" ctx.request.path = "test/authorisation" ctx.response = {} authorisation.authorise ctx, -> ctx.authorisedChannel.should.exist done() it 'should authorise if message content matches the channel rules', (done) -> # Setup a channel for the mock endpoint channel = new Channel name: "Authorisation mock channel 4" urlPattern: "test/authorisation" allow: [ "Test1", "Musha_OpenMRS", "Test2" ] routes: [ name: "test route" host: "localhost" port: 9876 primary: true ] matchContentXpath: "string(/careServicesRequest/function/@uuid)" matchContentValue: "4e8bbeb9-f5f5-11e2-b778-0800200c9a66" addedChannelNames.push channel.name channel.save (err) -> if err return done err # Setup test data, will need authentication mechanisms to set ctx.authenticated ctx = {} ctx.body = validTestBody ctx.authenticated = clientID: "Musha_OpenMRS" clientDomain: "poc1.jembi.org" name: "OpenMRS Musha instance" roles: [ "OpenMRS_PoC", "PoC" ] passwordHash: "" cert: "" ctx.request = {} ctx.request.url = "test/authorisation" ctx.request.path = "test/authorisation" ctx.response = {} authorisation.authorise ctx, -> ctx.authorisedChannel.should.exist done() it 'should NOT authorise if message content DOES NOT matches the channel rules', (done) -> # Setup a channel for the mock endpoint channel = new Channel name: "Authorisation mock channel 4" urlPattern: "test/authorisation" allow: [ "Test1", "Musha_OpenMRS", "Test2" ] routes: [ name: "test route" host: "localhost" port: 9876 primary: true ] matchContentXpath: "string(/careServicesRequest/function/@uuid)" matchContentValue: "4e8bbeb9-f5f5-11e2-b778-0800200c9a66" addedChannelNames.push channel.name channel.save (err) -> if err return done err # Setup test data, will need authentication mechanisms to set ctx.authenticated ctx = {} ctx.body = invalidTestBody ctx.authenticated = clientID: "Musha_OpenMRS" clientDomain: "poc1.jembi.org" name: "OpenMRS Musha instance" roles: [ "OpenMRS_PoC", "PoC" ] passwordHash: "" cert: "" ctx.request = {} ctx.request.url = "test/authorisation" ctx.request.path = "test/authorisation" ctx.response = {} ctx.set = -> authorisation.authorise ctx, -> (ctx.authorisedChannel == undefined).should.be.true done() it 'should authorise if message content matches the content-type', (done) -> # Setup a channel for the mock endpoint channel = new Channel name: "Authorisation mock channel 4" urlPattern: "test/authorisation" allow: [ "Test1", "Musha_OpenMRS", "Test2" ] routes: [ name: "test route" host: "localhost" port: 9876 primary: true ] matchContentTypes: [ "text/xml" ] matchContentXpath: "string(/careServicesRequest/function/@uuid)" matchContentValue: "4e8bbeb9-f5f5-11e2-b778-0800200c9a66" addedChannelNames.push channel.name channel.save (err) -> if err return done err # Setup test data, will need authentication mechanisms to set ctx.authenticated ctx = {} ctx.body = validTestBody ctx.authenticated = clientID: "Musha_OpenMRS" clientDomain: "poc1.jembi.org" name: "OpenMRS Musha instance" roles: [ "OpenMRS_PoC", "PoC" ] passwordHash: "" cert: "" ctx.request = {} ctx.request.url = "test/authorisation" ctx.request.path = "test/authorisation" ctx.request.header = {} ctx.request.header['content-type'] = "text/xml; charset=utf-8" ctx.response = {} authorisation.authorise ctx, -> ctx.authorisedChannel.should.exist done() it 'should NOT authorise if message content DOES NOT matches the channel rules', (done) -> # Setup a channel for the mock endpoint channel = new Channel name: "Authorisation mock channel 4" urlPattern: "test/authorisation" allow: [ "Test1", "Musha_OpenMRS", "Test2" ] routes: [ name: "test route" host: "localhost" port: 9876 primary: true ] matchContentTypes: [ "text/xml" ] matchContentXpath: "string(/careServicesRequest/function/@uuid)" matchContentValue: "4e8bbeb9-f5f5-11e2-b778-0800200c9a66" addedChannelNames.push channel.name channel.save (err) -> if err return done err # Setup test data, will need authentication mechanisms to set ctx.authenticated ctx = {} ctx.body = invalidTestBody ctx.authenticated = clientID: "Musha_OpenMRS" clientDomain: "poc1.jembi.org" name: "OpenMRS Musha instance" roles: [ "OpenMRS_PoC", "PoC" ] passwordHash: "" cert: "" ctx.request = {} ctx.request.url = "test/authorisation" ctx.request.path = "test/authorisation" ctx.request.header = {} ctx.request.header['content-type'] = "text/dodgy-xml; charset=utf-8" ctx.response = {} ctx.set = -> authorisation.authorise ctx, -> (ctx.authorisedChannel == undefined).should.be.true done() it "should allow a request if the client is authorised and the channel is enabled", (done) -> # Setup a channel for the mock endpoint channel = new Channel name: "Mock for Channel Status Test (enabled)" urlPattern: "test/status/enabled" allow: [ "PoC", "Test1", "Test2" ] routes: [ name: "test route" host: "localhost" port: 9876 primary: true ] status: "enabled" addedChannelNames.push channel.name channel.save (err) -> if err return done err # Setup test data, will need authentication mechanisms to set ctx.authenticated ctx = {} ctx.authenticated = clientID: "Musha_OpenMRS" domain: "poc1.jembi.org" name: "OpenMRS Musha instance" roles: [ "OpenMRS_PoC", "PoC" ] passwordHash: "" cert: "" ctx.request = {} ctx.request.url = "test/status/enabled" ctx.request.path = "test/status/enabled" ctx.response = {} authorisation.authorise ctx, -> ctx.authorisedChannel.should.exist done() it "should NOT allow a request if the client is authorised but the channel is disabled", (done) -> # Setup a channel for the mock endpoint channel = new Channel name: "Mock for Channel Status Test (disabled)" urlPattern: "test/status/disabled" allow: [ "PoC", "Test1", "Test2" ] routes: [ name: "test route" host: "localhost" port: 9876 primary: true ] status: "disabled" addedChannelNames.push channel.name channel.save (err) -> if err return done err # Setup test data, will need authentication mechanisms to set ctx.authenticated ctx = {} ctx.authenticated = clientID: "Musha_OpenMRS" domain: "poc1.jembi.org" name: "OpenMRS Musha instance" roles: [ "OpenMRS_PoC", "PoC" ] passwordHash: "" cert: "" ctx.request = {} ctx.request.url = "test/status/disabled" ctx.request.path = "test/status/disabled" ctx.response = {} ctx.set = -> authorisation.authorise ctx, -> (ctx.authorisedChannel == undefined).should.be.true done() it "should NOT allow a request if the client is authorised but the channel is deleted", (done) -> # Setup a channel for the mock endpoint channel = new Channel name: "Mock for Channel Status Test (deleted)" urlPattern: "test/status/deleted" allow: [ "PoC", "Test1", "Test2" ] routes: [ name: "test route" host: "localhost" port: 9876 primary: true ] status: "deleted" addedChannelNames.push channel.name channel.save (err) -> if err return done err # Setup test data, will need authentication mechanisms to set ctx.authenticated ctx = {} ctx.authenticated = clientID: "Musha_OpenMRS" domain: "poc1.jembi.org" name: "OpenMRS Musha instance" roles: [ "OpenMRS_PoC", "PoC" ] passwordHash: "" cert: "" ctx.request = {} ctx.request.url = "test/status/deleted" ctx.request.path = "test/status/deleted" ctx.response = {} ctx.set = -> authorisation.authorise ctx, -> (ctx.authorisedChannel == undefined).should.be.true done() describe '.matchReg(regexPat, body)', -> it 'should return true if the regex pattern finds a match in the body', -> (authorisation.matchRegex '123', new Buffer('aaa123aaa')).should.be.true (authorisation.matchRegex 'functionId:\\s[a-z]{3}\\d{3}\\s', new Buffer('data: xyz\\nfunctionId: abc123\n')).should.be.true it 'should return false if the regex pattern DOES NOT find a match in the body', -> (authorisation.matchRegex '123', new Buffer('aaa124aaa')).should.be.false (authorisation.matchRegex 'functionId:\\s[a-z]{3}\\d{3}\\s', new Buffer('data: xyz\\nfunctionId: somethingelse\n')).should.be.false describe '.matchXpath(xpath, val, xml)', -> it 'should return true if the xpath value matches', -> (authorisation.matchXpath 'string(/root/function/@uuid)', 'da98db33-dd94-4e2a-ba6c-ac3f016dbdf1', new Buffer('<root><function uuid="da98db33-dd94-4e2a-ba6c-ac3f016dbdf1" /></root>')).should.be.true it 'should return false if the xpath value DOES NOT match', -> (authorisation.matchXpath 'string(/root/function/@uuid)', 'not-correct', new Buffer('<root><function uuid="da98db33-dd94-4e2a-ba6c-ac3f016dbdf1" /></root>')).should.be.false describe '.matchJsonPath(xpath, val, xml)', -> it 'should return true if the json path value matches', -> (authorisation.matchJsonPath 'metadata.function.id', 'da98db33-dd94-4e2a-ba6c-ac3f016dbdf1', new Buffer('{"metadata": {"function": {"id": "da98db33-dd94-4e2a-ba6c-ac3f016dbdf1"}}}')).should.be.true it 'should return false if the json path value DOES NOT match', -> (authorisation.matchJsonPath 'metadata.function.id', 'not-correct', new Buffer('{"metadata": {"function": {"id": "da98db33-dd94-4e2a-ba6c-ac3f016dbdf1"}}}')).should.be.false describe '.matchContent(channel, body)', -> channelRegex = matchContentRegex: /\d{6}/ channelXpath = matchContentXpath: 'string(/function/uuid)' matchContentValue: '123456789' channelJson = matchContentJson: 'function.uuid' matchContentValue: '123456789' noMatchChannel = {} channelInvalid = matchContentJson: 'function.uuid' it 'should call the correct matcher', -> authorisation.matchContent(channelRegex, new Buffer('--------123456------')).should.be.true authorisation.matchContent(channelXpath, new Buffer('<function><uuid>123456789</uuid></function>')).should.be.true authorisation.matchContent(channelJson, new Buffer('{"function": {"uuid": "123456789"}}')).should.be.true authorisation.matchContent(channelRegex, new Buffer('--------1234aaa56------')).should.be.false authorisation.matchContent(channelXpath, new Buffer('<function><uuid>1234aaa56789</uuid></function>')).should.be.false authorisation.matchContent(channelJson, new Buffer('{"function": {"uuid": "1234aaa56789"}}')).should.be.false it 'should return true if no matching properties are present', -> authorisation.matchContent(noMatchChannel, new Buffer('someBody')).should.be.true it 'should return false for invalid channel configs', -> authorisation.matchContent(channelInvalid, new Buffer('someBody')).should.be.false describe '.extractContentType', -> it 'should extract a correct content-type', -> authorisation.extractContentType('text/xml; charset=utf-8').should.be.exactly 'text/xml' authorisation.extractContentType('text/xml').should.be.exactly 'text/xml' authorisation.extractContentType(' text/xml ').should.be.exactly 'text/xml' authorisation.extractContentType('text/xml;').should.be.exactly 'text/xml'