From f19128a804d6558f831a9269dfb4c26c70a0ad99 Mon Sep 17 00:00:00 2001 From: orian Date: Mon, 3 Aug 2015 22:35:43 +0200 Subject: [PATCH] add Facebook provider for oauth2 --- oauth2/oauth2_test.go | 10 ++++++++++ oauth2/providers.go | 32 ++++++++++++++++++++++++++++++++ oauth2/providers_test.go | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+) diff --git a/oauth2/oauth2_test.go b/oauth2/oauth2_test.go index 36e97de..75d4f90 100644 --- a/oauth2/oauth2_test.go +++ b/oauth2/oauth2_test.go @@ -12,6 +12,7 @@ import ( "golang.org/x/net/context" "golang.org/x/oauth2" + "golang.org/x/oauth2/facebook" "gopkg.in/authboss.v0" "gopkg.in/authboss.v0/internal/mocks" ) @@ -27,6 +28,15 @@ var testProviders = map[string]authboss.OAuth2Provider{ Callback: Google, AdditionalParams: url.Values{"include_requested_scopes": []string{"true"}}, }, + "facebook": authboss.OAuth2Provider{ + OAuth2Config: &oauth2.Config{ + ClientID: `jazz`, + ClientSecret: `hands`, + Scopes: []string{`email`}, + Endpoint: facebook.Endpoint, + }, + Callback: Facebook, + }, } func TestInitialize(t *testing.T) { diff --git a/oauth2/providers.go b/oauth2/providers.go index eca6159..33975ef 100644 --- a/oauth2/providers.go +++ b/oauth2/providers.go @@ -45,3 +45,35 @@ func Google(cfg oauth2.Config, token *oauth2.Token) (authboss.Attributes, error) authboss.StoreEmail: jsonResp.Email, }, nil } + +type facebookMeResponse struct { + ID string `json:"id"` + Email string `json:"email"` + Name string `json:"name"` +} + +const ( + facebookInfoEndpoint = "https://graph.facebook.com/me?fields=name,email" +) + +// Google is a callback appropriate for use with Google's OAuth2 configuration. +func Facebook(cfg oauth2.Config, token *oauth2.Token) (authboss.Attributes, error) { + client := cfg.Client(oauth2.NoContext, token) + resp, err := clientGet(client, facebookInfoEndpoint) + if err != nil { + return nil, err + } + + defer resp.Body.Close() + dec := json.NewDecoder(resp.Body) + var jsonResp facebookMeResponse + if err = dec.Decode(&jsonResp); err != nil { + return nil, err + } + + return authboss.Attributes{ + "name": jsonResp.Name, + authboss.StoreOAuth2UID: jsonResp.ID, + authboss.StoreEmail: jsonResp.Email, + }, nil +} diff --git a/oauth2/providers_test.go b/oauth2/providers_test.go index 4d9159c..02ee88f 100644 --- a/oauth2/providers_test.go +++ b/oauth2/providers_test.go @@ -43,3 +43,39 @@ func TestGoogle(t *testing.T) { t.Error("Email wrong:", email) } } + +func TestFacebook(t *testing.T) { + saveClientGet := clientGet + defer func() { + clientGet = saveClientGet + }() + + clientGet = func(_ *http.Client, url string) (*http.Response, error) { + return &http.Response{ + Body: ioutil.NopCloser(strings.NewReader(`{"id":"id", "email":"email", "name":"name"}`)), + }, nil + } + + cfg := *testProviders["facebook"].OAuth2Config + tok := &oauth2.Token{ + AccessToken: "token", + TokenType: "Bearer", + RefreshToken: "refresh", + Expiry: time.Now().Add(60 * time.Minute), + } + + user, err := Facebook(cfg, tok) + if err != nil { + t.Error(err) + } + + if uid, ok := user[authboss.StoreOAuth2UID]; !ok || uid != "id" { + t.Error("UID wrong:", uid) + } + if email, ok := user[authboss.StoreEmail]; !ok || email != "email" { + t.Error("Email wrong:", email) + } + if name, ok := user["name"]; !ok || name != "name" { + t.Error("Name wrong:", name) + } +}