How to narrow scopes for Google Apps Script to specific files - google-apps-script

Main Issue:
I have two Google spreadsheets: a template and a master.
The template is sent out to people to make a copy of, fill in, and then I have a script that copies their tab to the master spreadsheet.
Currently the authorization is very broad- to view, edit, delete all of the users' spreadsheets. Since only two files are involved, I'd like to narrow the scope to just those two, mainly because the authorization process looks sketchy to the users right now.
Is there a way to limit scope to specific spreadsheets vs all spreadsheets?
What I've found/researched so far:
It seems that you can easily only limit scope to the current file, or demand access to all spreadsheets.
I've found two methods:
1) current only
Add this to the top of the script:
/**
* #OnlyCurrentDoc
*/
This means that I can't copy the tab to the master spreadsheet.
2) Set Explicit Scopes
Go into the manifest as described here:
https://developers.google.com/apps-script/concepts/scopes
Seems that this also only allows for current file only or full spreadsheet access.
Similar Questions:
Others have asked similar questions but haven't gotten an answer to this specific issue where there are multiple specific files in question.
How to use narrower Google Apps Script Authorization Scope when accessing file from own drive
How to narrow down the auth/drive scope for a google apps script?
Code and potential ideas:
I haven't tried whitelisting- could that help? Would I whitelist the master spreadsheet on the template?
The authorization when I tried '#OnlyCurrentDoc' defines the permission as 'View and manage spreadsheets that this application has been installed in'. Can I install this application in my master spreadsheet and have them talk? Any ideas?
//this is pretty much the only applicable code:
var admin_ss = SpreadsheetApp.openById([ID]);
var this_ss = SpreadsheetApp.getActiveSpreadsheet();

Possible approaches:
CurrentOnly scope:
https://www.googleapis.com/auth/spreadsheets.currentonly
You can install it in many sheets as a add-on by publishing your script OR
Publish a web-app in the master spreadsheet. You can create a doPost() function to receive and authorize any request to write to the master spreadsheet from the slave spreadsheets.
Drive.file scope:
https://www.googleapis.com/auth/drive.file
You can use this scope to access any file created/opened with this project.
You can create a web app to execute as the user and to create a slave spreadsheet from the master spreadsheet. Master needs to be shared to the user OR
Use Google picker/web app to make the user manually choose/open the master/slave spreadsheet to provide access to the app to only those sheets.
References:
Add on current only scope
Web app guide
OAuth scopes list
Google Picker

Related

Authorization scopes for spreadsheets

I have created a standalone Google Apps Script (it does not belong to any document). The script get triggered automatically at some fixed intervals. This script
creates a couple of folder (if they don't exist)
creates a Google spreadsheet (if it doesn exist). Read said
spreadsheet.
update calendar events
I noticed that when I first run it, it asked for permissions to read, delete all Google Drive items, all spreadsheets and all calendar events
I work on tailoring the scopes required and at least Google Drive does not have those broad permissions. I am still unable to reduce the scope for Google spreadsheet (And also calendar).
An expert #TheMaster made a post some years but is not exactly the same case.
I tried changing the scopes but the editor complained and requested that to use openById I need to change the scopes back
Ok, I ended up changing how my solution was structured.
Before Script lived outside the spreadsheet
Now script lives inside the spreadsheet. I am now know doing scopes directly on the manifest and using onlycurrentdoc.
From https://developers.google.com/apps-script/guides/services/authorization#manual_authorization_scopes_for_sheets_docs_slides_and_forms
Manual authorization scopes for Sheets, Docs, Slides, and Forms
If you're building an add-on or other script that uses the Spreadsheet service, Document service, Slides service, or Forms service, you can force the authorization dialog to ask only for access to files in which the add-on or script is used, rather than all of a user's spreadsheets, documents, or forms. To do so, include the following JsDoc annotation in a file-level comment:
/**
* #OnlyCurrentDoc
*/
Besides the above, look at each method reference documentation at the https://developers.google.com/apps-script/reference. At the bottom of the corresponding section you will find a list of the scopes that might be u sed for each method. Some methods have more than one scope, choose the one that better fits what you need.
Related
How to narrow scopes for Google Apps Script to specific files
References
https://developers.google.com/apps-script/guides/services/authorization
https://developers.google.com/identity/protocols/oauth2/scopes

How can I set an app script on a Google Sheet via the API?

Is there a way to set an App Script on a new Google Sheet via the Google Sheets API? We use pygsheets as our Python API Client for Google Sheets. Since we are using the onSelectionChange trigger to populate certain cells with a date, we would like to setup the app script after we have populated rows in the spreadsheet.
The Google Sheets API doesn't have a method to do this. You can use the Apps Script API instead, but there are a few caveats which may or may not work with your use case:
You can use projects.create to create a new Apps Script project and attach it to a Sheets file by specifying the parentId field, which is the Sheet's ID. However, there are no methods to attach a preexisting script to a Sheet. You can still use projects.updateContent to add the required script files, though.
You cannot unbind the script once it has been attached.
This API does not work with service accounts, and the user running it needs to explicitly allow it in their settings page. This is for security reasons, since allowing a malicious app to freely write scripts on your account could be catastrophic, but it adds more steps that your users would need to take in order to run your app.

Google doc generated by app script has unexpected owner

Beginner question – I have an app script in a Google Sheet (response sheet from a Google Form) generating Google Docs. It is unexpectedly making me the owner of those docs. The business owner is the owner of the form, sheet, doc template, and shared Google Drive folder where the docs are. She has given me edit access to all. She also is shown as the owner of the app script “project” in the sheet. The app script creates a copy of the template doc in the shared folder, and populates it with data from the form. I am the owner of these new documents, why is that? I am only editor of all the components involved. Can I fix it so that she is the default owner of the new docs?
The newly created documents will be owned by the account that runs the script. This is clear enough when you run the script manually, but it also happens when you run it through an installable trigger. The trigger owner will own the files created while the function runs.
Check who owns the 'formSubmit' trigger.
(From your script editor, view your triggers. The left most column will show who the trigger is owned by.) Since your name is appearing as owner, the trigger is most likely still owned by you.

Enable Google Sheet Protection via Google Script

I have been searching for a solution to a Sheet Protection issue, I have a Sheet that includes automated scripts to write data into the Sheet below from some fields at the top. I want the user to be able to provide the data in the fields at the top and then to run a script that adds the data below. The script to add the data works fine for the owner of the sheet if Protection is enabled, but fails for any user that has Edit rights as the Protection cannot be cleared by script for the data to be written to the bottom of the sheet.
https://developers.googleblog.com/2015/02/control-protected-ranges-and-sheets-in.html
I found this code from a Google blog post a few years ago and have tried variations without success....is this type of approach just not possible with Google Sheets and Google Script ?
Unfortunately, that is not currently possible to run a bound script as the owner without using a workaround. Scripts can only be run as the owner when they use Triggers or when you make a standalone Script Web App. You can see this for more information.
This should bypass fooling around with scripting protection ranges!
The Workaround!
There is a way you can get around this by creating a web app so that your bound script talks to the web app which runs on the spreadsheet. See this answer for more information.
So the process looks like this: User clicks a button that runs a function on a bound script. This function makes a web call to a web app that can run a function as the person who created the script.
I would also recommend you pay attention to a comment by Augustine C:
...you may also find it helpful to have a shared secret key saved in your spreadsheet and then verify it using the backend webapp script, or to perhaps verify that the recipient of the email is, in fact, also an editor of your Google Sheet.

How to share a Google Spreadsheet that utilizes Google App Scripts within a company domain?

I have a seemingly simple problem that seems to get more complicated the more I get into it.
I have one spreadsheet document.
This spreadsheet utilizes a google apps script, that in turn utilizes various APIs: Domains, Sites, Spreadsheets...
To use this spreadsheet I have to take a few steps -
Authorize the spreadsheets. This dialog only comes up if I use the
script editor, otherwise the Spreadsheet fails silently.
Enable Domain API in Editor -> Resources -> Advanced Google Services
Enable Domain API in Google Developer Console to a seemingly hidden
project that is attached to my spreadsheet. The only way I can access this secret page is through the Advanced Google Services menu in step #2.
After getting through these hurdles, the spreadsheet now functions correctly without having to use the Script Editor.
Now I want to share this spreadsheet with other users in my company's domain.
Is there any easy way to do this, or will every single user I share it to have to jump through these hurdles as well?
Am I thinking about this wrong? The documentation states the script is 'attached' to the spreadsheet. But the more I get into it, the more separate these two things seem to be. I can share a spreadsheet - but the script won't function properly. I can publish a 'web app' with the script editor - but it won't come with the spreadsheet.
Any help appreciated
Frusteratingly yours...
Other users will have to have the same domain permissions as you do.
An approach you could take is have all the permissions related work done on a script that is published as a web app that will take url parameters (to trigger tasks), which is run as you and accessible to others.
From there, your original script can call the published url and send instructions via parameters.
https://developers.google.com/apps-script/guides/content