-
Notifications
You must be signed in to change notification settings - Fork 211
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support functions for provider.auth
and provider.token
#463
base: master
Are you sure you want to change the base?
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -56,9 +56,10 @@ exports.v1 = function (settings) { | |
|
||
// Obtain temporary OAuth credentials | ||
|
||
const temporaryEndpoint = internals.resolveProviderEndpoint(request, settings.provider.temporary); | ||
const oauth_callback = internals.location(request, protocol, settings.location); | ||
try { | ||
var { payload: temp } = await client.temporary(oauth_callback); | ||
var { payload: temp } = await client.temporary(temporaryEndpoint, oauth_callback); | ||
} | ||
catch (err) { | ||
return h.unauthenticated(err, { credentials }); | ||
|
@@ -79,7 +80,8 @@ exports.v1 = function (settings) { | |
Hoek.merge(authQuery, request.query); | ||
} | ||
|
||
return h.redirect(settings.provider.auth + '?' + internals.queryString(authQuery)).takeover(); | ||
const authEndpoint = internals.resolveProviderEndpoint(request, settings.provider.auth); | ||
return h.redirect(authEndpoint + '?' + internals.queryString(authQuery)).takeover(); | ||
} | ||
|
||
// Authorization callback | ||
|
@@ -102,8 +104,9 @@ exports.v1 = function (settings) { | |
|
||
// Obtain token OAuth credentials | ||
|
||
const tokenEndpoint = internals.resolveProviderEndpoint(request, settings.provider.token); | ||
try { | ||
var { payload: token } = await client.token(state.token, request.query.oauth_verifier, state.secret); | ||
var { payload: token } = await client.token(tokenEndpoint, state.token, request.query.oauth_verifier, state.secret); | ||
} | ||
catch (err) { | ||
return h.unauthenticated(err, { credentials }); | ||
|
@@ -230,7 +233,9 @@ exports.v2 = function (settings) { | |
} | ||
|
||
h.state(cookie, state); | ||
return h.redirect(settings.provider.auth + '?' + internals.queryString(query)).takeover(); | ||
|
||
const authEndpoint = internals.resolveProviderEndpoint(request, settings.provider.auth); | ||
return h.redirect(authEndpoint + '?' + internals.queryString(query)).takeover(); | ||
} | ||
|
||
// Authorization callback | ||
|
@@ -286,8 +291,9 @@ exports.v2 = function (settings) { | |
|
||
// Obtain token | ||
|
||
const tokenEndpoint = internals.resolveProviderEndpoint(request, settings.provider.token); | ||
try { | ||
var { res: tokenRes, payload } = await Wreck.post(settings.provider.token, requestOptions); | ||
var { res: tokenRes, payload } = await Wreck.post(tokenEndpoint, requestOptions); | ||
} | ||
catch (err) { | ||
return h.unauthenticated(Boom.internal('Failed obtaining ' + name + ' access token', err), { credentials }); | ||
|
@@ -387,28 +393,26 @@ exports.Client = internals.Client = function (options) { | |
|
||
this.provider = options.name; | ||
this.settings = { | ||
temporary: internals.Client.baseUri(options.provider.temporary), | ||
token: internals.Client.baseUri(options.provider.token), | ||
clientId: options.clientId, | ||
clientSecret: options.provider.signatureMethod === 'RSA-SHA1' ? options.clientSecret : internals.encode(options.clientSecret || '') + '&', | ||
signatureMethod: options.provider.signatureMethod | ||
}; | ||
}; | ||
|
||
|
||
internals.Client.prototype.temporary = function (oauth_callback) { | ||
internals.Client.prototype.temporary = function (uri, oauth_callback) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a breaking change. The |
||
|
||
// Temporary Credentials (2.1) | ||
|
||
const oauth = { | ||
oauth_callback | ||
}; | ||
|
||
return this._request('post', this.settings.temporary, null, oauth, { desc: 'temporary credentials' }); | ||
return this._request('post', internals.Client.baseUri(uri), null, oauth, { desc: 'temporary credentials' }); | ||
}; | ||
|
||
|
||
internals.Client.prototype.token = function (oauthToken, oauthVerifier, tokenSecret) { | ||
internals.Client.prototype.token = function (uri, oauthToken, oauthVerifier, tokenSecret) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same on every There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I reverted the changes to these method signatures but kept their ability to resolve endpoints from a function, if a function is provided. It's a bit ugly since it potentially requires setting I didn't catch that |
||
|
||
// Token Credentials (2.3) | ||
|
||
|
@@ -417,7 +421,7 @@ internals.Client.prototype.token = function (oauthToken, oauthVerifier, tokenSec | |
oauth_verifier: oauthVerifier | ||
}; | ||
|
||
return this._request('post', this.settings.token, null, oauth, { secret: tokenSecret, desc: 'token credentials' }); | ||
return this._request('post', internals.Client.baseUri(uri), null, oauth, { secret: tokenSecret, desc: 'token credentials' }); | ||
}; | ||
|
||
|
||
|
@@ -723,6 +727,12 @@ internals.getProtocol = function (request, settings) { | |
}; | ||
|
||
|
||
internals.resolveProviderEndpoint = function (request, endpoint) { | ||
|
||
return typeof endpoint === 'function' ? endpoint(request) : endpoint; | ||
}; | ||
|
||
|
||
internals.resolveProviderParams = function (request, params) { | ||
|
||
const obj = typeof params === 'function' ? params(request) : params; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -344,6 +344,47 @@ describe('Bell', () => { | |
expect(res.headers.location).to.equal(mock.uri + '/auth?oauth_token=1&runtime=true'); | ||
}); | ||
|
||
it('authenticates an endpoint via oauth with auth provider (function)', async (flags) => { | ||
|
||
const mock = await Mock.v1(flags); | ||
const server = Hapi.server({ host: 'localhost', port: 8080 }); | ||
await server.register(Bell); | ||
|
||
const provider = Hoek.merge(mock.provider, { | ||
temporary: (request) => request.query.host + '/temporary', | ||
auth: (request) => request.query.host + '/auth', | ||
token: (request) => request.query.host + '/token' | ||
}); | ||
|
||
server.auth.strategy('custom', 'bell', { | ||
password: 'cookie_encryption_password_secure', | ||
isSecure: false, | ||
clientId: 'test', | ||
clientSecret: 'secret', | ||
provider | ||
}); | ||
|
||
server.route({ | ||
method: '*', | ||
path: '/login', | ||
options: { | ||
auth: 'custom', | ||
handler: function (request, h) { | ||
|
||
return request.auth.credentials; | ||
} | ||
} | ||
}); | ||
|
||
const res1 = await server.inject('/login?host=' + mock.uri); | ||
|
||
const cookie = res1.headers['set-cookie'][0].split(';')[0] + ';'; | ||
const res2 = await mock.server.inject(res1.headers.location + '&host=' + mock.uri); | ||
|
||
const res3 = await server.inject({ url: res2.headers.location + '&host=' + mock.uri, headers: { cookie } }); | ||
expect(res3.statusCode).to.equal(200); | ||
}); | ||
|
||
it('authenticates an endpoint via oauth with auth provider parameters', async (flags) => { | ||
|
||
const mock = await Mock.v1(flags); | ||
|
@@ -897,6 +938,46 @@ describe('Bell', () => { | |
|
||
describe('v2()', () => { | ||
|
||
it('authenticates an endpoint with provider (function)', async (flags) => { | ||
|
||
const mock = await Mock.v2(flags); | ||
const server = Hapi.server({ host: 'localhost', port: 8080 }); | ||
await server.register(Bell); | ||
|
||
const provider = Hoek.merge(mock.provider, { | ||
auth: (request) => request.query.host + '/auth', | ||
token: (request) => request.query.host + '/token' | ||
}); | ||
|
||
server.auth.strategy('custom', 'bell', { | ||
password: 'cookie_encryption_password_secure', | ||
isSecure: false, | ||
clientId: 'test', | ||
clientSecret: 'secret', | ||
provider | ||
}); | ||
|
||
server.route({ | ||
method: '*', | ||
path: '/login', | ||
options: { | ||
auth: 'custom', | ||
handler: function (request, h) { | ||
|
||
return request.auth.credentials; | ||
} | ||
} | ||
}); | ||
|
||
const res1 = await server.inject('/login?host=' + mock.uri); | ||
const cookie = res1.headers['set-cookie'][0].split(';')[0] + ';'; | ||
|
||
const res2 = await mock.server.inject(res1.headers.location + '&host=' + mock.uri); | ||
|
||
const res3 = await server.inject({ url: res2.headers.location + '&host=' + mock.uri, headers: { cookie } }); | ||
expect(res3.statusCode).to.equal(200); | ||
}); | ||
|
||
it('authenticates an endpoint with provider parameters', async (flags) => { | ||
|
||
const mock = await Mock.v2(flags); | ||
|
@@ -2154,6 +2235,12 @@ describe('Bell', () => { | |
expect(OAuth.Client.baseUri('http://example.com:8080/x')).to.equal('http://example.com:8080/x'); | ||
expect(OAuth.Client.baseUri('https://example.com:8080/x')).to.equal('https://example.com:8080/x'); | ||
}); | ||
|
||
it('passes through without port', () => { | ||
|
||
expect(OAuth.Client.baseUri('http://example.com/x')).to.equal('http://example.com/x'); | ||
expect(OAuth.Client.baseUri('https://example.com/x')).to.equal('https://example.com/x'); | ||
}); | ||
Comment on lines
+2239
to
+2243
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is unrelated, but after my changes we lost coverage on this case. This adds it back. |
||
}); | ||
|
||
describe('signature()', () => { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My interest is only in
auth
andtoken
, but I thought it might be odd to leave this out.