UNPKG

atlassian-oauth2

Version:

Atlassian Connect OAuth2 library

236 lines (198 loc) 9.84 kB
var should = require('should'), nock = require('nock'), moment = require('moment'), qs = require('qs'), extend = require('extend'), jwt = require('atlassian-jwt'), oauth2 = require('../index'); describe('oauth2', function () { var hostBaseUrl = 'https://test.atlassian.net'; var issuer = 'com.atlassian.test'; var oauthClientId = 'my.oauth-client_Id'; var sharedSecret = 'a-s3cr3t-k3y'; describe('#createJwtClaim()', function () { it('Claimset should have correct iss claim', function (done) { var token = oauth2._createAssertionPayload(hostBaseUrl, oauthClientId, "admin"); token.iss.should.be.eql("urn:atlassian:connect:clientid:" + oauthClientId); done(); }); it('Claimset should have correct sub claim', function (done) { var token = oauth2._createAssertionPayload(hostBaseUrl, oauthClientId, "admin"); token.sub.should.be.eql("urn:atlassian:connect:userkey:admin"); done(); }); it('Claimset should correctly encode user key in sub claim', function (done) { var userkey = "苏千"; var token = oauth2._createAssertionPayload(hostBaseUrl, oauthClientId, userkey); token.sub.should.equal("urn:atlassian:connect:userkey:" + userkey); done(); }); it('Claimset should have correct aud claim', function (done) { var token = oauth2._createAssertionPayload(hostBaseUrl, oauthClientId, "admin"); token.aud.should.be.eql("https://oauth-2-authorization-server.services.atlassian.com"); done(); }); it('Claimset should respect custom aud parameter', function (done) { var token = oauth2._createAssertionPayload(hostBaseUrl, oauthClientId, "admin", "custom-aud"); token.aud.should.be.eql("custom-aud"); done(); }); it('Claimset should have correct tnt claim', function (done) { var token = oauth2._createAssertionPayload(hostBaseUrl, oauthClientId, "admin"); token.tnt.should.be.eql(hostBaseUrl); done(); }); it('Claimset should have a number iat claim', function (done) { var token = oauth2._createAssertionPayload(hostBaseUrl, oauthClientId, "admin"); token.iat.should.be.a.Number(); done(); }); it('Claimset should have a number exp claim', function (done) { var token = oauth2._createAssertionPayload(hostBaseUrl, oauthClientId, "admin"); token.exp.should.be.a.Number(); done(); }); it('Claimset should have aaid if supplied', function(done) { var aaid = "21d6059f-cdfe-4db7-85c7-4a250c94667a"; var token = oauth2._createAAIDAssertingPayload(hostBaseUrl, oauthClientId, aaid); token.sub.should.be.eql('urn:atlassian:connect:useraccountid:' + aaid); done(); }) }); describe('#getAccessToken()', function () { function createBaseOpts(opts) { return extend({ hostBaseUrl: hostBaseUrl, oauthClientId: oauthClientId, userKey: 'admin', scopes: ['READ', 'WRITE'], sharedSecret: sharedSecret }, opts || {}); } function interceptRequest(testCallback, replyCallback, opts) { opts = opts || {}; var interceptor = nock(opts.authorizationServerBaseUrl || 'https://oauth-2-authorization-server.services.atlassian.com') .post(opts.authorizationPath || '/oauth2/token') .reply(replyCallback); oauth2.getAccessToken(createBaseOpts(opts)).then(function () { interceptor.done(); // will throw assertion if endpoint is not intercepted testCallback(); }, function (err) { testCallback(err || new Error('access token retrieval should have reported success')); }); } function interceptFailedRequest(testCallback, replyCallback, failureMessage, opts) { var interceptor = nock('https://oauth-2-authorization-server.services.atlassian.com') .post('/oauth2/token') .reply(replyCallback); oauth2.getAccessToken(createBaseOpts(opts)).then(function () { interceptor.done(); // will throw assertion if endpoint is not intercepted testCallback(new Error(failureMessage)); }, function () { interceptor.done(); // will throw assertion if endpoint is not intercepted testCallback(); }); } it('Retrieves access token from OAuth service', function (done) { interceptRequest(done, 200); }); it('Retrieves access token from alternative OAuth service', function (done) { interceptRequest(done, 200, { authorizationServerBaseUrl: 'https://auth.example.com', authorizationPath: '/some/other/path' }); }); it('Rejects if access token response code is > 299', function (done) { interceptFailedRequest(done, 400, 'should reject if response code is 400'); }); it('Rejects if access token response code is < 200', function (done) { interceptFailedRequest(done, 110, 'should reject if response code is 110'); }); it('Accept header is application/json', function (done) { interceptRequest(done, function () { this.req.headers.accept.should.be.eql("application/json"); }); }); it('Request content-type is application/x-www-form-urlencoded', function (done) { interceptRequest(done, function () { this.req.headers['content-type'].should.be.eql("application/x-www-form-urlencoded"); }); }); it('Request grant_type is \'urn:ietf:params:oauth:grant-type:jwt-bearer\'', function (done) { interceptRequest(done, function (uri, requestBody) { var body = qs.parse(requestBody); body.grant_type.should.be.eql('urn:ietf:params:oauth:grant-type:jwt-bearer'); }); }); it('Request assertion exists', function (done) { interceptRequest(done, function (uri, requestBody) { var body = qs.parse(requestBody); should.exist(body.assertion); }); }); it('Request assertion is a JWT token with an issuer', function (done) { interceptRequest(done, function (uri, requestBody) { var body = qs.parse(requestBody); should.exist(jwt.decode(body.assertion, sharedSecret).iss); }); }); it('Request assertion is a JWT token with custom baseurl as aud', function (done) { var customAuthUrl = 'https://auth2.atlassian.io'; interceptRequest(done, function (uri, requestBody) { var body = qs.parse(requestBody); jwt.decode(body.assertion, sharedSecret).aud.should.be.eql([customAuthUrl]); }, { authorizationServerBaseUrl: customAuthUrl }); }); it('Request should work when only accountId provided', function(done) { interceptRequest(done, 200, { userKey: null, // this should remove the 'admin' default. userAccountId: '21d6059f-cdfe-4db7-85c7-4a250c94667a' }) }); it('Request should work when both accountId and userKey supplied', function(done) { // It should use accountId if both provided interceptRequest(done, 200, { userKey: 'admin', userAccountId: '21d6059f-cdfe-4db7-85c7-4a250c94667a' }); }); describe('scopes', function () { it('no scopes', function (done) { interceptRequest(done, function (uri, requestBody) { var body = qs.parse(requestBody); should.not.exist(body.scope); }, { scopes: false }); }); it('one scope', function (done) { interceptRequest(done, function (uri, requestBody) { var body = qs.parse(requestBody); body.scope.should.be.eql('READ'); }, { scopes: ['READ'] }); }); it('two scopes', function (done) { interceptRequest(done, function (uri, requestBody) { var body = qs.parse(requestBody); body.scope.should.be.eql('READ WRITE'); }, { scopes: ['READ', 'WRITE'] }); }); it('two scopes reversed', function (done) { interceptRequest(done, function (uri, requestBody) { var body = qs.parse(requestBody); body.scope.should.be.eql('WRITE READ'); }, { scopes: ['WRITE', 'READ'] }); }); it('two scopes in one string', function (done) { interceptRequest(done, function (uri, requestBody) { var body = qs.parse(requestBody); body.scope.should.be.eql('READ WRITE'); }, { scopes: ['READ WRITE'] }); }); it('lowercase scopes are uppercased', function (done) { interceptRequest(done, function (uri, requestBody) { var body = qs.parse(requestBody); body.scope.should.be.eql('READ WRITE'); }, { scopes: ['read', 'WriTe'] }); }); }); }); });