set perm level on middleware to not check it redundantly, easier to maintain

merge-requests/208/head
fatchan 5 years ago
parent 95ba3b8caa
commit 8cdd235e8f
  1. 34
      controllers/forms.js
  2. 5
      controllers/pages.js
  3. 20
      helpers/build.js
  4. 5
      helpers/checks/bancheck.js
  5. 8
      helpers/checks/calcpermsmiddleware.js
  6. 5
      helpers/checks/haspermsmiddleware.js
  7. 3
      helpers/checks/spamcheck.js

@ -46,8 +46,8 @@ const express = require('express')
, changeBoardSettings = require(__dirname+'/../models/forms/changeboardsettings.js') , changeBoardSettings = require(__dirname+'/../models/forms/changeboardsettings.js')
, registerAccount = require(__dirname+'/../models/forms/register.js') , registerAccount = require(__dirname+'/../models/forms/register.js')
, createBoard = require(__dirname+'/../models/forms/create.js') , createBoard = require(__dirname+'/../models/forms/create.js')
, checkPermsMiddleware = require(__dirname+'/../helpers/checks/haspermsmiddleware.js') , calcPerms = require(__dirname+'/../helpers/checks/calcpermsmiddleware.js')
, checkPerms = require(__dirname+'/../helpers/checks/hasperms.js') , hasPerms = require(__dirname+'/../helpers/checks/haspermsmiddleware.js')
, spamCheck = require(__dirname+'/../helpers/checks/spamcheck.js') , spamCheck = require(__dirname+'/../helpers/checks/spamcheck.js')
, paramConverter = require(__dirname+'/../helpers/paramconverter.js') , paramConverter = require(__dirname+'/../helpers/paramconverter.js')
, banCheck = require(__dirname+'/../helpers/checks/bancheck.js') , banCheck = require(__dirname+'/../helpers/checks/bancheck.js')
@ -149,10 +149,9 @@ router.post('/changepassword', verifyCaptcha, async (req, res, next) => {
}); });
//create board //create board
router.post('/create', csrf, isLoggedIn, verifyCaptcha, (req, res, next) => { router.post('/create', csrf, isLoggedIn, verifyCaptcha, calcPerms, hasPerms(4), (req, res, next) => {
res.locals.authLevel = checkPerms(req, res); if (enableUserBoards === false && res.locals.permLevel !== 0) {
if (enableUserBoards === false && res.locals.authLevel !== 0) {
//only board admin can create boards when user board creation disabled //only board admin can create boards when user board creation disabled
return res.status(400).render('message', { return res.status(400).render('message', {
'title': 'Bad request', 'title': 'Bad request',
@ -251,7 +250,7 @@ router.post('/register', verifyCaptcha, (req, res, next) => {
// make new post // make new post
router.post('/board/:board/post', Boards.exists, banCheck, postFiles, paramConverter, verifyCaptcha, async (req, res, next) => { router.post('/board/:board/post', Boards.exists, calcPerms, banCheck, postFiles, paramConverter, verifyCaptcha, async (req, res, next) => {
if (req.files && req.files.file) { if (req.files && req.files.file) {
if (Array.isArray(req.files.file)) { if (Array.isArray(req.files.file)) {
@ -333,7 +332,7 @@ router.post('/board/:board/post', Boards.exists, banCheck, postFiles, paramConve
}); });
//board settings //board settings
router.post('/board/:board/settings', csrf, Boards.exists, banCheck, isLoggedIn, checkPermsMiddleware(2), paramConverter, async (req, res, next) => { router.post('/board/:board/settings', csrf, Boards.exists, calcPerms, banCheck, isLoggedIn, hasPerms(2), paramConverter, async (req, res, next) => {
const errors = []; const errors = [];
@ -394,7 +393,7 @@ router.post('/board/:board/settings', csrf, Boards.exists, banCheck, isLoggedIn,
}); });
//upload banners //upload banners
router.post('/board/:board/addbanners', bannerFiles, csrf, Boards.exists, banCheck, isLoggedIn, checkPermsMiddleware(2), paramConverter, async (req, res, next) => { router.post('/board/:board/addbanners', bannerFiles, csrf, Boards.exists, calcPerms, banCheck, isLoggedIn, hasPerms(2), paramConverter, async (req, res, next) => {
if (req.files && req.files.file) { if (req.files && req.files.file) {
if (Array.isArray(req.files.file)) { if (Array.isArray(req.files.file)) {
@ -433,7 +432,7 @@ router.post('/board/:board/addbanners', bannerFiles, csrf, Boards.exists, banChe
}); });
//delete banners //delete banners
router.post('/board/:board/deletebanners', csrf, Boards.exists, banCheck, isLoggedIn, checkPermsMiddleware(2), paramConverter, async (req, res, next) => { router.post('/board/:board/deletebanners', csrf, Boards.exists, calcPerms, banCheck, isLoggedIn, hasPerms(2), paramConverter, async (req, res, next) => {
const errors = []; const errors = [];
@ -469,8 +468,8 @@ router.post('/board/:board/deletebanners', csrf, Boards.exists, banCheck, isLogg
}); });
//actions for a specific board //actions for a specific board
router.post('/board/:board/actions', Boards.exists, banCheck, paramConverter, verifyCaptcha, boardActionController); //Captcha on regular actions router.post('/board/:board/actions', Boards.exists, calcPerms, banCheck, paramConverter, verifyCaptcha, boardActionController); //Captcha on regular actions
router.post('/board/:board/modactions', csrf, Boards.exists, banCheck, isLoggedIn, checkPermsMiddleware(3), paramConverter, boardActionController); //CSRF for mod actions router.post('/board/:board/modactions', csrf, Boards.exists, calcPerms, banCheck, isLoggedIn, hasPerms(3), paramConverter, boardActionController); //CSRF for mod actions
async function boardActionController(req, res, next) { async function boardActionController(req, res, next) {
const errors = []; const errors = [];
@ -488,9 +487,8 @@ async function boardActionController(req, res, next) {
} }
//check if they have permission to perform the actions //check if they have permission to perform the actions
res.locals.authLevel = checkPerms(req, res); if (res.locals.permLevel >= 4) {
if (res.locals.authLevel >= 4) { if (res.locals.permLevel > res.locals.actions.authRequired) {
if (res.locals.authLevel > res.locals.actions.authRequired) {
errors.push('No permission'); errors.push('No permission');
} }
if (req.body.delete && !res.locals.board.settings.userPostDelete) { if (req.body.delete && !res.locals.board.settings.userPostDelete) {
@ -545,7 +543,7 @@ async function boardActionController(req, res, next) {
} }
//global actions (global manage page) //global actions (global manage page)
router.post('/global/actions', csrf, isLoggedIn, checkPermsMiddleware(1), paramConverter, globalActionController); router.post('/global/actions', csrf, calcPerms, isLoggedIn, hasPerms(1), paramConverter, globalActionController);
async function globalActionController(req, res, next) { async function globalActionController(req, res, next) {
const errors = []; const errors = [];
@ -599,7 +597,7 @@ async function globalActionController(req, res, next) {
} }
//unban //unban
router.post('/board/:board/unban', csrf, Boards.exists, banCheck, isLoggedIn, checkPermsMiddleware(3), paramConverter, async (req, res, next) => { router.post('/board/:board/unban', csrf, Boards.exists, calcPerms, banCheck, isLoggedIn, hasPerms(3), paramConverter, async (req, res, next) => {
//keep this for later in case i add other options to unbans //keep this for later in case i add other options to unbans
const errors = []; const errors = [];
@ -632,7 +630,7 @@ router.post('/board/:board/unban', csrf, Boards.exists, banCheck, isLoggedIn, ch
}); });
//delete board //delete board
router.post('/board/:board/deleteboard', csrf, Boards.exists, banCheck, isLoggedIn, checkPermsMiddleware(2), async (req, res, next) => { router.post('/board/:board/deleteboard', csrf, Boards.exists, calcPerms, banCheck, isLoggedIn, hasPerms(2), async (req, res, next) => {
const errors = []; const errors = [];
@ -673,7 +671,7 @@ router.post('/board/:board/deleteboard', csrf, Boards.exists, banCheck, isLogged
}); });
router.post('/global/unban', csrf, isLoggedIn, checkPermsMiddleware(1), paramConverter, async(req, res, next) => { router.post('/global/unban', csrf, calcPerms, isLoggedIn, hasPerms(1), paramConverter, async(req, res, next) => {
const errors = []; const errors = [];

@ -4,6 +4,7 @@ const express = require('express')
, router = express.Router() , router = express.Router()
, Boards = require(__dirname+'/../db/boards.js') , Boards = require(__dirname+'/../db/boards.js')
, Posts = require(__dirname+'/../db/posts.js') , Posts = require(__dirname+'/../db/posts.js')
, calcPerms = require(__dirname+'/../helpers/checks/calcpermsmiddleware.js')
, hasPerms = require(__dirname+'/../helpers/checks/haspermsmiddleware.js') , hasPerms = require(__dirname+'/../helpers/checks/haspermsmiddleware.js')
, isLoggedIn = require(__dirname+'/../helpers/checks/isloggedin.js') , isLoggedIn = require(__dirname+'/../helpers/checks/isloggedin.js')
, paramConverter = require(__dirname+'/../helpers/paramconverter.js') , paramConverter = require(__dirname+'/../helpers/paramconverter.js')
@ -70,10 +71,10 @@ router.get('/logout', (req, res, next) => {
router.get('/:board/banners.html', Boards.exists, banners); router.get('/:board/banners.html', Boards.exists, banners);
//board manage page //board manage page
router.get('/:board/manage.html', Boards.exists, isLoggedIn, hasPerms(3), csrf, manage); router.get('/:board/manage.html', isLoggedIn, Boards.exists, calcPerms, hasPerms(3), csrf, manage);
//global manage page //global manage page
router.get('/globalmanage.html', isLoggedIn, hasPerms(1), csrf, globalManage); router.get('/globalmanage.html', isLoggedIn, calcPerms, hasPerms(1), csrf, globalManage);
module.exports = router; module.exports = router;

@ -12,17 +12,12 @@ const Mongo = require(__dirname+'/../db/db.js')
module.exports = { module.exports = {
buildBanners: async(board) => { buildBanners: async(board) => {
const buildName = `Building: ${board._id}/banners.html`;
console.time(buildName);
await render(`${board._id}/banners.html`, 'banners.pug', { await render(`${board._id}/banners.html`, 'banners.pug', {
board: board, board: board,
}); });
console.timeEnd(buildName);
}, },
buildCatalog: async (board) => { buildCatalog: async (board) => {
const buildName = `Building: ${board._id}/catalog.html`;
console.time(buildName);
if (!board._id) { if (!board._id) {
board = await Boards.findOne(board); board = await Boards.findOne(board);
} }
@ -31,30 +26,23 @@ module.exports = {
board, board,
threads, threads,
}); });
console.timeEnd(buildName);
}, },
buildThread: async (threadId, board) => { buildThread: async (threadId, board) => {
const buildName = `Building: ${board._id || board}/thread/${threadId}.html`;
console.time(buildName);
if (!board._id) { if (!board._id) {
board = await Boards.findOne(board); board = await Boards.findOne(board);
} }
const thread = await Posts.getThread(board._id, threadId) const thread = await Posts.getThread(board._id, threadId)
if (!thread) { if (!thread) {
console.timeEnd(buildName, 'deleted OP')
return; //this thread may have been an OP that was deleted return; //this thread may have been an OP that was deleted
} }
await render(`${board._id}/thread/${threadId}.html`, 'thread.pug', { await render(`${board._id}/thread/${threadId}.html`, 'thread.pug', {
board, board,
thread, thread,
}); });
console.timeEnd(buildName);
}, },
buildBoard: async (board, page, maxPage=null) => { buildBoard: async (board, page, maxPage=null) => {
const buildName = `Building: ${board._id || board}/${page === 1 ? 'index' : page}.html`;
console.time(buildName);
const threads = await Posts.getRecent(board._id, page); const threads = await Posts.getRecent(board._id, page);
if (maxPage == null) { if (maxPage == null) {
maxPage = Math.min(Math.ceil((await Posts.getPages(board._id)) / 10), Math.ceil(board.settings.threadLimit/10)); maxPage = Math.min(Math.ceil((await Posts.getPages(board._id)) / 10), Math.ceil(board.settings.threadLimit/10));
@ -66,13 +54,10 @@ module.exports = {
maxPage, maxPage,
page, page,
}); });
console.timeEnd(buildName);
}, },
//building multiple pages (for rebuilds) //building multiple pages (for rebuilds)
buildBoardMultiple: async (board, startpage=1, endpage) => { buildBoardMultiple: async (board, startpage=1, endpage) => {
const buildName = 'multi page build';
console.time(buildName);
const maxPage = Math.min(Math.ceil((await Posts.getPages(board._id)) / 10), Math.ceil(board.settings.threadLimit/10)); const maxPage = Math.min(Math.ceil((await Posts.getPages(board._id)) / 10), Math.ceil(board.settings.threadLimit/10));
if (endpage === 0) { if (endpage === 0) {
//deleted only/all posts, so only 1 page will remain //deleted only/all posts, so only 1 page will remain
@ -83,7 +68,6 @@ module.exports = {
} }
const difference = endpage-startpage + 1; //+1 because for single pagemust be > 0 const difference = endpage-startpage + 1; //+1 because for single pagemust be > 0
const threads = await Posts.getRecent(board._id, startpage, difference*10); const threads = await Posts.getRecent(board._id, startpage, difference*10);
console.timeLog(buildName, `${board._id}/ ${startpage === 1 ? 'index' : startpage} -> ${endpage === 1 ? 'index' : endpage} .html`);
const buildArray = []; const buildArray = [];
for (let i = startpage; i <= endpage; i++) { for (let i = startpage; i <= endpage; i++) {
let spliceStart = (i-1)*10; let spliceStart = (i-1)*10;
@ -100,12 +84,9 @@ module.exports = {
); );
} }
await Promise.all(buildArray); await Promise.all(buildArray);
console.timeEnd(buildName);
}, },
buildHomepage: async () => { buildHomepage: async () => {
const buildName = `Building: index.html`;
console.time(buildName);
//getting boards //getting boards
const boards = await Boards.find(); const boards = await Boards.find();
//geting PPH for each board //geting PPH for each board
@ -157,7 +138,6 @@ module.exports = {
boards, boards,
fileStats, fileStats,
}); });
console.timeEnd(buildName);
}, },
buildChangePassword: () => { buildChangePassword: () => {

@ -5,12 +5,11 @@ const Bans = require(__dirname+'/../../db/bans.js')
module.exports = async (req, res, next) => { module.exports = async (req, res, next) => {
const permLevel = hasPerms(req, res); if (res.locals.permLevel > 1) {//global staff or admin bypass
if (permLevel > 1) {//global staff or admin bypass
const bans = await Bans.find(res.locals.ip, res.locals.board ? res.locals.board._id : null); const bans = await Bans.find(res.locals.ip, res.locals.board ? res.locals.board._id : null);
if (bans && bans.length > 0) { if (bans && bans.length > 0) {
const globalBans = bans.filter(ban => { return board === null }); const globalBans = bans.filter(ban => { return board === null });
if (globalBans.length > 0 || (permLevel >= 4 && globalBans.length !== bans.length)) { if (globalBans.length > 0 || (res.locals.permLevel >= 4 && globalBans.length !== bans.length)) {
//board staff bypass bans on their own board, but not global bans //board staff bypass bans on their own board, but not global bans
return res.status(403).render('ban', { return res.status(403).render('ban', {
bans: bans bans: bans

@ -0,0 +1,8 @@
'use strict';
const hasPerms = require(__dirname+'/hasperms.js');
module.exports = (req, res, next) => {
res.locals.permLevel = hasPerms(req, res);
next();
}

@ -1,12 +1,9 @@
'use strict'; 'use strict';
const hasPerms = require(__dirname+'/hasperms.js');
module.exports = (requiredLevel) => { module.exports = (requiredLevel) => {
return function(req, res, next) { return function(req, res, next) {
const authLevel = hasPerms(req, res); if (res.locals.permLevel > requiredLevel) {
if (authLevel > requiredLevel) {
return res.status(403).render('message', { return res.status(403).render('message', {
'title': 'Forbidden', 'title': 'Forbidden',
'message': 'No Permission', 'message': 'No Permission',

@ -3,11 +3,10 @@
const Mongo = require(__dirname+'/../../db/db.js') const Mongo = require(__dirname+'/../../db/db.js')
, Posts = require(__dirname+'/../../db/posts.js') , Posts = require(__dirname+'/../../db/posts.js')
, msTime = require(__dirname+'/../mstime.js') , msTime = require(__dirname+'/../mstime.js')
, hasPerms = require(__dirname+'/hasperms.js')
module.exports = async (req, res) => { module.exports = async (req, res) => {
if (hasPerms(req, res) <= 1) { //global staff bypass spam check if (res.locals.permLevel <= 1) { //global staff bypass spam check
return false; return false;
} }

Loading…
Cancel
Save