Last active
February 28, 2022 08:41
-
-
Save pfelipm/6e9a6053a7159ec9fb87e91125ace934 to your computer and use it in GitHub Desktop.
Get
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Recursively gets all groups that a given user/group is a member | |
* of, either directly or indirectly, in a GWS domain. | |
* | |
* -OR- | |
* | |
* checks whether user/group is a member of provided group, | |
* both tasks support external users to the domain. | |
* Uses the AdminDirectory advanced service, and should be invoked by domain Admins! | |
* | |
* Article: https://pablofelip.online/google-groups-membership-recursively-appsscript | |
* Pablo Felip (@pfelipm) | |
* | |
* @param {string} userGroupEmail Email of user or group | |
* @param {string} [group] Group to check membership in (optional, if provided, behaviour & returned result are different) | |
* @return {Array|Boolean} Sorted array of group email addresses, empty if no memberships found or TRUE/FALSE | |
*/ | |
function checkMembership(userGroupEmail = '[email protected]', groupEmail) { | |
/** | |
* Helper function to retrieve groups that a given user or group is a direct-member of | |
* @param {string} email Email of user or group | |
* @return {Array] Array of group email addresses | |
*/ | |
const getDirectGroups = (email) => { | |
let token, groups = []; | |
try { | |
do { | |
const response = AdminDirectory.Groups.list({ userKey: email, maxResults: 200, pageToken: token }); | |
if (response.groups) groups = [...groups, ...response.groups.map(group => group.email)]; | |
token = response.token | |
} while (token); | |
} catch (e) { | |
// Error handling here! | |
} | |
return groups; | |
}; | |
console.info(`[START] Finding group memberships for: "${userGroupEmail}"`); | |
const t1 = new Date().getTime(); | |
/** | |
* IIFE that performs a recursive membership search | |
* @param {Array} groups Array of groups to check | |
* @return {Array} Array of group email addresses, can contain duplicates | |
*/ | |
let allGroups = (seekGroups = (groups) => { | |
if (groups.length == 0) { | |
// Base case, we have no problem to solve here! | |
console.info('Empty array of groups to inspect, nothing to do.'); | |
return []; | |
} else if (groups.length == 1) { | |
// [A] general case → complexity reduction [depth] | |
console.info(`Finding memberships for: ${groups[0]}...`); | |
return [groups[0], ...seekGroups(getDirectGroups(groups[0]))]; | |
} else if (groups.length > 1) { | |
// [B] general case → complexity reduction [width] | |
console.info(`Splitting problem → ${groups.length} groups left, ["${groups[0]}", ...rest].`); | |
return [...seekGroups([groups.shift()]), ...seekGroups(groups)]; | |
} | |
})(getDirectGroups(userGroupEmail)); | |
// Remove (possible) duplicates & sort list of group emails | |
allGroups = allGroups.filter((group, index, groups) => groups.indexOf(group) == index).sort(); | |
const t2 = new Date().getTime(); | |
if (!groupEmail) { | |
// Return array of groups that provided user/group is a member of | |
console.info(`[END] "${userGroupEmail}" is a member of ${allGroups.length} groups (${t2 - t1} ms).`, '\n', allGroups); | |
return allGroups; | |
} else { | |
// Return membership to provided group (TRUE/FALSE) | |
const isMember = allGroups.some(group => group == groupEmail); | |
console.info(`[END] "${userGroupEmail}" ${isMember ? 'is a' : 'is not a'} member of "${groupEmail}" (${t2 - t1} ms)`); | |
return isMember; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment