Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(379)

Side by Side Diff: server/auth/xsrf/xsrf.go

Issue 2043423004: Make HTTP middleware easier to use (Closed) Base URL: https://github.com/luci/luci-go@master
Patch Set: gaemiddleware: add middleware func for WithProd Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « server/auth/signing/context_test.go ('k') | server/auth/xsrf/xsrf_test.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The LUCI Authors. All rights reserved. 1 // Copyright 2015 The LUCI Authors. All rights reserved.
2 // Use of this source code is governed under the Apache License, Version 2.0 2 // Use of this source code is governed under the Apache License, Version 2.0
3 // that can be found in the LICENSE file. 3 // that can be found in the LICENSE file.
4 4
5 // Package xsrf provides Cross Site Request Forgery prevention middleware. 5 // Package xsrf provides Cross Site Request Forgery prevention middleware.
6 // 6 //
7 // Usage: 7 // Usage:
8 // 1. When serving GET request put hidden "xsrf_token" input field with 8 // 1. When serving GET request put hidden "xsrf_token" input field with
9 // the token value into the form. Use TokenField(...) to generate it. 9 // the token value into the form. Use TokenField(...) to generate it.
10 // 2. Wrap POST-handling route with WithTokenCheck(...) middleware. 10 // 2. Wrap POST-handling route with WithTokenCheck(...) middleware.
11 package xsrf 11 package xsrf
12 12
13 import ( 13 import (
14 "fmt" 14 "fmt"
15 "html/template" 15 "html/template"
16 "net/http" 16 "net/http"
17 "time" 17 "time"
18 18
19 "github.com/julienschmidt/httprouter"
20 "golang.org/x/net/context" 19 "golang.org/x/net/context"
21 20
22 "github.com/luci/luci-go/common/errors" 21 "github.com/luci/luci-go/common/errors"
23 "github.com/luci/luci-go/common/logging" 22 "github.com/luci/luci-go/common/logging"
24 23
25 "github.com/luci/luci-go/server/auth" 24 "github.com/luci/luci-go/server/auth"
26 » "github.com/luci/luci-go/server/middleware" 25 » "github.com/luci/luci-go/server/router"
27 "github.com/luci/luci-go/server/tokens" 26 "github.com/luci/luci-go/server/tokens"
28 ) 27 )
29 28
30 // xsrfToken described how to generate tokens. 29 // xsrfToken described how to generate tokens.
31 var xsrfToken = tokens.TokenKind{ 30 var xsrfToken = tokens.TokenKind{
32 Algo: tokens.TokenAlgoHmacSHA256, 31 Algo: tokens.TokenAlgoHmacSHA256,
33 Expiration: 4 * time.Hour, 32 Expiration: 4 * time.Hour,
34 SecretKey: "xsrf_token", 33 SecretKey: "xsrf_token",
35 Version: 1, 34 Version: 1,
36 } 35 }
(...skipping 26 matching lines...) Expand all
63 panic(err) 62 panic(err)
64 } 63 }
65 return template.HTML(fmt.Sprintf(`<input type="hidden" name="xsrf_token" value="%s">`, tok)) 64 return template.HTML(fmt.Sprintf(`<input type="hidden" name="xsrf_token" value="%s">`, tok))
66 } 65 }
67 66
68 // WithTokenCheck is middleware that checks validity of XSRF tokens. 67 // WithTokenCheck is middleware that checks validity of XSRF tokens.
69 // 68 //
70 // If searches for the token in "xsrf_token" POST form field (as generated by 69 // If searches for the token in "xsrf_token" POST form field (as generated by
71 // TokenField). Aborts the request with HTTP 403 if XSRF token is missing or 70 // TokenField). Aborts the request with HTTP 403 if XSRF token is missing or
72 // invalid. 71 // invalid.
73 func WithTokenCheck(h middleware.Handler) middleware.Handler { 72 func WithTokenCheck(c *router.Context, next router.Handler) {
74 » return func(c context.Context, rw http.ResponseWriter, r *http.Request, p httprouter.Params) { 73 » tok := c.Request.PostFormValue("xsrf_token")
75 » » tok := r.PostFormValue("xsrf_token") 74 » if tok == "" {
76 » » if tok == "" { 75 » » replyError(c.Context, c.Writer, http.StatusForbidden, "XSRF toke n is missing")
77 » » » replyError(c, rw, http.StatusForbidden, "XSRF token is m issing") 76 » » return
78 » » » return 77 » }
79 » » } 78 » switch err := Check(c.Context, tok); {
80 » » switch err := Check(c, tok); { 79 » case errors.IsTransient(err):
81 » » case errors.IsTransient(err): 80 » » replyError(c.Context, c.Writer, http.StatusInternalServerError, "Transient error when checking XSRF token - %s", err)
82 » » » replyError(c, rw, http.StatusInternalServerError, "Trans ient error when checking XSRF token - %s", err) 81 » case err != nil:
83 » » case err != nil: 82 » » replyError(c.Context, c.Writer, http.StatusForbidden, "Bad XSRF token - %s", err)
84 » » » replyError(c, rw, http.StatusForbidden, "Bad XSRF token - %s", err) 83 » default:
85 » » default: 84 » » next(c)
86 » » » h(c, rw, r, p)
87 » » }
88 } 85 }
89 } 86 }
90 87
91 /// 88 ///
92 89
93 // state must return exact same value when generating and verifying token for 90 // state must return exact same value when generating and verifying token for
94 // the verification to succeed. 91 // the verification to succeed.
95 func state(c context.Context) []byte { 92 func state(c context.Context) []byte {
96 return []byte(auth.CurrentUser(c).Identity) 93 return []byte(auth.CurrentUser(c).Identity)
97 } 94 }
98 95
99 // replyError sends error response and logs it. 96 // replyError sends error response and logs it.
100 func replyError(c context.Context, rw http.ResponseWriter, code int, msg string, args ...interface{}) { 97 func replyError(c context.Context, rw http.ResponseWriter, code int, msg string, args ...interface{}) {
101 text := fmt.Sprintf(msg, args...) 98 text := fmt.Sprintf(msg, args...)
102 logging.Errorf(c, "xsrf: %s", text) 99 logging.Errorf(c, "xsrf: %s", text)
103 http.Error(rw, text, code) 100 http.Error(rw, text, code)
104 } 101 }
OLDNEW
« no previous file with comments | « server/auth/signing/context_test.go ('k') | server/auth/xsrf/xsrf_test.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698