How to change the google API "service account" name/email address - oauth

I am using the Google API to create a spreadsheet on google drive.
My app has a link that says 'Download To Google Doc'
The app sends a file to google docs and shares it with the user.
The user can then see it in google docs.
This all works good.
The problem is the identity of the service account sharing the doc.
It is a generated id. I want it to be branded to my app.
Is this possible?
-

You can't change the service account email address, nor can you supply a real world user name to it. The service account email address is created by Google in the Google Developer console.
The only way to change the email address would be to delete it and create a new one but again you would be stuck with the one Google Created. I suspect that the client id and email address are a pair used for identification of your application. Similar to client id and client secret, but I cant verify that.
I do see your point it would be nice if we could.

Google Service Accounts do allow you to impersonate an existing user account (for some services). I haven't tested it on Google Drive, but I have used it with the Webmaster tools API. The instructions can be found here: https://developers.google.com/identity/protocols/OAuth2ServiceAccount
To sum them up, when creating the service account credentials you can specify the "sub" parameter with "The email address of the user for which the application is requesting delegated access." The account you're requesting access for must exist and have permission to access to the services you're requesting.
In the link above Google provides examples for Java, Python and HTTP/REST, here's the Python example:
credentials = SignedJwtAssertionCredentials(client_email, private_key,
'https://www.googleapis.com/auth/sqlservice.admin',
sub='user#example.org')
I'm using the Ruby google-api-client gem (0.9.pre3) and the ServiceAccountCredentials constructor does not pass the 'sub' parameter to its parent class so it has to be specified in another step:
client = Google::Auth::ServiceAccountCredentials.new(json_key_io: json_key_io, scope: scope)
client.update!(sub: 'user#example.org')
client.fetch_access_token!
service = Google::Apis::WebmastersV3::WebmastersService.new
service.authorization = client
Using this code I can authenticate using my service account and I have access to the sites

Related

What am I doing wrong to get group.selected working in graph API?

I'm currently trying implement an app to read calendars only for a group that's permitted to the app. The idea behind this is that when I want to add a another calendar all I'd have to do is add the object to a specific o365 group. I'm taking the application approach over delegation that way I don't have anything actually logging in to utilize the app. Ultimately I'd like to stay away from any of the *.All permissions for security reasons.
Steps taken :
- created o365 group
- added resource objects and one user service account (just for testing) to the group
- registered app
- generated secret
- assigned group to the app
- granted admin consent to groups.selected via the azure portal
When I run a GET for group/{id}/members :
{'error': {'code': 'Authorization_RequestDenied', 'message': 'Insufficient privileges to complete the operation.', 'innerError': {'request-id': '473410a8-4db4-49d6-8d2c-92b9fbd4edb1', 'date': '2020-03-05T14:59:28'}}}
As per the docs
https://learn.microsoft.com/en-us/graph/api/group-list-members?view=graph-rest-1.0&tabs=http
If you are using Application permissions to Get Members for a group. you will need User.Read.All, Group.Read.All, Directory.Read.All.
The usual issue is not granting that permissions to the application in Portal.azure.com and admin consenting it.
If you're confident with that. Then I'd eliminate your code as being the issue by using something like postman with your app id and client secret. We have a sample Postman collection here https://learn.microsoft.com/en-us/graph/use-postman . for delegated permissions you can use our Graph Explorer playground.
MS docs says:
Note: This permission is exposed in the Azure portal for a feature that is not available for general use. Do not use this permission as it is subject to change.
https://learn.microsoft.com/en-us/graph/permissions-reference

G Suite Service Account Fails Requests But Delegation Works?

I have followed the documentation for creating a G Suite Service Account. The following works fine to emulate a given user in my domain:
def create_directory_service(user_email):
credentials = ServiceAccountCredentials.from_json_keyfile_name(
SERVICE_ACCOUNT_FILE_PATH,
scopes = SCOPES)
credentials = credentials.create_delegated(user_email)
return build('admin', 'directory_v1', credentials=credentials)
However, I want to be able to just use the service account to access domain information without needing to emulate a particular user. But if I pass in the service account's email address (as given in its key file), I just get HttpError 503: "Service unavailable. Please try again".
I've added the service account's email address as a Service Account Admin, but it still doesn't work. Again, delegation works fine, but not using the service account directly.
Does anyone know what I'm missing?
To use Directory API, you must use delegation to impersonate a user in the domain, that can use Directory API (so usually an admin).

ruby google api client, service account and Google app to use google drive

You can skip to the problem below but in short I can auth, upload and get a file list but it doesn't correspond to the gmail account I setup with the service account and google dev console
longer version:
I created a new email account say blah#gmail.com and used the google development console to enable drive, contacts and a few other APIs for my project.
Then I created the service account API keys/secrets and downloaded the client_secrets.json as well.
It took a while but got authentication working with the ruby google-api-client and I can login via rails console.
Problem:
I'm getting file.list but it only has the Getting Started.pdf even though I've created a few docs and spreadsheets on the blah#gmail.com service account.
I can also upload a file but don't see it.
I "think" that it's uploading to Google Apps related account? but I have neither set one up nor do I own domain for the organization I'm setting this up with.
I have no idea where the files are going or uploading or how I can access the drive account I actually did setup with blah#gmail.com
what's going on .
EDIT:
Can i get some code example on how to modify this to impersonate user?
require 'google/apis/drive_v2'
Drive = Google::Apis::DriveV2
#drive = Drive::DriveService.new
scope = 'https://www.googleapis.com/auth/drive'
#drive.authorization = Google::Auth.get_application_default([scope])
#give me list of files
#files = #drive.list_files
puts "Search results:"
#files.items.each do |file|
puts "- File: #{file.title} (#{file.id})"
end
If I have to setup google apps this might be tough since they only have subdomains and I don't have direct access. The type of thing I wish I had been told up front.

Using Email Settings API from app engine with service account

I'm trying to use the Email Settings API from within a google marketplace app. Because I need all the logic to happen offline (in a cron job). I'm using an app engine Service Account, but when I'm trying to actually change the email settings for the users of the domain that installed it I'm getting this error:
You are not authorized to access this API.
Error 403
this is the scope: https://apps-apis.google.com/a/feeds/emailsettings/2.0/
I'm probably missing something, but I couldn't find the right docs to show me the way. How would I go about implementing an app that accesses the email settings even when the admin is offline?
You need to set the prn attribute to address of an admin account.
Examples for the directory API are at:
https://developers.google.com/admin-sdk/directory/v1/guides/delegation#instantiate_an_admin_sdk_directory_service_object
In terms of accessing the Email Settings API, you're really unlikely to get people to give you Service Account access to their domain.
On the other hand, if it's your domain (and thus you can add Service Account access), couple of pointers below:
What is important is that you add the following to the header:
"Authorization" = "Bearer <your_token>"
(note the very specific syntax - "Bearer+<1 space>+", as per https://www.rfc-editor.org/rfc/rfc6750 section 2.1)
"Content-Type" = "application/atom+xml"
(important for POST/PUT/DELETE requests, doesn't matter for GET)
that should get you up and running.

Creating Admin Accounts for Domains Created from Reseller API

I am trying to automate the entire process of creating a google apps account through my company's reseller account with google, without any human having to manually enable anything.
Here's a quick scenario of what I am doing.
Create Customer (Domain) with Reseller API
Create Subscription with Reseller API
Create Admin Account for the Sold Domain
I am having trouble automating step 3.
There are 2 different APIs that can accomplish this tast, Provisioning (depricated) and Directory.
I have already successfully created user accounts with the Directory API, but this step requires you to enable API access for that domain, and that can only be done manually by a human - So thats a break in automation flow, and wont work for what I am trying to accomplish.
I was instructed by google tech support to use the Provisioning API, wich is deprecated, because it supposedly allows you to create an admin user without the need to enable the API access manually per domain. When I attempt to do this, I face this error:
Uncaught exception 'Zend_Gdata_App_HttpException' with message 'Expected response code 200, got 403 <HTML> <HEAD> <TITLE>You are not authorized to perform operations on the domain mydomain.com</TITLE>
Here's the code im attempting to run:
// .....
$customerid = "somedomain.com";
$client = Zend_Gdata_ClientLogin::getHttpClient("mylogin#foo.com", "mypassword",Zend_Gdata_Gapps::AUTH_SERVICE_NAME);
$gdata = new Zend_Gdata_Gapps($client, $customerid);
$gdata->createUser('Admin', 'Firstname', 'Lastname', 'somerandompassword', TRUE);
//......
When I consulted google tech support, they told me I needed to enable the provisioning api following the same instruction I posted earlier (enable api access per domain). I have done this on both my reseller domain, and the customer domain Im trying to provision on (just to test, becasue the entire point is to be able to make an admin account WITHOUT enabling it on the customer domain.) - But it still returns this error.
Here's my settings -- as you can see, its enabled.
In google's docs, under "Enabling the Provisioning API", it has some instructions, but they appear to be out of date and dont really reflect sections available in the current google apps admin panel.
Im at a loss. Am I missing something obvious, or is it just not possible to do at this time?
Just for reference, I have found a few other people asking a similar question, but with less detail:
Google Reseller Customer Admin User Creation Admin SDK How
How to create the domain administrator of a Google Apps domain purchased via the reseller API
EDIT: Added image showing settings, and code sample.
try to delete "TRUE" parameter in createUser , it's works for me.
$customerid = "sampledomain.com";
$client = Zend_Gdata_ClientLogin::getHttpClient($email, $password, Zend_Gdata_Gapps::AUTH_SERVICE_NAME);
$gdata = new Zend_Gdata_Gapps($client, $customerid);
var_dump($gdata->createUser('trial', 'Firstname', 'Lastname', 'somerandompassword'));
in Google app console
domain settings ->user settings
check the box "enable API access"
in Google app console --> advanced tools --> Manage third party OAuth Client access
Add the scope :
https://apps-apis.google.com/a/feeds/user

Resources