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

Side by Side Diff: common/auth/localauth/server_test.go

Issue 2951553002: Extend LUCI_CONTEXT["local_auth"] protocol to understand accounts. (Closed)
Patch Set: Created 3 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 2017 The LUCI Authors. All rights reserved. 1 // Copyright 2017 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 localauth 5 package localauth
6 6
7 import ( 7 import (
8 "bytes" 8 "bytes"
9 "encoding/json" 9 "encoding/json"
10 "fmt" 10 "fmt"
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 func TestProtocol(t *testing.T) { 83 func TestProtocol(t *testing.T) {
84 t.Parallel() 84 t.Parallel()
85 85
86 ctx := context.Background() 86 ctx := context.Background()
87 ctx, _ = testclock.UseTime(ctx, testclock.TestRecentTimeLocal) 87 ctx, _ = testclock.UseTime(ctx, testclock.TestRecentTimeLocal)
88 88
89 Convey("With server", t, func(c C) { 89 Convey("With server", t, func(c C) {
90 // Use channels to pass mocked requests/responses back and forth . 90 // Use channels to pass mocked requests/responses back and forth .
91 requests := make(chan []string, 10000) 91 requests := make(chan []string, 10000)
92 responses := make(chan interface{}, 1) 92 responses := make(chan interface{}, 1)
93
94 testGen := func(ctx context.Context, scopes []string, lifetime t ime.Duration) (*oauth2.Token, error) {
Vadim Sh. 2017/06/19 20:16:28 no changes here, just moved
95 requests <- scopes
96 var resp interface{}
97 select {
98 case resp = <-responses:
99 default:
100 c.Println("Unexpected token request")
101 return nil, fmt.Errorf("Unexpected request")
102 }
103 switch resp := resp.(type) {
104 case error:
105 return nil, resp
106 case *oauth2.Token:
107 return resp, nil
108 default:
109 panic("unknown response")
110 }
111 }
112
93 s := Server{ 113 s := Server{
94 » » » TokenGenerator: func(ctx context.Context, scopes []strin g, lifetime time.Duration) (*oauth2.Token, error) { 114 » » » TokenGenerators: map[string]TokenGenerator{"acc_id": tes tGen},
95 » » » » requests <- scopes
96 » » » » var resp interface{}
97 » » » » select {
98 » » » » case resp = <-responses:
99 » » » » default:
100 » » » » » c.Println("Unexpected token request")
101 » » » » » return nil, fmt.Errorf("Unexpected reque st")
102 » » » » }
103 » » » » switch resp := resp.(type) {
104 » » » » case error:
105 » » » » » return nil, resp
106 » » » » case *oauth2.Token:
107 » » » » » return resp, nil
108 » » » » default:
109 » » » » » panic("unknown response")
110 » » » » }
111 » » » },
112 } 115 }
113 p, err := s.Initialize(ctx) 116 p, err := s.Initialize(ctx)
114 So(err, ShouldBeNil) 117 So(err, ShouldBeNil)
115 118
116 done := make(chan struct{}) 119 done := make(chan struct{})
117 go func() { 120 go func() {
118 s.Serve() 121 s.Serve()
119 close(done) 122 close(done)
120 }() 123 }()
121 defer func() { 124 defer func() {
122 s.Close() 125 s.Close()
123 <-done 126 <-done
124 }() 127 }()
125 128
126 goodRequest := func() *http.Request { 129 goodRequest := func() *http.Request {
127 return prepReq(p, "/rpc/LuciLocalAuthService.GetOAuthTok en", map[string]interface{}{ 130 return prepReq(p, "/rpc/LuciLocalAuthService.GetOAuthTok en", map[string]interface{}{
128 » » » » "scopes": []string{"B", "A"}, 131 » » » » "scopes": []string{"B", "A"},
129 » » » » "secret": p.Secret, 132 » » » » "secret": p.Secret,
133 » » » » "account_id": "acc_id",
130 }) 134 })
131 } 135 }
132 136
133 Convey("Happy path", func() { 137 Convey("Happy path", func() {
134 responses <- &oauth2.Token{ 138 responses <- &oauth2.Token{
135 AccessToken: "tok1", 139 AccessToken: "tok1",
136 Expiry: clock.Now(ctx).Add(30 * time.Minute ), 140 Expiry: clock.Now(ctx).Add(30 * time.Minute ),
137 } 141 }
138 So(call(goodRequest()), ShouldEqual, `HTTP 200 (json): { "access_token":"tok1","expiry":1454502906}`) 142 So(call(goodRequest()), ShouldEqual, `HTTP 200 (json): { "access_token":"tok1","expiry":1454502906}`)
139 So(<-requests, ShouldResemble, []string{"A", "B"}) 143 So(<-requests, ShouldResemble, []string{"A", "B"})
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 198
195 Convey("Unknown RPC method", func() { 199 Convey("Unknown RPC method", func() {
196 req := prepReq(p, "/rpc/LuciLocalAuthService.UnknownMeth od", map[string]interface{}{}) 200 req := prepReq(p, "/rpc/LuciLocalAuthService.UnknownMeth od", map[string]interface{}{})
197 So(call(req), ShouldEqual, `HTTP 404: Unknown RPC method "UnknownMethod"`) 201 So(call(req), ShouldEqual, `HTTP 404: Unknown RPC method "UnknownMethod"`)
198 }) 202 })
199 203
200 Convey("No scopes", func() { 204 Convey("No scopes", func() {
201 req := prepReq(p, "/rpc/LuciLocalAuthService.GetOAuthTok en", map[string]interface{}{ 205 req := prepReq(p, "/rpc/LuciLocalAuthService.GetOAuthTok en", map[string]interface{}{
202 "secret": p.Secret, 206 "secret": p.Secret,
203 }) 207 })
204 » » » So(call(req), ShouldEqual, `HTTP 400: Field "scopes" is required.`) 208 » » » So(call(req), ShouldEqual, `HTTP 400: Bad request: field "scopes" is required.`)
205 }) 209 })
206 210
207 Convey("No secret", func() { 211 Convey("No secret", func() {
208 req := prepReq(p, "/rpc/LuciLocalAuthService.GetOAuthTok en", map[string]interface{}{ 212 req := prepReq(p, "/rpc/LuciLocalAuthService.GetOAuthTok en", map[string]interface{}{
209 "scopes": []string{"B", "A"}, 213 "scopes": []string{"B", "A"},
210 }) 214 })
211 » » » So(call(req), ShouldEqual, `HTTP 400: Field "secret" is required.`) 215 » » » So(call(req), ShouldEqual, `HTTP 400: Bad request: field "secret" is required.`)
212 }) 216 })
213 217
214 Convey("Bad secret", func() { 218 Convey("Bad secret", func() {
215 req := prepReq(p, "/rpc/LuciLocalAuthService.GetOAuthTok en", map[string]interface{}{ 219 req := prepReq(p, "/rpc/LuciLocalAuthService.GetOAuthTok en", map[string]interface{}{
216 » » » » "scopes": []string{"B", "A"}, 220 » » » » "scopes": []string{"B", "A"},
217 » » » » "secret": []byte{0, 1, 2, 3}, 221 » » » » "secret": []byte{0, 1, 2, 3},
222 » » » » "account_id": "acc_id",
218 }) 223 })
219 So(call(req), ShouldEqual, `HTTP 403: Invalid secret.`) 224 So(call(req), ShouldEqual, `HTTP 403: Invalid secret.`)
220 }) 225 })
221 226
227 Convey("No account ID", func() {
228 req := prepReq(p, "/rpc/LuciLocalAuthService.GetOAuthTok en", map[string]interface{}{
229 "scopes": []string{"B", "A"},
230 "secret": p.Secret,
231 })
232 So(call(req), ShouldEqual, `HTTP 400: Bad request: field "account_id" is required.`)
233 })
234
235 Convey("Unknown account ID", func() {
236 req := prepReq(p, "/rpc/LuciLocalAuthService.GetOAuthTok en", map[string]interface{}{
237 "scopes": []string{"B", "A"},
238 "secret": p.Secret,
239 "account_id": "unknown_acc_id",
240 })
241 So(call(req), ShouldEqual, `HTTP 404: Unrecognized accou nt ID "unknown_acc_id".`)
242 })
243
222 Convey("Token generator returns fatal error", func() { 244 Convey("Token generator returns fatal error", func() {
223 responses <- fmt.Errorf("fatal!!111") 245 responses <- fmt.Errorf("fatal!!111")
224 So(call(goodRequest()), ShouldEqual, `HTTP 200 (json): { "error_code":-1,"error_message":"fatal!!111"}`) 246 So(call(goodRequest()), ShouldEqual, `HTTP 200 (json): { "error_code":-1,"error_message":"fatal!!111"}`)
225 }) 247 })
226 248
227 Convey("Token generator returns ErrorWithCode", func() { 249 Convey("Token generator returns ErrorWithCode", func() {
228 responses <- errWithCode{ 250 responses <- errWithCode{
229 error: fmt.Errorf("with code"), 251 error: fmt.Errorf("with code"),
230 code: 123, 252 code: 123,
231 } 253 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 panic(err) 307 panic(err)
286 } 308 }
287 309
288 tp := "" 310 tp := ""
289 if resp.Header.Get("Content-Type") == "application/json; charset=utf-8" { 311 if resp.Header.Get("Content-Type") == "application/json; charset=utf-8" {
290 tp = " (json)" 312 tp = " (json)"
291 } 313 }
292 314
293 return fmt.Sprintf("HTTP %d%s: %s", resp.StatusCode, tp, strings.TrimSpa ce(string(blob))) 315 return fmt.Sprintf("HTTP %d%s: %s", resp.StatusCode, tp, strings.TrimSpa ce(string(blob)))
294 } 316 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698