OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 The LUCI Authors. All rights reserved. |
| 2 // Use of this source code is governed under the Apache License, Version 2.0 |
| 3 // that can be found in the LICENSE file. |
| 4 |
| 5 package delegation |
| 6 |
| 7 import ( |
| 8 "bytes" |
| 9 "io/ioutil" |
| 10 "net/http" |
| 11 "testing" |
| 12 "time" |
| 13 |
| 14 "golang.org/x/net/context" |
| 15 |
| 16 "github.com/luci/luci-go/common/clock/testclock" |
| 17 "github.com/luci/luci-go/common/logging/memlogger" |
| 18 "github.com/luci/luci-go/server/auth/identity" |
| 19 "github.com/luci/luci-go/server/auth/internal" |
| 20 |
| 21 . "github.com/luci/luci-go/common/testing/assertions" |
| 22 . "github.com/smartystreets/goconvey/convey" |
| 23 ) |
| 24 |
| 25 func TestCreateToken(t *testing.T) { |
| 26 ctx := memlogger.Use(context.Background()) |
| 27 ctx, _ = testclock.UseTime(ctx, testclock.TestRecentTimeUTC) |
| 28 |
| 29 goodReq := TokenRequest{ |
| 30 AuthServiceURL: "example.com", |
| 31 Audience: []identity.Identity{"user:a@example.com"}, |
| 32 AudienceGroups: []string{"group"}, |
| 33 TargetServices: []identity.Identity{"service:abc"}, |
| 34 Impersonate: "user:b@example.com", |
| 35 ValidityDuration: time.Hour, |
| 36 Intent: "intent", |
| 37 } |
| 38 |
| 39 ctx, tr := withTestTransport(ctx, `{ |
| 40 "delegation_token": "tok", |
| 41 "validity_duration": 3600, |
| 42 "subtoken_id": "123" |
| 43 }`) |
| 44 |
| 45 Convey("Works", t, func() { |
| 46 tok, err := CreateToken(ctx, goodReq) |
| 47 So(err, ShouldBeNil) |
| 48 So(tok, ShouldResemble, &Token{ |
| 49 Token: "tok", |
| 50 SubtokenID: "123", |
| 51 Expiry: testclock.TestRecentTimeUTC.Add(time.Hour), |
| 52 }) |
| 53 So(tr.request, ShouldEqual, |
| 54 `{"audience":["user:a@example.com","group:group"],`+ |
| 55 `"services":["service:abc"],"validity_duration":
3600,`+ |
| 56 `"impersonate":"user:b@example.com","intent":"in
tent"}`) |
| 57 }) |
| 58 |
| 59 Convey("Audience check works", t, func() { |
| 60 req := goodReq |
| 61 req.Audience = nil |
| 62 req.AudienceGroups = nil |
| 63 _, err := CreateToken(ctx, req) |
| 64 So(err, ShouldErrLike, "either Audience/AudienceGroups or Unlimi
tedAudience=true are required") |
| 65 |
| 66 req = goodReq |
| 67 req.UnlimitedAudience = true |
| 68 _, err = CreateToken(ctx, req) |
| 69 So(err, ShouldErrLike, "can't specify audience for UnlimitedAudi
ence=true token") |
| 70 |
| 71 req = goodReq |
| 72 req.Audience = nil |
| 73 req.AudienceGroups = nil |
| 74 req.UnlimitedAudience = true |
| 75 _, err = CreateToken(ctx, req) |
| 76 So(err, ShouldBeNil) |
| 77 }) |
| 78 |
| 79 Convey("Services check works", t, func() { |
| 80 req := goodReq |
| 81 req.TargetServices = nil |
| 82 _, err := CreateToken(ctx, req) |
| 83 So(err, ShouldErrLike, "either TargetServices or Untargeted=true
are required") |
| 84 |
| 85 req = goodReq |
| 86 req.Untargeted = true |
| 87 _, err = CreateToken(ctx, req) |
| 88 So(err, ShouldErrLike, "can't specify TargetServices for Untarge
ted=true token") |
| 89 |
| 90 req = goodReq |
| 91 req.TargetServices = nil |
| 92 req.Untargeted = true |
| 93 _, err = CreateToken(ctx, req) |
| 94 So(err, ShouldBeNil) |
| 95 }) |
| 96 } |
| 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 |