OAuth/User models refractoring -> use mongoose api

This commit is contained in:
Chocobozzz 2016-07-01 16:03:53 +02:00
parent a3ee6fa22d
commit 69b0a27cbb
14 changed files with 217 additions and 156 deletions

View File

@ -13,14 +13,6 @@ const WebSocketServer = require('ws').Server
// Create our main app
const app = express()
// ----------- Checker -----------
const checker = require('./server/initializers/checker')
const miss = checker.checkConfig()
if (miss.length !== 0) {
throw new Error('Miss some configurations keys : ' + miss)
}
// ----------- Database -----------
const config = require('config')
const constants = require('./server/initializers/constants')
@ -29,6 +21,14 @@ const logger = require('./server/helpers/logger')
database.connect()
// ----------- Checker -----------
const checker = require('./server/initializers/checker')
const miss = checker.checkConfig()
if (miss.length !== 0) {
throw new Error('Miss some configurations keys : ' + miss)
}
// ----------- PeerTube modules -----------
const customValidators = require('./server/helpers/customValidators')
const installer = require('./server/initializers/installer')

View File

@ -7,7 +7,7 @@ const mongoose = require('mongoose')
const logger = require('../../../helpers/logger')
const friends = require('../../../lib/friends')
const middlewares = require('../../../middlewares')
const oAuth2 = middlewares.oauth2
const oAuth = middlewares.oauth
const reqValidator = middlewares.reqValidators.pods
const signatureValidator = middlewares.reqValidators.remote.signature
@ -17,8 +17,8 @@ const Video = mongoose.model('Video')
router.get('/', listPodsUrl)
router.post('/', reqValidator.podsAdd, addPods)
router.get('/makefriends', oAuth2.authenticate, reqValidator.makeFriends, makeFriends)
router.get('/quitfriends', oAuth2.authenticate, quitFriends)
router.get('/makefriends', oAuth.authenticate, reqValidator.makeFriends, makeFriends)
router.get('/quitfriends', oAuth.authenticate, quitFriends)
// Post because this is a secured request
router.post('/remove', signatureValidator, removePods)

View File

@ -1,15 +1,16 @@
'use strict'
const config = require('config')
const mongoose = require('mongoose')
const express = require('express')
const oAuth2 = require('../../../middlewares').oauth2
const oAuth = require('../../../middlewares').oauth
const Users = require('../../../models/users')
const Client = mongoose.model('OAuthClient')
const router = express.Router()
router.get('/client', getAngularClient)
router.post('/token', oAuth2.token, success)
router.post('/token', oAuth.token, success)
// ---------------------------------------------------------------------------
@ -27,7 +28,7 @@ function getAngularClient (req, res, next) {
if (req.get('host') !== headerHostShouldBe) return res.type('json').status(403).end()
Users.getFirstClient(function (err, client) {
Client.loadFirstClient(function (err, client) {
if (err) return next(err)
if (!client) return next(new Error('No client available.'))

View File

@ -9,7 +9,7 @@ const multer = require('multer')
const logger = require('../../../helpers/logger')
const friends = require('../../../lib/friends')
const middlewares = require('../../../middlewares')
const oAuth2 = middlewares.oauth2
const oAuth = middlewares.oauth
const pagination = middlewares.pagination
const reqValidator = middlewares.reqValidators
const reqValidatorPagination = reqValidator.pagination
@ -51,7 +51,7 @@ router.get('/',
listVideos
)
router.post('/',
oAuth2.authenticate,
oAuth.authenticate,
reqFiles,
reqValidatorVideos.videosAdd,
addVideo
@ -61,7 +61,7 @@ router.get('/:id',
getVideo
)
router.delete('/:id',
oAuth2.authenticate,
oAuth.authenticate,
reqValidatorVideos.videosRemove,
removeVideo
)

View File

@ -1,8 +1,10 @@
'use strict'
const config = require('config')
const mongoose = require('mongoose')
const Users = require('../models/users')
const Client = mongoose.model('OAuthClient')
const User = mongoose.model('User')
const checker = {
checkConfig: checkConfig,
@ -29,7 +31,7 @@ function checkConfig () {
}
function clientsExist (callback) {
Users.getClients(function (err, clients) {
Client.list(function (err, clients) {
if (err) return callback(err)
return callback(null, clients.length !== 0)
@ -37,7 +39,7 @@ function clientsExist (callback) {
}
function usersExist (callback) {
Users.getUsers(function (err, users) {
User.list(function (err, users) {
if (err) return callback(err)
return callback(null, users.length !== 0)

View File

@ -6,6 +6,9 @@ const mongoose = require('mongoose')
const logger = require('../helpers/logger')
// Bootstrap models
require('../models/user')
require('../models/oauth-client')
require('../models/oauth-token')
require('../models/pods')
require('../models/video')
// Request model needs Video model

View File

@ -3,13 +3,16 @@
const async = require('async')
const config = require('config')
const mkdirp = require('mkdirp')
const mongoose = require('mongoose')
const passwordGenerator = require('password-generator')
const path = require('path')
const checker = require('./checker')
const logger = require('../helpers/logger')
const peertubeCrypto = require('../helpers/peertubeCrypto')
const Users = require('../models/users')
const Client = mongoose.model('OAuthClient')
const User = mongoose.model('User')
const installer = {
installApplication: installApplication
@ -60,11 +63,16 @@ function createOAuthClientIfNotExist (callback) {
logger.info('Creating a default OAuth Client.')
const secret = passwordGenerator(32, false)
Users.createClient(secret, [ 'password' ], function (err, id) {
const client = new Client({
clientSecret: secret,
grants: [ 'password' ]
})
client.save(function (err, createdClient) {
if (err) return callback(err)
logger.info('Client id: ' + id)
logger.info('Client secret: ' + secret)
logger.info('Client id: ' + createdClient._id)
logger.info('Client secret: ' + createdClient.clientSecret)
return callback(null)
})
@ -94,11 +102,16 @@ function createOAuthUserIfNotExist (callback) {
password = passwordGenerator(8, true)
}
Users.createUser(username, password, function (err) {
const user = new User({
username: username,
password: password
})
user.save(function (err, createdUser) {
if (err) return callback(err)
logger.info('Username: ' + username)
logger.info('User password: ' + password)
logger.info('Username: ' + createdUser.username)
logger.info('User password: ' + createdUser.password)
return callback(null)
})

70
server/lib/oauth-model.js Normal file
View File

@ -0,0 +1,70 @@
const mongoose = require('mongoose')
const logger = require('../helpers/logger')
const OAuthClient = mongoose.model('OAuthClient')
const OAuthToken = mongoose.model('OAuthToken')
const User = mongoose.model('User')
// See https://github.com/oauthjs/node-oauth2-server/wiki/Model-specification for the model specifications
const OAuthModel = {
getAccessToken: getAccessToken,
getClient: getClient,
getRefreshToken: getRefreshToken,
getUser: getUser,
saveToken: saveToken
}
// ---------------------------------------------------------------------------
function getAccessToken (bearerToken) {
logger.debug('Getting access token (bearerToken: ' + bearerToken + ').')
return OAuthToken.loadByTokenAndPopulateUser(bearerToken)
}
function getClient (clientId, clientSecret) {
logger.debug('Getting Client (clientId: ' + clientId + ', clientSecret: ' + clientSecret + ').')
// TODO req validator
const mongoId = new mongoose.mongo.ObjectID(clientId)
return OAuthClient.loadByIdAndSecret(mongoId, clientSecret)
}
function getRefreshToken (refreshToken) {
logger.debug('Getting RefreshToken (refreshToken: ' + refreshToken + ').')
return OAuthToken.loadByRefreshToken(refreshToken)
}
function getUser (username, password) {
logger.debug('Getting User (username: ' + username + ', password: ' + password + ').')
return User.loadByUsernameAndPassword(username, password)
}
function saveToken (token, client, user) {
logger.debug('Saving token for client ' + client.id + ' and user ' + user.id + '.')
const tokenObj = new OAuthToken({
accessToken: token.accessToken,
accessTokenExpiresOn: token.accessTokenExpiresOn,
client: client.id,
refreshToken: token.refreshToken,
refreshTokenExpiresOn: token.refreshTokenExpiresOn,
user: user.id
})
return tokenObj.save(function (err, tokenCreated) {
if (err) throw err // node-oauth2-server library uses Promise.try
tokenCreated.client = client
tokenCreated.user = user
return tokenCreated
})
}
// ---------------------------------------------------------------------------
module.exports = OAuthModel

View File

@ -1,6 +1,6 @@
'use strict'
const oauth2 = require('./oauth2')
const oauth = require('./oauth')
const pagination = require('./pagination')
const reqValidatorsMiddleware = require('./reqValidators')
const search = require('./search')
@ -8,7 +8,7 @@ const sort = require('./sort')
const secureMiddleware = require('./secure')
const middlewares = {
oauth2: oauth2,
oauth: oauth,
pagination: pagination,
reqValidators: reqValidatorsMiddleware,
search: search,

View File

@ -5,10 +5,10 @@ const OAuthServer = require('express-oauth-server')
const logger = require('../helpers/logger')
const oAuthServer = new OAuthServer({
model: require('../models/users')
model: require('../lib/oauth-model')
})
const oAuth2 = {
const oAuth = {
authenticate: authenticate,
token: token
}
@ -32,4 +32,4 @@ function token (req, res, next) {
// ---------------------------------------------------------------------------
module.exports = oAuth2
module.exports = oAuth

View File

@ -0,0 +1,33 @@
const mongoose = require('mongoose')
// ---------------------------------------------------------------------------
const OAuthClientSchema = mongoose.Schema({
clientSecret: String,
grants: Array,
redirectUris: Array
})
OAuthClientSchema.path('clientSecret').required(true)
OAuthClientSchema.statics = {
list: list,
loadByIdAndSecret: loadByIdAndSecret,
loadFirstClient: loadFirstClient
}
mongoose.model('OAuthClient', OAuthClientSchema)
// ---------------------------------------------------------------------------
function list (callback) {
return this.find(callback)
}
function loadFirstClient (callback) {
return this.findOne({}, callback)
}
function loadByIdAndSecret (id, clientSecret) {
return this.findOne({ _id: id, clientSecret: clientSecret })
}

View File

@ -0,0 +1,34 @@
const mongoose = require('mongoose')
// ---------------------------------------------------------------------------
const OAuthTokenSchema = mongoose.Schema({
accessToken: String,
accessTokenExpiresOn: Date,
client: { type: mongoose.Schema.Types.ObjectId, ref: 'OAuthClient' },
refreshToken: String,
refreshTokenExpiresOn: Date,
user: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }
})
OAuthTokenSchema.path('accessToken').required(true)
OAuthTokenSchema.path('client').required(true)
OAuthTokenSchema.path('user').required(true)
OAuthTokenSchema.statics = {
loadByRefreshToken: loadByRefreshToken,
loadByTokenAndPopulateUser: loadByTokenAndPopulateUser
}
mongoose.model('OAuthToken', OAuthTokenSchema)
// ---------------------------------------------------------------------------
function loadByRefreshToken (refreshToken, callback) {
return this.findOne({ refreshToken: refreshToken }, callback)
}
function loadByTokenAndPopulateUser (bearerToken, callback) {
// FIXME: allow to use callback
return this.findOne({ accessToken: bearerToken }).populate('user')
}

28
server/models/user.js Normal file
View File

@ -0,0 +1,28 @@
const mongoose = require('mongoose')
// ---------------------------------------------------------------------------
const UserSchema = mongoose.Schema({
password: String,
username: String
})
UserSchema.path('password').required(true)
UserSchema.path('username').required(true)
UserSchema.statics = {
list: list,
loadByUsernameAndPassword: loadByUsernameAndPassword
}
mongoose.model('User', UserSchema)
// ---------------------------------------------------------------------------
function list (callback) {
return this.find(callback)
}
function loadByUsernameAndPassword (username, password, callback) {
return this.findOne({ username: username, password: password }, callback)
}

View File

@ -1,123 +0,0 @@
const mongoose = require('mongoose')
const logger = require('../helpers/logger')
// ---------------------------------------------------------------------------
const oAuthTokensSchema = mongoose.Schema({
accessToken: String,
accessTokenExpiresOn: Date,
client: { type: mongoose.Schema.Types.ObjectId, ref: 'oAuthClients' },
refreshToken: String,
refreshTokenExpiresOn: Date,
user: { type: mongoose.Schema.Types.ObjectId, ref: 'users' }
})
const OAuthTokensDB = mongoose.model('oAuthTokens', oAuthTokensSchema)
const oAuthClientsSchema = mongoose.Schema({
clientSecret: String,
grants: Array,
redirectUris: Array
})
const OAuthClientsDB = mongoose.model('oAuthClients', oAuthClientsSchema)
const usersSchema = mongoose.Schema({
password: String,
username: String
})
const UsersDB = mongoose.model('users', usersSchema)
// ---------------------------------------------------------------------------
const Users = {
createClient: createClient,
createUser: createUser,
getAccessToken: getAccessToken,
getClient: getClient,
getClients: getClients,
getFirstClient: getFirstClient,
getRefreshToken: getRefreshToken,
getUser: getUser,
getUsers: getUsers,
saveToken: saveToken
}
function createClient (secret, grants, callback) {
logger.debug('Creating client.')
const mongoId = new mongoose.mongo.ObjectID()
return OAuthClientsDB.create({ _id: mongoId, clientSecret: secret, grants: grants }, function (err) {
if (err) return callback(err)
return callback(null, mongoId)
})
}
function createUser (username, password, callback) {
logger.debug('Creating user.')
return UsersDB.create({ username: username, password: password }, callback)
}
function getAccessToken (bearerToken, callback) {
logger.debug('Getting access token (bearerToken: ' + bearerToken + ').')
return OAuthTokensDB.findOne({ accessToken: bearerToken }).populate('user')
}
function getFirstClient (callback) {
return OAuthClientsDB.findOne({}, callback)
}
function getClient (clientId, clientSecret) {
logger.debug('Getting Client (clientId: ' + clientId + ', clientSecret: ' + clientSecret + ').')
// TODO req validator
const mongoId = new mongoose.mongo.ObjectID(clientId)
return OAuthClientsDB.findOne({ _id: mongoId, clientSecret: clientSecret })
}
function getClients (callback) {
return OAuthClientsDB.find(callback)
}
function getRefreshToken (refreshToken) {
logger.debug('Getting RefreshToken (refreshToken: ' + refreshToken + ').')
return OAuthTokensDB.findOne({ refreshToken: refreshToken })
}
function getUser (username, password) {
logger.debug('Getting User (username: ' + username + ', password: ' + password + ').')
return UsersDB.findOne({ username: username, password: password })
}
function getUsers (callback) {
return UsersDB.find(callback)
}
function saveToken (token, client, user) {
logger.debug('Saving token for client ' + client.id + ' and user ' + user.id + '.')
const tokenToCreate = {
accessToken: token.accessToken,
accessTokenExpiresOn: token.accessTokenExpiresOn,
client: client.id,
refreshToken: token.refreshToken,
refreshTokenExpiresOn: token.refreshTokenExpiresOn,
user: user.id
}
return OAuthTokensDB.create(tokenToCreate, function (err, tokenCreated) {
if (err) throw err // node-oauth2-server library uses Promise.try
tokenCreated.client = client
tokenCreated.user = user
return tokenCreated
})
}
// ---------------------------------------------------------------------------
module.exports = Users