git.iko.soy/typeable/oauth2-proxy
on v3.2.0 help sign in
typeable/oauth2-proxy/providers/provider_default.go
131 lines 3.5 kB history raw
1package providers
3import (
4 "bytes"
5 "encoding/json"
6 "errors"
7 "fmt"
8 "io/ioutil"
9 "net/http"
10 "net/url"
12 "github.com/pusher/oauth2_proxy/cookie"
15// Redeem provides a default implementation of the OAuth2 token redemption process
16func (p *ProviderData) Redeem(redirectURL, code string) (s *SessionState, err error) {
17 if code == "" {
18 err = errors.New("missing code")
19 return
20 }
22 params := url.Values{}
23 params.Add("redirect_uri", redirectURL)
24 params.Add("client_id", p.ClientID)
25 params.Add("client_secret", p.ClientSecret)
26 params.Add("code", code)
27 params.Add("grant_type", "authorization_code")
28 if p.ProtectedResource != nil && p.ProtectedResource.String() != "" {
29 params.Add("resource", p.ProtectedResource.String())
30 }
32 var req *http.Request
33 req, err = http.NewRequest("POST", p.RedeemURL.String(), bytes.NewBufferString(params.Encode()))
34 if err != nil {
35 return
36 }
37 req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
39 var resp *http.Response
40 resp, err = http.DefaultClient.Do(req)
41 if err != nil {
42 return nil, err
43 }
44 var body []byte
45 body, err = ioutil.ReadAll(resp.Body)
46 resp.Body.Close()
47 if err != nil {
48 return
49 }
51 if resp.StatusCode != 200 {
52 err = fmt.Errorf("got %d from %q %s", resp.StatusCode, p.RedeemURL.String(), body)
53 return
54 }
56 // blindly try json and x-www-form-urlencoded
57 var jsonResponse struct {
58 AccessToken string `json:"access_token"`
59 }
60 err = json.Unmarshal(body, &jsonResponse)
61 if err == nil {
62 s = &SessionState{
63 AccessToken: jsonResponse.AccessToken,
64 }
65 return
66 }
68 var v url.Values
69 v, err = url.ParseQuery(string(body))
70 if err != nil {
71 return
72 }
73 if a := v.Get("access_token"); a != "" {
74 s = &SessionState{AccessToken: a}
75 } else {
76 err = fmt.Errorf("no access token found %s", body)
77 }
78 return
81// GetLoginURL with typical oauth parameters
82func (p *ProviderData) GetLoginURL(redirectURI, state string) string {
83 var a url.URL
84 a = *p.LoginURL
85 params, _ := url.ParseQuery(a.RawQuery)
86 params.Set("redirect_uri", redirectURI)
87 params.Set("approval_prompt", p.ApprovalPrompt)
88 params.Add("scope", p.Scope)
89 params.Set("client_id", p.ClientID)
90 params.Set("response_type", "code")
91 params.Add("state", state)
92 a.RawQuery = params.Encode()
93 return a.String()
96// CookieForSession serializes a session state for storage in a cookie
97func (p *ProviderData) CookieForSession(s *SessionState, c *cookie.Cipher) (string, error) {
98 return s.EncodeSessionState(c)
101// SessionFromCookie deserializes a session from a cookie value
102func (p *ProviderData) SessionFromCookie(v string, c *cookie.Cipher) (s *SessionState, err error) {
103 return DecodeSessionState(v, c)
106// GetEmailAddress returns the Account email address
107func (p *ProviderData) GetEmailAddress(s *SessionState) (string, error) {
108 return "", errors.New("not implemented")
111// GetUserName returns the Account username
112func (p *ProviderData) GetUserName(s *SessionState) (string, error) {
113 return "", errors.New("not implemented")
116// ValidateGroup validates that the provided email exists in the configured provider
117// email group(s).
118func (p *ProviderData) ValidateGroup(email string) bool {
119 return true
122// ValidateSessionState validates the AccessToken
123func (p *ProviderData) ValidateSessionState(s *SessionState) bool {
124 return validateToken(p, s.AccessToken, nil)
127// RefreshSessionIfNeeded should refresh the user's session if required and
128// do nothing if a refresh is not required
129func (p *ProviderData) RefreshSessionIfNeeded(s *SessionState) (bool, error) {
130 return false, nil