git.iko.soy/typeable/oauth2-proxy
on master help sign in
cleanup error handling
4235933Jehiah Czebotar
oauthproxy.go+24−20
@@ -100,7 +100,6 @@ func apiRequest(req *http.Request) (*simplejson.Json, error) {
100}
100}
101
101
102func (p *OauthProxy) redeemCode(code string) (string, error) {
102func (p *OauthProxy) redeemCode(code string) (string, error) {
103−
104 params := url.Values{}
103 params := url.Values{}
105 params.Add("redirect_uri", p.redirectUrl.String())
104 params.Add("redirect_uri", p.redirectUrl.String())
106 params.Add("client_id", p.clientID)
105 params.Add("client_id", p.clientID)
@@ -125,6 +124,7 @@ func (p *OauthProxy) redeemCode(code string) (string, error) {
125 }
124 }
126 return access_token, nil
125 return access_token, nil
127}
126}
127+
128func (p *OauthProxy) getUserInfo(token string) (string, error) {
128func (p *OauthProxy) getUserInfo(token string) (string, error) {
129 params := url.Values{}
129 params := url.Values{}
130 params.Add("access_token", token)
130 params.Add("access_token", token)
@@ -164,29 +164,33 @@ func ClearCookie(rw http.ResponseWriter, req *http.Request, key string) {
164 http.SetCookie(rw, cookie)
164 http.SetCookie(rw, cookie)
165}
165}
166
166
167−func ErrorPage(rw http.ResponseWriter, code int, title string, message string, signinmessage string) {
167+func (p *OauthProxy) ErrorPage(rw http.ResponseWriter, code int, title string, message string) {
168− log.Printf("ErrorPage %d %s %s %s", code, title, message, signinmessage)
168+ log.Printf("ErrorPage %d %s %s", code, title, message)
169 rw.WriteHeader(code)
169 rw.WriteHeader(code)
170− t := getTemplates()
170+ templates := getTemplates()
171− p := struct {
171+ t := struct {
172 Title string
172 Title string
173 Message string
173 Message string
174− SignInMessage string
175 }{
174 }{
176 Title: fmt.Sprintf("%d %s", code, title),
175 Title: fmt.Sprintf("%d %s", code, title),
177 Message: message,
176 Message: message,
178− SignInMessage: signinmessage,
179 }
177 }
180− t.ExecuteTemplate(rw, "error.html", p)
178+ templates.ExecuteTemplate(rw, "error.html", t)
179+}
180+
181+func (p *OauthProxy) SignInPage(rw http.ResponseWriter, req *http.Request, code int) {
182+ // TODO: capture state for which url to redirect to at the end
183+ rw.WriteHeader(code)
184+ templates := getTemplates()
185+ t := struct{ SignInMessage string }{SignInMessage: p.SignInMessage}
186+ templates.ExecuteTemplate(rw, "sign_in.html", t)
181}
187}
182
188
183func (p *OauthProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
189func (p *OauthProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
184 // check if this is a redirect back at the end of oauth
190 // check if this is a redirect back at the end of oauth
185 if req.URL.Path == signInPath {
191 if req.URL.Path == signInPath {
186 ClearCookie(rw, req, p.CookieKey)
192 ClearCookie(rw, req, p.CookieKey)
187− t := getTemplates()
193+ p.SignInPage(rw, req, 200)
188− p := struct{ SignInMessage string }{SignInMessage: p.SignInMessage}
189− t.ExecuteTemplate(rw, "sign_in.html", p)
190 return
194 return
191 }
195 }
192 if req.URL.Path == oauthStartPath {
196 if req.URL.Path == oauthStartPath {
@@ -197,31 +201,31 @@ func (p *OauthProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
197 // finish the oauth cycle
201 // finish the oauth cycle
198 reqParams, err := url.ParseQuery(req.URL.RawQuery)
202 reqParams, err := url.ParseQuery(req.URL.RawQuery)
199 if err != nil {
203 if err != nil {
200− ErrorPage(rw, 500, "Internal Error", err.Error(), p.SignInMessage)
204+ p.ErrorPage(rw, 500, "Internal Error", err.Error())
201 return
205 return
202 }
206 }
203 errorString, ok := reqParams["error"]
207 errorString, ok := reqParams["error"]
204 if ok && len(errorString) == 1 {
208 if ok && len(errorString) == 1 {
205− ErrorPage(rw, 403, "Permission Denied", errorString[0], p.SignInMessage)
209+ p.ErrorPage(rw, 403, "Permission Denied", errorString[0])
206 return
210 return
207 }
211 }
208 code, ok := reqParams["code"]
212 code, ok := reqParams["code"]
209 if !ok || len(code) != 1 {
213 if !ok || len(code) != 1 {
210− ErrorPage(rw, 500, "Internal Error", "Invalid API response", p.SignInMessage)
214+ p.ErrorPage(rw, 500, "Internal Error", "Invalid API response")
211 return
215 return
212 }
216 }
213
217
214 token, err := p.redeemCode(code[0])
218 token, err := p.redeemCode(code[0])
215 if err != nil {
219 if err != nil {
216 log.Printf("error redeeming code %s", err.Error())
220 log.Printf("error redeeming code %s", err.Error())
217− ErrorPage(rw, 500, "Internal Error", err.Error(), p.SignInMessage)
221+ p.ErrorPage(rw, 500, "Internal Error", err.Error())
218 return
222 return
219 }
223 }
220 // validate user
224 // validate user
221 email, err := p.getUserInfo(token)
225 email, err := p.getUserInfo(token)
222 if err != nil {
226 if err != nil {
223 log.Printf("error redeeming code %s", err.Error())
227 log.Printf("error redeeming code %s", err.Error())
224− ErrorPage(rw, 500, "Internal Error", err.Error(), p.SignInMessage)
228+ p.ErrorPage(rw, 500, "Internal Error", err.Error())
225 return
229 return
226 }
230 }
227
231
@@ -246,10 +250,11 @@ func (p *OauthProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
246 http.Redirect(rw, req, "/", 302)
250 http.Redirect(rw, req, "/", 302)
247 return
251 return
248 } else {
252 } else {
249− ErrorPage(rw, 403, "Permission Denied", "Invalid Account", p.SignInMessage)
253+ p.ErrorPage(rw, 403, "Permission Denied", "Invalid Account")
250 return
254 return
251 }
255 }
252 }
256 }
257+
253 cookie, err := req.Cookie(p.CookieKey)
258 cookie, err := req.Cookie(p.CookieKey)
254 var ok bool
259 var ok bool
255 var email string
260 var email string
@@ -264,9 +269,8 @@ func (p *OauthProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
264 }
269 }
265
270
266 if !ok {
271 if !ok {
267− log.Printf("invalid cookie. redirecting to sign in")
272+ log.Printf("invalid cookie")
268− // TODO: capture state for which url to redirect to at the end
273+ p.SignInPage(rw, req, 403)
269− http.Redirect(rw, req, "/oauth2/sign_in", 302)
270 return
274 return
271 }
275 }
272
276
templates.go+2−4
@@ -18,16 +18,14 @@ func getTemplates() *template.Template {
18 if err != nil {
18 if err != nil {
19 log.Fatalf("failed parsing template %s", err.Error())
19 log.Fatalf("failed parsing template %s", err.Error())
20 }
20 }
21+
21 t, err = t.Parse(`{{define "error.html"}}
22 t, err = t.Parse(`{{define "error.html"}}
22<html><head><title>{{.Title}}</title></head>
23<html><head><title>{{.Title}}</title></head>
23<body>
24<body>
24 <h2>{{.Title}}</h2>
25 <h2>{{.Title}}</h2>
25 <p>{{.Message}}</p>
26 <p>{{.Message}}</p>
26 <hr>
27 <hr>
27− <form method="GET" action="/oauth2/start">
28+ <p><a href="/oauth2/sign_in">Sign In</a></p>
28− <button type="submit">Sign In w/ Google</button>
29− {{.SignInMessage}}
30− </form>
31</body>
29</body>
32</html>{{end}}`)
30</html>{{end}}`)
33 if err != nil {
31 if err != nil {