0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-01-20 22:42:53 -05:00
ghost/core/server/auth/passport.js

136 lines
5.2 KiB
JavaScript
Raw Normal View History

var ClientPasswordStrategy = require('passport-oauth2-client-password').Strategy,
BearerStrategy = require('passport-http-bearer').Strategy,
GhostOAuth2Strategy = require('passport-ghost').Strategy,
passport = require('passport'),
🎨 logging improvements (#7597) * 🎨 rotation config - every parameter is configureable - increase default number of files to 100 * 🎨 ghost.log location - example: content/logs/http___my_ghost_blog_com_ghost.log - user can change the path to something custom by setting logging.path * 🛠 add response-time as dependency * 🎨 readable PrettyStream - tidy up - generic handling (was important to support more use cases, for example: logging.info({ anyKey: anyValue })) - common log format - less code 🕵🏻 * 🎨 GhostLogger cleanup - remove setLoggers -> this function had too much of redundant code - instead: add smart this.log function - remove logging.request (---> GhostLogger just forwards the values, it doesn't matter if that is a request or not a request) - make .warn .debug .info .error small and smart * 🎨 app.js: add response time as middleware and remove logging.request * 🎨 setStdoutStream and setFileStream - redesign GhostLogger to add CustomLoggers very easily ----> Example CustomLogger function CustomLogger(options) { // Base iterates over defined transports // EXAMPLE: ['stdout', 'elasticsearch'] Base.call(this, options); } util.inherits(...); // OVERRIDE default stdout stream and your own!!! CustomLogger.prototype.setStdoutStream = function() {} // add a new stream // get's called automatically when transport elasticsearch is defined CustomLogger.prototype.setElasticsearchStream = function() {} * 🎨 log into multiple file by default - content/logs/domain.error.log --> contains only the errors - content/logs/domain.log --> contains everything - rotation for both files * 🔥 remove logging.debug and use npm debug only * ✨ shortcuts for mode and level * 🎨 jshint/jscs * 🎨 stdout as much as possible for an error * 🎨 fix tests * 🎨 remove req.ip from log output, remove response-time dependency * 🎨 create middleware for logging - added TODO to move logging middleware to ignition
2016-10-25 13:17:43 +02:00
debug = require('debug')('ghost:auth'),
Promise = require('bluebird'),
authStrategies = require('./auth-strategies'),
errors = require('../errors'),
logging = require('../logging'),
models = require('../models'),
_private = {
retryTimeout: 3000,
retries: 10
};
_private.registerClient = function (options) {
var ghostOAuth2Strategy = options.ghostOAuth2Strategy,
clientName = options.clientName,
redirectUri = options.redirectUri;
return models.Client.findOne({slug: 'ghost-auth'}, {context: {internal: true}})
.then(function fetchedClient(client) {
// CASE: Ghost Auth client is already registered
if (client) {
if (client.get('redirection_uri') === redirectUri) {
return {
client_id: client.get('uuid'),
client_secret: client.get('secret')
};
}
🎨 logging improvements (#7597) * 🎨 rotation config - every parameter is configureable - increase default number of files to 100 * 🎨 ghost.log location - example: content/logs/http___my_ghost_blog_com_ghost.log - user can change the path to something custom by setting logging.path * 🛠 add response-time as dependency * 🎨 readable PrettyStream - tidy up - generic handling (was important to support more use cases, for example: logging.info({ anyKey: anyValue })) - common log format - less code 🕵🏻 * 🎨 GhostLogger cleanup - remove setLoggers -> this function had too much of redundant code - instead: add smart this.log function - remove logging.request (---> GhostLogger just forwards the values, it doesn't matter if that is a request or not a request) - make .warn .debug .info .error small and smart * 🎨 app.js: add response time as middleware and remove logging.request * 🎨 setStdoutStream and setFileStream - redesign GhostLogger to add CustomLoggers very easily ----> Example CustomLogger function CustomLogger(options) { // Base iterates over defined transports // EXAMPLE: ['stdout', 'elasticsearch'] Base.call(this, options); } util.inherits(...); // OVERRIDE default stdout stream and your own!!! CustomLogger.prototype.setStdoutStream = function() {} // add a new stream // get's called automatically when transport elasticsearch is defined CustomLogger.prototype.setElasticsearchStream = function() {} * 🎨 log into multiple file by default - content/logs/domain.error.log --> contains only the errors - content/logs/domain.log --> contains everything - rotation for both files * 🔥 remove logging.debug and use npm debug only * ✨ shortcuts for mode and level * 🎨 jshint/jscs * 🎨 stdout as much as possible for an error * 🎨 fix tests * 🎨 remove req.ip from log output, remove response-time dependency * 🎨 create middleware for logging - added TODO to move logging middleware to ignition
2016-10-25 13:17:43 +02:00
debug('Update ghost client callback url...');
return ghostOAuth2Strategy.changeCallbackURL({
callbackURL: redirectUri,
clientId: client.get('uuid'),
clientSecret: client.get('secret')
}).then(function changedCallbackURL() {
client.set('redirection_uri', redirectUri);
return client.save(null, {context: {internal: true}});
}).then(function updatedClient() {
return {
client_id: client.get('uuid'),
client_secret: client.get('secret')
};
});
}
return ghostOAuth2Strategy.registerClient({clientName: clientName})
.then(function addClient(credentials) {
return models.Client.add({
name: 'Ghost Auth',
slug: 'ghost-auth',
uuid: credentials.client_id,
secret: credentials.client_secret,
redirection_uri: redirectUri
}, {context: {internal: true}});
})
.then(function returnClient(client) {
return {
client_id: client.get('uuid'),
client_secret: client.get('secret')
};
});
});
};
_private.startPublicClientRegistration = function startPublicClientRegistration(options) {
return new Promise(function (resolve, reject) {
(function retry(retries) {
options.retryCount = retries;
_private.registerClient(options)
.then(resolve)
.catch(function publicClientRegistrationError(err) {
logging.error(err);
if (options.retryCount < 0) {
return reject(new errors.IncorrectUsageError({
message: 'Public client registration failed: ' + err.code || err.message,
context: 'Please verify that the url can be reached: ' + options.ghostOAuth2Strategy.url
}));
}
🎨 logging improvements (#7597) * 🎨 rotation config - every parameter is configureable - increase default number of files to 100 * 🎨 ghost.log location - example: content/logs/http___my_ghost_blog_com_ghost.log - user can change the path to something custom by setting logging.path * 🛠 add response-time as dependency * 🎨 readable PrettyStream - tidy up - generic handling (was important to support more use cases, for example: logging.info({ anyKey: anyValue })) - common log format - less code 🕵🏻 * 🎨 GhostLogger cleanup - remove setLoggers -> this function had too much of redundant code - instead: add smart this.log function - remove logging.request (---> GhostLogger just forwards the values, it doesn't matter if that is a request or not a request) - make .warn .debug .info .error small and smart * 🎨 app.js: add response time as middleware and remove logging.request * 🎨 setStdoutStream and setFileStream - redesign GhostLogger to add CustomLoggers very easily ----> Example CustomLogger function CustomLogger(options) { // Base iterates over defined transports // EXAMPLE: ['stdout', 'elasticsearch'] Base.call(this, options); } util.inherits(...); // OVERRIDE default stdout stream and your own!!! CustomLogger.prototype.setStdoutStream = function() {} // add a new stream // get's called automatically when transport elasticsearch is defined CustomLogger.prototype.setElasticsearchStream = function() {} * 🎨 log into multiple file by default - content/logs/domain.error.log --> contains only the errors - content/logs/domain.log --> contains everything - rotation for both files * 🔥 remove logging.debug and use npm debug only * ✨ shortcuts for mode and level * 🎨 jshint/jscs * 🎨 stdout as much as possible for an error * 🎨 fix tests * 🎨 remove req.ip from log output, remove response-time dependency * 🎨 create middleware for logging - added TODO to move logging middleware to ignition
2016-10-25 13:17:43 +02:00
debug('Trying to register Public Client...');
var timeout = setTimeout(function () {
clearTimeout(timeout);
options.retryCount = options.retryCount - 1;
retry(options.retryCount);
}, _private.retryTimeout);
});
})(_private.retries);
});
};
/**
* auth types:
* - password: local login
* - ghost: remote login at Ghost.org
*/
exports.init = function initPassport(options) {
var authType = options.authType,
clientName = options.clientName,
ghostAuthUrl = options.ghostAuthUrl,
redirectUri = options.redirectUri,
blogUri = options.blogUri;
return new Promise(function (resolve, reject) {
passport.use(new ClientPasswordStrategy(authStrategies.clientPasswordStrategy));
passport.use(new BearerStrategy(authStrategies.bearerStrategy));
if (authType !== 'ghost') {
return resolve({passport: passport.initialize()});
}
var ghostOAuth2Strategy = new GhostOAuth2Strategy({
callbackURL: redirectUri,
blogUri: blogUri,
url: ghostAuthUrl,
passReqToCallback: true
}, authStrategies.ghostStrategy);
_private.startPublicClientRegistration({
ghostOAuth2Strategy: ghostOAuth2Strategy,
clientName: clientName,
redirectUri: redirectUri
}).then(function setClient(client) {
🎨 logging improvements (#7597) * 🎨 rotation config - every parameter is configureable - increase default number of files to 100 * 🎨 ghost.log location - example: content/logs/http___my_ghost_blog_com_ghost.log - user can change the path to something custom by setting logging.path * 🛠 add response-time as dependency * 🎨 readable PrettyStream - tidy up - generic handling (was important to support more use cases, for example: logging.info({ anyKey: anyValue })) - common log format - less code 🕵🏻 * 🎨 GhostLogger cleanup - remove setLoggers -> this function had too much of redundant code - instead: add smart this.log function - remove logging.request (---> GhostLogger just forwards the values, it doesn't matter if that is a request or not a request) - make .warn .debug .info .error small and smart * 🎨 app.js: add response time as middleware and remove logging.request * 🎨 setStdoutStream and setFileStream - redesign GhostLogger to add CustomLoggers very easily ----> Example CustomLogger function CustomLogger(options) { // Base iterates over defined transports // EXAMPLE: ['stdout', 'elasticsearch'] Base.call(this, options); } util.inherits(...); // OVERRIDE default stdout stream and your own!!! CustomLogger.prototype.setStdoutStream = function() {} // add a new stream // get's called automatically when transport elasticsearch is defined CustomLogger.prototype.setElasticsearchStream = function() {} * 🎨 log into multiple file by default - content/logs/domain.error.log --> contains only the errors - content/logs/domain.log --> contains everything - rotation for both files * 🔥 remove logging.debug and use npm debug only * ✨ shortcuts for mode and level * 🎨 jshint/jscs * 🎨 stdout as much as possible for an error * 🎨 fix tests * 🎨 remove req.ip from log output, remove response-time dependency * 🎨 create middleware for logging - added TODO to move logging middleware to ignition
2016-10-25 13:17:43 +02:00
debug('Public Client Registration was successful');
ghostOAuth2Strategy.setClient(client);
passport.use(ghostOAuth2Strategy);
return resolve({passport: passport.initialize()});
}).catch(reject);
});
};