git.iko.soy/typeable/oauth2-proxy
on master help sign in
Merge pull request #108 from jehiah/unmarshal_error_108

Page defaults to Google sign in

commit5a5d6dff7e454b46041650bd9f0f775fd6a38435 authorJehiah Czebotar <jehiah@gmail.com> dateSun 7 Jun 2015, 21:06 (11 years ago) parent13e8292f5db2e1
7 files changed+61−61
README.md+1−1 api/api.go+5−14 oauthproxy.go+14−36 providers/github.go+20−8 providers/internal_util.go+1−2 providers/provider_default.go+19 providers/providers.go+1
README.md+1−1
@@ -184,7 +184,7 @@ OAuth2 Proxy responds directly to the following endpoints. All other endpoints w
184184
185185## Logging Format
186186
187−OAuth2 Proxy Proxy logs requests to stdout in a format similar to Apache Combined Log.
187+OAuth2 Proxy logs requests to stdout in a format similar to Apache Combined Log.
188188
189189```
190190<REMOTE_ADDRESS> - <user@domain.com> [19/Mar/2015:17:20:19 -0400] <HOST_HEADER> GET <UPSTREAM_HOST> "/path/" HTTP/1.1 "<USER_AGENT>" <RESPONSE_CODE> <RESPONSE_BYTES> <REQUEST_DURATION>
api/api.go+5−14
@@ -1,9 +1,8 @@
11package api
22
33import (
4− "errors"
4+ "fmt"
55 "io/ioutil"
6− "log"
76 "net/http"
87
98 "github.com/bitly/go-simplejson"
@@ -20,8 +19,7 @@ func Request(req *http.Request) (*simplejson.Json, error) {
2019 return nil, err
2120 }
2221 if resp.StatusCode != 200 {
23− log.Printf("got response code %d - %s", resp.StatusCode, body)
24− return nil, errors.New("api request returned non 200 status code")
22+ return nil, fmt.Errorf("got %d %s", resp.StatusCode, body)
2523 }
2624 data, err := simplejson.NewJson(body)
2725 if err != nil {
@@ -30,19 +28,12 @@ func Request(req *http.Request) (*simplejson.Json, error) {
3028 return data, nil
3129}
3230
33−func RequestUnparsedResponse(url string, header http.Header) (
34− response *http.Response, err error) {
31+func RequestUnparsedResponse(url string, header http.Header) (resp *http.Response, err error) {
3532 req, err := http.NewRequest("GET", url, nil)
3633 if err != nil {
37− return nil, errors.New("failed building request for " +
38− url + ": " + err.Error())
34+ return nil, err
3935 }
4036 req.Header = header
4137
42− httpclient := &http.Client{}
43− if response, err = httpclient.Do(req); err != nil {
44− return nil, errors.New("request failed for " +
45− url + ": " + err.Error())
46− }
47− return
38+ return http.DefaultClient.Do(req)
4839}
oauthproxy.go+14−36
@@ -37,11 +37,6 @@ type OauthProxy struct {
3737
3838 redirectUrl *url.URL // the url to receive requests at
3939 provider providers.Provider
40− oauthLoginUrl *url.URL // to redirect the user to
41− oauthValidateUrl *url.URL // to validate the access token
42− oauthScope string
43− clientID string
44− clientSecret string
4540 ProxyPrefix string
4641 SignInMessage string
4742 HtpasswdFile *HtpasswdFile
@@ -147,25 +142,20 @@ func NewOauthProxy(opts *Options, validator func(string) bool) *OauthProxy {
147142 OauthStartPath: fmt.Sprintf("%s/start", opts.ProxyPrefix),
148143 OauthCallbackPath: fmt.Sprintf("%s/callback", opts.ProxyPrefix),
149144
150− clientID: opts.ClientID,
151− clientSecret: opts.ClientSecret,
152− ProxyPrefix: opts.ProxyPrefix,
153− oauthScope: opts.provider.Data().Scope,
154− provider: opts.provider,
155− oauthLoginUrl: opts.provider.Data().LoginUrl,
156− oauthValidateUrl: opts.provider.Data().ValidateUrl,
157− serveMux: serveMux,
158− redirectUrl: redirectUrl,
159− skipAuthRegex: opts.SkipAuthRegex,
160− compiledRegex: opts.CompiledRegex,
161− PassBasicAuth: opts.PassBasicAuth,
162− PassAccessToken: opts.PassAccessToken,
163− AesCipher: aes_cipher,
164− templates: loadTemplates(opts.CustomTemplatesDir),
145+ ProxyPrefix: opts.ProxyPrefix,
146+ provider: opts.provider,
147+ serveMux: serveMux,
148+ redirectUrl: redirectUrl,
149+ skipAuthRegex: opts.SkipAuthRegex,
150+ compiledRegex: opts.CompiledRegex,
151+ PassBasicAuth: opts.PassBasicAuth,
152+ PassAccessToken: opts.PassAccessToken,
153+ AesCipher: aes_cipher,
154+ templates: loadTemplates(opts.CustomTemplatesDir),
165155 }
166156}
167157
168−func (p *OauthProxy) GetRedirectUrl(host string) string {
158+func (p *OauthProxy) GetRedirectURI(host string) string {
169159 // default to the request Host if not set
170160 if p.redirectUrl.Host != "" {
171161 return p.redirectUrl.String()
@@ -183,19 +173,6 @@ func (p *OauthProxy) GetRedirectUrl(host string) string {
183173 return u.String()
184174}
185175
186−func (p *OauthProxy) GetLoginURL(host, redirect string) string {
187− params := url.Values{}
188− params.Add("redirect_uri", p.GetRedirectUrl(host))
189− params.Add("approval_prompt", "force")
190− params.Add("scope", p.oauthScope)
191− params.Add("client_id", p.clientID)
192− params.Add("response_type", "code")
193− if strings.HasPrefix(redirect, "/") {
194− params.Add("state", redirect)
195− }
196− return fmt.Sprintf("%s?%s", p.oauthLoginUrl, params.Encode())
197−}
198−
199176func (p *OauthProxy) displayCustomLoginForm() bool {
200177 return p.HtpasswdFile != nil && p.DisplayHtpasswdForm
201178}
@@ -204,7 +181,7 @@ func (p *OauthProxy) redeemCode(host, code string) (string, string, error) {
204181 if code == "" {
205182 return "", "", errors.New("missing code")
206183 }
207− redirectUri := p.GetRedirectUrl(host)
184+ redirectUri := p.GetRedirectURI(host)
208185 body, access_token, err := p.provider.Redeem(redirectUri, code)
209186 if err != nil {
210187 return "", "", err
@@ -416,7 +393,8 @@ func (p *OauthProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
416393 p.ErrorPage(rw, 500, "Internal Error", err.Error())
417394 return
418395 }
419− http.Redirect(rw, req, p.GetLoginURL(req.Host, redirect), 302)
396+ redirectURI := p.GetRedirectURI(req.Host)
397+ http.Redirect(rw, req, p.provider.GetLoginURL(redirectURI, redirect), 302)
420398 return
421399 }
422400 if req.URL.Path == p.OauthCallbackPath {
providers/github.go+20−8
@@ -2,6 +2,7 @@ package providers
22
33import (
44 "encoding/json"
5+ "fmt"
56 "io/ioutil"
67 "net/http"
78 "net/url"
@@ -58,10 +59,11 @@ func (p *GitHubProvider) hasOrg(accessToken string) (bool, error) {
5859
5960 params := url.Values{
6061 "access_token": {accessToken},
61− "limit": {"100"},
62+ "limit": {"100"},
6263 }
6364
64− req, _ := http.NewRequest("GET", "https://api.github.com/user/orgs?"+params.Encode(), nil)
65+ endpoint := "https://api.github.com/user/orgs?" + params.Encode()
66+ req, _ := http.NewRequest("GET", endpoint, nil)
6567 req.Header.Set("Accept", "application/vnd.github.moondragon+json")
6668 resp, err := http.DefaultClient.Do(req)
6769 if err != nil {
@@ -73,6 +75,9 @@ func (p *GitHubProvider) hasOrg(accessToken string) (bool, error) {
7375 if err != nil {
7476 return false, err
7577 }
78+ if resp.StatusCode != 200 {
79+ return false, fmt.Errorf("got %d from %q %s", resp.StatusCode, endpoint, body)
80+ }
7681
7782 if err := json.Unmarshal(body, &orgs); err != nil {
7883 return false, err
@@ -99,10 +104,11 @@ func (p *GitHubProvider) hasOrgAndTeam(accessToken string) (bool, error) {
99104
100105 params := url.Values{
101106 "access_token": {accessToken},
102− "limit": {"100"},
107+ "limit": {"100"},
103108 }
104109
105− req, _ := http.NewRequest("GET", "https://api.github.com/user/teams?"+params.Encode(), nil)
110+ endpoint := "https://api.github.com/user/teams?" + params.Encode()
111+ req, _ := http.NewRequest("GET", endpoint, nil)
106112 req.Header.Set("Accept", "application/vnd.github.moondragon+json")
107113 resp, err := http.DefaultClient.Do(req)
108114 if err != nil {
@@ -114,9 +120,12 @@ func (p *GitHubProvider) hasOrgAndTeam(accessToken string) (bool, error) {
114120 if err != nil {
115121 return false, err
116122 }
123+ if resp.StatusCode != 200 {
124+ return false, fmt.Errorf("got %d from %q %s", resp.StatusCode, endpoint, body)
125+ }
117126
118127 if err := json.Unmarshal(body, &teams); err != nil {
119− return false, err
128+ return false, fmt.Errorf("%s unmarshaling %s", err, body)
120129 }
121130
122131 for _, team := range teams {
@@ -136,7 +145,6 @@ func (p *GitHubProvider) GetEmailAddress(body []byte, access_token string) (stri
136145 Primary bool `json:"primary"`
137146 }
138147
139−
140148 // if we require an Org or Team, check that first
141149 if p.Org != "" {
142150 if p.Team != "" {
@@ -153,7 +161,8 @@ func (p *GitHubProvider) GetEmailAddress(body []byte, access_token string) (stri
153161 params := url.Values{
154162 "access_token": {access_token},
155163 }
156− resp, err := http.DefaultClient.Get("https://api.github.com/user/emails?" + params.Encode())
164+ endpoint := "https://api.github.com/user/emails?" + params.Encode()
165+ resp, err := http.DefaultClient.Get(endpoint)
157166 if err != nil {
158167 return "", err
159168 }
@@ -162,9 +171,12 @@ func (p *GitHubProvider) GetEmailAddress(body []byte, access_token string) (stri
162171 if err != nil {
163172 return "", err
164173 }
174+ if resp.StatusCode != 200 {
175+ return "", fmt.Errorf("got %d from %q %s", resp.StatusCode, endpoint, body)
176+ }
165177
166178 if err := json.Unmarshal(body, &emails); err != nil {
167− return "", err
179+ return "", fmt.Errorf("%s unmarshaling %s", err, body)
168180 }
169181
170182 for _, email := range emails {
providers/internal_util.go+1−2
@@ -6,8 +6,7 @@ import (
66 "net/http"
77)
88
9−func validateToken(p Provider, access_token string,
10− header http.Header) bool {
9+func validateToken(p Provider, access_token string, header http.Header) bool {
1110 if access_token == "" || p.Data().ValidateUrl == nil {
1211 return false
1312 }
providers/provider_default.go+19
@@ -4,9 +4,11 @@ import (
44 "bytes"
55 "encoding/json"
66 "errors"
7+ "fmt"
78 "io/ioutil"
89 "net/http"
910 "net/url"
11+ "strings"
1012)
1113
1214func (p *ProviderData) Redeem(redirectUrl, code string) (body []byte, token string, err error) {
@@ -37,6 +39,10 @@ func (p *ProviderData) Redeem(redirectUrl, code string) (body []byte, token stri
3739 return nil, "", err
3840 }
3941
42+ if resp.StatusCode != 200 {
43+ return body, "", fmt.Errorf("got %d from %q %s", resp.StatusCode, p.RedeemUrl.String(), body)
44+ }
45+
4046 // blindly try json and x-www-form-urlencoded
4147 var jsonResponse struct {
4248 AccessToken string `json:"access_token"`
@@ -49,3 +55,16 @@ func (p *ProviderData) Redeem(redirectUrl, code string) (body []byte, token stri
4955 v, err := url.ParseQuery(string(body))
5056 return body, v.Get("access_token"), err
5157}
58+
59+func (p *ProviderData) GetLoginURL(redirectURI, finalRedirect string) string {
60+ params := url.Values{}
61+ params.Add("redirect_uri", redirectURI)
62+ params.Add("approval_prompt", "force")
63+ params.Add("scope", p.Scope)
64+ params.Add("client_id", p.ClientID)
65+ params.Add("response_type", "code")
66+ if strings.HasPrefix(finalRedirect, "/") {
67+ params.Add("state", finalRedirect)
68+ }
69+ return fmt.Sprintf("%s?%s", p.LoginUrl, params.Encode())
70+}
providers/providers.go+1
@@ -5,6 +5,7 @@ type Provider interface {
55 GetEmailAddress(body []byte, access_token string) (string, error)
66 Redeem(string, string) ([]byte, string, error)
77 ValidateToken(access_token string) bool
8+ GetLoginURL(redirectURI, finalRedirect string) string
89}
910
1011func New(provider string, p *ProviderData) Provider {