| 
									
										
										
										
											2014-05-14 17:53:23 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-20 22:12:22 -04:00
										 |  |  | const _ = require('lodash'); | 
					
						
							| 
									
										
										
										
											2017-12-20 14:49:20 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-20 22:12:22 -04:00
										 |  |  | const groups = require('../groups'); | 
					
						
							|  |  |  | const user = require('../user'); | 
					
						
							|  |  |  | const plugins = require('../plugins'); | 
					
						
							| 
									
										
										
										
											2014-05-14 17:53:23 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-20 22:12:22 -04:00
										 |  |  | const helpers = module.exports; | 
					
						
							| 
									
										
										
										
											2014-05-14 17:53:23 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-20 22:12:22 -04:00
										 |  |  | const uidToSystemGroup = { | 
					
						
							| 
									
										
										
										
											2018-01-31 15:20:17 -05:00
										 |  |  | 	0: 'guests', | 
					
						
							|  |  |  | 	'-1': 'spiders', | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-20 22:12:22 -04:00
										 |  |  | helpers.isUserAllowedTo = async function (privilege, uid, cid) { | 
					
						
							| 
									
										
										
										
											2016-09-15 14:01:56 +03:00
										 |  |  | 	if (Array.isArray(privilege) && !Array.isArray(cid)) { | 
					
						
							| 
									
										
										
										
											2019-07-20 22:12:22 -04:00
										 |  |  | 		return await isUserAllowedToPrivileges(privilege, uid, cid); | 
					
						
							| 
									
										
										
										
											2016-09-15 14:01:56 +03:00
										 |  |  | 	} else if (Array.isArray(cid) && !Array.isArray(privilege)) { | 
					
						
							| 
									
										
										
										
											2019-07-20 22:12:22 -04:00
										 |  |  | 		return await isUserAllowedToCids(privilege, uid, cid); | 
					
						
							| 
									
										
										
										
											2016-09-15 14:01:56 +03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-07-20 22:12:22 -04:00
										 |  |  | 	throw new Error('[[error:invalid-data]]'); | 
					
						
							| 
									
										
										
										
											2016-09-15 14:01:56 +03:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-20 22:12:22 -04:00
										 |  |  | async function isUserAllowedToCids(privilege, uid, cids) { | 
					
						
							| 
									
										
										
										
											2018-01-31 15:20:17 -05:00
										 |  |  | 	if (parseInt(uid, 10) <= 0) { | 
					
						
							| 
									
										
										
										
											2019-07-20 22:12:22 -04:00
										 |  |  | 		return await isSystemGroupAllowedToCids(privilege, uid, cids); | 
					
						
							| 
									
										
										
										
											2014-07-29 21:51:46 -04:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-20 22:12:22 -04:00
										 |  |  | 	const userKeys = []; | 
					
						
							|  |  |  | 	const groupKeys = []; | 
					
						
							| 
									
										
										
										
											2017-05-25 21:17:20 -04:00
										 |  |  | 	cids.forEach(function (cid) { | 
					
						
							|  |  |  | 		userKeys.push('cid:' + cid + ':privileges:' + privilege); | 
					
						
							|  |  |  | 		groupKeys.push('cid:' + cid + ':privileges:groups:' + privilege); | 
					
						
							| 
									
										
										
										
											2014-05-14 17:53:23 -04:00
										 |  |  | 	}); | 
					
						
							| 
									
										
										
										
											2017-05-25 21:17:20 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-20 22:12:22 -04:00
										 |  |  | 	return await checkIfAllowed(uid, userKeys, groupKeys); | 
					
						
							| 
									
										
										
										
											2016-09-15 14:01:56 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-20 22:12:22 -04:00
										 |  |  | async function isUserAllowedToPrivileges(privileges, uid, cid) { | 
					
						
							| 
									
										
										
										
											2018-01-31 15:20:17 -05:00
										 |  |  | 	if (parseInt(uid, 10) <= 0) { | 
					
						
							| 
									
										
										
										
											2019-07-20 22:12:22 -04:00
										 |  |  | 		return await isSystemGroupAllowedToPrivileges(privileges, uid, cid); | 
					
						
							| 
									
										
										
										
											2016-09-15 14:01:56 +03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-20 22:12:22 -04:00
										 |  |  | 	const userKeys = []; | 
					
						
							|  |  |  | 	const groupKeys = []; | 
					
						
							| 
									
										
										
										
											2017-05-25 21:17:20 -04:00
										 |  |  | 	privileges.forEach(function (privilege) { | 
					
						
							|  |  |  | 		userKeys.push('cid:' + cid + ':privileges:' + privilege); | 
					
						
							|  |  |  | 		groupKeys.push('cid:' + cid + ':privileges:groups:' + privilege); | 
					
						
							|  |  |  | 	}); | 
					
						
							| 
									
										
										
										
											2016-09-15 14:01:56 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-20 22:12:22 -04:00
										 |  |  | 	return await checkIfAllowed(uid, userKeys, groupKeys); | 
					
						
							| 
									
										
										
										
											2017-05-25 21:17:20 -04:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-09-15 14:01:56 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-20 22:12:22 -04:00
										 |  |  | async function checkIfAllowed(uid, userKeys, groupKeys) { | 
					
						
							|  |  |  | 	const [hasUserPrivilege, hasGroupPrivilege] = await Promise.all([ | 
					
						
							|  |  |  | 		groups.isMemberOfGroups(uid, userKeys), | 
					
						
							|  |  |  | 		groups.isMemberOfGroupsList(uid, groupKeys), | 
					
						
							|  |  |  | 	]); | 
					
						
							|  |  |  | 	return userKeys.map((key, index) => hasUserPrivilege[index] || hasGroupPrivilege[index]); | 
					
						
							| 
									
										
										
										
											2016-09-15 14:01:56 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-20 22:12:22 -04:00
										 |  |  | helpers.isUsersAllowedTo = async function (privilege, uids, cid) { | 
					
						
							|  |  |  | 	const [hasUserPrivilege, hasGroupPrivilege] = await Promise.all([ | 
					
						
							|  |  |  | 		groups.isMembers(uids, 'cid:' + cid + ':privileges:' + privilege), | 
					
						
							|  |  |  | 		groups.isMembersOfGroupList(uids, 'cid:' + cid + ':privileges:groups:' + privilege), | 
					
						
							|  |  |  | 	]); | 
					
						
							|  |  |  | 	return uids.map((uid, index) => hasUserPrivilege[index] || hasGroupPrivilege[index]); | 
					
						
							| 
									
										
										
										
											2014-09-09 15:19:57 -04:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-20 22:12:22 -04:00
										 |  |  | async function isSystemGroupAllowedToCids(privilege, uid, cids) { | 
					
						
							| 
									
										
										
										
											2019-05-30 19:30:47 -04:00
										 |  |  | 	const groupKeys = cids.map(cid => 'cid:' + cid + ':privileges:groups:' + privilege); | 
					
						
							| 
									
										
										
										
											2019-07-20 22:12:22 -04:00
										 |  |  | 	return await groups.isMemberOfGroups(uidToSystemGroup[uid], groupKeys); | 
					
						
							| 
									
										
										
										
											2014-07-29 21:51:46 -04:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-05-14 17:53:23 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-20 22:12:22 -04:00
										 |  |  | async function isSystemGroupAllowedToPrivileges(privileges, uid, cid) { | 
					
						
							| 
									
										
										
										
											2019-05-30 19:30:47 -04:00
										 |  |  | 	const groupKeys = privileges.map(privilege => 'cid:' + cid + ':privileges:groups:' + privilege); | 
					
						
							| 
									
										
										
										
											2019-07-20 22:12:22 -04:00
										 |  |  | 	return await groups.isMemberOfGroups(uidToSystemGroup[uid], groupKeys); | 
					
						
							| 
									
										
										
										
											2016-09-15 14:01:56 +03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-12-20 14:49:20 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-20 22:12:22 -04:00
										 |  |  | helpers.getUserPrivileges = async function (cid, hookName, userPrivilegeList) { | 
					
						
							|  |  |  | 	const userPrivileges = await plugins.fireHook(hookName, userPrivilegeList.slice()); | 
					
						
							|  |  |  | 	let memberSets = await groups.getMembersOfGroups(userPrivileges.map(privilege => 'cid:' + cid + ':privileges:' + privilege)); | 
					
						
							|  |  |  | 	memberSets = memberSets.map(function (set) { | 
					
						
							|  |  |  | 		return set.map(uid => parseInt(uid, 10)); | 
					
						
							|  |  |  | 	}); | 
					
						
							| 
									
										
										
										
											2017-12-20 14:49:20 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-20 22:12:22 -04:00
										 |  |  | 	const members = _.uniq(_.flatten(memberSets)); | 
					
						
							|  |  |  | 	const memberData = await user.getUsersFields(members, ['picture', 'username']); | 
					
						
							| 
									
										
										
										
											2017-12-20 14:49:20 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-20 22:12:22 -04:00
										 |  |  | 	memberData.forEach(function (member) { | 
					
						
							|  |  |  | 		member.privileges = {}; | 
					
						
							|  |  |  | 		for (var x = 0, numPrivs = userPrivileges.length; x < numPrivs; x += 1) { | 
					
						
							|  |  |  | 			member.privileges[userPrivileges[x]] = memberSets[x].includes(parseInt(member.uid, 10)); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	}); | 
					
						
							| 
									
										
										
										
											2017-12-20 14:49:20 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-20 22:12:22 -04:00
										 |  |  | 	return memberData; | 
					
						
							| 
									
										
										
										
											2017-12-20 14:49:20 -05:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-20 22:12:22 -04:00
										 |  |  | helpers.getGroupPrivileges = async function (cid, hookName, groupPrivilegeList) { | 
					
						
							|  |  |  | 	const groupPrivileges = await plugins.fireHook(hookName, groupPrivilegeList.slice()); | 
					
						
							|  |  |  | 	const [memberSets, allGroupNames] = await Promise.all([ | 
					
						
							|  |  |  | 		groups.getMembersOfGroups(groupPrivileges.map(privilege => 'cid:' + cid + ':privileges:' + privilege)), | 
					
						
							|  |  |  | 		groups.getGroups('groups:createtime', 0, -1), | 
					
						
							|  |  |  | 	]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	const uniqueGroups = _.uniq(_.flatten(memberSets)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	let groupNames = allGroupNames.filter(groupName => !groupName.includes(':privileges:') && uniqueGroups.includes(groupName)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	groupNames = groups.ephemeralGroups.concat(groupNames); | 
					
						
							|  |  |  | 	moveToFront(groupNames, 'Global Moderators'); | 
					
						
							|  |  |  | 	moveToFront(groupNames, 'registered-users'); | 
					
						
							| 
									
										
										
										
											2017-12-20 14:49:20 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-20 22:12:22 -04:00
										 |  |  | 	const adminIndex = groupNames.indexOf('administrators'); | 
					
						
							|  |  |  | 	if (adminIndex !== -1) { | 
					
						
							|  |  |  | 		groupNames.splice(adminIndex, 1); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	const groupData = await groups.getGroupsFields(groupNames, ['private']); | 
					
						
							|  |  |  | 	const memberData = groupNames.map(function (member, index) { | 
					
						
							|  |  |  | 		const memberPrivs = {}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for (var x = 0, numPrivs = groupPrivileges.length; x < numPrivs; x += 1) { | 
					
						
							|  |  |  | 			memberPrivs[groupPrivileges[x]] = memberSets[x].includes(member); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return { | 
					
						
							|  |  |  | 			name: member, | 
					
						
							|  |  |  | 			privileges: memberPrivs, | 
					
						
							|  |  |  | 			isPrivate: groupData[index] && !!groupData[index].private, | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 	}); | 
					
						
							|  |  |  | 	return memberData; | 
					
						
							| 
									
										
										
										
											2017-12-20 15:19:22 -05:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2018-01-03 13:27:30 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-30 19:30:47 -04:00
										 |  |  | function moveToFront(groupNames, groupToMove) { | 
					
						
							|  |  |  | 	const index = groupNames.indexOf(groupToMove); | 
					
						
							|  |  |  | 	if (index !== -1) { | 
					
						
							|  |  |  | 		groupNames.splice(0, 0, groupNames.splice(index, 1)[0]); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		groupNames.unshift(groupToMove); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-20 22:12:22 -04:00
										 |  |  | helpers.giveOrRescind = async function (method, privileges, cids, groupNames) { | 
					
						
							| 
									
										
										
										
											2018-10-15 13:45:55 -04:00
										 |  |  | 	groupNames = Array.isArray(groupNames) ? groupNames : [groupNames]; | 
					
						
							|  |  |  | 	cids = Array.isArray(cids) ? cids : [cids]; | 
					
						
							| 
									
										
										
										
											2019-07-20 22:12:22 -04:00
										 |  |  | 	for (const groupName of groupNames) { | 
					
						
							|  |  |  | 		const groupKeys = []; | 
					
						
							| 
									
										
										
										
											2019-08-13 14:33:37 -04:00
										 |  |  | 		cids.forEach(cid => { | 
					
						
							|  |  |  | 			privileges.forEach(privilege => { | 
					
						
							| 
									
										
										
										
											2018-10-15 13:45:55 -04:00
										 |  |  | 				groupKeys.push('cid:' + cid + ':privileges:groups:' + privilege); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2019-07-20 22:12:22 -04:00
										 |  |  | 		/* eslint-disable no-await-in-loop */ | 
					
						
							|  |  |  | 		await method(groupKeys, groupName); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-01-03 13:27:30 -05:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2019-07-20 22:12:22 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | require('../promisify')(helpers); |