Server: encrypt password in database

This commit is contained in:
Chocobozzz 2016-08-25 17:57:37 +02:00
parent f84a89f0e7
commit 26d7d31ba3
6 changed files with 74 additions and 15 deletions

View File

@ -35,6 +35,7 @@
}, },
"dependencies": { "dependencies": {
"async": "^2.0.0", "async": "^2.0.0",
"bcrypt": "^0.8.7",
"bittorrent-tracker": "^8.0.0", "bittorrent-tracker": "^8.0.0",
"body-parser": "^1.12.4", "body-parser": "^1.12.4",
"concurrently": "^2.0.0", "concurrently": "^2.0.0",

View File

@ -1,5 +1,6 @@
'use strict' 'use strict'
const bcrypt = require('bcrypt')
const crypto = require('crypto') const crypto = require('crypto')
const fs = require('fs') const fs = require('fs')
const openssl = require('openssl-wrapper') const openssl = require('openssl-wrapper')
@ -12,7 +13,9 @@ const algorithm = 'aes-256-ctr'
const peertubeCrypto = { const peertubeCrypto = {
checkSignature: checkSignature, checkSignature: checkSignature,
comparePassword: comparePassword,
createCertsIfNotExist: createCertsIfNotExist, createCertsIfNotExist: createCertsIfNotExist,
cryptPassword: cryptPassword,
decrypt: decrypt, decrypt: decrypt,
encrypt: encrypt, encrypt: encrypt,
sign: sign sign: sign
@ -24,6 +27,14 @@ function checkSignature (publicKey, rawData, hexSignature) {
return isValid return isValid
} }
function comparePassword (plainPassword, hashPassword, callback) {
bcrypt.compare(plainPassword, hashPassword, function (err, isPasswordMatch) {
if (err) return callback(err)
return callback(null, isPasswordMatch)
})
}
function createCertsIfNotExist (callback) { function createCertsIfNotExist (callback) {
certsExist(function (exist) { certsExist(function (exist) {
if (exist === true) { if (exist === true) {
@ -36,6 +47,16 @@ function createCertsIfNotExist (callback) {
}) })
} }
function cryptPassword (password, callback) {
bcrypt.genSalt(constants.BCRYPT_SALT_SIZE, function (err, salt) {
if (err) return callback(err)
bcrypt.hash(password, salt, function (err, hash) {
return callback(err, hash)
})
})
}
function decrypt (key, data, callback) { function decrypt (key, data, callback) {
fs.readFile(constants.CONFIG.STORAGE.CERT_DIR + 'peertube.key.pem', function (err, file) { fs.readFile(constants.CONFIG.STORAGE.CERT_DIR + 'peertube.key.pem', function (err, file) {
if (err) return callback(err) if (err) return callback(err)

View File

@ -6,6 +6,8 @@ const path = require('path')
// API version of our pod // API version of our pod
const API_VERSION = 'v1' const API_VERSION = 'v1'
const BCRYPT_SALT_SIZE = 10
const CONFIG = { const CONFIG = {
DATABASE: { DATABASE: {
DBNAME: 'peertube' + config.get('database.suffix'), DBNAME: 'peertube' + config.get('database.suffix'),
@ -115,6 +117,7 @@ if (isTestInstance() === true) {
module.exports = { module.exports = {
API_VERSION: API_VERSION, API_VERSION: API_VERSION,
BCRYPT_SALT_SIZE: BCRYPT_SALT_SIZE,
CONFIG: CONFIG, CONFIG: CONFIG,
CONSTRAINTS_FIELDS: CONSTRAINTS_FIELDS, CONSTRAINTS_FIELDS: CONSTRAINTS_FIELDS,
FRIEND_SCORE: FRIEND_SCORE, FRIEND_SCORE: FRIEND_SCORE,

View File

@ -114,8 +114,8 @@ function createOAuthAdminIfNotExist (callback) {
user.save(function (err, createdUser) { user.save(function (err, createdUser) {
if (err) return callback(err) if (err) return callback(err)
logger.info('Username: ' + createdUser.username) logger.info('Username: ' + username)
logger.info('User password: ' + createdUser.password) logger.info('User password: ' + password)
return callback(null) return callback(null)
}) })

View File

@ -41,7 +41,22 @@ function getRefreshToken (refreshToken, callback) {
function getUser (username, password) { function getUser (username, password) {
logger.debug('Getting User (username: ' + username + ', password: ' + password + ').') logger.debug('Getting User (username: ' + username + ', password: ' + password + ').')
return User.getByUsernameAndPassword(username, password) return User.getByUsername(username).then(function (user) {
if (!user) return null
// We need to return a promise
return new Promise(function (resolve, reject) {
return user.isPasswordMatch(password, function (err, isPasswordMatch) {
if (err) return reject(err)
if (isPasswordMatch === true) {
return resolve(user)
}
return resolve(null)
})
})
})
} }
function revokeToken (token) { function revokeToken (token) {

View File

@ -2,6 +2,7 @@ const mongoose = require('mongoose')
const customUsersValidators = require('../helpers/custom-validators').users const customUsersValidators = require('../helpers/custom-validators').users
const modelUtils = require('./utils') const modelUtils = require('./utils')
const peertubeCrypto = require('../helpers/peertube-crypto')
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@ -20,27 +21,53 @@ UserSchema.path('username').required(customUsersValidators.isUserUsernameValid)
UserSchema.path('role').validate(customUsersValidators.isUserRoleValid) UserSchema.path('role').validate(customUsersValidators.isUserRoleValid)
UserSchema.methods = { UserSchema.methods = {
isPasswordMatch: isPasswordMatch,
toFormatedJSON: toFormatedJSON toFormatedJSON: toFormatedJSON
} }
UserSchema.statics = { UserSchema.statics = {
countTotal: countTotal, countTotal: countTotal,
getByUsernameAndPassword: getByUsernameAndPassword, getByUsername: getByUsername,
listForApi: listForApi, listForApi: listForApi,
loadById: loadById, loadById: loadById,
loadByUsername: loadByUsername loadByUsername: loadByUsername
} }
UserSchema.pre('save', function (next) {
const user = this
peertubeCrypto.cryptPassword(this.password, function (err, hash) {
if (err) return next(err)
user.password = hash
return next()
})
})
mongoose.model('User', UserSchema) mongoose.model('User', UserSchema)
// --------------------------------------------------------------------------- // ------------------------------ METHODS ------------------------------
function isPasswordMatch (password, callback) {
return peertubeCrypto.comparePassword(password, this.password, callback)
}
function toFormatedJSON () {
return {
id: this._id,
username: this.username,
role: this.role
}
}
// ------------------------------ STATICS ------------------------------
function countTotal (callback) { function countTotal (callback) {
return this.count(callback) return this.count(callback)
} }
function getByUsernameAndPassword (username, password) { function getByUsername (username) {
return this.findOne({ username: username, password: password }) return this.findOne({ username: username })
} }
function listForApi (start, count, sort, callback) { function listForApi (start, count, sort, callback) {
@ -55,11 +82,3 @@ function loadById (id, callback) {
function loadByUsername (username, callback) { function loadByUsername (username, callback) {
return this.findOne({ username: username }, callback) return this.findOne({ username: username }, callback)
} }
function toFormatedJSON () {
return {
id: this._id,
username: this.username,
role: this.role
}
}