@@ -0,0 +1,80 @@
1+package providers
2+
3+import (
4+ "errors"
5+ "fmt"
6+ "net/http"
7+ "net/url"
8+
9+ "github.com/bitly/oauth2_proxy/api"
10+)
11+
12+type FacebookProvider struct {
13+ *ProviderData
14+}
15+
16+func NewFacebookProvider(p *ProviderData) *FacebookProvider {
17+ p.ProviderName = "Facebook"
18+ if p.LoginURL.String() == "" {
19+ p.LoginURL = &url.URL{Scheme: "https",
20+ Host: "www.facebook.com",
21+ Path: "/v2.5/dialog/oauth",
22+ // ?granted_scopes=true
23+ }
24+ }
25+ if p.RedeemURL.String() == "" {
26+ p.RedeemURL = &url.URL{Scheme: "https",
27+ Host: "graph.facebook.com",
28+ Path: "/v2.5/oauth/access_token",
29+ }
30+ }
31+ if p.ProfileURL.String() == "" {
32+ p.ProfileURL = &url.URL{Scheme: "https",
33+ Host: "graph.facebook.com",
34+ Path: "/v2.5/me",
35+ }
36+ }
37+ if p.ValidateURL.String() == "" {
38+ p.ValidateURL = p.ProfileURL
39+ }
40+ if p.Scope == "" {
41+ p.Scope = "public_profile email"
42+ }
43+ return &FacebookProvider{ProviderData: p}
44+}
45+
46+func getFacebookHeader(access_token string) http.Header {
47+ header := make(http.Header)
48+ header.Set("Accept", "application/json")
49+ header.Set("x-li-format", "json")
50+ header.Set("Authorization", fmt.Sprintf("Bearer %s", access_token))
51+ return header
52+}
53+
54+func (p *FacebookProvider) GetEmailAddress(s *SessionState) (string, error) {
55+ if s.AccessToken == "" {
56+ return "", errors.New("missing access token")
57+ }
58+ req, err := http.NewRequest("GET", p.ProfileURL.String()+"?fields=name,email", nil)
59+ if err != nil {
60+ return "", err
61+ }
62+ req.Header = getFacebookHeader(s.AccessToken)
63+
64+ type result struct {
65+ Email string
66+ }
67+ var r result
68+ err = api.RequestJson(req, &r)
69+ if err != nil {
70+ return "", err
71+ }
72+ if r.Email == "" {
73+ return "", errors.New("no email")
74+ }
75+ return r.Email, nil
76+}
77+
78+func (p *FacebookProvider) ValidateSessionState(s *SessionState) bool {
79+ return validateToken(p, s.AccessToken, getFacebookHeader(s.AccessToken))
80+}