Removed defunct Ghost OAuth code (#9014)

closes #8342

- no need to add a migration, because when we'released 1.0, OAuth was never an option
- it was disabled in April, 1.0-beta was released in June
- remove all remote authentication code
This commit is contained in:
Katharina Irrgang 2017-09-18 14:01:58 +02:00 committed by Kevin Ansfield
parent 1868285bed
commit 7b4c3fc085
16 changed files with 20 additions and 762 deletions

View File

@ -46,8 +46,6 @@ function getBaseConfig() {
* ## Configuration API Methods
*
* We need to load the client credentials dynamically.
* For example: on bootstrap ghost-auth get's created and if we load them here in parallel,
* it can happen that we won't get any client credentials or wrong credentials.
*
* **See:** [API Methods](index.js.html#api%20methods)
*/
@ -61,26 +59,14 @@ configuration = {
*/
read: function read(options) {
options = options || {};
var ops = {};
if (!options.key) {
ops.ghostAdmin = models.Client.findOne({slug: 'ghost-admin'});
if (config.get('auth:type') === 'ghost') {
ops.ghostAuth = models.Client.findOne({slug: 'ghost-auth'});
}
return Promise.props(ops)
.then(function (result) {
return models.Client.findOne({slug: 'ghost-admin'})
.then(function (ghostAdmin) {
var configuration = getBaseConfig();
configuration.clientId = result.ghostAdmin.get('slug');
configuration.clientSecret = result.ghostAdmin.get('secret');
if (config.get('auth:type') === 'ghost') {
configuration.ghostAuthId = result.ghostAuth && result.ghostAuth.get('uuid') || 'not-available';
configuration.ghostAuthUrl = config.get('auth:url');
}
configuration.clientId = ghostAdmin.get('slug');
configuration.clientSecret = ghostAdmin.get('secret');
return {configuration: [configuration]};
});

View File

@ -1,19 +0,0 @@
var passport = require('passport'),
Promise = require('bluebird');
module.exports.getUser = function getUser(options) {
options = options || {};
var id = options.id,
ghostOAuth2Strategy = passport._strategies.ghost;
return new Promise(function (resolve, reject) {
ghostOAuth2Strategy.userProfileByIdentityId(id, function (err, profile) {
if (err) {
return reject(err);
}
resolve(profile);
});
});
};

View File

@ -1,23 +1,13 @@
var passport = require('./passport'),
authorize = require('./authorize'),
authenticate = require('./authenticate'),
sync = require('./sync'),
oauth = require('./oauth'),
validation = require('./validation'),
ghostAuth = require('./ghost-auth');
oauth = require('./oauth');
exports.init = function (options) {
oauth.init(options);
sync.init(options);
return passport.init(options)
.then(function (response) {
return {auth: response.passport};
});
return passport.init(options);
};
exports.validation = validation;
exports.oauth = oauth;
exports.authorize = authorize;
exports.authenticate = authenticate;
exports.ghostAuth = ghostAuth;

View File

@ -1,221 +1,15 @@
var ClientPasswordStrategy = require('passport-oauth2-client-password').Strategy,
BearerStrategy = require('passport-http-bearer').Strategy,
GhostOAuth2Strategy = require('passport-ghost').Strategy,
passport = require('passport'),
_ = require('lodash'),
debug = require('ghost-ignition').debug('auth'),
Promise = require('bluebird'),
authStrategies = require('./auth-strategies'),
errors = require('../errors'),
events = require('../events'),
logging = require('../logging'),
models = require('../models'),
_private = {};
/**
* Update client name and description if changes in the blog settings
*/
_private.registerEvents = function registerEvents() {
events.on('settings.edited', function onSettingsChanged(settingModel) {
var titleHasChanged = settingModel.attributes.key === 'title' && settingModel.attributes.value !== settingModel._updatedAttributes.value,
descriptionHasChanged = settingModel.attributes.key === 'description' && settingModel.attributes.value !== settingModel._updatedAttributes.value,
options = {
ghostOAuth2Strategy: passport._strategies.ghost
};
if (!titleHasChanged && !descriptionHasChanged) {
return;
}
if (titleHasChanged) {
options.clientName = settingModel.attributes.value;
debug('Ghost Auth Client title has changed: ' + options.clientName);
}
if (descriptionHasChanged) {
options.clientDescription = settingModel.attributes.value;
debug('Ghost AuthClient description has changed: ' + options.clientDescription);
}
_private.updateClient(options).catch(function onUpdatedClientError(err) {
// @TODO: see https://github.com/TryGhost/Ghost/issues/7627
if (_.isArray(err)) {
err = err[0];
}
logging.error(err);
});
});
};
/**
* smart function
*/
_private.updateClient = function updateClient(options) {
var ghostOAuth2Strategy = options.ghostOAuth2Strategy,
redirectUri = options.redirectUri,
clientUri = options.clientUri,
clientName = options.clientName,
clientDescription = options.clientDescription;
return models.Client.findOne({slug: 'ghost-auth'}, {context: {internal: true}})
.then(function (client) {
// CASE: we have to create the client
if (!client) {
debug('Client does not exist');
return ghostOAuth2Strategy.registerClient({
name: clientName,
description: clientDescription
}).then(function registeredRemoteClient(credentials) {
debug('Registered remote client: ' + JSON.stringify(credentials));
logging.info('Registered remote client successfully.');
return models.Client.add({
name: credentials.name,
description: credentials.description,
slug: 'ghost-auth',
uuid: credentials.client_id,
secret: credentials.client_secret,
redirection_uri: credentials.redirect_uri,
client_uri: credentials.blog_uri,
auth_uri: ghostOAuth2Strategy.url
}, {context: {internal: true}});
}).then(function addedLocalClient(client) {
debug('Added local client: ' + JSON.stringify(client.toJSON()));
return {
client_id: client.get('uuid'),
client_secret: client.get('secret')
};
});
}
// CASE: auth url has changed, create client
if (client.get('auth_uri') !== ghostOAuth2Strategy.url) {
return models.Client.destroy({id: client.id})
.then(function () {
return _private.updateClient(options);
});
}
// CASE: nothing changed
if (client.get('redirection_uri') === redirectUri &&
client.get('name') === clientName &&
client.get('description') === clientDescription &&
client.get('client_uri') === clientUri) {
debug('Client did not change');
return {
client_id: client.get('uuid'),
client_secret: client.get('secret')
};
}
debug('Update client...');
return ghostOAuth2Strategy.updateClient(_.omit({
clientId: client.get('uuid'),
clientSecret: client.get('secret'),
redirectUri: redirectUri,
blogUri: clientUri,
name: clientName,
description: clientDescription
}, _.isUndefined)).then(function updatedRemoteClient(updatedRemoteClient) {
debug('Update remote client: ' + JSON.stringify(updatedRemoteClient));
client.set('auth_uri', ghostOAuth2Strategy.url);
client.set('redirection_uri', updatedRemoteClient.redirect_uri);
client.set('client_uri', updatedRemoteClient.blog_uri);
client.set('name', updatedRemoteClient.name);
client.set('description', updatedRemoteClient.description);
return client.save(null, {context: {internal: true}});
}).then(function updatedLocalClient() {
logging.info('Updated remote client successfully.');
return {
client_id: client.get('uuid'),
client_secret: client.get('secret')
};
});
});
};
authStrategies = require('./auth-strategies');
/**
* auth types:
* - password: local login
* - ghost: remote login at Ghost.org
*/
exports.init = function initPassport(options) {
var authType = options.authType,
clientName = options.clientName,
clientDescription = options.clientDescription,
ghostAuthUrl = options.ghostAuthUrl,
redirectUri = options.redirectUri,
clientUri = options.clientUri;
exports.init = function initPassport() {
passport.use(new ClientPasswordStrategy(authStrategies.clientPasswordStrategy));
passport.use(new BearerStrategy(authStrategies.bearerStrategy));
return new Promise(function (resolve, reject) {
passport.use(new ClientPasswordStrategy(authStrategies.clientPasswordStrategy));
passport.use(new BearerStrategy(authStrategies.bearerStrategy));
// CASE: use switches from password to ghost and back
// If we don't clean up the database, it can happen that the auth switch validation fails
if (authType !== 'ghost') {
return models.Client.findOne({slug: 'ghost-auth'})
.then(function (client) {
if (!client) {
return;
}
return models.Client.destroy({id: client.id});
})
.then(function () {
resolve({passport: passport.initialize()});
})
.catch(reject);
}
var ghostOAuth2Strategy = new GhostOAuth2Strategy({
redirectUri: redirectUri,
blogUri: clientUri,
url: ghostAuthUrl,
passReqToCallback: true,
retryHook: function retryHook(err) {
logging.error(err);
}
}, authStrategies.ghostStrategy);
_private.updateClient({
ghostOAuth2Strategy: ghostOAuth2Strategy,
clientName: clientName,
clientDescription: clientDescription,
redirectUri: redirectUri,
clientUri: clientUri
}).then(function setClient(client) {
ghostOAuth2Strategy.setClient(client);
passport.use(ghostOAuth2Strategy);
_private.registerEvents();
return resolve({passport: passport.initialize()});
}).catch(function onError(err) {
debug('Public registration failed:' + err.message);
// @TODO: see https://github.com/TryGhost/Ghost/issues/7627
// CASE: can happen if database query fails
if (_.isArray(err)) {
err = err[0];
}
if (!errors.utils.isIgnitionError(err)) {
err = new errors.GhostError({
err: err
});
}
err.level = 'critical';
err.context = err.context || 'Public client registration failed';
err.help = err.help || 'Please verify the configured url: ' + ghostOAuth2Strategy.url;
return reject(err);
});
});
return passport.initialize();
};

View File

@ -1,63 +0,0 @@
var debug = require('ghost-ignition').debug('sync'),
models = require('../models'),
ghostAuth = require('./ghost-auth'),
logging = require('../logging'),
errors = require('../errors'),
events = require('../events'),
knex = require('../data/db').knex,
_private = {
syncIntervalInMs: 1000 * 60 * 60,
lastSync: {}
};
/**
* @TODO: support long polling in the ghost auth service
*/
_private.syncUser = function syncUser(loggedInUserModel) {
debug('syncUser');
// CASE: sync every hour for now
if (_private.lastSync[loggedInUserModel.id]) {
if ((_private.lastSync[loggedInUserModel.id] + _private.syncIntervalInMs) > Date.now()) {
debug('too early too sync');
return;
}
}
return ghostAuth.getUser({
id: loggedInUserModel.get('ghost_auth_id')
}).then(function (ghostUser) {
debug('ghost_email', ghostUser.email);
debug('user_email', loggedInUserModel.get('email'));
if (ghostUser.email === loggedInUserModel.get('email')) {
debug('email has not changed');
return;
}
debug('sync email');
// CASE: we update the user in a transaction to avoid collisions
return knex.transaction(function onTransaction(transaction) {
return models.User.edit({
email: ghostUser.email
}, {id: loggedInUserModel.id, transacting: transaction});
});
}).then(function () {
debug('update lastSync');
_private.lastSync[loggedInUserModel.id] = Date.now();
}).catch(function onError(err) {
logging.error(new errors.InternalServerError({
message: 'ghost-auth: sync failed',
err: err
}));
});
};
module.exports.init = function init(options) {
var authType = options.authType;
if (authType === 'ghost') {
events.on('read:users:me', _private.syncUser);
}
};

View File

@ -1,42 +0,0 @@
var Promise = require('bluebird'),
models = require('../models'),
errors = require('../errors');
/**
* If the setup is completed and...
* 1. the public client does exist, deny to switch to local
* 2. the public client does not exist, deny to switch to remote
*
* See https://github.com/TryGhost/Ghost/issues/8342
* Remote authentication is disabled right now.
*/
exports.validate = function validate(options) {
var authType = options.authType;
if (authType === 'ghost') {
return Promise.reject(new errors.InternalServerError({
code: 'AUTH_TYPE',
message: 'Ghost doesn\'t support remote authentication at the moment.',
help: 'Set `auth.type` to "password".'
}));
}
return models.User.isSetup()
.then(function (isSetup) {
if (!isSetup) {
return;
}
return models.Client.findOne({slug: 'ghost-auth'}, {columns: 'id'})
.then(function (client) {
if ((client && authType === 'password') || !client && authType === 'ghost') {
return Promise.reject(new errors.InternalServerError({
code: 'AUTH_SWITCH',
message: 'Switching the auth strategy is not allowed.',
context: 'Please reset your database and start from scratch.',
help: 'NODE_ENV=production|development knex-migrator reset && NODE_ENV=production|development knex-migrator init\n'
}));
}
});
});
};

View File

@ -7,9 +7,6 @@
},
"debug": false
},
"auth": {
"type": "password"
},
"paths": {
"contentPath": "content/"
},

View File

@ -8,9 +8,6 @@
"database" : "ghost"
}
},
"auth": {
"type": "password"
},
"paths": {
"contentPath": "content/"
},

View File

@ -12,9 +12,6 @@
"database" : "ghost_testing"
}
},
"auth": {
"type": "password"
},
"logging": {
"level": "fatal"
},

View File

@ -11,9 +11,6 @@
"server": {
"port": 2369
},
"auth": {
"type": "password"
},
"logging": {
"level": "fatal"
},

View File

@ -17,7 +17,6 @@ var debug = require('ghost-ignition').debug('boot:init'),
// Config should be first require, as it triggers the initial load of the config files
config = require('./config'),
Promise = require('bluebird'),
logging = require('./logging'),
i18n = require('./i18n'),
models = require('./models'),
permissions = require('./permissions'),
@ -29,7 +28,6 @@ var debug = require('ghost-ignition').debug('boot:init'),
GhostServer = require('./ghost-server'),
scheduling = require('./adapters/scheduling'),
settings = require('./settings'),
settingsCache = require('./settings/cache'),
themes = require('./themes'),
utils = require('./utils');
@ -78,25 +76,9 @@ function init() {
debug('Express Apps done');
}).then(function () {
return auth.validation.validate({
authType: config.get('auth:type')
});
}).then(function () {
// runs asynchronous
auth.init({
authType: config.get('auth:type'),
ghostAuthUrl: config.get('auth:url'),
redirectUri: utils.url.urlFor('admin', true),
clientUri: utils.url.urlFor('home', true),
clientName: settingsCache.get('title'),
clientDescription: settingsCache.get('description')
}).then(function (response) {
parentApp.use(response.auth);
}).catch(function onAuthError(err) {
logging.error(err);
});
}).then(function () {
parentApp.use(auth.init());
debug('Auth done');
return new GhostServer(parentApp);
}).then(function (_ghostServer) {
ghostServer = _ghostServer;

View File

@ -18,9 +18,6 @@ describe('Configuration API', function () {
should.exist(ConfigurationAPI);
it('can read basic config and get all expected properties', function (done) {
configUtils.set('auth:type', 'ghost');
configUtils.set('auth:url', 'https://auth.ghost.com');
ConfigurationAPI.read().then(function (response) {
var props;
@ -45,14 +42,9 @@ describe('Configuration API', function () {
props.publicAPI.should.eql(false);
props.clientId.should.eql('ghost-admin');
props.clientSecret.should.eql('not_available');
props.ghostAuthUrl.should.eql('https://auth.ghost.com');
// value not available, because settings API was not called yet
props.hasOwnProperty('blogTitle').should.eql(true);
// uuid
props.hasOwnProperty('ghostAuthId').should.eql(true);
done();
}).catch(done);
});

View File

@ -1,258 +1,23 @@
var should = require('should'), // jshint ignore:line
sinon = require('sinon'),
passport = require('passport'),
Promise = require('bluebird'),
rewire = require('rewire'),
testUtils = require('../../utils'),
GhostPassport = rewire('../../../server/auth/passport'),
models = require('../../../server/models'),
utils = require('../../../server/utils'),
errors = require('../../../server/errors'),
ghostPassport = require('../../../server/auth/passport'),
sandbox = sinon.sandbox.create();
describe('Ghost Passport', function () {
var client, events, registeredEvents = {};
function FakeGhostOAuth2Strategy(options) {
this.name = 'ghost';
should.exist(options.blogUri);
should.exist(options.url);
should.exist(options.redirectUri);
options.passReqToCallback.should.eql(true);
this.blogUri = options.blogUri;
this.redirectUri = options.redirectUri;
}
before(function () {
models.init();
events = {
on: function (name, onEvent) {
registeredEvents[name] = onEvent;
}
};
GhostPassport.__set__('events', events);
GhostPassport.__set__('GhostOAuth2Strategy', FakeGhostOAuth2Strategy);
GhostPassport.__set__('_private.retryTimeout', 50);
});
beforeEach(function () {
sandbox.spy(passport, 'use');
sandbox.stub(models.Client, 'findOne', function () {
if (client) {
client.save = sandbox.stub();
}
return Promise.resolve(client);
});
sandbox.stub(models.Client, 'destroy').returns(Promise.resolve());
sandbox.stub(models.Client, 'add', function () {
client = new models.Client(testUtils.DataGenerator.forKnex.createClient());
return Promise.resolve(client);
});
FakeGhostOAuth2Strategy.prototype.setClient = sandbox.stub();
FakeGhostOAuth2Strategy.prototype.registerClient = function () {
};
FakeGhostOAuth2Strategy.prototype.updateClient = function () {
};
sandbox.stub(FakeGhostOAuth2Strategy.prototype, 'registerClient', function (options) {
return Promise.resolve({
redirect_uri: this.redirectUri,
blog_uri: this.blogUri,
name: options.name,
description: options.description
});
});
sandbox.stub(FakeGhostOAuth2Strategy.prototype, 'updateClient', function () {
return Promise.resolve({
redirect_uri: client.get('redirection_uri'),
blog_uri: client.get('blog_uri'),
name: client.get('name'),
description: client.get('description')
});
});
});
afterEach(function () {
sandbox.restore();
});
describe('auth_type: password', function () {
describe('[default] local auth', function () {
it('initialise passport with passport auth type', function () {
return GhostPassport.init({
authType: 'passport'
}).then(function (response) {
should.exist(response.passport);
passport.use.callCount.should.eql(2);
models.Client.findOne.called.should.eql(true);
models.Client.destroy.called.should.eql(false);
models.Client.add.called.should.eql(false);
FakeGhostOAuth2Strategy.prototype.setClient.called.should.eql(false);
FakeGhostOAuth2Strategy.prototype.registerClient.called.should.eql(false);
FakeGhostOAuth2Strategy.prototype.updateClient.called.should.eql(false);
});
});
it('initialise passport with passport auth type [auth client exists]', function () {
return models.Client.add({slug: 'ghost-auth'})
.then(function () {
models.Client.add.called.should.eql(true);
models.Client.add.reset();
return GhostPassport.init({
authType: 'passport'
});
})
.then(function (response) {
should.exist(response.passport);
passport.use.callCount.should.eql(2);
models.Client.findOne.called.should.eql(true);
models.Client.destroy.called.should.eql(true);
models.Client.add.called.should.eql(false);
FakeGhostOAuth2Strategy.prototype.setClient.called.should.eql(false);
FakeGhostOAuth2Strategy.prototype.registerClient.called.should.eql(false);
FakeGhostOAuth2Strategy.prototype.updateClient.called.should.eql(false);
});
});
});
describe('auth_type: ghost', function () {
it('ghost client is already present in database and nothing has changed', function () {
client = new models.Client(testUtils.DataGenerator.forKnex.createClient({
name: 'Ghost',
client_uri: 'http://my-blog.com',
redirection_uri: utils.url.urlFor('home', true)
}));
return GhostPassport.init({
authType: 'ghost',
clientUri: 'http://my-blog.com',
ghostAuthUrl: 'http://devauth.ghost.org',
redirectUri: utils.url.urlFor('home', true),
clientName: 'Ghost'
}).then(function (response) {
should.exist(response.passport);
passport.use.callCount.should.eql(3);
models.Client.findOne.called.should.eql(true);
models.Client.add.called.should.eql(false);
FakeGhostOAuth2Strategy.prototype.setClient.called.should.eql(true);
FakeGhostOAuth2Strategy.prototype.registerClient.called.should.eql(false);
FakeGhostOAuth2Strategy.prototype.updateClient.called.should.eql(false);
});
});
it('ghost client is already present in database and redirect_uri has changed', function () {
client = new models.Client(testUtils.DataGenerator.forKnex.createClient({
name: 'Ghost',
client_uri: 'http://my-blog.com',
redirection_uri: 'URL-HAS-CHANGED'
}));
return GhostPassport.init({
authType: 'ghost',
clientUri: 'http://my-blog.com',
ghostAuthUrl: 'http://devauth.ghost.org',
redirectUri: utils.url.urlFor('home', true),
clientName: 'Ghost'
}).then(function (response) {
should.exist(response.passport);
passport.use.callCount.should.eql(3);
models.Client.findOne.called.should.eql(true);
models.Client.add.called.should.eql(false);
FakeGhostOAuth2Strategy.prototype.setClient.called.should.eql(true);
FakeGhostOAuth2Strategy.prototype.registerClient.called.should.eql(false);
FakeGhostOAuth2Strategy.prototype.updateClient.called.should.eql(true);
});
});
it('ghost client is already present in database and title changes', function (done) {
client = null;
GhostPassport.init({
authType: 'ghost',
clientUri: 'http://my-blog.com',
ghostAuthUrl: 'http://devauth.ghost.org',
redirectUri: utils.url.urlFor('home', true),
clientName: 'Ghost'
}).then(function () {
FakeGhostOAuth2Strategy.prototype.registerClient.called.should.eql(true);
FakeGhostOAuth2Strategy.prototype.updateClient.called.should.eql(false);
registeredEvents['settings.edited']({
attributes: {
key: 'title',
value: 'new-title'
},
_updatedAttributes: {
value: 'old-title'
}
});
(function retry() {
if (FakeGhostOAuth2Strategy.prototype.updateClient.called === true) {
return done();
}
setTimeout(retry, 100);
})();
}).catch(done);
});
it('ghost client does not exist', function () {
client = null;
return GhostPassport.init({
authType: 'ghost',
clientUri: 'http://my-blog.com',
ghostAuthUrl: 'http://devauth.ghost.org',
redirectUri: utils.url.urlFor('home', true),
clientName: 'custom client name'
}).then(function (response) {
should.exist(response.passport);
passport.use.callCount.should.eql(3);
models.Client.findOne.called.should.eql(true);
models.Client.add.called.should.eql(true);
FakeGhostOAuth2Strategy.prototype.setClient.called.should.eql(true);
FakeGhostOAuth2Strategy.prototype.registerClient.called.should.eql(true);
FakeGhostOAuth2Strategy.prototype.registerClient.calledWith({
name: 'custom client name',
description: undefined
}).should.eql(true);
});
});
it('ghost client does not exist, ghost.org register client does not work', function () {
client = null;
FakeGhostOAuth2Strategy.prototype.registerClient.restore();
FakeGhostOAuth2Strategy.prototype.registerClient = sandbox.stub();
FakeGhostOAuth2Strategy.prototype.registerClient.returns(Promise.reject(new Error('cannot connect to ghost.org')));
return GhostPassport.init({
authType: 'ghost',
clientUri: 'http://my-blog.com',
ghostAuthUrl: 'http://devauth.ghost.org',
redirectUri: utils.url.urlFor('home', true)
}).catch(function (err) {
(err instanceof errors.GhostError).should.eql(true);
FakeGhostOAuth2Strategy.prototype.registerClient.callCount.should.eql(1);
});
var response = ghostPassport.init();
should.exist(response);
passport.use.callCount.should.eql(2);
});
});
});

View File

@ -1,93 +0,0 @@
var should = require('should'),
sinon = require('sinon'),
Promise = require('bluebird'),
auth = require('../../../server/auth'),
models = require('../../../server/models'),
sandbox = sinon.sandbox.create();
/**
* See https://github.com/TryGhost/Ghost/issues/8342
* We have disabled Ghost authentication temporary.
* That's why some tests are skipped for now.
*/
describe('UNIT: auth validation', function () {
before(function () {
models.init();
});
afterEach(function () {
sandbox.restore();
});
describe('ghost is enabled', function () {
it('[failure]', function () {
return auth.validation.validate({
authType: 'ghost'
}).catch(function (err) {
should.exist(err);
err.code.should.eql('AUTH_TYPE');
});
});
it.skip('[success]', function () {
sandbox.stub(models.User, 'isSetup').returns(Promise.resolve(false));
return auth.validation.validate({
authType: 'ghost'
});
});
it.skip('[success]', function () {
sandbox.stub(models.User, 'isSetup').returns(Promise.resolve(true));
sandbox.stub(models.Client, 'findOne').returns(Promise.resolve(true));
return auth.validation.validate({
authType: 'ghost'
});
});
it.skip('[failure]', function () {
sandbox.stub(models.User, 'isSetup').returns(Promise.resolve(true));
sandbox.stub(models.Client, 'findOne').returns(Promise.resolve(true));
return auth.validation.validate({
authType: 'password'
}).catch(function (err) {
should.exist(err);
err.code.should.eql('AUTH_SWITCH');
});
});
});
describe('password is enabled', function () {
it('[success]', function () {
sandbox.stub(models.User, 'isSetup').returns(Promise.resolve(false));
return auth.validation.validate({
authType: 'password'
});
});
it('[success]', function () {
sandbox.stub(models.User, 'isSetup').returns(Promise.resolve(true));
sandbox.stub(models.Client, 'findOne').returns(Promise.resolve(false));
return auth.validation.validate({
authType: 'password'
});
});
it.skip('[failure]', function () {
sandbox.stub(models.User, 'isSetup').returns(Promise.resolve(true));
sandbox.stub(models.Client, 'findOne').returns(Promise.resolve(true));
return auth.validation.validate({
authType: 'ghost'
}).catch(function (err) {
should.exist(err);
err.code.should.eql('AUTH_SWITCH');
});
});
});
});

View File

@ -78,7 +78,6 @@
"nodemailer": "0.7.1",
"oauth2orize": "1.8.0",
"passport": "0.3.2",
"passport-ghost": "2.3.1",
"passport-http-bearer": "1.0.1",
"passport-oauth2-client-password": "0.1.2",
"path-match": "1.2.4",

View File

@ -322,7 +322,7 @@ bluebird@3.4.6:
version "3.4.6"
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.4.6.tgz#01da8d821d87813d158967e743d5fe6c62cf8c0f"
bluebird@3.5.0, bluebird@^3.0.5, bluebird@^3.4.1, bluebird@^3.4.3, bluebird@^3.4.6:
bluebird@3.5.0, bluebird@^3.0.5, bluebird@^3.4.3, bluebird@^3.4.6:
version "3.5.0"
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.0.tgz#791420d7f551eea2897453a8a77653f96606d67c"
@ -3168,7 +3168,7 @@ lodash@4.16.3:
version "4.16.3"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.16.3.tgz#0ba761439529127c7a38c439114ca153efa999a2"
lodash@4.17.4, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.16.4, lodash@^4.16.6, lodash@^4.17.4, lodash@^4.6.0, lodash@^4.7.0, lodash@^4.8.0, lodash@~4.17.2:
lodash@4.17.4, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.16.4, lodash@^4.17.4, lodash@^4.6.0, lodash@^4.7.0, lodash@^4.8.0, lodash@~4.17.2:
version "4.17.4"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
@ -3773,10 +3773,6 @@ oauth2orize@1.8.0:
uid2 "0.0.x"
utils-merge "1.x.x"
oauth@0.9.x:
version "0.9.15"
resolved "https://registry.yarnpkg.com/oauth/-/oauth-0.9.15.tgz#bd1fefaf686c96b75475aed5196412ff60cfb9c1"
object-assign@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-3.0.0.tgz#9bedd5ca0897949bca47e7ff408062d549f587f2"
@ -3892,15 +3888,6 @@ parseurl@~1.3.0, parseurl@~1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.1.tgz#c8ab8c9223ba34888aa64a297b28853bec18da56"
passport-ghost@2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/passport-ghost/-/passport-ghost-2.3.1.tgz#0dfa63d725bb7c8902acf91219b34b053f7cea9a"
dependencies:
bluebird "^3.4.1"
ghost-ignition "^2.8.7"
lodash "^4.16.6"
passport-oauth2 "1.1.2"
passport-http-bearer@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/passport-http-bearer/-/passport-http-bearer-1.0.1.tgz#147469ea3669e2a84c6167ef99dbb77e1f0098a8"
@ -3913,14 +3900,6 @@ passport-oauth2-client-password@0.1.2:
dependencies:
passport-strategy "1.x.x"
passport-oauth2@1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/passport-oauth2/-/passport-oauth2-1.1.2.tgz#bd7163b1b6090371868dc4ef6f9f2e1e4cc4b948"
dependencies:
oauth "0.9.x"
passport-strategy "1.x.x"
uid2 "0.0.x"
passport-strategy@1.x.x:
version "1.0.0"
resolved "https://registry.yarnpkg.com/passport-strategy/-/passport-strategy-1.0.0.tgz#b5539aa8fc225a3d1ad179476ddf236b440f52e4"