go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/server/auth/delegation_test.go (about) 1 // Copyright 2016 The LUCI Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package auth 16 17 import ( 18 "context" 19 "testing" 20 "time" 21 22 "google.golang.org/grpc" 23 24 "go.chromium.org/luci/common/clock" 25 "go.chromium.org/luci/common/clock/testclock" 26 "go.chromium.org/luci/tokenserver/api/minter/v1" 27 28 "go.chromium.org/luci/server/auth/delegation/messages" 29 "go.chromium.org/luci/server/caching" 30 31 . "github.com/smartystreets/goconvey/convey" 32 ) 33 34 type delegationTokenMinterMock struct { 35 request minter.MintDelegationTokenRequest 36 response minter.MintDelegationTokenResponse 37 err error 38 } 39 40 func (m *delegationTokenMinterMock) MintDelegationToken(ctx context.Context, in *minter.MintDelegationTokenRequest, opts ...grpc.CallOption) (*minter.MintDelegationTokenResponse, error) { 41 m.request = *in 42 if m.err != nil { 43 return nil, m.err 44 } 45 return &m.response, nil 46 } 47 48 func TestMintDelegationToken(t *testing.T) { 49 t.Parallel() 50 51 Convey("MintDelegationToken works", t, func() { 52 ctx := context.Background() 53 ctx, _ = testclock.UseTime(ctx, testclock.TestRecentTimeUTC) 54 ctx = caching.WithEmptyProcessCache(ctx) 55 ctx = Initialize(ctx, &Config{}) 56 57 mockedClient := &delegationTokenMinterMock{ 58 response: minter.MintDelegationTokenResponse{ 59 Token: "tok", 60 DelegationSubtoken: &messages.Subtoken{ 61 Kind: messages.Subtoken_BEARER_DELEGATION_TOKEN, 62 ValidityDuration: int32(MaxDelegationTokenTTL.Seconds()), 63 }, 64 }, 65 } 66 67 ctx = WithState(ctx, &state{ 68 user: &User{Identity: "user:abc@example.com"}, 69 db: &fakeDB{tokenServiceURL: "https://tokens.example.com"}, 70 }) 71 72 Convey("Works (including caching)", func(c C) { 73 tok, err := MintDelegationToken(ctx, DelegationTokenParams{ 74 TargetHost: "hostname.example.com", 75 MinTTL: time.Hour, 76 Tags: []string{"c:d", "a:b"}, 77 Intent: "intent", 78 rpcClient: mockedClient, 79 }) 80 So(err, ShouldBeNil) 81 So(tok, ShouldResemble, &Token{ 82 Token: "tok", 83 Expiry: testclock.TestRecentTimeUTC.Add(MaxDelegationTokenTTL), 84 }) 85 So(mockedClient.request, ShouldResemble, minter.MintDelegationTokenRequest{ 86 DelegatedIdentity: "user:abc@example.com", 87 ValidityDuration: 10800, 88 Audience: []string{"REQUESTOR"}, 89 Services: []string{"https://hostname.example.com"}, 90 Intent: "intent", 91 Tags: []string{"a:b", "c:d"}, 92 }) 93 94 // Cached now. 95 So(delegationTokenCache.lc.CachedLocally(ctx), ShouldEqual, 1) 96 97 // On subsequence request the cached token is used. 98 mockedClient.response.Token = "another token" 99 tok, err = MintDelegationToken(ctx, DelegationTokenParams{ 100 TargetHost: "hostname.example.com", 101 MinTTL: time.Hour, 102 Intent: "intent", 103 Tags: []string{"c:d", "a:b"}, 104 rpcClient: mockedClient, 105 }) 106 So(err, ShouldBeNil) 107 So(tok.Token, ShouldResemble, "tok") // old one 108 109 // Unless it expires sooner than requested TTL. 110 clock.Get(ctx).(testclock.TestClock).Add(MaxDelegationTokenTTL - 30*time.Minute) 111 tok, err = MintDelegationToken(ctx, DelegationTokenParams{ 112 TargetHost: "hostname.example.com", 113 MinTTL: time.Hour, 114 Intent: "intent", 115 Tags: []string{"c:d", "a:b"}, 116 rpcClient: mockedClient, 117 }) 118 So(err, ShouldBeNil) 119 So(tok.Token, ShouldResemble, "another token") // new one 120 }) 121 122 Convey("Untargeted token works", func(c C) { 123 tok, err := MintDelegationToken(ctx, DelegationTokenParams{ 124 Untargeted: true, 125 MinTTL: time.Hour, 126 Intent: "intent", 127 rpcClient: mockedClient, 128 }) 129 So(err, ShouldBeNil) 130 So(tok, ShouldResemble, &Token{ 131 Token: "tok", 132 Expiry: testclock.TestRecentTimeUTC.Add(MaxDelegationTokenTTL), 133 }) 134 So(mockedClient.request, ShouldResemble, minter.MintDelegationTokenRequest{ 135 DelegatedIdentity: "user:abc@example.com", 136 ValidityDuration: 10800, 137 Audience: []string{"REQUESTOR"}, 138 Services: []string{"*"}, 139 Intent: "intent", 140 }) 141 }) 142 }) 143 }