B4J Question Acl rules with Google Calendar API: 403 Forbidden Error (SOLVED!)

jmon

Well-Known Member
Licensed User
Longtime User
Hi,

I'm using the Google API to syncronize my calendars to Google Calendar. I managed to connect using OAuth 2.0 and everything works. I can create my calendars, delete them, add events etc...

But just one thing doesn't work... The Acl Rule INSERT.
https://developers.google.com/google-apps/calendar/v3/reference/acl/insert

Whenever I want to insert my acl rule (i.e. sharing my calendar with another email address) I get this error 403:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "forbidden",
"message": "Forbidden"
}
],
"code": 403,
"message": "Forbidden"
}
}

Right now I'm logged into OAuth 2.0 with my email address [email protected]. In the developper console of Google API, I can also create a "Service Account", that manages the interaction between my app and the Google servers.

From what I read on internet, it could be because Google Calendar doesn't recognizes my credentials. I think I need to tell OAuth 2.0 that my connection is done via the "Service Account", and that I will be using this service account to modify my calendar.

I've seen that most of the java examples use a "GoogleCredential" object that write the information of the "Service account" before connecting. Is there something similar to this object in B4J?

This is my code to insert the acl:
B4X:
Public Sub AclInsert(CalendarId As String, Role As String, ScopeType As String, ScopeValue As String)
    If Not(oAuthLoggedIn) Then
        LogIn
        Return
    End If
    Dim m As Map = CreateMap("id":CalendarId, "role":Role, _
        "scope": CreateMap("type":ScopeType, "value":ScopeValue))  
    Dim job As HttpJob
    job.Initialize("AclInsert", Me)
    job.PostString("https://www.googleapis.com/calendar/v3/calendars/" & su.EncodeUrl(CalendarId, "UTF8") & "/acl" _
        & "?access_token=" & oAuthAccessToken, Parse2(m))
    job.GetRequest.SetContentType("application/json")
End Sub

The OAuth 2.0 connection code is the same as the OAuth 2.0 Example by @Erel.

I've been trying to make sense of this error for 3 days now. Maybe someone here has an idea?

Thanks for your help.
Jmon.
 
Last edited:

jmon

Well-Known Member
Licensed User
Longtime User
I'm continuing my research, and I found that maybe it could be because I didn't set the header.

https://developers.google.com/identity/protocols/OAuth2InstalledApp (at "Calling a Google API" 3/4 page)
A call to the drive.files endpoint (the Drive API) using the access_token query string parameter might look like the following, though you'll need to specify your own access token:

GET https://www.googleapis.com/drive/v2/files?access_token=1/fFBGRNJru1FQd44AzqT3Zg

Here is a call to the same API for the authenticated user (me) using the Authorization: Bearer HTTP header:

GET /drive/v2/files HTTP/1.1
Authorization: Bearer 1/fFBGRNJru1FQd44AzqT3Zg
Host: googleapis.com

I've never tried that, and this code doesn't work either:
B4X:
Public Sub AclInsert(CalendarId As String, Role As String, ScopeType As String, ScopeValue As String)
    If Not(oAuthLoggedIn) Then
        LogIn
        Return
    End If
    Dim m As Map = CreateMap("id":CalendarId, "role":Role, _
        "scope": CreateMap("type":ScopeType, "value":ScopeValue))   
    Dim job As HttpJob
    job.Initialize("AclInsert", Me)
    job.PostString("https://www.googleapis.com/calendar/v3/calendars/" & su.EncodeUrl(CalendarId, "UTF8") & "/acl" _
        & "?access_token=" & oAuthAccessToken, Parse2(m))
    job.GetRequest.SetContentType("application/json")
    job.GetRequest.SetHeader("Authorization", "Bearer " & oAuthAccessToken)
    job.GetRequest.SetHeader("Host", "googleapis.com")
End Sub
 
Upvote 0

jmon

Well-Known Member
Licensed User
Longtime User
Solved!

It wasn't any of that. the problem was my code!

this is the solution:
B4X:
Dim m As Map = CreateMap("role":Role, _
    "scope": CreateMap("type":ScopeType, "value":ScopeValue))

I had to remove the "id" parameter from the JSON. I thought it was the id of the calendar, but it was the id of the ACL! :mad:
 
Upvote 0
Top