Created
September 13, 2022 05:42
-
-
Save emmaly/462013df01232122320923b30d8fc7be to your computer and use it in GitHub Desktop.
Google Sheet Protection Maintenance
This file contains hidden or 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
| { | |
| "timeZone": "America/Los_Angeles", | |
| "dependencies": { | |
| "enabledAdvancedServices": [ | |
| { | |
| "userSymbol": "Drive", | |
| "version": "v2", | |
| "serviceId": "drive" | |
| } | |
| ] | |
| }, | |
| "exceptionLogging": "STACKDRIVER", | |
| "runtimeVersion": "V8" | |
| } |
This file contains hidden or 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
| const PROJECTSHEET_FILE_ID = "..........................................."; | |
| const PROJECTSHEET_ADMINSHEET_ID = 123123123; | |
| /** | |
| * @returns {SpreadsheetApp.Spreadsheet} Project Spreadsheet File | |
| */ | |
| function getProjectSheetFile() { | |
| return SpreadsheetApp.openById(PROJECTSHEET_FILE_ID); | |
| } | |
| /** | |
| * @returns {SpreadsheetApp.Sheet} Project Admin Sheet | |
| */ | |
| function getProjectAdminSheet() { | |
| const file = getProjectSheetFile(); | |
| if (!file) throw new Error("Couldn't get the project sheet file."); | |
| return file | |
| .getSheets() | |
| .filter(sheet => sheet.getSheetId() === PROJECTSHEET_ADMINSHEET_ID) | |
| .shift(); | |
| } | |
| /** | |
| * | |
| */ | |
| function setProjectAdmins() { | |
| const driveAdmins = getWorkloadForecastingManagers(); | |
| if (driveAdmins.length === 0) throw new Error("No workload forecasting managers found."); | |
| const adminSheet = getProjectAdminSheet(); | |
| if (!adminSheet) throw new Error("Couldn't get the project admin sheet."); | |
| const file = adminSheet.getParent(); | |
| if (!file) throw new Error("Couldn't get the project sheet file."); | |
| const projectAdminSheetProtection = adminSheet | |
| .getProtections(SpreadsheetApp.ProtectionType.SHEET) | |
| .shift(); | |
| setProtectionEditors(projectAdminSheetProtection, driveAdmins); | |
| [ | |
| ...( | |
| file.getProtections(SpreadsheetApp.ProtectionType.SHEET) | |
| .filter(protection => protection.getRange().getSheet().getSheetId() !== adminSheet.getSheetId()) | |
| ), | |
| ...file.getProtections(SpreadsheetApp.ProtectionType.RANGE), | |
| ] | |
| .filter(protection => !protection.isWarningOnly()) | |
| .forEach(protection => setProtectionEditors(protection, driveAdmins)); | |
| } |
This file contains hidden or 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
| /** | |
| * @param {SpreadsheetApp.Protection} protection - Sheet or Range protection to update. | |
| * @param {string[]|null} editors - List of editors to set for this `Protection`. | |
| */ | |
| function setProtectionEditors(protection, editors) { | |
| if (editors === null) { | |
| // null means empty array in this case... wipe out the editors list in the Protection | |
| editors = []; | |
| } else { | |
| // ensure that the editors array is trimmed and lowercase | |
| editors = editors.map(editor => editor.toLowerCase().trim()); | |
| } | |
| // get the protection's current editors list (as an array of trimmed, lowercase email addresses) | |
| const protectionEditors = protection | |
| .getEditors() | |
| .map(editor => editor.getEmail().toLowerCase().trim()); | |
| // new/missing editors to add to this Protection | |
| const addEditors = editors | |
| .filter(editor => !protectionEditors.includes(editor)); | |
| // unwanted editors to remove from this Protection | |
| const delEditors = protectionEditors | |
| .filter(sheetAdmin => !editors.includes(sheetAdmin)); | |
| // if no changes, return early | |
| if (addEditors.length === 0 && delEditors.length === 0) return; | |
| const sheet = protection.getRange().getSheet(); | |
| const sheetName = sheet.getName(); | |
| const file = sheet.getParent(); | |
| const fileName = file.getName(); | |
| const a1Notation = protection.getRange().getA1Notation(); | |
| const description = protection.getDescription(); | |
| Logger.log( | |
| "****** %s", | |
| fileName, | |
| ); | |
| Logger.log( | |
| "%s: [%s%s%s]", | |
| protection.getProtectionType(), | |
| sheetName, | |
| a1Notation ? "!" : "", | |
| a1Notation, | |
| ); | |
| if (description) Logger.log(" DESC: %s", description); | |
| addEditors.forEach(member => Logger.log( | |
| Utilities.formatString( | |
| "%10s: <%s>", | |
| "adding", | |
| member, | |
| ) | |
| )); | |
| if (addEditors.length > 0) protection.addEditors(addEditors); | |
| delEditors.forEach(member => Logger.log( | |
| Utilities.formatString( | |
| "%10s: <%s>", | |
| "removing", | |
| member, | |
| ) | |
| )); | |
| if (delEditors.length > 0) protection.removeEditors(delEditors); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment