How do I access service account details from main account [google]? - google-apps-script

Context:
I have a service account that updates a Google Sheet on a daily basis and I want to add functionalities to the Sheet by extending it with Apps Script. I developed the script with my own personal account (same I used to create the service account) and it seems I can't access the service-account information when it's making changes to the Spreadsheet. What I mean is that I set up a trigger for changes on the spreadsheet but when I try to verify who made the changes I get a blank string.
Quoting the docs:
The circumstances in which the email address is available vary: for example, the user's email address is not available in any context that allows a script to run without that user's authorization, like a simple onOpen(e) or onEdit(e) trigger, a custom function in Google Sheets
How do I fix this? Is there a different design I should use?

Service accounts are not real users, this can be noted in this documentation. Please note the following:
Service accounts do not belong to your Google Workspace domain, unlike user accounts. If you share Google Workspace assets, like docs or events, with your entire Google Workspace domain, they are not shared with service accounts. Similarly, Google Workspace assets created by a service account are not created in your Google Workspace domain. As a result, your Google Workspace and Cloud Identity admins can't own or manage these assets.
Service accounts do not have passwords, and cannot log in via browsers or cookies.
The triggers that are setup on your script would require them to be logged in to the browser in order to capture the email address, a service account can't do that so that would be the reason why you are unable to gather this information.

Related

Apps Script (Google Sheet) not allowing me to Run Script

I have a fairly simple dataset in a Google Sheet. I created an AutoSort script. I saved it, and when I click "Run," I get the following errors. One from a pop-up, and another from the Execution Log.
Pop-up error:
Authorization required
This project requires your permission to access your data.
*For this error, there is a button to "Review Permissions" and I log in using my google account and then just nothing happens.
Execution Log error:
Warning This project requires access to your Google Account to run. Please try again and allow it this time.
The Owner of this Google Sheet is my personal Gmail account, and I am making these edits and created the script using my business Gmail Admin account. I also tried to access this sheet and run the script USING my personal Gmail account, and received the same error:
Google hasn’t verified this app
The app is requesting access to sensitive info in your Google Account. Until the developer ({mypersonalemail}#gmail.com) verifies this app with Google, you shouldn't use it.
Any insight as to how I can authorize this would be appreciated. It sounds like something small I'm missing.
Also, in my personal email I receive a message with subject:
Review edits to your Apps Script project within your document
and it allows me links to access the worksheet and the script, but I don't see any way to approve the edits, or anything like that.
Expected behavior: What I am expecting is for the script to Run, when I click "Run."
It's not a good idea to mix accounts from different domains, specially when using a free account and a Google Workspace account like you have done because that is the cause of the situation that you are facing.
My hypothesis is that the Google Cloud default project linked to the bounded script is created with the account used to create the project.
If you need that you personal account be the spreadsheet owner the best is to create the script using the personal account, and when needed, create a Google Cloud Standard project (GCSP) using the the personal account. You might try to fix the problem with your spreadsheet and the current Apps Script project by creating a GCSP, as was mentioned previously, by using the account that is the owner of the spreadsheet and linking it to the Apps Script project.
Note: If your script is using sensitive scopes you might have to set the OAuth Consent Screen publishing status to tes and add your Google Workspace account as tester.
Ref: Setting up your OAuth consent screen
Once you have finished the setup of your Google Apps Script project you should be able to use your Google Workspace account to update and run the Apps Script code but any new deployment and new version should be done using your personal account.
If you have access to Shared Drives and are allowed to use them for your spreasheet, consider to move it to a Shared Drive as this will make a lot easier to manage your script.

User access request when GAS run as the user

In a GAS published as webapp bound to a spreadsheet in a public (free) Gmail account, I'm compiling information from many unrelated users into that spreadsheet, where any Gmail user account can access the webapp.
But when script is run as the user, the user can access the app (after user grants permissions to the app), but it stops at point where script accesses the spreadsheet. The user is told to request access. I have to "share" the spreadsheet to the user for the app to function when run as that user, but that is problematic--too many potential users.
If another version of the script is run instead under my account, then user has access to the webapp, but the script cannot access the user's Gmail address. Big problem because the webapp must have the user's Gmail address for security/application access controls.
(The webapp is in development and Google "approval" has not yet been sought.)
How do I have a webapp (a) that modifies content in a central spreadsheet, (b) that any Gmail user can access, (c) where the script has access to Session.getActiveUser().getEmail(), and (d) the user does not need to have edit permissions for that central spreadsheet? The only user-account information that the script needs is the user Gmail address--again for application access control and security. (Since Google provides me a link that gives anyone full access to the spreadsheet (if they also have its URL), can't I give the bound script access to the spreadsheet when run under any Gmail account, where the integrity of the spreadsheet content is managed through the app's functions and internal access controls?)
If there is no solution except to run the webapp under the user's Gmail account and give that user edit rights to the spreadsheet, would that create significant risk (where I don't intentionally/overtly disclose the spreadsheet's URL) that a user could access and alter the spreadsheet beyond the insert/edit functions performed by the webapp? If that risk is low, is there a function I could use in the webapp to automatically grant spreadsheet edit rights to a Gmail account when its Gmail address is pre-registered in the user list for the webapp?
Thank you!
Let me start with c): there is no way to make that Session.getActiveUser().getEmail() works for free Google accounts (i.e. gmail.com accounts) other than for the container / script owner.
Regarding a) b) and d) you might use the Google Sheets API making the calls to it by using UrlFetch Service and a service account instead of the Spreadsheet Service or the Advanced Sheets Service.
Regarding allowing anyone to edit a central spreadsheet, once they open it either by using the Google Sheets apps or by means a web app, they will be able to find the spreadsheet in Google Drive > Shared with me among other places... IMHO the risk in terms of how likely is to have issues is big but in terms of the the impact depends on several factors, i.e. some changes might be reverted by using the version history but spreadsheet might become corrupted. If you have not used Google Sheets version history intensively the best is to get deeply familiar with it before relying on it as a backup / disaster recovery main tool .
From https://developers.google.com/apps-script/reference/base/session#getactiveuser
getActiveUser()
Gets information about the current user. If security policies do not allow access to the user's identity, User.getEmail() returns a blank string. The circumstances in which the email address is available vary: for example, the user's email address is not available in any context that allows a script to run without that user's authorization, like a simple onOpen(e) or onEdit(e) trigger, a custom function in Google Sheets, or a web app deployed to "execute as me" (that is, authorized by the developer instead of the user). However, these restrictions generally do not apply if the developer runs the script themselves or belongs to the same Google Workspace domain as the user.
Related
Use Apps Script URLFetchApp to access Google Datastore Data
Google Service Accounts / API - I keep getting the Error: Access not granted or expired. (line 454, file "Service")

How to change email signature via google form with data from google directory

I am using a Google Apps Script to change the signature of each user with personal data which is accessed via Directory API. Therefore I have a Service account with Domain Wide Delegation, which impersonates with an admin account to get all the users and their data and then impersonates which each and every user to change the signature via GmailAPI.
However now in addition I want to provide a Google Form for each user where the user can add additional information to its signature and set it. The script will need the users information from the Directory but I was wondering if the same approach with impersonating is needed.
With The Apps Script advanced Gmail Service it is possible to set the signature but I did not find a way to access the users data in the Google Directory of the specific user which is sending the form.
If I a service account is needed for that I was wondering where to store the access credentials for that? I don't want is be accessible by every user.

Google apps script authorisation by admin for all users of a domain

I have a timesheet application for employees of my company. I am not the admin. The application is a google apps script which takes the time sheet inputs and then writes them to a spreadsheet on my google drive. When I try to publish the app to users to run under their own login (company domain maintained by google mail), it states that "Users will be asked to authorize the script." Which means I have to give them the right to view the script. I only want them to use the url and see the pages rendered by the script.
Can the admin of the domain authorise so that all users using the email for the company can login using the email and use the script.
Do I need to transfer the script and the spreadsheet to someone with admin rights or can I continue to keep both on my drive and have admin authorise.
Regards
Which means I have to give them the right to view the script.
No, it doesn't.
I only want them to use the url and see the pages rendered by the script.
That's what they will see.
Can the admin of the domain authorise so that all users using the email for the company can login using the email and use the script.
No they can't because you set your webapp to run under the users login. One alternative is to create a service account which could be authorized by the domain-administrator to run domain-wide delegation of authority.
Do I need to transfer the script and the spreadsheet to someone with admin rights or can I continue to keep both on my drive and have admin authorise.
As explained previously, there is no need to have an admin authorize to keep your script code "secret".

Provisioning new accounts with template data across accounts

When a new user accepts an invitation for a new account to use my program by clicking a URL I have to accomplish in script:
copy data from a template spreadsheet to a new spreadsheet for the new user
There are several conditions to work around:
- the template spreadsheet to copy resides in the administrative account
- the web app for the user is configured to log with the user's account, not my administrative account
I am struggling with how to read and copy the template spreadsheet data while logged into the user's account? As Google Apps has no scriptable interface for accessing a spreadsheet from a different account..even though the user will have read privilege to the template spreadsheet.
I have contemplated different ideas but am not sure..can I chain web apps together and pass data between web apps accessed from different accounts? Or, do I have to script a totally new data store other than spreadsheets and Google Drive? The new data store would have to be accessible from both the administrative account and a user's account.
If you program is a GAS WebApp, then deploy it from your admin account with settings:
Execute the app as: me (admin.account#yourdomain.com)
Who has access to the app: Anyone
This way the server-side code of your app will run under admin account, and will have access to your template spreadsheet, and signed-in users will be able to interface with the client-side of your app. You may have to implement some user authorization in your app, so only specific users who received an invitation are allowed to access it. For example, you can store users' email addresses in a sheet in your admin template spreadsheet, and check if current use is in the list before creating an account for the user. Session.getActiveUser().getEmail() will give you current active user's email address. Similarly you can check if an active user already has an account created.
If your program is not a GAS WebApp - please edit your question to add more pertinent details.