go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/auth/integration/authtest/faketokengen.go (about) 1 // Copyright 2017 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 authtest 16 17 import ( 18 "context" 19 "fmt" 20 "sync" 21 "time" 22 23 "golang.org/x/oauth2" 24 25 "go.chromium.org/luci/common/clock" 26 ) 27 28 // Defaults for FakeTokenGenerator. 29 const ( 30 DefaultFakeEmail = "fake_test@example.com" 31 DefaultFakeLifetime = 5 * time.Minute 32 ) 33 34 // FakeTokenGenerator implements localauth.TokenGenerator by returning fake 35 // data. 36 // 37 // Useful for integration tests that involve local auth server. 38 // 39 // Each GenerateOAuthToken and GenerateIDToken call returns a token 40 // "<prefix><N>", where "<prefix>" is by default "fake_token_" (it can be 41 // changed via Prefix) and N starts from 0 and incremented for each call. 42 // 43 // If KeepRecord is true, each generated token is recorded along with a list of 44 // scopes that were used to generate it. Use TokenScopes() to see what scopes 45 // have been used to generate a particular token. 46 type FakeTokenGenerator struct { 47 Email string // email of the default account (default "fake_test@example.com") 48 Prefix string // prefix of fake generated tokens (default "fake_token_") 49 Lifetime time.Duration // lifetime of the returned token (default 5 min) 50 KeepRecord bool // if true, record all generated tokens 51 52 m sync.Mutex 53 n int 54 toks map[string][]string // fake token => list of its scopes or an audience 55 } 56 57 // GenerateOAuthToken is part of TokenGenerator interface. 58 func (f *FakeTokenGenerator) GenerateOAuthToken(ctx context.Context, scopes []string, lifetime time.Duration) (*oauth2.Token, error) { 59 f.m.Lock() 60 defer f.m.Unlock() 61 62 pfx := "fake_token_" 63 if f.Prefix != "" { 64 pfx = f.Prefix 65 } 66 67 token := fmt.Sprintf("%s%d", pfx, f.n) 68 f.n++ 69 if f.KeepRecord { 70 if f.toks == nil { 71 f.toks = make(map[string][]string, 1) 72 } 73 f.toks[token] = append([]string(nil), scopes...) 74 } 75 76 tokenLifetime := f.Lifetime 77 if tokenLifetime == 0 { 78 tokenLifetime = DefaultFakeLifetime 79 } 80 81 return &oauth2.Token{ 82 AccessToken: token, 83 Expiry: clock.Now(ctx).Add(tokenLifetime), 84 }, nil 85 } 86 87 // GenerateIDToken is part of TokenGenerator interface. 88 func (f *FakeTokenGenerator) GenerateIDToken(ctx context.Context, audience string, lifetime time.Duration) (*oauth2.Token, error) { 89 // Reuse GenerateOAuthToken implementation. We are generating fake tokens 90 // after all. 91 return f.GenerateOAuthToken(ctx, []string{"audience:" + audience}, lifetime) 92 } 93 94 // GetEmail is part of TokenGenerator interface. 95 func (f *FakeTokenGenerator) GetEmail() (string, error) { 96 if f.Email == "" { 97 return DefaultFakeEmail, nil 98 } 99 return f.Email, nil 100 } 101 102 // TokenScopes returns scopes that were used to generate given fake token. 103 // 104 // Returns nil for unknown tokens or if KeepRecord is false and tokens weren't 105 // recorded. 106 func (f *FakeTokenGenerator) TokenScopes(token string) []string { 107 f.m.Lock() 108 defer f.m.Unlock() 109 return f.toks[token] 110 }