Moved permission-related functions to permissionController

Fix: non-root staffs are now able to delete files by any users (previously they could only list them).
This commit is contained in:
Bobby Wibowo 2018-10-13 18:06:58 +07:00
parent c763d9b1ea
commit fcf4c00de7
No known key found for this signature in database
GPG Key ID: 51C3A1E1E22D26CF
7 changed files with 50 additions and 43 deletions

View File

@ -1,40 +1,12 @@
const bcrypt = require('bcrypt')
const config = require('./../config')
const db = require('knex')(config.database)
const perms = require('./permissionController')
const randomstring = require('randomstring')
const utils = require('./utilsController')
const authController = {}
authController.permissions = {
user: 0, // upload & delete own files, create & delete albums
moderator: 50, // delete other user's files
admin: 80, // manage users (disable accounts) & create moderators
superadmin: 100 // create admins
// groups will inherit permissions from groups which have lower value
}
authController.is = (user, group) => {
// root bypass
if (user.username === 'root') { return true }
const permission = user.permission || 0
return permission >= authController.permissions[group]
}
authController.higher = (user, target) => {
const userPermission = user.permission || 0
const targetPermission = target.permission || 0
return userPermission > targetPermission
}
authController.mapPermissions = user => {
const map = {}
Object.keys(authController.permissions).forEach(group => {
map[group] = authController.is(user, group)
})
return map
}
authController.verify = async (req, res, next) => {
const username = req.body.username
const password = req.body.password
@ -92,7 +64,7 @@ authController.register = async (req, res, next) => {
password: hash,
token,
enabled: 1,
permission: authController.permissions.user
permission: perms.permissions.user
})
return res.json({ success: true, token })
})
@ -191,7 +163,7 @@ authController.editUser = async (req, res, next) => {
if (!target) {
return res.json({ success: false, description: 'Could not get user with the specified ID.' })
} else if (!authController.higher(user, target)) {
} else if (!perms.higher(user, target)) {
return res.json({ success: false, description: 'The user is in the same or higher group as you.' })
} else if (target.username === 'root') {
return res.json({ success: false, description: 'Root user may not be edited.' })
@ -202,7 +174,7 @@ authController.editUser = async (req, res, next) => {
return res.json({ success: false, description: 'Username must have 4-32 characters.' })
}
let permission = req.body.group ? authController.permissions[req.body.group] : target.permission
let permission = req.body.group ? perms.permissions[req.body.group] : target.permission
if (typeof permission !== 'number' || permission < 0) { permission = target.permission }
await db.table('users')
@ -236,7 +208,7 @@ authController.listUsers = async (req, res, next) => {
const user = await utils.authorize(req, res)
if (!user) { return }
const isadmin = authController.is(user, 'admin')
const isadmin = perms.is(user, 'admin')
if (!isadmin) { return res.status(403) }
let offset = req.params.page

View File

@ -0,0 +1,32 @@
const permissionController = {}
permissionController.permissions = {
user: 0, // upload & delete own files, create & delete albums
moderator: 50, // delete other user's files
admin: 80, // manage users (disable accounts) & create moderators
superadmin: 100 // create admins
// groups will inherit permissions from groups which have lower value
}
permissionController.is = (user, group) => {
// root bypass
if (user.username === 'root') { return true }
const permission = user.permission || 0
return permission >= permissionController.permissions[group]
}
permissionController.higher = (user, target) => {
const userPermission = user.permission || 0
const targetPermission = target.permission || 0
return userPermission > targetPermission
}
permissionController.mapPermissions = user => {
const map = {}
Object.keys(permissionController.permissions).forEach(group => {
map[group] = permissionController.is(user, group)
})
return map
}
module.exports = permissionController

View File

@ -1,6 +1,6 @@
const auth = require('./authController')
const config = require('./../config')
const db = require('knex')(config.database)
const perms = require('./permissionController')
const randomstring = require('randomstring')
const utils = require('./utilsController')
@ -26,7 +26,7 @@ tokenController.verify = async (req, res, next) => {
return res.json({
success: true,
username: user.username,
permissions: auth.mapPermissions(user)
permissions: perms.mapPermissions(user)
})
}

View File

@ -1,4 +1,3 @@
const auth = require('./authController')
const config = require('./../config')
const crypto = require('crypto')
const db = require('knex')(config.database)
@ -6,6 +5,7 @@ const fetch = require('node-fetch')
const fs = require('fs')
const multer = require('multer')
const path = require('path')
const perms = require('./permissionController')
const randomstring = require('randomstring')
const utils = require('./utilsController')
@ -652,7 +652,7 @@ uploadsController.list = async (req, res) => {
// Headers is string-only, this seem to be the safest and lightest
const all = req.headers.all === '1'
const ismoderator = auth.is(user, 'moderator')
const ismoderator = perms.is(user, 'moderator')
if (all && !ismoderator) { return res.json(403) }
const files = await db.table('files')

View File

@ -5,6 +5,7 @@ const ffmpeg = require('fluent-ffmpeg')
const fs = require('fs')
const gm = require('gm')
const path = require('path')
const perms = require('./permissionController')
const utilsController = {}
const uploadsDir = path.join(__dirname, '..', config.uploads.folder)
@ -167,10 +168,12 @@ utilsController.deleteFile = file => {
utilsController.bulkDeleteFiles = async (field, values, user) => {
if (!user || !['id', 'name'].includes(field)) { return }
console.log(require('util').inspect(perms))
const ismoderator = perms.is(user, 'moderator')
const files = await db.table('files')
.whereIn(field, values)
.where(function () {
if (user.username !== 'root') {
if (!ismoderator) {
this.where('userid', user.id)
}
})

View File

@ -1,4 +1,4 @@
const { permissions } = require('./../controllers/authController')
const perms = require('./../controllers/permissionController')
const init = function (db) {
// Create the tables we need to store galleries and files
@ -59,7 +59,7 @@ const init = function (db) {
password: hash,
token: require('randomstring').generate(64),
timestamp: Math.floor(Date.now() / 1000),
permission: permissions.superadmin
permission: perms.permissions.superadmin
}).then(() => {})
})
})

View File

@ -1,6 +1,6 @@
const config = require('./../config')
const db = require('knex')(config.database)
const { permissions } = require('./../controllers/authController')
const perms = require('./../controllers/permissionController')
const map = {
albums: {
@ -36,11 +36,11 @@ migration.start = async () => {
.where('username', 'root')
.first()
.update({
permission: permissions.superadmin
permission: perms.permissions.superadmin
})
.then(rows => {
if (!rows) { return console.log('Unable to update root\'s permission into superadmin.') }
console.log(`Updated root's permission to ${permissions.superadmin} (superadmin).`)
console.log(`Updated root's permission to ${perms.permissions.superadmin} (superadmin).`)
})
console.log('Migration finished! Now start lolisafe normally')