Skip to content
This repository was archived by the owner on Feb 25, 2019. It is now read-only.

tweaks to get server talking to external Java (mitreid) and passport-openid clients #59

Merged
merged 7 commits into from
Dec 4, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions config/passport.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,15 @@ module.exports = function (passport) {
*/

passport.use(new LocalStrategy(
{ usernameField: 'email' },
function (email, password, done) {
{ usernameField: 'email', passReqToCallback: 'true' },
function (req, email, password, done) {
User.authenticate(email, password, function (err, user, info) {
if (user) {
// throw password value away so isn't included in URLs/logged
delete req.connectParams.password;
delete req.connectParams.email;
}

done(err, user, info);
});
}
Expand Down Expand Up @@ -110,6 +116,7 @@ module.exports = function (passport) {
});
}

if (config.providers) {
Object.keys(config.providers).forEach(function (name) {
var prov = providers[name]
, conf = config.providers[name]
Expand All @@ -118,7 +125,8 @@ module.exports = function (passport) {
if (prov && prov.protocol === 'OAuth 2.0') {
passport.use(new OAuth2Strategy(prov, conf, verifier));
}
});
});
}


};
2 changes: 1 addition & 1 deletion config/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -600,7 +600,7 @@ module.exports = function (server) {


// JWKs
server.set('jwks', [jwk(publicKey)]);
server.set('jwks', {keys: [jwk(publicKey)]});


/**
Expand Down
3 changes: 2 additions & 1 deletion lib/oidc/authorize.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ var crypto = require('crypto')
, AccessToken = require('../../models/AccessToken')
, AuthorizationCode = require('../../models/AuthorizationCode')
, FormUrlencoded = require('form-urlencoded')
, nowSeconds = require('../time-utils').nowSeconds
;


Expand Down Expand Up @@ -91,7 +92,7 @@ module.exports = function (server) {
iss: server.settings.issuer,
sub: req.user._id,
aud: req.client._id,
exp: Date.now() + (response.expires_in) * 1000,
exp: nowSeconds(response.expires_in),
nonce: params.nonce,
at_hash: atHash
});
Expand Down
5 changes: 3 additions & 2 deletions lib/oidc/token.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ var fs = require('fs')
, config = require(path.join(cwd, 'config.' + env + '.json'))
, AccessToken = require('../../models/AccessToken')
, IDToken = require('../../models/IDToken')
, nowSeconds = require('../time-utils').nowSeconds
;


Expand Down Expand Up @@ -44,7 +45,7 @@ module.exports = function (server) {
iss: config.issuer,
sub: ac.user_id,
aud: ac.client_id,
exp: Date.now() + (token.expires_in) * 1000,
exp: nowSeconds(token.expires_in)
});
}

Expand All @@ -53,7 +54,7 @@ module.exports = function (server) {
iss: config.issuer,
sub: token.cid,
aud: token.uid,
exp: Date.now() + (token.expires_in) * 1000,
exp: nowSeconds(token.expires_in)
});
}

Expand Down
5 changes: 3 additions & 2 deletions lib/oidc/verifyAuthorizationCode.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
* Module dependencies
*/

var AuthorizationCode = require('../../models/AuthorizationCode')
var AuthorizationCode = require('../../models/AuthorizationCode')
, AuthorizationError = require('../../errors/AuthorizationError')
, nowSeconds = require('../time-utils').nowSeconds
;


Expand Down Expand Up @@ -38,7 +39,7 @@ function verifyAuthorizationCode (req, res, next) {
}

// Authorization code is expired
if (Date.now() > ac.expires_at) {
if (nowSeconds() > ac.expires_at) {
return next(new AuthorizationError({
error: 'invalid_grant',
error_description: 'Authorization code expired',
Expand Down
6 changes: 2 additions & 4 deletions lib/strategies/OAuth.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ var pkg = require('../../package.json')
, request = require('superagent')
, Strategy = require('passport-strategy')
, agent = 'Anvil Connect/v' + pkg.version
, nowSeconds = require('../../lib/time-utils').nowSeconds
;


Expand Down Expand Up @@ -85,10 +86,7 @@ OAuthStrategy.encodeOAuthData = encodeOAuthData;
*/

function timestamp () {
return Math.floor(
(new Date())
.getTime() / 1000
);
return nowSeconds();
}

OAuthStrategy.timestamp = timestamp;
Expand Down
18 changes: 18 additions & 0 deletions lib/time-utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* http://openid.net/specs/openid-connect-core-1_0.html states exp/iat times are in secs, not millis
*
* @param {long} deltaSecs optional delta to be added to "now", in seconds.
* @return {long} "now" in seconds, with deltaSecs added if it was supplied.
* @api private
*/
exports.nowSeconds = function (deltaSecs) {
var secs = Date.now();
var secs = Math.round(secs / 1000);
var secsStr;

if (deltaSecs) {
secs += deltaSecs;
}
secsStr = secs.toString();
return secs;
};
15 changes: 8 additions & 7 deletions models/AccessToken.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ var async = require('async')
, Modinha = require('modinha')
, Document = require('modinha-redis')
, random = Modinha.defaults.random
, InvalidTokenError = require('../errors/InvalidTokenError')
, UnauthorizedError = require('../errors/UnauthorizedError')
, InvalidTokenError = require('../errors/InvalidTokenError')
, UnauthorizedError = require('../errors/UnauthorizedError')
, InsufficientScopeError = require('../errors/InsufficientScopeError')
, nowSeconds = require('../lib/time-utils').nowSeconds
;


Expand Down Expand Up @@ -313,7 +314,7 @@ AccessToken.verify = function (token, options, callback) {
sub: instance.uid,
aud: instance.cid,
iat: instance.created,
exp: instance.created + (instance.ei * 1000),
exp: instance.created + instance.ei,
scope: instance.scope
});
});
Expand Down Expand Up @@ -344,7 +345,7 @@ AccessToken.verify = function (token, options, callback) {
}

// expired token
if (Date.now() > claims.exp) {
if (nowSeconds() > claims.exp) {
return callback(new UnauthorizedError({
realm: 'user',
error: 'invalid_token',
Expand Down Expand Up @@ -396,7 +397,7 @@ var AccessJWT = JWT.define({
registeredClaims: {
jti: { format: 'String', required: true, from: 'at' },
iss: { format: 'URI', required: true },
iat: { format: 'IntDate', required: true, default: Date.now },
iat: { format: 'IntDate', required: true, default: nowSeconds },
exp: { format: 'IntDate', required: true, default: expires },
sub: { format: 'String', required: true, from: 'uid' },
aud: { format: 'String', required: true, from: 'cid' },
Expand All @@ -406,14 +407,14 @@ var AccessJWT = JWT.define({
});

function expires () {
return Date.now() + (3600 * 1000);
return nowSeconds(3600);
}

AccessToken.AccessJWT = AccessJWT;

AccessToken.prototype.toJWT = function (secret) {
var jwt = new AccessJWT(this);
jwt.payload.exp = Date.now() + (this.ei * 1000);
jwt.payload.exp = nowSeconds(this.ei);
return jwt.encode(secret);
}

Expand Down
5 changes: 4 additions & 1 deletion models/AuthorizationCode.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ var client = require('../config/redis')
, Modinha = require('modinha')
, Document = require('modinha-redis')
, AuthorizationError = require('../errors/AuthorizationError')
, nowSeconds = require('../lib/time-utils').nowSeconds
;


Expand Down Expand Up @@ -66,7 +67,9 @@ var AuthorizationCode = Modinha.define('authorizationcodes', {
*/

function expires () {
return Date.now() + (600 * 1000);
var secs = nowSeconds(600);

return secs;
}


Expand Down
5 changes: 3 additions & 2 deletions models/ClientToken.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
* Module dependencies
*/

var JWT = require('anvil-connect-jwt');
var JWT = require('anvil-connect-jwt')
, nowSeconds = require('../lib/time-utils').nowSeconds


/**
Expand Down Expand Up @@ -35,7 +36,7 @@ var ClientToken = JWT.define({
sub: { format: 'StringOrURI', required: true },
aud: { format: 'StringOrURI', required: true },
//exp: { format: 'IntDate', required: true, default: expires('day') },
iat: { format: 'IntDate', required: true, default: Date.now },
iat: { format: 'IntDate', required: true, default: nowSeconds },
scope: { format: 'String', required: true, default: 'client' }
}

Expand Down
13 changes: 7 additions & 6 deletions models/IDToken.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
* Module dependencies
*/

var JWT = require('anvil-connect-jwt');
var JWT = require('anvil-connect-jwt')
, nowSeconds = require('../lib/time-utils').nowSeconds


/**
Expand All @@ -11,13 +12,13 @@ var JWT = require('anvil-connect-jwt');

function expires (duration) {
var fromNow = {
day: (1000 * 60 * 60 * 24),
week: (1000 * 60 * 60 * 24 * 7),
month: (1000 * 60 * 60 * 24 * 30)
day: (60 * 60 * 24),
week: (60 * 60 * 24 * 7),
month: (60 * 60 * 24 * 30)
};

return function () {
return Date.now() + fromNow[duration];
return nowSeconds(fromNow[duration]);
};
}

Expand Down Expand Up @@ -52,7 +53,7 @@ var IDToken = JWT.define({
sub: { format: 'StringOrURI', required: true },
aud: { format: 'StringOrURI', required: true },
exp: { format: 'IntDate', required: true, default: expires('day') },
iat: { format: 'IntDate', required: true, default: Date.now },
iat: { format: 'IntDate', required: true, default: nowSeconds },
nonce: { format: 'String' },
acr: { format: 'String' },
at_hash: { format: 'String' }
Expand Down
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@
"fakeredis": "~0.2.0",
"sinon": "~1.9.0",
"sinon-chai": "~2.5.0",
"supertest": "^0.14.0"
"supertest": "^0.14.0",
"mocha": "^2.0.1",
"coffee-script": "^1.8.0",
"nock": "^0.51.0"
},
"dependencies": {
"anvil-connect-jwt": "^0.1.2",
Expand Down Expand Up @@ -68,9 +71,11 @@
"passport-http-bearer": "~1.0.1",
"passport-local": "~1.0.0",
"passport-oauth": "^1.0.0",
"passport-strategy": "~1.0.0",
"passport-twitter": "~1.0.2",
"qs": "^2.3.2",
"redis": "~0.10.1",
"superagent": "~0.21.0",
"uri-js": "~1.4.2",
"yargs": "~1.2.2"
}
Expand Down
25 changes: 17 additions & 8 deletions test/models/accessTokenSpec.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ server = require path.join(cwd, 'server')
Modinha = require 'modinha'
AccessToken = require path.join(cwd, 'models/AccessToken')
AccessJWT = AccessToken.AccessJWT
{nowSeconds} = require '../../lib/time-utils'



Expand Down Expand Up @@ -244,7 +245,15 @@ describe 'AccessToken', ->
expect(err).to.be.null

it 'should provide an "issue" projection of the token', ->
res.access_token.length.should.equal 568
res.access_token.length.should.be.above 100
options =
key: server.settings.publicKey
decoded = AccessJWT.decode(res.access_token, options.key)
decoded.payload.should.have.property('iss', server.settings.issuer)
decoded.payload.should.have.property('sub', 'uuid1')
decoded.payload.should.have.property 'iat'
decoded.payload.should.have.property 'exp'
decoded.payload.should.have.property 'scope'

it 'should expire in the default duration', ->
res.expires_in.should.equal AccessToken.schema.ei.default
Expand Down Expand Up @@ -410,7 +419,7 @@ describe 'AccessToken', ->

it 'should calculate exp', ->
decoded.payload.exp.should.equal(
decoded.payload.iat + (token.ei * 1000)
decoded.payload.iat + token.ei
)


Expand Down Expand Up @@ -473,7 +482,7 @@ describe 'AccessToken', ->
iss: server.settings.issuer
uid: 'uuid1'
cid: 'uuid2'
exp: Date.now() - 10000
exp: nowSeconds(-1)
scope: 'openid'
})).encode(server.settings.privateKey)
options =
Expand Down Expand Up @@ -583,7 +592,7 @@ describe 'AccessToken', ->
sinon.stub(AccessToken, 'get').callsArgWith(1, null, {
iss: server.settings.issuer
ei: -10000
created: Date.now()
created: nowSeconds()
})
token = 'r4nd0m'
options =
Expand Down Expand Up @@ -614,7 +623,7 @@ describe 'AccessToken', ->
iss: server.settings.issuer
ei: 10000
scope: 'openid'
created: Date.now()
created: nowSeconds()
})
token = 'r4nd0m'
options =
Expand Down Expand Up @@ -647,9 +656,9 @@ describe 'AccessToken', ->
iss: server.settings.issuer
uid: 'uuid1'
cid: 'uuid2'
ei: 10000
ei: 10
scope: 'openid'
created: Date.now()
created: nowSeconds()

sinon.stub(AccessToken, 'get').callsArgWith(1, null, instance)
token = 'r4nd0m'
Expand Down Expand Up @@ -683,7 +692,7 @@ describe 'AccessToken', ->
claims.iat.should.equal instance.created

it 'should provide "exp" claim', ->
claims.exp.should.equal instance.created + (instance.ei * 1000)
claims.exp.should.equal instance.created + instance.ei

it 'should provide "scope" claim', ->
claims.scope.should.equal instance.scope
Expand Down
Loading