Reputation: 533
Just want to ask if there is a way for a user to use a button with a lock or unlock script even if the permission on Protected Sheets and Ranges is in "View Only" mode? Will using a web app work or it is still impossible?
Upvotes: 0
Views: 1620
Reputation: 19309
A script cannot protect/unprotect a sheet or range if the user executing it doesn't have edit access
to the protected sheet/range.
Trying to do so this result in a message like:
You are trying to edit a protected cell or object. Please contact the spreadsheet owner to remove protection if you need to edit.
In order to avoid the script throwing this exception, it's useful to first check if the user has edit access, using Protection.canEdit().
When you deploy a script as a web app, you can set Execute the app as: Me (that is, the user deploying the web app). If this user has edit access to the protected sheet/range, the web app will be able to unprotect the sheet/range, even if it's accessed by a user who doesn't have edit access.
For example, let's say you have a spreadsheet with a sheet named Sheet1
, which is protected and can only be edited by user #1. In this case, you could have the following doGet
function to unprotect it:
function doGet(e) {
const sheet = SpreadsheetApp.getActive().getSheetByName("Sheet1");
const protection = sheet.getProtections(SpreadsheetApp.ProtectionType.SHEET)[0];
if (protection && protection.canEdit()) {
protection.remove();
}
return ContentService.createTextOutput("Sheet unprotected!");
}
And then, while logged in with user #1, deploy the web app the following way:
Publish > Deploy as web app...
.Execute the app as: Me
.Who has access to the app:
to an audience that will include the other users who should be able to access this.Deploy
.Current web app URL:
.Finally, access this URL with user #2 (which doesn't have edit access to the protected sheet). The sheet will become unprotected.
You could write another function to access this URL programmatically via UrlFetch. See, for example:
function unprotect() {
const url = "WEB_APP_URL";
const options = {
headers: { Authorization: "Bearer " + ScriptApp.getOAuthToken() }
}
UrlFetchApp.fetch(url, options);
}
Accessing this URL via UrlFetch
might require setting scopes explicitly in the manifest file of the script:
"oauthScopes": [
"https://www.googleapis.com/auth/script.external_request",
"https://www.googleapis.com/auth/drive",
"https://www.googleapis.com/auth/spreadsheets"
]
Upvotes: 2