diff --git a/core/server/api/configuration.js b/core/server/api/configuration.js index becf07f733..c491b6ebcd 100644 --- a/core/server/api/configuration.js +++ b/core/server/api/configuration.js @@ -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]}; }); diff --git a/core/server/auth/ghost-auth.js b/core/server/auth/ghost-auth.js deleted file mode 100644 index 642cc6000b..0000000000 --- a/core/server/auth/ghost-auth.js +++ /dev/null @@ -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); - }); - }); -}; diff --git a/core/server/auth/index.js b/core/server/auth/index.js index 747a9745bd..ab0b665581 100644 --- a/core/server/auth/index.js +++ b/core/server/auth/index.js @@ -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; diff --git a/core/server/auth/passport.js b/core/server/auth/passport.js index bf716672f9..b20c70b393 100644 --- a/core/server/auth/passport.js +++ b/core/server/auth/passport.js @@ -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(); }; diff --git a/core/server/auth/sync.js b/core/server/auth/sync.js deleted file mode 100644 index f2b28caf9b..0000000000 --- a/core/server/auth/sync.js +++ /dev/null @@ -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); - } -}; diff --git a/core/server/auth/validation.js b/core/server/auth/validation.js deleted file mode 100644 index 199784cf2f..0000000000 --- a/core/server/auth/validation.js +++ /dev/null @@ -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' - })); - } - }); - }); -}; diff --git a/core/server/config/env/config.development.json b/core/server/config/env/config.development.json index 56aa8a4460..5cd8e57c8b 100644 --- a/core/server/config/env/config.development.json +++ b/core/server/config/env/config.development.json @@ -7,9 +7,6 @@ }, "debug": false }, - "auth": { - "type": "password" - }, "paths": { "contentPath": "content/" }, diff --git a/core/server/config/env/config.production.json b/core/server/config/env/config.production.json index 7db148b76c..4ae3b8b62b 100644 --- a/core/server/config/env/config.production.json +++ b/core/server/config/env/config.production.json @@ -8,9 +8,6 @@ "database" : "ghost" } }, - "auth": { - "type": "password" - }, "paths": { "contentPath": "content/" }, diff --git a/core/server/config/env/config.testing-mysql.json b/core/server/config/env/config.testing-mysql.json index 2518e21aa2..f2fafeb9a8 100644 --- a/core/server/config/env/config.testing-mysql.json +++ b/core/server/config/env/config.testing-mysql.json @@ -12,9 +12,6 @@ "database" : "ghost_testing" } }, - "auth": { - "type": "password" - }, "logging": { "level": "fatal" }, diff --git a/core/server/config/env/config.testing.json b/core/server/config/env/config.testing.json index f4f37533c4..2c096a0ab7 100644 --- a/core/server/config/env/config.testing.json +++ b/core/server/config/env/config.testing.json @@ -11,9 +11,6 @@ "server": { "port": 2369 }, - "auth": { - "type": "password" - }, "logging": { "level": "fatal" }, diff --git a/core/server/index.js b/core/server/index.js index 2f5eda82f6..210b293a27 100644 --- a/core/server/index.js +++ b/core/server/index.js @@ -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; diff --git a/core/test/integration/api/api_configuration_spec.js b/core/test/integration/api/api_configuration_spec.js index 33a3ed012b..e298b432e7 100644 --- a/core/test/integration/api/api_configuration_spec.js +++ b/core/test/integration/api/api_configuration_spec.js @@ -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); }); diff --git a/core/test/unit/auth/passport_spec.js b/core/test/unit/auth/passport_spec.js index 4707ea94cc..f93760001b 100644 --- a/core/test/unit/auth/passport_spec.js +++ b/core/test/unit/auth/passport_spec.js @@ -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); }); }); }); diff --git a/core/test/unit/auth/validation_spec.js b/core/test/unit/auth/validation_spec.js deleted file mode 100644 index 937b4b68ba..0000000000 --- a/core/test/unit/auth/validation_spec.js +++ /dev/null @@ -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'); - }); - }); - }); -}); diff --git a/package.json b/package.json index cd4604f4a9..e89ee9dd94 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/yarn.lock b/yarn.lock index aeeade775e..86eeeaccff 100644 --- a/yarn.lock +++ b/yarn.lock @@ -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"