oauth2_proxy/providers/provider_default.go
Ed Bardsley 33045a792b Add a flag to set the value of "approval_prompt".
By setting this to "force", certain providers, like Google,
will interject an additional prompt on every new session. With other values,
like "auto", this prompt is not forced upon the user.
2015-07-31 00:43:47 -07:00

116 lines
2.8 KiB
Go

package providers
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"strings"
"github.com/bitly/oauth2_proxy/cookie"
)
func (p *ProviderData) Redeem(redirectUrl, code string) (s *SessionState, err error) {
if code == "" {
err = errors.New("missing code")
return
}
params := url.Values{}
params.Add("redirect_uri", redirectUrl)
params.Add("client_id", p.ClientID)
params.Add("client_secret", p.ClientSecret)
params.Add("code", code)
params.Add("grant_type", "authorization_code")
var req *http.Request
req, err = http.NewRequest("POST", p.RedeemUrl.String(), bytes.NewBufferString(params.Encode()))
if err != nil {
return
}
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
var resp *http.Response
resp, err = http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
var body []byte
body, err = ioutil.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
return
}
if resp.StatusCode != 200 {
err = fmt.Errorf("got %d from %q %s", resp.StatusCode, p.RedeemUrl.String(), body)
return
}
// blindly try json and x-www-form-urlencoded
var jsonResponse struct {
AccessToken string `json:"access_token"`
}
err = json.Unmarshal(body, &jsonResponse)
if err == nil {
s = &SessionState{
AccessToken: jsonResponse.AccessToken,
}
return
}
var v url.Values
v, err = url.ParseQuery(string(body))
if err != nil {
return
}
if a := v.Get("access_token"); a != "" {
s = &SessionState{AccessToken: a}
} else {
err = fmt.Errorf("no access token found %s", body)
}
return
}
// GetLoginURL with typical oauth parameters
func (p *ProviderData) GetLoginURL(redirectURI, finalRedirect string) string {
var a url.URL
a = *p.LoginUrl
params, _ := url.ParseQuery(a.RawQuery)
params.Set("redirect_uri", redirectURI)
params.Set("approval_prompt", p.ApprovalPrompt)
params.Add("scope", p.Scope)
params.Set("client_id", p.ClientID)
params.Set("response_type", "code")
if strings.HasPrefix(finalRedirect, "/") {
params.Add("state", finalRedirect)
}
a.RawQuery = params.Encode()
return a.String()
}
// CookieForSession serializes a session state for storage in a cookie
func (p *ProviderData) CookieForSession(s *SessionState, c *cookie.Cipher) (string, error) {
return s.EncodeSessionState(c)
}
// SessionFromCookie deserializes a session from a cookie value
func (p *ProviderData) SessionFromCookie(v string, c *cookie.Cipher) (s *SessionState, err error) {
return DecodeSessionState(v, c)
}
func (p *ProviderData) GetEmailAddress(s *SessionState) (string, error) {
return "", errors.New("not implemented")
}
func (p *ProviderData) ValidateSessionState(s *SessionState) bool {
return validateToken(p, s.AccessToken, nil)
}
// RefreshSessionIfNeeded
func (p *ProviderData) RefreshSessionIfNeeded(s *SessionState) (bool, error) {
return false, nil
}