mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-14 09:52:09 +03:00
c8e8da4780
closes #2759 closes #3027 - added oauth2orize library for server side oAuth handling - added ember-simple-auth library for admin oAuth handling - added tables for client, accesstoken and refreshtoken - implemented RFC6749 4.3 Ressouce Owner Password Credentials Grant - updated api tests with oAuth - removed session, authentication is now token based Known issues: - Restore spam prevention #3128 - Signin after Signup #3125 - Signin validation #3125 **Attention** - oldClient doesn't work with this PR anymore, session authentication was removed
116 lines
4.2 KiB
JavaScript
116 lines
4.2 KiB
JavaScript
var oauth2orize = require('oauth2orize'),
|
|
models = require('../models'),
|
|
|
|
oauth;
|
|
|
|
|
|
/**
|
|
* Return a random int, used by `utils.uid()`
|
|
*
|
|
* @param {Number} min
|
|
* @param {Number} max
|
|
* @return {Number}
|
|
* @api private
|
|
*/
|
|
function getRandomInt(min, max) {
|
|
return Math.floor(Math.random() * (max - min + 1)) + min;
|
|
}
|
|
|
|
/**
|
|
* Return a unique identifier with the given `len`.
|
|
*
|
|
* utils.uid(10);
|
|
* // => "FDaS435D2z"
|
|
*
|
|
* @param {Number} len
|
|
* @return {String}
|
|
* @api private
|
|
*/
|
|
function uid(len) {
|
|
var buf = [],
|
|
chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',
|
|
charlen = chars.length,
|
|
i;
|
|
|
|
for (i = 1; i < len; i = i + 1) {
|
|
buf.push(chars[getRandomInt(0, charlen - 1)]);
|
|
}
|
|
|
|
return buf.join('');
|
|
}
|
|
|
|
oauth = {
|
|
|
|
init: function (oauthServer) {
|
|
|
|
// remove all expired accesstokens on startup
|
|
models.Accesstoken.destroyAllExpired();
|
|
|
|
// remove all expired refreshtokens on startup
|
|
models.Refreshtoken.destroyAllExpired();
|
|
|
|
// Exchange user id and password for access tokens. The callback accepts the
|
|
// `client`, which is exchanging the user's name and password from the
|
|
// authorization request for verification. If these values are validated, the
|
|
// application issues an access token on behalf of the user who authorized the code.
|
|
oauthServer.exchange(oauth2orize.exchange.password(function (client, username, password, scope, done) {
|
|
// Validate the client
|
|
models.Client.forge({slug: client.slug})
|
|
.fetch()
|
|
.then(function (client) {
|
|
if (!client) {
|
|
return done(null, false);
|
|
}
|
|
// Validate the user
|
|
return models.User.check({email: username, password: password}).then(function (user) {
|
|
|
|
//Everything validated, return the access- and refreshtoken
|
|
var accessToken = uid(256),
|
|
refreshToken = uid(256),
|
|
accessExpires = Date.now() + 3600 * 1000,
|
|
refreshExpires = Date.now() + 3600 * 24 * 1000;
|
|
|
|
return models.Accesstoken.add({token: accessToken, user_id: user.id, client_id: client.id, expires: accessExpires}).then(function () {
|
|
return models.Refreshtoken.add({token: refreshToken, user_id: user.id, client_id: client.id, expires: refreshExpires});
|
|
}).then(function () {
|
|
return done(null, accessToken, refreshToken, {expires_in: 3600});
|
|
}).catch(function () {
|
|
return done(null, false);
|
|
});
|
|
}).catch(function () {
|
|
return done(null, false);
|
|
});
|
|
});
|
|
}));
|
|
|
|
// Exchange the refresh token to obtain an access token. The callback accepts the
|
|
// `client`, which is exchanging a `refreshToken` previously issued by the server
|
|
// for verification. If these values are validated, the application issues an
|
|
// access token on behalf of the user who authorized the code.
|
|
oauthServer.exchange(oauth2orize.exchange.refreshToken(function (client, refreshToken, scope, done) {
|
|
models.Refreshtoken.forge({token: refreshToken})
|
|
.fetch()
|
|
.then(function (model) {
|
|
if (!model) {
|
|
return done(null, false);
|
|
} else {
|
|
var token = model.toJSON(),
|
|
accessToken = uid(256),
|
|
accessExpires = Date.now() + 3600 * 1000;
|
|
|
|
if (token.expires > Date.now()) {
|
|
models.Accesstoken.add({token: accessToken, user_id: token.user_id, client_id: token.client_id, expires: accessExpires}).then(function () {
|
|
return done(null, accessToken);
|
|
}).catch(function () {
|
|
return done(null, false);
|
|
});
|
|
} else {
|
|
done(null, false);
|
|
}
|
|
}
|
|
});
|
|
}));
|
|
}
|
|
};
|
|
|
|
module.exports = oauth; |