multi_auth icon indicating copy to clipboard operation
multi_auth copied to clipboard

Retrieve github user email

Open kefahi opened this issue 5 years ago • 5 comments

One additional api call is required to retrieve the github user's email. The returned json i format is

[ {"email":"email ... address", ...}]

For simplicity it was done as a one-liner.

kefahi avatar Sep 27 '20 10:09 kefahi

@kefahi Do you have plans to apply the requested changes? This would save me an extra API call I'm manually making, as well 😄

stephendolan avatar May 07 '21 16:05 stephendolan

@stephendolan
The suggested code is now surrounded within begin/rescue/end block. This should protect in case email is not returned. I hope this is an acceptable solution. Let me know what you think.

kefahi avatar May 09 '21 04:05 kefahi

@stephendolan @kefahi I just realized that get-the-authenticated-user already return the email. Why needs additional requests?

msa7 avatar May 20 '21 09:05 msa7

@msa7 It had something to do with this user setting:

CleanShot 2021-05-21 at 11 27 00

When that box was checked, I'd get no email in the default response and had to make a follow-up request, which did return the email, even if it was private. Here's the full method I wrote that jogged my memory:

  # If a user's email is set to private, we have to make a subsequent request
  # and fetch the primary email.
  private def fetch_email_from_github(user : GitHubOAuthUser)
    headers = HTTP::Headers{
      "Authorization" => "token #{user.access_token}",
      "Accept"        => "application/vnd.github.v3+json",
    }
    api_response = HTTP::Client.get "https://api.github.com/user/emails", headers: headers

    if api_response.status == HTTP::Status::OK
      github_emails = Array(GitHubEmail).from_json(api_response.body)
      primary_github_email = github_emails.find(&.primary)

      if primary_github_email
        primary_github_email.email
      else
        raise "User retrieved from GitHub API had no primary email."
      end
    else
      raise "Failed to retrieve emails for user from GitHub API."
    end
  end

And the little helper class for the response:

  class GitHubEmail
    include JSON::Serializable

    property email : String
    property primary : Bool
  end

stephendolan avatar May 21 '21 15:05 stephendolan

In reviewing the code I'd previously written, @kefahi, I do wonder if it'd be better to search for the primary email explicitly rather than just pulling the first one from the response.

I'm not sure that the primary email is always guaranteed to be first in the response.

stephendolan avatar May 21 '21 15:05 stephendolan