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

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: Update tests 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
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, handlers ...router.Handler) *httptest.Re sponseRecorder {
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 » » initializer := []router.Handler{func(ctx *router.Context) {
61 » » » ctx.Context = c
62 » » » ctx.Writer = w
63 » » » ctx.Request = req
64 » » }}
65 » » router.ChainHandlers(append(initializer, handlers...)...)()
62 return w 66 return w
63 } 67 }
64 68
65 » handler := func(c context.Context, rw http.ResponseWriter, r *http.Reque st, p httprouter.Params) { 69 » handler := func(c *router.Context) {
66 » » fmt.Fprintf(rw, "%s", CurrentIdentity(c)) 70 » » fmt.Fprintf(c.Writer, "%s", CurrentIdentity(c.Context))
67 } 71 }
68 72
69 Convey("Not configured", t, func() { 73 Convey("Not configured", t, func() {
70 » » rr := call(context.Background(), Authenticate(handler)) 74 » » rr := call(context.Background(), Authenticate(), handler)
71 So(rr.Code, ShouldEqual, 500) 75 So(rr.Code, ShouldEqual, 500)
72 So(rr.Body.String(), ShouldEqual, "Authentication middleware is not configured\n") 76 So(rr.Body.String(), ShouldEqual, "Authentication middleware is not configured\n")
73 }) 77 })
74 78
75 Convey("Transient error", t, func() { 79 Convey("Transient error", t, func() {
76 c := prepareCtx(fakeMethod{authError: errors.WrapTransient(error s.New("boo"))}) 80 c := prepareCtx(fakeMethod{authError: errors.WrapTransient(error s.New("boo"))})
77 » » rr := call(c, Authenticate(handler)) 81 » » rr := call(c, Authenticate(), handler)
78 So(rr.Code, ShouldEqual, 500) 82 So(rr.Code, ShouldEqual, 500)
79 So(rr.Body.String(), ShouldEqual, "Transient error during authen tication - boo\n") 83 So(rr.Body.String(), ShouldEqual, "Transient error during authen tication - boo\n")
80 }) 84 })
81 85
82 Convey("Fatal error", t, func() { 86 Convey("Fatal error", t, func() {
83 c := prepareCtx(fakeMethod{authError: errors.New("boo")}) 87 c := prepareCtx(fakeMethod{authError: errors.New("boo")})
84 » » rr := call(c, Authenticate(handler)) 88 » » rr := call(c, Authenticate(), handler)
85 So(rr.Code, ShouldEqual, 401) 89 So(rr.Code, ShouldEqual, 401)
86 So(rr.Body.String(), ShouldEqual, "Authentication error - boo\n" ) 90 So(rr.Body.String(), ShouldEqual, "Authentication error - boo\n" )
87 }) 91 })
88 92
89 Convey("Works", t, func() { 93 Convey("Works", t, func() {
90 c := prepareCtx(fakeMethod{userID: "user:abc@example.com"}) 94 c := prepareCtx(fakeMethod{userID: "user:abc@example.com"})
91 » » rr := call(c, Authenticate(handler)) 95 » » rr := call(c, Authenticate(), handler)
92 So(rr.Code, ShouldEqual, 200) 96 So(rr.Code, ShouldEqual, 200)
93 So(rr.Body.String(), ShouldEqual, "user:abc@example.com") 97 So(rr.Body.String(), ShouldEqual, "user:abc@example.com")
94 }) 98 })
95 99
96 Convey("Anonymous works", t, func() { 100 Convey("Anonymous works", t, func() {
97 c := prepareCtx(fakeMethod{anon: true}) 101 c := prepareCtx(fakeMethod{anon: true})
98 » » rr := call(c, Authenticate(handler)) 102 » » rr := call(c, Authenticate(), handler)
99 So(rr.Code, ShouldEqual, 200) 103 So(rr.Code, ShouldEqual, 200)
100 So(rr.Body.String(), ShouldEqual, "anonymous:anonymous") 104 So(rr.Body.String(), ShouldEqual, "anonymous:anonymous")
101 }) 105 })
102 106
103 Convey("Broken ID is rejected", t, func() { 107 Convey("Broken ID is rejected", t, func() {
104 c := prepareCtx(fakeMethod{userID: "???"}) 108 c := prepareCtx(fakeMethod{userID: "???"})
105 » » rr := call(c, Authenticate(handler)) 109 » » rr := call(c, Authenticate(), handler)
106 So(rr.Code, ShouldEqual, 401) 110 So(rr.Code, ShouldEqual, 401)
107 So(rr.Body.String(), ShouldEqual, "Authentication error - auth: bad identity string \"???\"\n") 111 So(rr.Body.String(), ShouldEqual, "Authentication error - auth: bad identity string \"???\"\n")
108 }) 112 })
109 } 113 }
110 114
111 func TestAutologin(t *testing.T) { 115 func TestAutologin(t *testing.T) {
112 » call := func(c context.Context, h middleware.Handler) *httptest.Response Recorder { 116 » call := func(c context.Context, handlers ...router.Handler) *httptest.Re sponseRecorder {
113 req, err := http.NewRequest("GET", "http://example.com/foo", nil ) 117 req, err := http.NewRequest("GET", "http://example.com/foo", nil )
114 So(err, ShouldBeNil) 118 So(err, ShouldBeNil)
115 w := httptest.NewRecorder() 119 w := httptest.NewRecorder()
116 » » h(c, w, req, nil) 120 » » initializer := []router.Handler{func(ctx *router.Context) {
121 » » » ctx.Context = c
122 » » » ctx.Writer = w
123 » » » ctx.Request = req
124 » » }}
125 » » router.ChainHandlers(append(initializer, handlers...)...)()
117 return w 126 return w
118 } 127 }
119 128
120 » handler := func(c context.Context, rw http.ResponseWriter, r *http.Reque st, p httprouter.Params) { 129 » handler := func(c *router.Context) {
121 » » fmt.Fprintf(rw, "%s", CurrentIdentity(c)) 130 » » fmt.Fprintf(c.Writer, "%s", CurrentIdentity(c.Context))
122 } 131 }
123 132
124 Convey("Not configured", t, func() { 133 Convey("Not configured", t, func() {
125 » » rr := call(context.Background(), Autologin(handler)) 134 » » rr := call(context.Background(), Autologin(), handler)
126 So(rr.Code, ShouldEqual, 500) 135 So(rr.Code, ShouldEqual, 500)
127 So(rr.Body.String(), ShouldEqual, "Authentication middleware is not configured\n") 136 So(rr.Body.String(), ShouldEqual, "Authentication middleware is not configured\n")
128 }) 137 })
129 138
130 Convey("Transient error", t, func() { 139 Convey("Transient error", t, func() {
131 c := prepareCtx(fakeMethod{authError: errors.WrapTransient(error s.New("boo"))}) 140 c := prepareCtx(fakeMethod{authError: errors.WrapTransient(error s.New("boo"))})
132 » » rr := call(c, Autologin(handler)) 141 » » rr := call(c, Autologin(), handler)
133 So(rr.Code, ShouldEqual, 500) 142 So(rr.Code, ShouldEqual, 500)
134 So(rr.Body.String(), ShouldEqual, "Transient error during authen tication - boo\n") 143 So(rr.Body.String(), ShouldEqual, "Transient error during authen tication - boo\n")
135 }) 144 })
136 145
137 Convey("Fatal error", t, func() { 146 Convey("Fatal error", t, func() {
138 c := prepareCtx(fakeMethod{authError: errors.New("boo")}) 147 c := prepareCtx(fakeMethod{authError: errors.New("boo")})
139 » » rr := call(c, Autologin(handler)) 148 » » rr := call(c, Autologin(), handler)
140 So(rr.Code, ShouldEqual, 401) 149 So(rr.Code, ShouldEqual, 401)
141 }) 150 })
142 151
143 Convey("Anonymous is redirected to login if has UsersAPI", t, func() { 152 Convey("Anonymous is redirected to login if has UsersAPI", t, func() {
144 c := prepareCtx(fakeMethod{anon: true}) 153 c := prepareCtx(fakeMethod{anon: true})
145 » » rr := call(c, Autologin(handler)) 154 » » rr := call(c, Autologin(), handler)
146 So(rr.Code, ShouldEqual, 302) 155 So(rr.Code, ShouldEqual, 302)
147 So(rr.Header().Get("Location"), ShouldEqual, "http://login_url?r =%2Ffoo") 156 So(rr.Header().Get("Location"), ShouldEqual, "http://login_url?r =%2Ffoo")
148 }) 157 })
149 158
150 Convey("Anonymous is rejected if no UsersAPI", t, func() { 159 Convey("Anonymous is rejected if no UsersAPI", t, func() {
151 c := prepareCtx(noUserAPI{}) 160 c := prepareCtx(noUserAPI{})
152 » » rr := call(c, Autologin(handler)) 161 » » rr := call(c, Autologin(), handler)
153 So(rr.Code, ShouldEqual, 401) 162 So(rr.Code, ShouldEqual, 401)
154 So(rr.Body.String(), ShouldEqual, "Authentication error - auth: methods do not support login or logout URL\n") 163 So(rr.Body.String(), ShouldEqual, "Authentication error - auth: methods do not support login or logout URL\n")
155 }) 164 })
156 165
157 Convey("Handles transient error in LoginURL", t, func() { 166 Convey("Handles transient error in LoginURL", t, func() {
158 c := prepareCtx(fakeMethod{anon: true, loginURLError: errors.Wra pTransient(errors.New("boo"))}) 167 c := prepareCtx(fakeMethod{anon: true, loginURLError: errors.Wra pTransient(errors.New("boo"))})
159 » » rr := call(c, Autologin(handler)) 168 » » rr := call(c, Autologin(), handler)
160 So(rr.Code, ShouldEqual, 500) 169 So(rr.Code, ShouldEqual, 500)
161 So(rr.Body.String(), ShouldEqual, "Transient error during authen tication - boo\n") 170 So(rr.Body.String(), ShouldEqual, "Transient error during authen tication - boo\n")
162 }) 171 })
163 172
164 Convey("Passes authenticated user through", t, func() { 173 Convey("Passes authenticated user through", t, func() {
165 c := prepareCtx(fakeMethod{userID: "user:abc@example.com"}) 174 c := prepareCtx(fakeMethod{userID: "user:abc@example.com"})
166 » » rr := call(c, Autologin(handler)) 175 » » rr := call(c, Autologin(), handler)
167 So(rr.Code, ShouldEqual, 200) 176 So(rr.Code, ShouldEqual, 200)
168 So(rr.Body.String(), ShouldEqual, "user:abc@example.com") 177 So(rr.Body.String(), ShouldEqual, "user:abc@example.com")
169 }) 178 })
170 } 179 }
171 180
172 func prepareCtx(m ...Method) context.Context { 181 func prepareCtx(m ...Method) context.Context {
173 c := SetAuthenticator(context.Background(), Authenticator(m)) 182 c := SetAuthenticator(context.Background(), Authenticator(m))
174 c = UseDB(c, func(context.Context) (DB, error) { 183 c = UseDB(c, func(context.Context) (DB, error) {
175 return &fakeDB{}, nil 184 return &fakeDB{}, nil
176 }) 185 })
(...skipping 30 matching lines...) Expand all
207 v := url.Values{} 216 v := url.Values{}
208 v.Set("r", dest) 217 v.Set("r", dest)
209 return "http://login_url?" + v.Encode(), nil 218 return "http://login_url?" + v.Encode(), nil
210 } 219 }
211 220
212 func (m fakeMethod) LogoutURL(c context.Context, dest string) (string, error) { 221 func (m fakeMethod) LogoutURL(c context.Context, dest string) (string, error) {
213 v := url.Values{} 222 v := url.Values{}
214 v.Set("r", dest) 223 v.Set("r", dest)
215 return "http://logout_url?" + v.Encode(), nil 224 return "http://logout_url?" + v.Encode(), nil
216 } 225 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698