diff --git a/authenticator.js b/authenticator.js index e976953..0604486 100644 --- a/authenticator.js +++ b/authenticator.js @@ -11,6 +11,7 @@ function AuthenticateGithub(opts) { debug: true, githubHost: config.githubHost, githubPathPrefix: '/api/v3', + githubOrg: config.githubOrg, // label the token that we generate. note: 'npm on premises solution', noteUrl: 'https://www.npmjs.org' @@ -82,6 +83,22 @@ AuthenticateGithub.prototype.getAuthorizationToken = function(username, password if (err) reject(err); else resolve(res.token); }); + }).then(this.githubOrg && function(token) { + return new Promise(function(resolve, reject) { + github.orgs.getMember({ user: username, org: _this.githubOrg }, function(err, res) { + if (err) reject(err); + else resolve(token); + }); + }).catch(function(err) { + if (err.code === 404) { + err.code = 401; + err.message = 'unauthorized'; + } else if (err.code === 500) { + err.message = 'GitHub enterprise unavailable'; + } + // this is an error state + throw err; + }); }); }; diff --git a/test/authenticate-test.js b/test/authenticate-test.js index 2fdc0a9..7c9aaec 100644 --- a/test/authenticate-test.js +++ b/test/authenticate-test.js @@ -109,6 +109,74 @@ Lab.experiment('getAuthorizationToken', function() { done(); }).done(); }); + + Lab.it("returns authorization token if username and password are valid, and user is a member of the org", function(done) { + var authenticateGithub = new AuthenticateGithub({ + githubHost: 'https://github.example.com', + githubOrg: 'acme', + timestamp: function() { + return 0; + }, + debug: false + }); + + var packageApi = nock('https://github.example.com', { + // we should populate the auth headers with appropriate + // username and password. + reqheaders: { + 'authorization': 'Basic YmNvZS10ZXN0OmZvb2Jhcg==' + } + }) + .post('/api/v3/authorizations', { + scopes: ["user","public_repo","repo","repo:status","gist"], + note: 'npm on premises solution (0)', + note_url: 'https://www.npmjs.org' + }) + .reply(200, fs.readFileSync('./test/fixtures/authenticate-success.json')) + .get('/api/v3/orgs/acme/members/bcoe-test') + .reply(204); + + authenticateGithub.getAuthorizationToken('bcoe-test', 'foobar').nodeify(function(err, token) { + Code.expect(!!err).to.equal(false); + Code.expect(token).to.deep.equal('cc84252fd8061b232beb5e345f33b13d120c236c'); + packageApi.done(); + done(); + }); + }); + + Lab.it("executes callback with an error if user is not a member of the org", function(done) { + var authenticateGithub = new AuthenticateGithub({ + githubHost: 'https://github.example.com', + githubOrg: 'acme', + timestamp: function() { + return 0; + }, + debug: false + }); + + var packageApi = nock('https://github.example.com', { + // we should populate the auth headers with appropriate + // username and password. + reqheaders: { + 'authorization': 'Basic YmNvZS10ZXN0OmZvb2Jhcg==' + } + }) + .post('/api/v3/authorizations', { + scopes: ["user","public_repo","repo","repo:status","gist"], + note: 'npm on premises solution (0)', + note_url: 'https://www.npmjs.org' + }) + .reply(200, fs.readFileSync('./test/fixtures/authenticate-success.json')) + .get('/api/v3/orgs/acme/members/bcoe-test') + .reply(404); + + authenticateGithub.getAuthorizationToken('bcoe-test', 'foobar').nodeify(function(err, token) { + Code.expect(err.code).to.equal(401); + Code.expect(!!token).to.equal(false); + packageApi.done(); + done(); + }); + }); }); Lab.experiment('authenticate', function() {