I am new to the Google API. I have a google workspace account registered with its own domain. I would like to be able to perform actions on users mailboxes using the google java api. I was using the quick start project and played with authentications as scopes.
I can perform actions on the user account that I performed my OAuth consent.
looking at the example
String user = "me";
ListLabelsResponse listResponse = service.users()
.labels().list(user).execute();
It uses the "me" keyword as the user, I would like to use one of the users in the account and perform the same action. When I switch the "me" to one of the users in my domain I get the following.
GET https://gmail.googleapis.com/gmail/v1/users/user@somedomain.what.ever/labels
{
"code" : 403,
"errors" : [ {
"domain" : "global",
"message" : "Delegation denied for admin@mirncast.uk",
"reason" : "forbidden"
} ],
"message" : "Delegation denied for admin@mirncast.uk",
"status" : "PERMISSION_DENIED"
}
As far as I understand from the above I need to provide user delegation. User delegation requires a service account. So I tried to follow this tutorial
My code ended up as
Set<String> scope = Collections.singleton(GmailScopes.MAIL_GOOGLE_COM);
GoogleCredential credentialFromJson = GoogleCredential
.fromStream(new FileInputStream(
"/certificate.json"))
.createScoped(scope);
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(jsonFactory)
.setServiceAccountId(credentialFromJson.getServiceAccountId())
.setServiceAccountPrivateKey(credentialFromJson.getServiceAccountPrivateKey())
.setServiceAccountScopes(Collections.singleton(GmailScopes.MAIL_GOOGLE_COM))
.setServiceAccountUser("user@somedomain.what.ever")
//.setServiceAccountUser("service@custom-octagon-1234567.iam.gserviceaccount.com")
.build();
Gmail service = new Gmail.Builder(httpTransport, jsonFactory, credential).setApplicationName("remediation service").build();
String user = "user@somedomain.what.ever";
final var messagesResponse = service.users().messages().list(user).execute();
System.out.println(messagesResponse.getMessages().stream().map(message -> message.getId()).collect(Collectors.joining(",")));
This code has a few problems.
I was only able to make it work when I set the setServiceAccountUser with the same email address I am trying to access. Using the API that way defeat the purpose from my point of view. when using the service account I get the following error
Exception in thread "main" com.google.api.client.googleapis.json.GoogleJsonResponseException: 400 Bad Request
GET https://gmail.googleapis.com/gmail/v1/users/hraman@gsuite-dev.mirncast.uk/messages
{
"code" : 400,
"errors" : [ {
"domain" : "global",
"message" : "Precondition check failed.",
"reason" : "failedPrecondition"
} ],
"message" : "Precondition check failed.",
"status" : "FAILED_PRECONDITION"
}
The example uses deprecated API GoogleCredential and I cann't figure what is the latest API for this based on OAuth2 authentication
My maven dependencies
<dependencies>
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-gmail</artifactId>
<version>v1-rev20210301-1.31.0</version>
</dependency>
<dependency>
<groupId>com.google.oauth-client</groupId>
<artifactId>google-oauth-client-jetty</artifactId>
<version>1.31.4</version>
</dependency>
</dependencies>