OLD | NEW |
1 // Copyright 2016 The LUCI Authors. All rights reserved. | 1 // Copyright 2016 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 delegation | 5 package delegation |
6 | 6 |
7 import ( | 7 import ( |
8 "bytes" | |
9 "io/ioutil" | |
10 "net/http" | 8 "net/http" |
11 "testing" | 9 "testing" |
12 "time" | 10 "time" |
13 | 11 |
14 "golang.org/x/net/context" | 12 "golang.org/x/net/context" |
15 | 13 |
16 "github.com/luci/luci-go/common/clock/testclock" | 14 "github.com/luci/luci-go/common/clock/testclock" |
17 "github.com/luci/luci-go/common/logging/memlogger" | 15 "github.com/luci/luci-go/common/logging/memlogger" |
18 "github.com/luci/luci-go/server/auth/identity" | 16 "github.com/luci/luci-go/server/auth/identity" |
19 "github.com/luci/luci-go/server/auth/internal" | 17 "github.com/luci/luci-go/server/auth/internal" |
20 | 18 |
21 . "github.com/luci/luci-go/common/testing/assertions" | 19 . "github.com/luci/luci-go/common/testing/assertions" |
22 . "github.com/smartystreets/goconvey/convey" | 20 . "github.com/smartystreets/goconvey/convey" |
23 ) | 21 ) |
24 | 22 |
25 func TestCreateToken(t *testing.T) { | 23 func TestCreateToken(t *testing.T) { |
26 ctx := memlogger.Use(context.Background()) | 24 ctx := memlogger.Use(context.Background()) |
27 ctx, _ = testclock.UseTime(ctx, testclock.TestRecentTimeUTC) | 25 ctx, _ = testclock.UseTime(ctx, testclock.TestRecentTimeUTC) |
28 | 26 |
29 goodReq := TokenRequest{ | 27 goodReq := TokenRequest{ |
30 AuthServiceURL: "example.com", | 28 AuthServiceURL: "example.com", |
31 Audience: []identity.Identity{"user:a@example.com"}, | 29 Audience: []identity.Identity{"user:a@example.com"}, |
32 AudienceGroups: []string{"group"}, | 30 AudienceGroups: []string{"group"}, |
33 TargetServices: []identity.Identity{"service:abc"}, | 31 TargetServices: []identity.Identity{"service:abc"}, |
34 Impersonate: "user:b@example.com", | 32 Impersonate: "user:b@example.com", |
35 ValidityDuration: time.Hour, | 33 ValidityDuration: time.Hour, |
36 Intent: "intent", | 34 Intent: "intent", |
37 } | 35 } |
38 | 36 |
39 » ctx, tr := withTestTransport(ctx, `{ | 37 » lastRequestBody := "" |
40 » » "delegation_token": "tok", | 38 » ctx = internal.WithTestTransport(ctx, func(r *http.Request, body string)
(int, string) { |
41 » » "validity_duration": 3600, | 39 » » lastRequestBody = body |
42 » » "subtoken_id": "123" | 40 » » return 200, `{ |
43 » }`) | 41 » » » "delegation_token": "tok", |
| 42 » » » "validity_duration": 3600, |
| 43 » » » "subtoken_id": "123" |
| 44 » » }` |
| 45 » }) |
44 | 46 |
45 Convey("Works", t, func() { | 47 Convey("Works", t, func() { |
46 tok, err := CreateToken(ctx, goodReq) | 48 tok, err := CreateToken(ctx, goodReq) |
47 So(err, ShouldBeNil) | 49 So(err, ShouldBeNil) |
48 So(tok, ShouldResemble, &Token{ | 50 So(tok, ShouldResemble, &Token{ |
49 Token: "tok", | 51 Token: "tok", |
50 SubtokenID: "123", | 52 SubtokenID: "123", |
51 Expiry: testclock.TestRecentTimeUTC.Add(time.Hour), | 53 Expiry: testclock.TestRecentTimeUTC.Add(time.Hour), |
52 }) | 54 }) |
53 » » So(tr.request, ShouldEqual, | 55 » » So(lastRequestBody, ShouldEqual, |
54 `{"audience":["user:a@example.com","group:group"],`+ | 56 `{"audience":["user:a@example.com","group:group"],`+ |
55 `"services":["service:abc"],"validity_duration":
3600,`+ | 57 `"services":["service:abc"],"validity_duration":
3600,`+ |
56 `"impersonate":"user:b@example.com","intent":"in
tent"}`) | 58 `"impersonate":"user:b@example.com","intent":"in
tent"}`) |
57 }) | 59 }) |
58 | 60 |
59 Convey("Audience check works", t, func() { | 61 Convey("Audience check works", t, func() { |
60 req := goodReq | 62 req := goodReq |
61 req.Audience = nil | 63 req.Audience = nil |
62 req.AudienceGroups = nil | 64 req.AudienceGroups = nil |
63 _, err := CreateToken(ctx, req) | 65 _, err := CreateToken(ctx, req) |
(...skipping 23 matching lines...) Expand all Loading... |
87 _, err = CreateToken(ctx, req) | 89 _, err = CreateToken(ctx, req) |
88 So(err, ShouldErrLike, "can't specify TargetServices for Untarge
ted=true token") | 90 So(err, ShouldErrLike, "can't specify TargetServices for Untarge
ted=true token") |
89 | 91 |
90 req = goodReq | 92 req = goodReq |
91 req.TargetServices = nil | 93 req.TargetServices = nil |
92 req.Untargeted = true | 94 req.Untargeted = true |
93 _, err = CreateToken(ctx, req) | 95 _, err = CreateToken(ctx, req) |
94 So(err, ShouldBeNil) | 96 So(err, ShouldBeNil) |
95 }) | 97 }) |
96 } | 98 } |
97 | |
98 var testTransportKey = "key for testTransport" | |
99 | |
100 func withTestTransport(c context.Context, response string) (context.Context, *te
stTransport) { | |
101 t := &testTransport{response: response} | |
102 return context.WithValue(c, &testTransportKey, t), t | |
103 } | |
104 | |
105 type testTransport struct { | |
106 response string | |
107 request string | |
108 } | |
109 | |
110 func (f *testTransport) RoundTrip(r *http.Request) (*http.Response, error) { | |
111 body, err := ioutil.ReadAll(r.Body) | |
112 r.Body.Close() | |
113 if err != nil { | |
114 return nil, err | |
115 } | |
116 f.request = string(body) | |
117 return &http.Response{ | |
118 StatusCode: 200, | |
119 Status: "OK", | |
120 Body: ioutil.NopCloser(bytes.NewReader([]byte(f.response))
), | |
121 }, nil | |
122 } | |
123 | |
124 func init() { | |
125 internal.RegisterClientFactory(func(c context.Context, scopes []string)
(*http.Client, error) { | |
126 return &http.Client{Transport: c.Value(&testTransportKey).(*test
Transport)}, nil | |
127 }) | |
128 } | |
OLD | NEW |