-
-
Notifications
You must be signed in to change notification settings - Fork 342
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
705db83
commit 0ff401b
Showing
2 changed files
with
284 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,277 @@ | ||
var OAuth2Strategy = require('../lib/strategy') | ||
, AuthorizationError = require('../lib/errors/authorizationerror') | ||
, TokenError = require('../lib/errors/tokenerror') | ||
, InternalOAuthError = require('../lib/errors/internaloautherror') | ||
, chai = require('chai') | ||
, uri = require('url'); | ||
|
||
|
||
describe('OAuth2Strategy', function() { | ||
|
||
describe('using default session state store', function() { | ||
|
||
describe('issuing authorization request', function() { | ||
var strategy = new OAuth2Strategy({ | ||
authorizationURL: 'https://www.example.com/oauth2/authorize', | ||
tokenURL: 'https://www.example.com/oauth2/token', | ||
clientID: 'ABC123', | ||
clientSecret: 'secret', | ||
callbackURL: 'https://www.example.net/auth/example/callback', | ||
state: true | ||
}, | ||
function(accessToken, refreshToken, profile, done) {}); | ||
|
||
|
||
describe('that redirects to service provider', function() { | ||
var request, url; | ||
|
||
before(function(done) { | ||
chai.passport.use(strategy) | ||
.redirect(function(u) { | ||
url = u; | ||
done(); | ||
}) | ||
.req(function(req) { | ||
request = req; | ||
req.session = {}; | ||
}) | ||
.authenticate(); | ||
}); | ||
|
||
it('should be redirected', function() { | ||
var u = uri.parse(url, true); | ||
expect(u.query.state).to.have.length(24); | ||
}); | ||
|
||
it('should save state in session', function() { | ||
var u = uri.parse(url, true); | ||
|
||
expect(request.session['oauth2:www.example.com'].state).to.have.length(24); | ||
expect(request.session['oauth2:www.example.com'].state).to.equal(u.query.state); | ||
}); | ||
}); // that redirects to service provider | ||
|
||
describe('that errors due to lack of session support in app', function() { | ||
var request, err; | ||
|
||
before(function(done) { | ||
chai.passport.use(strategy) | ||
.error(function(e) { | ||
err = e; | ||
done(); | ||
}) | ||
.req(function(req) { | ||
request = req; | ||
}) | ||
.authenticate(); | ||
}); | ||
|
||
it('should error', function() { | ||
expect(err).to.be.an.instanceof(Error) | ||
expect(err.message).to.equal('OAuth2Strategy requires session support when using state. Did you forget app.use(express.session(...))?'); | ||
}); | ||
}); // that errors due to lack of session support in app | ||
|
||
}); // issuing authorization request | ||
|
||
describe('processing response to authorization request', function() { | ||
var strategy = new OAuth2Strategy({ | ||
authorizationURL: 'https://www.example.com/oauth2/authorize', | ||
tokenURL: 'https://www.example.com/oauth2/token', | ||
clientID: 'ABC123', | ||
clientSecret: 'secret', | ||
callbackURL: 'https://www.example.net/auth/example/callback', | ||
state: true | ||
}, | ||
function(accessToken, refreshToken, profile, done) { | ||
if (accessToken !== '2YotnFZFEjr1zCsicMWpAA') { return done(new Error('incorrect accessToken argument')); } | ||
if (refreshToken !== 'tGzv3JOkF0XG5Qx2TlKWIA') { return done(new Error('incorrect refreshToken argument')); } | ||
if (typeof profile !== 'object') { return done(new Error('incorrect profile argument')); } | ||
if (Object.keys(profile).length !== 0) { return done(new Error('incorrect profile argument')); } | ||
|
||
return done(null, { id: '1234' }, { message: 'Hello' }); | ||
}); | ||
|
||
strategy._oauth2.getOAuthAccessToken = function(code, options, callback) { | ||
if (code !== 'SplxlOBeZQQYbYS6WxSbIA') { return callback(new Error('incorrect code argument')); } | ||
if (options.grant_type !== 'authorization_code') { return callback(new Error('incorrect options.grant_type argument')); } | ||
if (options.redirect_uri !== 'https://www.example.net/auth/example/callback') { return callback(new Error('incorrect options.redirect_uri argument')); } | ||
|
||
return callback(null, '2YotnFZFEjr1zCsicMWpAA', 'tGzv3JOkF0XG5Qx2TlKWIA', { token_type: 'example' }); | ||
} | ||
|
||
|
||
describe('that was approved', function() { | ||
var request | ||
, user | ||
, info; | ||
|
||
before(function(done) { | ||
chai.passport.use(strategy) | ||
.success(function(u, i) { | ||
user = u; | ||
info = i; | ||
done(); | ||
}) | ||
.req(function(req) { | ||
request = req; | ||
|
||
req.query = {}; | ||
req.query.code = 'SplxlOBeZQQYbYS6WxSbIA'; | ||
req.query.state = 'DkbychwKu8kBaJoLE5yeR5NK'; | ||
req.session = {}; | ||
req.session['oauth2:www.example.com'] = {}; | ||
req.session['oauth2:www.example.com']['state'] = 'DkbychwKu8kBaJoLE5yeR5NK'; | ||
}) | ||
.authenticate(); | ||
}); | ||
|
||
it('should supply user', function() { | ||
expect(user).to.be.an.object; | ||
expect(user.id).to.equal('1234'); | ||
}); | ||
|
||
it('should supply info', function() { | ||
expect(info).to.be.an.object; | ||
expect(info.message).to.equal('Hello'); | ||
}); | ||
|
||
it('should remove state from session', function() { | ||
expect(request.session['oauth2:www.example.com']).to.be.undefined; | ||
}); | ||
}); // that was approved | ||
|
||
describe('that fails due to state being invalid', function() { | ||
var request | ||
, info, status; | ||
|
||
before(function(done) { | ||
chai.passport.use(strategy) | ||
.fail(function(i, s) { | ||
info = i; | ||
status = s; | ||
done(); | ||
}) | ||
.req(function(req) { | ||
request = req; | ||
|
||
req.query = {}; | ||
req.query.code = 'SplxlOBeZQQYbYS6WxSbIA'; | ||
req.query.state = 'DkbychwKu8kBaJoLE5yeR5NK-WRONG'; | ||
req.session = {}; | ||
req.session['oauth2:www.example.com'] = {}; | ||
req.session['oauth2:www.example.com']['state'] = 'DkbychwKu8kBaJoLE5yeR5NK'; | ||
}) | ||
.authenticate(); | ||
}); | ||
|
||
it('should supply info', function() { | ||
expect(info).to.be.an.object; | ||
expect(info.message).to.equal('Invalid authorization request state.'); | ||
}); | ||
|
||
it('should supply status', function() { | ||
expect(status).to.equal(403); | ||
}); | ||
|
||
it('should remove state from session', function() { | ||
expect(request.session['oauth2:www.example.com']).to.be.undefined; | ||
}); | ||
}); // that fails due to state being invalid | ||
|
||
describe('that fails due to provider-specific state not found in session', function() { | ||
var request | ||
, info, status; | ||
|
||
before(function(done) { | ||
chai.passport.use(strategy) | ||
.fail(function(i, s) { | ||
info = i; | ||
status = s; | ||
done(); | ||
}) | ||
.req(function(req) { | ||
request = req; | ||
|
||
req.query = {}; | ||
req.query.code = 'SplxlOBeZQQYbYS6WxSbIA'; | ||
req.query.state = 'DkbychwKu8kBaJoLE5yeR5NK'; | ||
req.session = {}; | ||
}) | ||
.authenticate(); | ||
}); | ||
|
||
it('should supply info', function() { | ||
expect(info).to.be.an.object; | ||
expect(info.message).to.equal('Unable to verify authorization request state.'); | ||
}); | ||
|
||
it('should supply status', function() { | ||
expect(status).to.equal(403); | ||
}); | ||
}); // that fails due to state not found in session | ||
|
||
describe('that fails due to provider-specific state lacking state value', function() { | ||
var request | ||
, info, status; | ||
|
||
before(function(done) { | ||
chai.passport.use(strategy) | ||
.fail(function(i, s) { | ||
info = i; | ||
status = s; | ||
done(); | ||
}) | ||
.req(function(req) { | ||
request = req; | ||
|
||
req.query = {}; | ||
req.query.code = 'SplxlOBeZQQYbYS6WxSbIA'; | ||
req.query.state = 'DkbychwKu8kBaJoLE5yeR5NK'; | ||
req.session = {}; | ||
req.session['oauth2:www.example.com'] = {}; | ||
}) | ||
.authenticate(); | ||
}); | ||
|
||
it('should supply info', function() { | ||
expect(info).to.be.an.object; | ||
expect(info.message).to.equal('Unable to verify authorization request state.'); | ||
}); | ||
|
||
it('should supply status', function() { | ||
expect(status).to.equal(403); | ||
}); | ||
}); // that fails due to provider-specific state lacking state value | ||
|
||
describe('that errors due to lack of session support in app', function() { | ||
var request | ||
, err; | ||
|
||
before(function(done) { | ||
chai.passport.use(strategy) | ||
.error(function(e) { | ||
err = e; | ||
done(); | ||
}) | ||
.req(function(req) { | ||
request = req; | ||
|
||
req.query = {}; | ||
req.query.code = 'SplxlOBeZQQYbYS6WxSbIA'; | ||
req.query.state = 'DkbychwKu8kBaJoLE5yeR5NK'; | ||
}) | ||
.authenticate(); | ||
}); | ||
|
||
it('should error', function() { | ||
expect(err).to.be.an.instanceof(Error) | ||
expect(err.message).to.equal('OAuth2Strategy requires session support when using state. Did you forget app.use(express.session(...))?'); | ||
}); | ||
}); // that errors due to lack of session support in app | ||
|
||
}); // processing response to authorization request | ||
|
||
}); // using default session state store | ||
|
||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters