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

Side by Side Diff: server/auth/context_test.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/context.go ('k') | server/auth/db.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 auth 5 package auth
6 6
7 import ( 7 import (
8 "fmt" 8 "fmt"
9 "net/http" 9 "net/http"
10 "net/http/httptest" 10 "net/http/httptest"
11 "net/url" 11 "net/url"
12 "testing" 12 "testing"
13 13
14 "github.com/julienschmidt/httprouter"
15 "golang.org/x/net/context" 14 "golang.org/x/net/context"
16 15
17 "github.com/luci/luci-go/common/errors" 16 "github.com/luci/luci-go/common/errors"
18 "github.com/luci/luci-go/server/auth/identity" 17 "github.com/luci/luci-go/server/auth/identity"
19 » "github.com/luci/luci-go/server/middleware" 18 » "github.com/luci/luci-go/server/router"
20 . "github.com/smartystreets/goconvey/convey" 19 . "github.com/smartystreets/goconvey/convey"
21 ) 20 )
22 21
23 func TestContext(t *testing.T) { 22 func TestContext(t *testing.T) {
24 Convey("Works", t, func() { 23 Convey("Works", t, func() {
25 c := context.Background() 24 c := context.Background()
26 25
27 So(GetAuthenticator(c), ShouldBeNil) 26 So(GetAuthenticator(c), ShouldBeNil)
28 _, err := LoginURL(c, "dest") 27 _, err := LoginURL(c, "dest")
29 So(err, ShouldEqual, ErrNoUsersAPI) 28 So(err, ShouldEqual, ErrNoUsersAPI)
(...skipping 17 matching lines...) Expand all
47 So(err, ShouldBeNil) 46 So(err, ShouldBeNil)
48 So(dest, ShouldEqual, "http://login_url?r=dest") 47 So(dest, ShouldEqual, "http://login_url?r=dest")
49 dest, err = LogoutURL(c, "dest") 48 dest, err = LogoutURL(c, "dest")
50 So(err, ShouldBeNil) 49 So(err, ShouldBeNil)
51 So(dest, ShouldEqual, "http://logout_url?r=dest") 50 So(dest, ShouldEqual, "http://logout_url?r=dest")
52 }) 51 })
53 52
54 } 53 }
55 54
56 func TestContextAuthenticate(t *testing.T) { 55 func TestContextAuthenticate(t *testing.T) {
57 » call := func(c context.Context, h middleware.Handler) *httptest.Response Recorder { 56 » call := func(c context.Context, m router.MiddlewareChain, h router.Handl er) *httptest.ResponseRecorder {
58 req, err := http.NewRequest("GET", "http://example.com/foo", nil ) 57 req, err := http.NewRequest("GET", "http://example.com/foo", nil )
59 So(err, ShouldBeNil) 58 So(err, ShouldBeNil)
60 w := httptest.NewRecorder() 59 w := httptest.NewRecorder()
61 » » h(c, w, req, nil) 60 » » router.RunMiddleware(&router.Context{
61 » » » Context: c,
62 » » » Writer: w,
63 » » » Request: req,
64 » » }, m, h)
62 return w 65 return w
63 } 66 }
64 67
65 » handler := func(c context.Context, rw http.ResponseWriter, r *http.Reque st, p httprouter.Params) { 68 » handler := func(c *router.Context) {
66 » » fmt.Fprintf(rw, "%s", CurrentIdentity(c)) 69 » » fmt.Fprintf(c.Writer, "%s", CurrentIdentity(c.Context))
67 } 70 }
68 71
69 Convey("Not configured", t, func() { 72 Convey("Not configured", t, func() {
70 » » rr := call(context.Background(), Authenticate(handler)) 73 » » rr := call(context.Background(), router.MiddlewareChain{Authenti cate}, handler)
71 So(rr.Code, ShouldEqual, 500) 74 So(rr.Code, ShouldEqual, 500)
72 So(rr.Body.String(), ShouldEqual, "Authentication middleware is not configured\n") 75 So(rr.Body.String(), ShouldEqual, "Authentication middleware is not configured\n")
73 }) 76 })
74 77
75 Convey("Transient error", t, func() { 78 Convey("Transient error", t, func() {
76 c := prepareCtx(fakeMethod{authError: errors.WrapTransient(error s.New("boo"))}) 79 c := prepareCtx(fakeMethod{authError: errors.WrapTransient(error s.New("boo"))})
77 » » rr := call(c, Authenticate(handler)) 80 » » rr := call(c, router.MiddlewareChain{Authenticate}, handler)
78 So(rr.Code, ShouldEqual, 500) 81 So(rr.Code, ShouldEqual, 500)
79 So(rr.Body.String(), ShouldEqual, "Transient error during authen tication - boo\n") 82 So(rr.Body.String(), ShouldEqual, "Transient error during authen tication - boo\n")
80 }) 83 })
81 84
82 Convey("Fatal error", t, func() { 85 Convey("Fatal error", t, func() {
83 c := prepareCtx(fakeMethod{authError: errors.New("boo")}) 86 c := prepareCtx(fakeMethod{authError: errors.New("boo")})
84 » » rr := call(c, Authenticate(handler)) 87 » » rr := call(c, router.MiddlewareChain{Authenticate}, handler)
85 So(rr.Code, ShouldEqual, 401) 88 So(rr.Code, ShouldEqual, 401)
86 So(rr.Body.String(), ShouldEqual, "Authentication error - boo\n" ) 89 So(rr.Body.String(), ShouldEqual, "Authentication error - boo\n" )
87 }) 90 })
88 91
89 Convey("Works", t, func() { 92 Convey("Works", t, func() {
90 c := prepareCtx(fakeMethod{userID: "user:abc@example.com"}) 93 c := prepareCtx(fakeMethod{userID: "user:abc@example.com"})
91 » » rr := call(c, Authenticate(handler)) 94 » » rr := call(c, router.MiddlewareChain{Authenticate}, handler)
92 So(rr.Code, ShouldEqual, 200) 95 So(rr.Code, ShouldEqual, 200)
93 So(rr.Body.String(), ShouldEqual, "user:abc@example.com") 96 So(rr.Body.String(), ShouldEqual, "user:abc@example.com")
94 }) 97 })
95 98
96 Convey("Anonymous works", t, func() { 99 Convey("Anonymous works", t, func() {
97 c := prepareCtx(fakeMethod{anon: true}) 100 c := prepareCtx(fakeMethod{anon: true})
98 » » rr := call(c, Authenticate(handler)) 101 » » rr := call(c, router.MiddlewareChain{Authenticate}, handler)
99 So(rr.Code, ShouldEqual, 200) 102 So(rr.Code, ShouldEqual, 200)
100 So(rr.Body.String(), ShouldEqual, "anonymous:anonymous") 103 So(rr.Body.String(), ShouldEqual, "anonymous:anonymous")
101 }) 104 })
102 105
103 Convey("Broken ID is rejected", t, func() { 106 Convey("Broken ID is rejected", t, func() {
104 c := prepareCtx(fakeMethod{userID: "???"}) 107 c := prepareCtx(fakeMethod{userID: "???"})
105 » » rr := call(c, Authenticate(handler)) 108 » » rr := call(c, router.MiddlewareChain{Authenticate}, handler)
106 So(rr.Code, ShouldEqual, 401) 109 So(rr.Code, ShouldEqual, 401)
107 So(rr.Body.String(), ShouldEqual, "Authentication error - auth: bad identity string \"???\"\n") 110 So(rr.Body.String(), ShouldEqual, "Authentication error - auth: bad identity string \"???\"\n")
108 }) 111 })
109 } 112 }
110 113
111 func TestAutologin(t *testing.T) { 114 func TestAutologin(t *testing.T) {
112 » call := func(c context.Context, h middleware.Handler) *httptest.Response Recorder { 115 » call := func(c context.Context, m router.MiddlewareChain, h router.Handl er) *httptest.ResponseRecorder {
113 req, err := http.NewRequest("GET", "http://example.com/foo", nil ) 116 req, err := http.NewRequest("GET", "http://example.com/foo", nil )
114 So(err, ShouldBeNil) 117 So(err, ShouldBeNil)
115 w := httptest.NewRecorder() 118 w := httptest.NewRecorder()
116 » » h(c, w, req, nil) 119 » » router.RunMiddleware(&router.Context{
120 » » » Context: c,
121 » » » Writer: w,
122 » » » Request: req,
123 » » }, m, h)
117 return w 124 return w
118 } 125 }
119 126
120 » handler := func(c context.Context, rw http.ResponseWriter, r *http.Reque st, p httprouter.Params) { 127 » handler := func(c *router.Context) {
121 » » fmt.Fprintf(rw, "%s", CurrentIdentity(c)) 128 » » fmt.Fprintf(c.Writer, "%s", CurrentIdentity(c.Context))
122 } 129 }
123 130
124 Convey("Not configured", t, func() { 131 Convey("Not configured", t, func() {
125 » » rr := call(context.Background(), Autologin(handler)) 132 » » rr := call(context.Background(), router.MiddlewareChain{Autologi n}, handler)
126 So(rr.Code, ShouldEqual, 500) 133 So(rr.Code, ShouldEqual, 500)
127 So(rr.Body.String(), ShouldEqual, "Authentication middleware is not configured\n") 134 So(rr.Body.String(), ShouldEqual, "Authentication middleware is not configured\n")
128 }) 135 })
129 136
130 Convey("Transient error", t, func() { 137 Convey("Transient error", t, func() {
131 c := prepareCtx(fakeMethod{authError: errors.WrapTransient(error s.New("boo"))}) 138 c := prepareCtx(fakeMethod{authError: errors.WrapTransient(error s.New("boo"))})
132 » » rr := call(c, Autologin(handler)) 139 » » rr := call(c, router.MiddlewareChain{Autologin}, handler)
133 So(rr.Code, ShouldEqual, 500) 140 So(rr.Code, ShouldEqual, 500)
134 So(rr.Body.String(), ShouldEqual, "Transient error during authen tication - boo\n") 141 So(rr.Body.String(), ShouldEqual, "Transient error during authen tication - boo\n")
135 }) 142 })
136 143
137 Convey("Fatal error", t, func() { 144 Convey("Fatal error", t, func() {
138 c := prepareCtx(fakeMethod{authError: errors.New("boo")}) 145 c := prepareCtx(fakeMethod{authError: errors.New("boo")})
139 » » rr := call(c, Autologin(handler)) 146 » » rr := call(c, router.MiddlewareChain{Autologin}, handler)
140 So(rr.Code, ShouldEqual, 401) 147 So(rr.Code, ShouldEqual, 401)
141 }) 148 })
142 149
143 Convey("Anonymous is redirected to login if has UsersAPI", t, func() { 150 Convey("Anonymous is redirected to login if has UsersAPI", t, func() {
144 c := prepareCtx(fakeMethod{anon: true}) 151 c := prepareCtx(fakeMethod{anon: true})
145 » » rr := call(c, Autologin(handler)) 152 » » rr := call(c, router.MiddlewareChain{Autologin}, handler)
146 So(rr.Code, ShouldEqual, 302) 153 So(rr.Code, ShouldEqual, 302)
147 So(rr.Header().Get("Location"), ShouldEqual, "http://login_url?r =%2Ffoo") 154 So(rr.Header().Get("Location"), ShouldEqual, "http://login_url?r =%2Ffoo")
148 }) 155 })
149 156
150 Convey("Anonymous is rejected if no UsersAPI", t, func() { 157 Convey("Anonymous is rejected if no UsersAPI", t, func() {
151 c := prepareCtx(noUserAPI{}) 158 c := prepareCtx(noUserAPI{})
152 » » rr := call(c, Autologin(handler)) 159 » » rr := call(c, router.MiddlewareChain{Autologin}, handler)
153 So(rr.Code, ShouldEqual, 401) 160 So(rr.Code, ShouldEqual, 401)
154 So(rr.Body.String(), ShouldEqual, "Authentication error - auth: methods do not support login or logout URL\n") 161 So(rr.Body.String(), ShouldEqual, "Authentication error - auth: methods do not support login or logout URL\n")
155 }) 162 })
156 163
157 Convey("Handles transient error in LoginURL", t, func() { 164 Convey("Handles transient error in LoginURL", t, func() {
158 c := prepareCtx(fakeMethod{anon: true, loginURLError: errors.Wra pTransient(errors.New("boo"))}) 165 c := prepareCtx(fakeMethod{anon: true, loginURLError: errors.Wra pTransient(errors.New("boo"))})
159 » » rr := call(c, Autologin(handler)) 166 » » rr := call(c, router.MiddlewareChain{Autologin}, handler)
160 So(rr.Code, ShouldEqual, 500) 167 So(rr.Code, ShouldEqual, 500)
161 So(rr.Body.String(), ShouldEqual, "Transient error during authen tication - boo\n") 168 So(rr.Body.String(), ShouldEqual, "Transient error during authen tication - boo\n")
162 }) 169 })
163 170
164 Convey("Passes authenticated user through", t, func() { 171 Convey("Passes authenticated user through", t, func() {
165 c := prepareCtx(fakeMethod{userID: "user:abc@example.com"}) 172 c := prepareCtx(fakeMethod{userID: "user:abc@example.com"})
166 » » rr := call(c, Autologin(handler)) 173 » » rr := call(c, router.MiddlewareChain{Autologin}, handler)
167 So(rr.Code, ShouldEqual, 200) 174 So(rr.Code, ShouldEqual, 200)
168 So(rr.Body.String(), ShouldEqual, "user:abc@example.com") 175 So(rr.Body.String(), ShouldEqual, "user:abc@example.com")
169 }) 176 })
170 } 177 }
171 178
172 func prepareCtx(m ...Method) context.Context { 179 func prepareCtx(m ...Method) context.Context {
173 c := SetAuthenticator(context.Background(), Authenticator(m)) 180 c := SetAuthenticator(context.Background(), Authenticator(m))
174 c = UseDB(c, func(context.Context) (DB, error) { 181 c = UseDB(c, func(context.Context) (DB, error) {
175 return &fakeDB{}, nil 182 return &fakeDB{}, nil
176 }) 183 })
(...skipping 30 matching lines...) Expand all
207 v := url.Values{} 214 v := url.Values{}
208 v.Set("r", dest) 215 v.Set("r", dest)
209 return "http://login_url?" + v.Encode(), nil 216 return "http://login_url?" + v.Encode(), nil
210 } 217 }
211 218
212 func (m fakeMethod) LogoutURL(c context.Context, dest string) (string, error) { 219 func (m fakeMethod) LogoutURL(c context.Context, dest string) (string, error) {
213 v := url.Values{} 220 v := url.Values{}
214 v.Set("r", dest) 221 v.Set("r", dest)
215 return "http://logout_url?" + v.Encode(), nil 222 return "http://logout_url?" + v.Encode(), nil
216 } 223 }
OLDNEW
« no previous file with comments | « server/auth/context.go ('k') | server/auth/db.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698