Ghost Auth: register client with blog_uri (#7680)

* 🛠  passport-ghost 1.1.0

*   register client: add blog_uri

refs #7654

- improve readability
- get rid of all the url util usages
- add blog_uri

[ci skip]

* 🎨  tests
This commit is contained in:
Katharina Irrgang 2016-11-07 12:38:05 +01:00 committed by Hannah Wolfe
parent 4e7779b783
commit a19fa8d3ac
4 changed files with 52 additions and 24 deletions

View File

@ -5,7 +5,6 @@ var ClientPasswordStrategy = require('passport-oauth2-client-password').Strategy
debug = require('debug')('ghost:auth'), debug = require('debug')('ghost:auth'),
Promise = require('bluebird'), Promise = require('bluebird'),
authStrategies = require('./auth-strategies'), authStrategies = require('./auth-strategies'),
utils = require('../utils'),
errors = require('../errors'), errors = require('../errors'),
logging = require('../logging'), logging = require('../logging'),
models = require('../models'), models = require('../models'),
@ -16,13 +15,14 @@ var ClientPasswordStrategy = require('passport-oauth2-client-password').Strategy
_private.registerClient = function (options) { _private.registerClient = function (options) {
var ghostOAuth2Strategy = options.ghostOAuth2Strategy, var ghostOAuth2Strategy = options.ghostOAuth2Strategy,
url = options.url; clientName = options.clientName,
redirectUri = options.redirectUri;
return models.Client.findOne({slug: 'ghost-auth'}, {context: {internal: true}}) return models.Client.findOne({slug: 'ghost-auth'}, {context: {internal: true}})
.then(function fetchedClient(client) { .then(function fetchedClient(client) {
// CASE: Ghost Auth client is already registered // CASE: Ghost Auth client is already registered
if (client) { if (client) {
if (client.get('redirection_uri') === url) { if (client.get('redirection_uri') === redirectUri) {
return { return {
client_id: client.get('uuid'), client_id: client.get('uuid'),
client_secret: client.get('secret') client_secret: client.get('secret')
@ -31,11 +31,11 @@ _private.registerClient = function (options) {
debug('Update ghost client callback url...'); debug('Update ghost client callback url...');
return ghostOAuth2Strategy.changeCallbackURL({ return ghostOAuth2Strategy.changeCallbackURL({
callbackURL: utils.url.urlJoin(url, 'ghost', '/'), callbackURL: redirectUri,
clientId: client.get('uuid'), clientId: client.get('uuid'),
clientSecret: client.get('secret') clientSecret: client.get('secret')
}).then(function changedCallbackURL() { }).then(function changedCallbackURL() {
client.set('redirection_uri', url); client.set('redirection_uri', redirectUri);
return client.save(null, {context: {internal: true}}); return client.save(null, {context: {internal: true}});
}).then(function updatedClient() { }).then(function updatedClient() {
return { return {
@ -45,14 +45,14 @@ _private.registerClient = function (options) {
}); });
} }
return ghostOAuth2Strategy.registerClient({clientName: url}) return ghostOAuth2Strategy.registerClient({clientName: clientName})
.then(function addClient(credentials) { .then(function addClient(credentials) {
return models.Client.add({ return models.Client.add({
name: 'Ghost Auth', name: 'Ghost Auth',
slug: 'ghost-auth', slug: 'ghost-auth',
uuid: credentials.client_id, uuid: credentials.client_id,
secret: credentials.client_secret, secret: credentials.client_secret,
redirection_uri: utils.url.urlJoin(url, 'ghost', '/') redirection_uri: redirectUri
}, {context: {internal: true}}); }, {context: {internal: true}});
}) })
.then(function returnClient(client) { .then(function returnClient(client) {
@ -99,26 +99,31 @@ _private.startPublicClientRegistration = function startPublicClientRegistration(
* - ghost: remote login at Ghost.org * - ghost: remote login at Ghost.org
*/ */
exports.init = function initPassport(options) { exports.init = function initPassport(options) {
var type = options.type, var authType = options.authType,
url = options.url; clientName = options.clientName,
ghostAuthUrl = options.ghostAuthUrl,
redirectUri = options.redirectUri,
blogUri = options.blogUri;
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
passport.use(new ClientPasswordStrategy(authStrategies.clientPasswordStrategy)); passport.use(new ClientPasswordStrategy(authStrategies.clientPasswordStrategy));
passport.use(new BearerStrategy(authStrategies.bearerStrategy)); passport.use(new BearerStrategy(authStrategies.bearerStrategy));
if (type !== 'ghost') { if (authType !== 'ghost') {
return resolve({passport: passport.initialize()}); return resolve({passport: passport.initialize()});
} }
var ghostOAuth2Strategy = new GhostOAuth2Strategy({ var ghostOAuth2Strategy = new GhostOAuth2Strategy({
callbackURL: utils.url.urlJoin(utils.url.getBaseUrl(), 'ghost', '/'), callbackURL: redirectUri,
url: url, blogUri: blogUri,
url: ghostAuthUrl,
passReqToCallback: true passReqToCallback: true
}, authStrategies.ghostStrategy); }, authStrategies.ghostStrategy);
_private.startPublicClientRegistration({ _private.startPublicClientRegistration({
ghostOAuth2Strategy: ghostOAuth2Strategy, ghostOAuth2Strategy: ghostOAuth2Strategy,
url: utils.url.getBaseUrl() clientName: clientName,
redirectUri: redirectUri
}).then(function setClient(client) { }).then(function setClient(client) {
debug('Public Client Registration was successful'); debug('Public Client Registration was successful');

View File

@ -115,10 +115,16 @@ function init(options) {
debug('Express Apps done'); debug('Express Apps done');
return auth.init(config.get('auth')) return auth.init({
.then(function (response) { authType: config.get('auth:type'),
parentApp.use(response.auth); ghostAuthUrl: config.get('auth:url'),
}); redirectUri: utils.url.urlJoin(utils.url.getBaseUrl(), 'ghost', '/'),
blogUri: utils.url.urlJoin(utils.url.getBaseUrl(), '/'),
// @TODO: set blog title
clientName: utils.url.getBaseUrl()
}).then(function (response) {
parentApp.use(response.auth);
});
}).then(function () { }).then(function () {
debug('Auth done'); debug('Auth done');
return new GhostServer(parentApp); return new GhostServer(parentApp);

View File

@ -15,8 +15,13 @@ should.equal(true, true);
describe('Ghost Passport', function () { describe('Ghost Passport', function () {
var client; var client;
function FakeGhostOAuth2Strategy() { function FakeGhostOAuth2Strategy(options) {
this.name = 'FakeGhostOAuth2Strategy'; this.name = 'FakeGhostOAuth2Strategy';
should.exist(options.blogUri);
should.exist(options.url);
should.exist(options.callbackURL);
options.passReqToCallback.should.eql(true);
} }
before(function () { before(function () {
@ -46,7 +51,7 @@ describe('Ghost Passport', function () {
describe('auth_type: password', function () { describe('auth_type: password', function () {
it('initialise passport with passport auth type', function () { it('initialise passport with passport auth type', function () {
return GhostPassport.init({ return GhostPassport.init({
type: 'passport' authType: 'passport'
}).then(function (response) { }).then(function (response) {
should.exist(response.passport); should.exist(response.passport);
passport.use.callCount.should.eql(2); passport.use.callCount.should.eql(2);
@ -67,7 +72,10 @@ describe('Ghost Passport', function () {
})); }));
return GhostPassport.init({ return GhostPassport.init({
type: 'ghost' authType: 'ghost',
blogUri: 'http://my-blog.com',
ghostAuthUrl: 'http://devauth.ghost.org',
redirectUri: utils.url.getBaseUrl()
}).then(function (response) { }).then(function (response) {
should.exist(response.passport); should.exist(response.passport);
passport.use.callCount.should.eql(3); passport.use.callCount.should.eql(3);
@ -86,7 +94,10 @@ describe('Ghost Passport', function () {
})); }));
return GhostPassport.init({ return GhostPassport.init({
type: 'ghost' authType: 'ghost',
blogUri: 'http://my-blog.com',
ghostAuthUrl: 'http://devauth.ghost.org',
redirectUri: utils.url.getBaseUrl()
}).then(function (response) { }).then(function (response) {
should.exist(response.passport); should.exist(response.passport);
passport.use.callCount.should.eql(3); passport.use.callCount.should.eql(3);
@ -103,7 +114,10 @@ describe('Ghost Passport', function () {
client = null; client = null;
return GhostPassport.init({ return GhostPassport.init({
type: 'ghost' authType: 'ghost',
blogUri: 'http://my-blog.com',
ghostAuthUrl: 'http://devauth.ghost.org',
redirectUri: utils.url.getBaseUrl()
}).then(function (response) { }).then(function (response) {
should.exist(response.passport); should.exist(response.passport);
passport.use.callCount.should.eql(3); passport.use.callCount.should.eql(3);
@ -121,7 +135,10 @@ describe('Ghost Passport', function () {
FakeGhostOAuth2Strategy.prototype.registerClient.returns(Promise.reject(new Error('cannot connect to ghost.org'))); FakeGhostOAuth2Strategy.prototype.registerClient.returns(Promise.reject(new Error('cannot connect to ghost.org')));
return GhostPassport.init({ return GhostPassport.init({
type: 'ghost' authType: 'ghost',
blogUri: 'http://my-blog.com',
ghostAuthUrl: 'http://devauth.ghost.org',
redirectUri: utils.url.getBaseUrl()
}).catch(function (err) { }).catch(function (err) {
(err instanceof errors.IncorrectUsageError).should.eql(true); (err instanceof errors.IncorrectUsageError).should.eql(true);
FakeGhostOAuth2Strategy.prototype.registerClient.callCount.should.eql(12); FakeGhostOAuth2Strategy.prototype.registerClient.callCount.should.eql(12);

View File

@ -68,7 +68,7 @@
"nodemailer": "0.7.1", "nodemailer": "0.7.1",
"oauth2orize": "1.5.1", "oauth2orize": "1.5.1",
"passport": "0.3.2", "passport": "0.3.2",
"passport-ghost": "1.0.3", "passport-ghost": "1.1.0",
"passport-http-bearer": "1.0.1", "passport-http-bearer": "1.0.1",
"passport-oauth2-client-password": "0.1.2", "passport-oauth2-client-password": "0.1.2",
"path-match": "1.2.4", "path-match": "1.2.4",