mirror of
				https://github.com/NodeBB/NodeBB.git
				synced 2025-10-31 02:55:58 +01:00 
			
		
		
		
	feat: add privilege give/rescind hooks (#8336)
* feat: add privilege give/rescind hooks action:privileges.categories.give/rescind action:privileges.global.give/rescind breaking change, privileges.categories.give/rescind and privileges.global.give/rescind use full privilege name for groups ie `groups:find` instead of `find` * fix: tests, privileges renamed
This commit is contained in:
		
				
					committed by
					
						 GitHub
						GitHub
					
				
			
			
				
	
			
			
			
						parent
						
							a0e243eea1
						
					
				
				
					commit
					ec5582b53c
				
			| @@ -1,14 +1,13 @@ | ||||
| 'use strict'; | ||||
|  | ||||
| var async = require('async'); | ||||
| var _ = require('lodash'); | ||||
| const async = require('async'); | ||||
| const _ = require('lodash'); | ||||
|  | ||||
| var db = require('../database'); | ||||
| var groups = require('../groups'); | ||||
| var plugins = require('../plugins'); | ||||
| var privileges = require('../privileges'); | ||||
| var utils = require('../utils'); | ||||
| var cache = require('../cache'); | ||||
| const db = require('../database'); | ||||
| const plugins = require('../plugins'); | ||||
| const privileges = require('../privileges'); | ||||
| const utils = require('../utils'); | ||||
| const cache = require('../cache'); | ||||
|  | ||||
| module.exports = function (Categories) { | ||||
| 	Categories.create = async function (data) { | ||||
| @@ -48,33 +47,34 @@ module.exports = function (Categories) { | ||||
| 		const result = await plugins.fireHook('filter:category.create', { category: category, data: data }); | ||||
| 		category = result.category; | ||||
|  | ||||
| 		const defaultPrivileges = [ | ||||
| 			'find', | ||||
| 			'read', | ||||
| 			'topics:read', | ||||
| 			'topics:create', | ||||
| 			'topics:reply', | ||||
| 			'topics:tag', | ||||
| 			'posts:edit', | ||||
| 			'posts:history', | ||||
| 			'posts:delete', | ||||
| 			'posts:upvote', | ||||
| 			'posts:downvote', | ||||
| 			'topics:delete', | ||||
| 		]; | ||||
| 		const modPrivileges = defaultPrivileges.concat([ | ||||
| 			'posts:view_deleted', | ||||
| 			'purge', | ||||
| 		]); | ||||
|  | ||||
| 		await db.setObject('category:' + category.cid, category); | ||||
| 		if (!category.descriptionParsed) { | ||||
| 			await Categories.parseDescription(category.cid, category.description); | ||||
| 		} | ||||
| 		await db.sortedSetsAdd(['categories:cid', 'cid:' + parentCid + ':children'], category.order, category.cid); | ||||
|  | ||||
| 		const defaultPrivileges = [ | ||||
| 			'groups:find', | ||||
| 			'groups:read', | ||||
| 			'groups:topics:read', | ||||
| 			'groups:topics:create', | ||||
| 			'groups:topics:reply', | ||||
| 			'groups:topics:tag', | ||||
| 			'groups:posts:edit', | ||||
| 			'groups:posts:history', | ||||
| 			'groups:posts:delete', | ||||
| 			'groups:posts:upvote', | ||||
| 			'groups:posts:downvote', | ||||
| 			'groups:topics:delete', | ||||
| 		]; | ||||
| 		const modPrivileges = defaultPrivileges.concat([ | ||||
| 			'groups:posts:view_deleted', | ||||
| 			'groups:purge', | ||||
| 		]); | ||||
| 		await privileges.categories.give(defaultPrivileges, category.cid, 'registered-users'); | ||||
| 		await privileges.categories.give(modPrivileges, category.cid, ['administrators', 'Global Moderators']); | ||||
| 		await privileges.categories.give(['find', 'read', 'topics:read'], category.cid, ['guests', 'spiders']); | ||||
| 		await privileges.categories.give(['groups:find', 'groups:read', 'groups:topics:read'], category.cid, ['guests', 'spiders']); | ||||
|  | ||||
| 		cache.del(['categories:cid', 'cid:' + parentCid + ':children']); | ||||
| 		if (data.cloneFromCid && parseInt(data.cloneFromCid, 10)) { | ||||
| @@ -110,10 +110,9 @@ module.exports = function (Categories) { | ||||
| 	} | ||||
|  | ||||
| 	Categories.assignColours = function () { | ||||
| 		var backgrounds = ['#AB4642', '#DC9656', '#F7CA88', '#A1B56C', '#86C1B9', '#7CAFC2', '#BA8BAF', '#A16946']; | ||||
| 		var text = ['#fff', '#fff', '#333', '#fff', '#333', '#fff', '#fff', '#fff']; | ||||
| 		var index = Math.floor(Math.random() * backgrounds.length); | ||||
|  | ||||
| 		const backgrounds = ['#AB4642', '#DC9656', '#F7CA88', '#A1B56C', '#86C1B9', '#7CAFC2', '#BA8BAF', '#A16946']; | ||||
| 		const text = ['#fff', '#fff', '#333', '#fff', '#333', '#fff', '#fff', '#fff']; | ||||
| 		const index = Math.floor(Math.random() * backgrounds.length); | ||||
| 		return [backgrounds[index], text[index]]; | ||||
| 	}; | ||||
|  | ||||
| @@ -192,14 +191,16 @@ module.exports = function (Categories) { | ||||
| 		}); | ||||
| 	} | ||||
|  | ||||
| 	async function copyPrivilegesByGroup(privileges, fromCid, toCid, group) { | ||||
| 		const leaveGroups = privileges.map(privilege => 'cid:' + toCid + ':privileges:' + privilege); | ||||
| 		await groups.leave(leaveGroups, group); | ||||
|  | ||||
| 		const checkGroups = privileges.map(privilege => 'group:cid:' + fromCid + ':privileges:' + privilege + ':members'); | ||||
| 		const isMembers = await db.isMemberOfSortedSets(checkGroups, group); | ||||
| 		privileges = privileges.filter((priv, index) => isMembers[index]); | ||||
| 		const joinGroups = privileges.map(privilege => 'cid:' + toCid + ':privileges:' + privilege); | ||||
| 		await groups.join(joinGroups, group); | ||||
| 	async function copyPrivilegesByGroup(privilegeList, fromCid, toCid, group) { | ||||
| 		const fromGroups = privilegeList.map(privilege => 'group:cid:' + fromCid + ':privileges:' + privilege + ':members'); | ||||
| 		const toGroups = privilegeList.map(privilege => 'group:cid:' + toCid + ':privileges:' + privilege + ':members'); | ||||
| 		const [fromChecks, toChecks] = await Promise.all([ | ||||
| 			db.isMemberOfSortedSets(fromGroups, group), | ||||
| 			db.isMemberOfSortedSets(toGroups, group), | ||||
| 		]); | ||||
| 		const givePrivs = privilegeList.filter((priv, index) => fromChecks[index] && !toChecks[index]); | ||||
| 		const rescindPrivs = privilegeList.filter((priv, index) => !fromChecks[index] && toChecks[index]); | ||||
| 		await privileges.categories.give(givePrivs, toCid, group); | ||||
| 		await privileges.categories.rescind(rescindPrivs, toCid, group); | ||||
| 	} | ||||
| }; | ||||
|   | ||||
| @@ -93,7 +93,7 @@ exports.reset = async function (options) { | ||||
| }; | ||||
|  | ||||
| async function resetSettings() { | ||||
| 	await privileges.global.give(['local:login'], 'registered-users'); | ||||
| 	await privileges.global.give(['groups:local:login'], 'registered-users'); | ||||
| 	winston.info('[reset] registered-users given login privilege'); | ||||
| 	winston.info('[reset] Settings reset to default'); | ||||
| } | ||||
|   | ||||
| @@ -404,22 +404,22 @@ function createGlobalModeratorsGroup(next) { | ||||
| function giveGlobalPrivileges(next) { | ||||
| 	var privileges = require('./privileges'); | ||||
| 	var defaultPrivileges = [ | ||||
| 		'chat', 'upload:post:image', 'signature', 'search:content', | ||||
| 		'search:users', 'search:tags', 'view:users', 'view:tags', 'view:groups', | ||||
| 		'local:login', | ||||
| 		'groups:chat', 'groups:upload:post:image', 'groups:signature', 'groups:search:content', | ||||
| 		'groups:search:users', 'groups:search:tags', 'groups:view:users', 'groups:view:tags', 'groups:view:groups', | ||||
| 		'groups:local:login', | ||||
| 	]; | ||||
| 	async.waterfall([ | ||||
| 		function (next) { | ||||
| 			privileges.global.give(defaultPrivileges, 'registered-users', next); | ||||
| 		}, | ||||
| 		function (next) { | ||||
| 			privileges.global.give(defaultPrivileges.concat(['ban', 'upload:post:file', 'view:users:info']), 'Global Moderators', next); | ||||
| 			privileges.global.give(defaultPrivileges.concat(['groups:ban', 'groups:upload:post:file', 'groups:view:users:info']), 'Global Moderators', next); | ||||
| 		}, | ||||
| 		function (next) { | ||||
| 			privileges.global.give(['view:users', 'view:tags', 'view:groups'], 'guests', next); | ||||
| 			privileges.global.give(['groups:view:users', 'groups:view:tags', 'groups:view:groups'], 'guests', next); | ||||
| 		}, | ||||
| 		function (next) { | ||||
| 			privileges.global.give(['view:users', 'view:tags', 'view:groups'], 'spiders', next); | ||||
| 			privileges.global.give(['groups:view:users', 'groups:view:tags', 'groups:view:groups'], 'spiders', next); | ||||
| 		}, | ||||
| 	], next); | ||||
| } | ||||
|   | ||||
| @@ -129,12 +129,22 @@ module.exports = function (privileges) { | ||||
| 		return uids.filter((uid, index) => allowedTo[index] || isAdmins[index]); | ||||
| 	}; | ||||
|  | ||||
| 	privileges.categories.give = async function (privileges, cid, groupName) { | ||||
| 		await helpers.giveOrRescind(groups.join, privileges, cid, groupName); | ||||
| 	privileges.categories.give = async function (privileges, cid, members) { | ||||
| 		await helpers.giveOrRescind(groups.join, privileges, cid, members); | ||||
| 		plugins.fireHook('action:privileges.categories.give', { | ||||
| 			privileges: privileges, | ||||
| 			cids: Array.isArray(cid) ? cid : [cid], | ||||
| 			members: Array.isArray(members) ? members : [members], | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	privileges.categories.rescind = async function (privileges, cid, groupName) { | ||||
| 		await helpers.giveOrRescind(groups.leave, privileges, cid, groupName); | ||||
| 	privileges.categories.rescind = async function (privileges, cid, members) { | ||||
| 		await helpers.giveOrRescind(groups.leave, privileges, cid, members); | ||||
| 		plugins.fireHook('action:privileges.categories.rescind', { | ||||
| 			privileges: privileges, | ||||
| 			cids: Array.isArray(cid) ? cid : [cid], | ||||
| 			members: Array.isArray(members) ? members : [members], | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	privileges.categories.canMoveAllTopics = async function (currentCid, targetCid, uid) { | ||||
|   | ||||
| @@ -101,10 +101,18 @@ module.exports = function (privileges) { | ||||
|  | ||||
| 	privileges.global.give = async function (privileges, groupName) { | ||||
| 		await helpers.giveOrRescind(groups.join, privileges, 0, groupName); | ||||
| 		plugins.fireHook('action:privileges.global.give', { | ||||
| 			privileges: privileges, | ||||
| 			groupNames: Array.isArray(groupName) ? groupName : [groupName], | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	privileges.global.rescind = async function (privileges, groupName) { | ||||
| 		await helpers.giveOrRescind(groups.leave, privileges, 0, groupName); | ||||
| 		plugins.fireHook('action:privileges.global.rescind', { | ||||
| 			privileges: privileges, | ||||
| 			groupNames: Array.isArray(groupName) ? groupName : [groupName], | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	privileges.global.userPrivileges = async function (uid) { | ||||
|   | ||||
| @@ -153,18 +153,18 @@ function moveToFront(groupNames, groupToMove) { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| helpers.giveOrRescind = async function (method, privileges, cids, groupNames) { | ||||
| 	groupNames = Array.isArray(groupNames) ? groupNames : [groupNames]; | ||||
| helpers.giveOrRescind = async function (method, privileges, cids, members) { | ||||
| 	members = Array.isArray(members) ? members : [members]; | ||||
| 	cids = Array.isArray(cids) ? cids : [cids]; | ||||
| 	for (const groupName of groupNames) { | ||||
| 	for (const member of members) { | ||||
| 		const groupKeys = []; | ||||
| 		cids.forEach((cid) => { | ||||
| 			privileges.forEach((privilege) => { | ||||
| 				groupKeys.push('cid:' + cid + ':privileges:groups:' + privilege); | ||||
| 				groupKeys.push('cid:' + cid + ':privileges:' + privilege); | ||||
| 			}); | ||||
| 		}); | ||||
| 		/* eslint-disable no-await-in-loop */ | ||||
| 		await method(groupKeys, groupName); | ||||
| 		await method(groupKeys, member); | ||||
| 	} | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -61,11 +61,9 @@ Categories.setPrivilege = async function (socket, data) { | ||||
| 		throw new Error('[[error:no-user-or-group]]'); | ||||
| 	} | ||||
|  | ||||
| 	if (Array.isArray(data.privilege)) { | ||||
| 		await Promise.all(data.privilege.map(privilege => groups[data.set ? 'join' : 'leave']('cid:' + data.cid + ':privileges:' + privilege, data.member))); | ||||
| 	} else { | ||||
| 		await groups[data.set ? 'join' : 'leave']('cid:' + data.cid + ':privileges:' + data.privilege, data.member); | ||||
| 	} | ||||
| 	await privileges.categories[data.set ? 'give' : 'rescind']( | ||||
| 		Array.isArray(data.privilege) ? data.privilege : [data.privilege], data.cid, data.member | ||||
| 	); | ||||
|  | ||||
| 	await events.log({ | ||||
| 		uid: socket.uid, | ||||
|   | ||||
| @@ -15,7 +15,7 @@ module.exports = { | ||||
| 				return callback(err); | ||||
| 			} | ||||
| 			async.eachSeries(cids, function (cid, next) { | ||||
| 				privileges.categories.give(['posts:history'], cid, 'registered-users', next); | ||||
| 				privileges.categories.give(['groups:posts:history'], cid, 'registered-users', next); | ||||
| 			}, callback); | ||||
| 		}); | ||||
| 	}, | ||||
|   | ||||
| @@ -12,17 +12,17 @@ module.exports = { | ||||
| 		var allowGuestUserSearching = parseInt(meta.config.allowGuestUserSearching, 10) === 1; | ||||
| 		async.waterfall([ | ||||
| 			function (next) { | ||||
| 				privileges.global.give(['search:content', 'search:users', 'search:tags'], 'registered-users', next); | ||||
| 				privileges.global.give(['groups:search:content', 'groups:search:users', 'groups:search:tags'], 'registered-users', next); | ||||
| 			}, | ||||
| 			function (next) { | ||||
| 				var guestPrivs = []; | ||||
| 				if (allowGuestSearching) { | ||||
| 					guestPrivs.push('search:content'); | ||||
| 					guestPrivs.push('groups:search:content'); | ||||
| 				} | ||||
| 				if (allowGuestUserSearching) { | ||||
| 					guestPrivs.push('search:users'); | ||||
| 					guestPrivs.push('groups:search:users'); | ||||
| 				} | ||||
| 				guestPrivs.push('search:tags'); | ||||
| 				guestPrivs.push('groups:search:tags'); | ||||
| 				privileges.global.give(guestPrivs, 'guests', next); | ||||
| 			}, | ||||
| 		], callback); | ||||
|   | ||||
| @@ -9,7 +9,7 @@ module.exports = { | ||||
| 		var allowLocalLogin = parseInt(meta.config.allowLocalLogin, 10) !== 0; | ||||
|  | ||||
| 		if (allowLocalLogin) { | ||||
| 			privileges.global.give(['local:login'], 'registered-users', callback); | ||||
| 			privileges.global.give(['groups:local:login'], 'registered-users', callback); | ||||
| 		} else { | ||||
| 			callback(); | ||||
| 		} | ||||
|   | ||||
| @@ -10,17 +10,17 @@ module.exports = { | ||||
| 		var meta = require('../../meta'); | ||||
|  | ||||
| 		var tasks = [ | ||||
| 			async.apply(privileges.global.give, ['view:users', 'view:tags', 'view:groups'], 'registered-users'), | ||||
| 			async.apply(privileges.global.give, ['groups:view:users', 'groups:view:tags', 'groups:view:groups'], 'registered-users'), | ||||
| 		]; | ||||
|  | ||||
| 		if (parseInt(meta.config.privateUserInfo, 10) !== 1) { | ||||
| 			tasks.push(async.apply(privileges.global.give, ['view:users', 'view:groups'], 'guests')); | ||||
| 			tasks.push(async.apply(privileges.global.give, ['view:users', 'view:groups'], 'spiders')); | ||||
| 			tasks.push(async.apply(privileges.global.give, ['groups:view:users', 'groups:view:groups'], 'guests')); | ||||
| 			tasks.push(async.apply(privileges.global.give, ['groups:view:users', 'groups:view:groups'], 'spiders')); | ||||
| 		} | ||||
|  | ||||
| 		if (parseInt(meta.config.privateTagListing, 10) !== 1) { | ||||
| 			tasks.push(async.apply(privileges.global.give, ['view:tags'], 'guests')); | ||||
| 			tasks.push(async.apply(privileges.global.give, ['view:tags'], 'spiders')); | ||||
| 			tasks.push(async.apply(privileges.global.give, ['groups:view:tags'], 'guests')); | ||||
| 			tasks.push(async.apply(privileges.global.give, ['groups:view:tags'], 'spiders')); | ||||
| 		} | ||||
|  | ||||
| 		async.series(tasks, callback); | ||||
|   | ||||
| @@ -8,7 +8,7 @@ module.exports = { | ||||
| 	method: function (callback) { | ||||
| 		var meta = require('../../meta'); | ||||
| 		if (parseInt(meta.config.allowGroupCreation, 10) === 1) { | ||||
| 			privileges.global.give(['groups:create'], 'registered-users', callback); | ||||
| 			privileges.global.give(['groups:group:create'], 'registered-users', callback); | ||||
| 		} else { | ||||
| 			setImmediate(callback); | ||||
| 		} | ||||
|   | ||||
| @@ -26,7 +26,7 @@ module.exports = { | ||||
| 				}, next); | ||||
| 			}, | ||||
| 			function (next) { | ||||
| 				privileges.global.give(['view:users:info'], 'Global Moderators', next); | ||||
| 				privileges.global.give(['groups:view:users:info'], 'Global Moderators', next); | ||||
| 			}, | ||||
| 		], callback); | ||||
| 		function givePrivsToModerators(cid, groupPrefix, callback) { | ||||
|   | ||||
| @@ -29,18 +29,18 @@ module.exports = { | ||||
| 		]); | ||||
|  | ||||
| 		const globalModPrivs = [ | ||||
| 			'chat', | ||||
| 			'upload:post:image', | ||||
| 			'upload:post:file', | ||||
| 			'signature', | ||||
| 			'ban', | ||||
| 			'search:content', | ||||
| 			'search:users', | ||||
| 			'search:tags', | ||||
| 			'view:users', | ||||
| 			'view:tags', | ||||
| 			'view:groups', | ||||
| 			'local:login', | ||||
| 			'groups:chat', | ||||
| 			'groups:upload:post:image', | ||||
| 			'groups:upload:post:file', | ||||
| 			'groups:signature', | ||||
| 			'groups:ban', | ||||
| 			'groups:search:content', | ||||
| 			'groups:search:users', | ||||
| 			'groups:search:tags', | ||||
| 			'groups:view:users', | ||||
| 			'groups:view:tags', | ||||
| 			'groups:view:groups', | ||||
| 			'groups:local:login', | ||||
| 		]; | ||||
|  | ||||
| 		async.waterfall([ | ||||
| @@ -57,7 +57,7 @@ module.exports = { | ||||
| 							givePrivsToModerators(cid, 'groups:', next); | ||||
| 						}, | ||||
| 						function (next) { | ||||
| 							privileges.categories.give(modPrivileges, cid, ['Global Moderators'], next); | ||||
| 							privileges.categories.give(modPrivileges.map(p => 'groups:' + p), cid, ['Global Moderators'], next); | ||||
| 						}, | ||||
| 					], next); | ||||
| 				}, next); | ||||
|   | ||||
| @@ -14,7 +14,7 @@ module.exports = { | ||||
| 		} | ||||
|  | ||||
| 		// Remove `upload:post:file` privilege for all groups | ||||
| 		await privileges.categories.rescind(['upload:post:file'], 0, ['guests', 'registered-users', 'Global Moderators']); | ||||
| 		await privileges.categories.rescind(['groups:upload:post:file'], 0, ['guests', 'registered-users', 'Global Moderators']); | ||||
|  | ||||
| 		// Clean up the old option from the config hash | ||||
| 		await db.deleteObjectField('config', 'allowFileUploads'); | ||||
|   | ||||
| @@ -13,7 +13,7 @@ module.exports = { | ||||
| 		batch.processSortedSet('categories:cid', function (cids, next) { | ||||
| 			async.eachSeries(cids, function (cid, next) { | ||||
| 				progress.incr(); | ||||
| 				privileges.categories.give(['topics:tag'], cid, 'registered-users', next); | ||||
| 				privileges.categories.give(['groups:topics:tag'], cid, 'registered-users', next); | ||||
| 			}, next); | ||||
| 		}, { | ||||
| 			progress: progress, | ||||
|   | ||||
| @@ -22,10 +22,10 @@ module.exports = { | ||||
|  | ||||
| 					var privs = []; | ||||
| 					if (groupPrivileges['groups:upload:post:image']) { | ||||
| 						privs.push('upload:post:image'); | ||||
| 						privs.push('groups:upload:post:image'); | ||||
| 					} | ||||
| 					if (groupPrivileges['groups:upload:post:file']) { | ||||
| 						privs.push('upload:post:file'); | ||||
| 						privs.push('groups:upload:post:file'); | ||||
| 					} | ||||
| 					privileges.global.give(privs, 'registered-users', next); | ||||
| 				}); | ||||
|   | ||||
| @@ -15,7 +15,7 @@ module.exports = { | ||||
| 				return callback(err); | ||||
| 			} | ||||
| 			async.eachSeries(cids, function (cid, next) { | ||||
| 				privileges.categories.give(['posts:upvote', 'posts:downvote'], cid, 'registered-users', next); | ||||
| 				privileges.categories.give(['groups:posts:upvote', 'groups:posts:downvote'], cid, 'registered-users', next); | ||||
| 			}, callback); | ||||
| 		}); | ||||
| 	}, | ||||
|   | ||||
| @@ -6,6 +6,6 @@ module.exports = { | ||||
| 	name: 'Give registered users signature privilege', | ||||
| 	timestamp: Date.UTC(2018, 1, 28), | ||||
| 	method: function (callback) { | ||||
| 		privileges.global.give(['signature'], 'registered-users', callback); | ||||
| 		privileges.global.give(['groups:signature'], 'registered-users', callback); | ||||
| 	}, | ||||
| }; | ||||
|   | ||||
| @@ -22,13 +22,13 @@ module.exports = { | ||||
|  | ||||
| 					var privs = []; | ||||
| 					if (groupPrivileges['groups:find']) { | ||||
| 						privs.push('find'); | ||||
| 						privs.push('groups:find'); | ||||
| 					} | ||||
| 					if (groupPrivileges['groups:read']) { | ||||
| 						privs.push('read'); | ||||
| 						privs.push('groups:read'); | ||||
| 					} | ||||
| 					if (groupPrivileges['groups:topics:read']) { | ||||
| 						privs.push('topics:read'); | ||||
| 						privs.push('groups:topics:read'); | ||||
| 					} | ||||
|  | ||||
| 					privileges.categories.give(privs, cid, 'spiders', next); | ||||
|   | ||||
| @@ -330,13 +330,13 @@ describe('authentication', function () { | ||||
| 	}); | ||||
|  | ||||
| 	it('should fail to login if local login is disabled', function (done) { | ||||
| 		privileges.global.rescind(['local:login'], 'registered-users', function (err) { | ||||
| 		privileges.global.rescind(['groups:local:login'], 'registered-users', function (err) { | ||||
| 			assert.ifError(err); | ||||
| 			loginUser('regular', 'regularpwd', function (err, response, body) { | ||||
| 				assert.ifError(err); | ||||
| 				assert.equal(response.statusCode, 403); | ||||
| 				assert.equal(body, '[[error:local-login-disabled]]'); | ||||
| 				privileges.global.give(['local:login'], 'registered-users', done); | ||||
| 				privileges.global.give(['groups:local:login'], 'registered-users', done); | ||||
| 			}); | ||||
| 		}); | ||||
| 	}); | ||||
|   | ||||
| @@ -689,13 +689,13 @@ describe('Controllers', function () { | ||||
| 	}); | ||||
|  | ||||
| 	it('should load users search page', function (done) { | ||||
| 		privileges.global.give(['search:users'], 'guests', function (err) { | ||||
| 		privileges.global.give(['groups:search:users'], 'guests', function (err) { | ||||
| 			assert.ifError(err); | ||||
| 			request(nconf.get('url') + '/users?term=bar§ion=sort-posts', function (err, res, body) { | ||||
| 				assert.ifError(err); | ||||
| 				assert.equal(res.statusCode, 200); | ||||
| 				assert(body); | ||||
| 				privileges.global.rescind(['search:users'], 'guests', done); | ||||
| 				privileges.global.rescind(['groups:search:users'], 'guests', done); | ||||
| 			}); | ||||
| 		}); | ||||
| 	}); | ||||
| @@ -1344,13 +1344,13 @@ describe('Controllers', function () { | ||||
| 		}); | ||||
|  | ||||
| 		it('should return 401 if user does not have view:users privilege', function (done) { | ||||
| 			privileges.global.rescind(['view:users'], 'guests', function (err) { | ||||
| 			privileges.global.rescind(['groups:view:users'], 'guests', function (err) { | ||||
| 				assert.ifError(err); | ||||
| 				request(nconf.get('url') + '/api/user/foo', { json: true }, function (err, res, body) { | ||||
| 					assert.ifError(err); | ||||
| 					assert.equal(res.statusCode, 401); | ||||
| 					assert.equal(body, 'not-authorized'); | ||||
| 					privileges.global.give(['view:users'], 'guests', done); | ||||
| 					privileges.global.give(['groups:view:users'], 'guests', done); | ||||
| 				}); | ||||
| 			}); | ||||
| 		}); | ||||
| @@ -1624,12 +1624,12 @@ describe('Controllers', function () { | ||||
| 		}); | ||||
|  | ||||
| 		it('should 403 if user does not have read privilege', function (done) { | ||||
| 			privileges.categories.rescind(['topics:read'], category.cid, 'registered-users', function (err) { | ||||
| 			privileges.categories.rescind(['groups:topics:read'], category.cid, 'registered-users', function (err) { | ||||
| 				assert.ifError(err); | ||||
| 				request(nconf.get('url') + '/api/post/' + pid, { jar: jar }, function (err, res) { | ||||
| 					assert.ifError(err); | ||||
| 					assert.equal(res.statusCode, 403); | ||||
| 					privileges.categories.give(['topics:read'], category.cid, 'registered-users', done); | ||||
| 					privileges.categories.give(['groups:topics:read'], category.cid, 'registered-users', done); | ||||
| 				}); | ||||
| 			}); | ||||
| 		}); | ||||
| @@ -1916,7 +1916,7 @@ describe('Controllers', function () { | ||||
| 		it('should return 401 if not allowed to read', function (done) { | ||||
| 			categories.create({ name: 'hidden' }, function (err, category) { | ||||
| 				assert.ifError(err); | ||||
| 				privileges.categories.rescind(['read'], category.cid, 'guests', function (err) { | ||||
| 				privileges.categories.rescind(['groups:read'], category.cid, 'guests', function (err) { | ||||
| 					assert.ifError(err); | ||||
| 					request(nconf.get('url') + '/api/category/' + category.slug, function (err, res) { | ||||
| 						assert.ifError(err); | ||||
|   | ||||
| @@ -91,14 +91,14 @@ describe('feeds', function () { | ||||
| 	}); | ||||
|  | ||||
| 	it('should redirect if we do not have read privilege', function (done) { | ||||
| 		privileges.categories.rescind(['topics:read'], cid, 'guests', function (err) { | ||||
| 		privileges.categories.rescind(['groups:topics:read'], cid, 'guests', function (err) { | ||||
| 			assert.ifError(err); | ||||
| 			request(nconf.get('url') + '/topic/' + tid + '.rss', function (err, res, body) { | ||||
| 				assert.ifError(err); | ||||
| 				assert.equal(res.statusCode, 200); | ||||
| 				assert(body); | ||||
| 				assert(body.includes('Login to your account')); | ||||
| 				privileges.categories.give(['topics:read'], cid, 'guests', done); | ||||
| 				privileges.categories.give(['groups:topics:read'], cid, 'guests', done); | ||||
| 			}); | ||||
| 		}); | ||||
| 	}); | ||||
| @@ -112,14 +112,14 @@ describe('feeds', function () { | ||||
| 	}); | ||||
|  | ||||
| 	it('should redirect if we do not have read privilege', function (done) { | ||||
| 		privileges.categories.rescind(['read'], cid, 'guests', function (err) { | ||||
| 		privileges.categories.rescind(['groups:read'], cid, 'guests', function (err) { | ||||
| 			assert.ifError(err); | ||||
| 			request(nconf.get('url') + '/category/' + cid + '.rss', function (err, res, body) { | ||||
| 				assert.ifError(err); | ||||
| 				assert.equal(res.statusCode, 200); | ||||
| 				assert(body); | ||||
| 				assert(body.includes('Login to your account')); | ||||
| 				privileges.categories.give(['read'], cid, 'guests', done); | ||||
| 				privileges.categories.give(['groups:read'], cid, 'guests', done); | ||||
| 			}); | ||||
| 		}); | ||||
| 	}); | ||||
| @@ -146,7 +146,7 @@ describe('feeds', function () { | ||||
|  | ||||
|  | ||||
| 		it('should not allow access if uid or token is missing', function (done) { | ||||
| 			privileges.categories.rescind(['read'], cid, 'guests', function (err) { | ||||
| 			privileges.categories.rescind(['groups:read'], cid, 'guests', function (err) { | ||||
| 				assert.ifError(err); | ||||
| 				async.parallel({ | ||||
| 					test1: function (next) { | ||||
| @@ -189,7 +189,7 @@ describe('feeds', function () { | ||||
| 		}); | ||||
|  | ||||
| 		it('should not allow access if token is correct but has no privilege', function (done) { | ||||
| 			privileges.categories.rescind(['read'], cid, 'registered-users', function (err) { | ||||
| 			privileges.categories.rescind(['groups:read'], cid, 'registered-users', function (err) { | ||||
| 				assert.ifError(err); | ||||
| 				request(nconf.get('url') + '/category/' + cid + '.rss?uid=' + fooUid + '&token=' + rssToken, { }, function (err, res, body) { | ||||
| 					assert.ifError(err); | ||||
|   | ||||
| @@ -655,7 +655,7 @@ describe('Flags', function () { | ||||
| 			it('should not allow flagging post in private category', async function () { | ||||
| 				const category = await Categories.create({ name: 'private category' }); | ||||
|  | ||||
| 				await Privileges.categories.rescind(['topics:read'], category.cid, 'registered-users'); | ||||
| 				await Privileges.categories.rescind(['groups:topics:read'], category.cid, 'registered-users'); | ||||
| 				const result = await Topics.post({ | ||||
| 					cid: category.cid, | ||||
| 					uid: adminUid, | ||||
|   | ||||
| @@ -579,7 +579,7 @@ describe('Groups', function () { | ||||
| 					Groups.create({ name: groupName }, next); | ||||
| 				}, | ||||
| 				function (groupData, next) { | ||||
| 					privileges.categories.give(['topics:create'], cid, groupName, next); | ||||
| 					privileges.categories.give(['groups:topics:create'], cid, groupName, next); | ||||
| 				}, | ||||
| 				function (next) { | ||||
| 					Groups.isMember(groupName, 'cid:1:privileges:groups:topics:create', next); | ||||
|   | ||||
| @@ -213,11 +213,12 @@ async function setupDefaultConfigs(meta) { | ||||
| async function giveDefaultGlobalPrivileges() { | ||||
| 	const privileges = require('../../src/privileges'); | ||||
| 	await privileges.global.give([ | ||||
| 		'chat', 'upload:post:image', 'signature', 'search:content', | ||||
| 		'search:users', 'search:tags', 'local:login', 'view:users', 'view:tags', 'view:groups', | ||||
| 		'groups:chat', 'groups:upload:post:image', 'groups:signature', 'groups:search:content', | ||||
| 		'groups:search:users', 'groups:search:tags', 'groups:local:login', 'groups:view:users', | ||||
| 		'groups:view:tags', 'groups:view:groups', | ||||
| 	], 'registered-users'); | ||||
| 	await privileges.global.give([ | ||||
| 		'view:users', 'view:tags', 'view:groups', | ||||
| 		'groups:view:users', 'groups:view:tags', 'groups:view:groups', | ||||
| 	], 'guests'); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -160,13 +160,13 @@ describe('Post\'s', function () { | ||||
|  | ||||
| 	describe('voting', function () { | ||||
| 		it('should fail to upvote post if group does not have upvote permission', function (done) { | ||||
| 			privileges.categories.rescind(['posts:upvote', 'posts:downvote'], cid, 'registered-users', function (err) { | ||||
| 			privileges.categories.rescind(['groups:posts:upvote', 'groups:posts:downvote'], cid, 'registered-users', function (err) { | ||||
| 				assert.ifError(err); | ||||
| 				socketPosts.upvote({ uid: voterUid }, { pid: postData.pid, room_id: 'topic_1' }, function (err) { | ||||
| 					assert.equal(err.message, '[[error:no-privileges]]'); | ||||
| 					socketPosts.downvote({ uid: voterUid }, { pid: postData.pid, room_id: 'topic_1' }, function (err) { | ||||
| 						assert.equal(err.message, '[[error:no-privileges]]'); | ||||
| 						privileges.categories.give(['posts:upvote', 'posts:downvote'], cid, 'registered-users', function (err) { | ||||
| 						privileges.categories.give(['groups:posts:upvote', 'groups:posts:downvote'], cid, 'registered-users', function (err) { | ||||
| 							assert.ifError(err); | ||||
| 							done(); | ||||
| 						}); | ||||
| @@ -320,7 +320,7 @@ describe('Post\'s', function () { | ||||
| 				tid = topicPostData.topicData.tid; | ||||
| 				mainPid = topicPostData.postData.pid; | ||||
| 				replyPid = replyData.pid; | ||||
| 				privileges.categories.give(['purge'], cid, 'registered-users', done); | ||||
| 				privileges.categories.give(['groups:purge'], cid, 'registered-users', done); | ||||
| 			}); | ||||
| 		}); | ||||
|  | ||||
| @@ -351,7 +351,7 @@ describe('Post\'s', function () { | ||||
| 					groups.join('Global Moderators', uid, next); | ||||
| 				}, | ||||
| 				function (next) { | ||||
| 					privileges.categories.rescind(['posts:view_deleted'], cid, 'Global Moderators', next); | ||||
| 					privileges.categories.rescind(['groups:posts:view_deleted'], cid, 'Global Moderators', next); | ||||
| 				}, | ||||
| 				function (next) { | ||||
| 					helpers.loginUser('global mod', '123456', function (err, _jar) { | ||||
| @@ -361,7 +361,7 @@ describe('Post\'s', function () { | ||||
| 						request(nconf.get('url') + '/api/topic/' + tid, { jar: jar, json: true }, function (err, res, body) { | ||||
| 							assert.ifError(err); | ||||
| 							assert.equal(body.posts[1].content, '[[topic:post_is_deleted]]'); | ||||
| 							privileges.categories.give(['posts:view_deleted'], cid, 'Global Moderators', next); | ||||
| 							privileges.categories.give(['groups:posts:view_deleted'], cid, 'Global Moderators', next); | ||||
| 						}); | ||||
| 					}); | ||||
| 				}, | ||||
| @@ -448,7 +448,7 @@ describe('Post\'s', function () { | ||||
| 				}, function (err, data) { | ||||
| 					assert.ifError(err); | ||||
| 					replyPid = data.pid; | ||||
| 					privileges.categories.give(['posts:edit'], cid, 'registered-users', done); | ||||
| 					privileges.categories.give(['groups:posts:edit'], cid, 'registered-users', done); | ||||
| 				}); | ||||
| 			}); | ||||
| 		}); | ||||
| @@ -783,7 +783,7 @@ describe('Post\'s', function () { | ||||
| 			}, function (err, postData) { | ||||
| 				assert.ifError(err); | ||||
| 				pid = postData.pid; | ||||
| 				privileges.categories.rescind(['topics:read'], cid, 'guests', done); | ||||
| 				privileges.categories.rescind(['groups:topics:read'], cid, 'guests', done); | ||||
| 			}); | ||||
| 		}); | ||||
|  | ||||
|   | ||||
| @@ -107,7 +107,7 @@ describe('Search', function () { | ||||
| 	it('should search term in titles and posts', function (done) { | ||||
| 		var meta = require('../src/meta'); | ||||
| 		var qs = '/api/search?term=cucumber&in=titlesposts&categories[]=' + cid1 + '&by=phoebe&replies=1&repliesFilter=atleast&sortBy=timestamp&sortDirection=desc&showAs=posts'; | ||||
| 		privileges.global.give(['search:content'], 'guests', function (err) { | ||||
| 		privileges.global.give(['groups:search:content'], 'guests', function (err) { | ||||
| 			assert.ifError(err); | ||||
| 			request({ | ||||
| 				url: nconf.get('url') + qs, | ||||
| @@ -120,7 +120,7 @@ describe('Search', function () { | ||||
| 				assert.equal(body.posts[0].pid, post1Data.pid); | ||||
| 				assert.equal(body.posts[0].uid, phoebeUid); | ||||
|  | ||||
| 				privileges.global.rescind(['search:content'], 'guests', done); | ||||
| 				privileges.global.rescind(['groups:search:content'], 'guests', done); | ||||
| 			}); | ||||
| 		}); | ||||
| 	}); | ||||
| @@ -230,7 +230,7 @@ describe('Search', function () { | ||||
|  | ||||
| 	it('should return json search data with no categories', function (done) { | ||||
| 		var qs = '/api/search?term=cucumber&in=titlesposts&searchOnly=1'; | ||||
| 		privileges.global.give(['search:content'], 'guests', function (err) { | ||||
| 		privileges.global.give(['groups:search:content'], 'guests', function (err) { | ||||
| 			assert.ifError(err); | ||||
| 			request({ | ||||
| 				url: nconf.get('url') + qs, | ||||
| @@ -244,7 +244,7 @@ describe('Search', function () { | ||||
| 				assert(body.hasOwnProperty('posts')); | ||||
| 				assert(!body.hasOwnProperty('categories')); | ||||
|  | ||||
| 				privileges.global.rescind(['search:content'], 'guests', done); | ||||
| 				privileges.global.rescind(['groups:search:content'], 'guests', done); | ||||
| 			}); | ||||
| 		}); | ||||
| 	}); | ||||
|   | ||||
| @@ -553,12 +553,12 @@ describe('Topic\'s', function () { | ||||
| 					groups.join('Global Moderators', uid, next); | ||||
| 				}, | ||||
| 				function (next) { | ||||
| 					privileges.categories.rescind(['purge'], categoryObj.cid, 'Global Moderators', next); | ||||
| 					privileges.categories.rescind(['groups:purge'], categoryObj.cid, 'Global Moderators', next); | ||||
| 				}, | ||||
| 				function (next) { | ||||
| 					socketTopics.purge({ uid: globalModUid }, { tids: [tid], cid: categoryObj.cid }, function (err) { | ||||
| 						assert.equal(err.message, '[[error:no-privileges]]'); | ||||
| 						privileges.categories.give(['purge'], categoryObj.cid, 'Global Moderators', next); | ||||
| 						privileges.categories.give(['groups:purge'], categoryObj.cid, 'Global Moderators', next); | ||||
| 					}); | ||||
| 				}, | ||||
| 			], done); | ||||
| @@ -979,13 +979,13 @@ describe('Topic\'s', function () { | ||||
|  | ||||
| 		it('should 401 if not allowed to read as guest', function (done) { | ||||
| 			var privileges = require('../src/privileges'); | ||||
| 			privileges.categories.rescind(['topics:read'], topicData.cid, 'guests', function (err) { | ||||
| 			privileges.categories.rescind(['groups:topics:read'], topicData.cid, 'guests', function (err) { | ||||
| 				assert.ifError(err); | ||||
| 				request(nconf.get('url') + '/api/topic/' + topicData.slug, function (err, response, body) { | ||||
| 					assert.ifError(err); | ||||
| 					assert.equal(response.statusCode, 401); | ||||
| 					assert(body); | ||||
| 					privileges.categories.give(['topics:read'], topicData.cid, 'guests', done); | ||||
| 					privileges.categories.give(['groups:topics:read'], topicData.cid, 'guests', done); | ||||
| 				}); | ||||
| 			}); | ||||
| 		}); | ||||
| @@ -1428,7 +1428,7 @@ describe('Topic\'s', function () { | ||||
| 				}, | ||||
| 				function (category, next) { | ||||
| 					privateCid = category.cid; | ||||
| 					privileges.categories.rescind(['topics:read'], category.cid, 'registered-users', next); | ||||
| 					privileges.categories.rescind(['groups:topics:read'], category.cid, 'registered-users', next); | ||||
| 				}, | ||||
| 				function (next) { | ||||
| 					topics.post({ uid: adminUid, title: 'topic in private category', content: 'registered-users cant see this', cid: privateCid }, next); | ||||
| @@ -1457,7 +1457,7 @@ describe('Topic\'s', function () { | ||||
| 				}, | ||||
| 				function (category, next) { | ||||
| 					ignoredCid = category.cid; | ||||
| 					privileges.categories.rescind(['topics:read'], category.cid, 'registered-users', next); | ||||
| 					privileges.categories.rescind(['groups:topics:read'], category.cid, 'registered-users', next); | ||||
| 				}, | ||||
| 				function (next) { | ||||
| 					topics.post({ uid: adminUid, title: 'topic in private category', content: 'registered-users cant see this', cid: ignoredCid }, next); | ||||
| @@ -2036,7 +2036,7 @@ describe('Topic\'s', function () { | ||||
| 		}); | ||||
|  | ||||
| 		it('should fail to post if user does not have tag privilege', function (done) { | ||||
| 			privileges.categories.rescind(['topics:tag'], cid, 'registered-users', function (err) { | ||||
| 			privileges.categories.rescind(['groups:topics:tag'], cid, 'registered-users', function (err) { | ||||
| 				assert.ifError(err); | ||||
| 				topics.post({ uid: uid, cid: cid, tags: ['tag1'], title: 'topic with tags', content: 'some content here' }, function (err) { | ||||
| 					assert.equal(err.message, '[[error:no-privileges]]'); | ||||
| @@ -2057,7 +2057,7 @@ describe('Topic\'s', function () { | ||||
| 		}); | ||||
|  | ||||
| 		it('should be able to edit topic and add tags if allowed', function (done) { | ||||
| 			privileges.categories.give(['topics:tag'], cid, 'registered-users', function (err) { | ||||
| 			privileges.categories.give(['groups:topics:tag'], cid, 'registered-users', function (err) { | ||||
| 				assert.ifError(err); | ||||
| 				topics.post({ uid: uid, cid: cid, tags: ['tag1'], title: 'topic with tags', content: 'some content here' }, function (err, result) { | ||||
| 					assert.ifError(err); | ||||
|   | ||||
| @@ -67,7 +67,7 @@ describe('Upload Controllers', function () { | ||||
| 				assert.ifError(err); | ||||
| 				jar = _jar; | ||||
| 				csrf_token = _csrf_token; | ||||
| 				privileges.global.give(['upload:post:file'], 'registered-users', done); | ||||
| 				privileges.global.give(['groups:upload:post:file'], 'registered-users', done); | ||||
| 			}); | ||||
| 		}); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user