10
votes

My app will publish, edit and delete events on users' Google Calendars. I am configuring OAuth to make this happen. The idea is that upon signup, the user will be able to go into their settings and give consent to connect my app to their Google Calendar. I will then be able to store the oauth token and refresh token in the database and use them to when I create/edit/delete events on the user's calendar.

Anyway, the issue is that I pick my account:

Choosing account

I then provide consent by clicking "Allow":

Allowing access

Here is where it gets weird: behind the scenes, the Google Calendar API reports a 403 Forbidden error.

%Ueberauth.Failure{errors: [%Ueberauth.Failure.Error{message: 403,
message_key: "OAuth2"}], provider: :google,
strategy: Ueberauth.Strategy.Google}

My ueberauth config:

config :ueberauth, Ueberauth,
  providers: [
    google: {Ueberauth.Strategy.Google, [default_scope: "https://www.googleapis.com/auth/calendar", approval_prompt: "force", access_type: "offline"]}
]

The request I'm making:

def callback(%{assigns: %{ueberauth_failure: fail}} = conn, _params) do
  IO.inspect fail
  conn
  |> put_flash(:error, "Failed to authenticate.")
  |> redirect(to: "/")
end

def callback(%{assigns: %{ueberauth_auth: auth}} = conn, _params) do
  IO.inspect auth
  conn
  |> put_flash(:success, "Connected to Google.")
  |> redirect(to: "/")
end

The first callback function is the one that matches (since it fails).

However, when I go to my Google account, I can see that the app has been granted permission:

Access granted

I am providing the correct client_id and client_secret. In addition, I have created a service account in the Google API Console and shared my calendar with that account:

Calendar sharing settings

What else do I need to do?

Edit: Some more info - I am able to grant access to all other Google modules via my code (which is boilerplate Ueberauth_Google). For example, if I make the request with email as the scope, it works and I get the auth_token from Google. Only Google Calendar gives 403, which leads me to believe there is something specific about it that is causing it.

Edit 2: I looked at the error handling section of the Google Calendar API, and none of the 403 errors listed there apply to me:

  • 403: Daily Limit Exceeded
  • 403: User Rate Limit Exceeded
  • 403: Rate Limit Exceeded
  • 403: Calendar usage limits exceeded

Edit 3: I created a brand new Google account and shared its calendar with my Google Service Account. That one gives the same error though.

1
Why do you tag the question elixir ?GavinBrelstaff
It looks like he's trying to use Elixir but it also looks like he hasn't done anywhere near enough work to try to isolate the actual problem. Downvote.Onorio Catenacci
@Onorio Catenacci: Your comment is absolutely is ridiculous because not only is it not helpful, it is also rude. How do you determine that I "haven't done anywhere near enough work to try to isolate the actual problem"? Please explain specifically what led you to this impression, because it is very wrong.Ege Ersoz
Post code that actually demonstrates your issue and I'll retract my comment. Until you can give us a minimal, complete, and viable example to reproduce your issue, as far as I'm concerned you haven't done anywhere near enough work to get an answer.Onorio Catenacci
Posting lots of information is not the same thing as posting the important information.Onorio Catenacci

1 Answers

7
votes

Finally figured it out.

The https://www.googleapis.com/auth/calendar scope by itself was not sufficient. Also needed to add https://www.googleapis.com/auth/userinfo.profile to the scope.