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  }