token_1.13.go raw

   1  //go:build go1.13
   2  // +build go1.13
   3  
   4  // Copyright 2017 Microsoft Corporation
   5  //
   6  //  Licensed under the Apache License, Version 2.0 (the "License");
   7  //  you may not use this file except in compliance with the License.
   8  //  You may obtain a copy of the License at
   9  //
  10  //      http://www.apache.org/licenses/LICENSE-2.0
  11  //
  12  //  Unless required by applicable law or agreed to in writing, software
  13  //  distributed under the License is distributed on an "AS IS" BASIS,
  14  //  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15  //  See the License for the specific language governing permissions and
  16  //  limitations under the License.
  17  
  18  package adal
  19  
  20  import (
  21  	"context"
  22  	"fmt"
  23  	"net/http"
  24  	"time"
  25  )
  26  
  27  func getMSIEndpoint(ctx context.Context, sender Sender) (*http.Response, error) {
  28  	tempCtx, cancel := context.WithTimeout(ctx, 2*time.Second)
  29  	defer cancel()
  30  	// http.NewRequestWithContext() was added in Go 1.13
  31  	req, _ := http.NewRequestWithContext(tempCtx, http.MethodGet, msiEndpoint, nil)
  32  	q := req.URL.Query()
  33  	q.Add("api-version", msiAPIVersion)
  34  	req.URL.RawQuery = q.Encode()
  35  	return sender.Do(req)
  36  }
  37  
  38  // EnsureFreshWithContext will refresh the token if it will expire within the refresh window (as set by
  39  // RefreshWithin) and autoRefresh flag is on.  This method is safe for concurrent use.
  40  func (mt *MultiTenantServicePrincipalToken) EnsureFreshWithContext(ctx context.Context) error {
  41  	if err := mt.PrimaryToken.EnsureFreshWithContext(ctx); err != nil {
  42  		return fmt.Errorf("failed to refresh primary token: %w", err)
  43  	}
  44  	for _, aux := range mt.AuxiliaryTokens {
  45  		if err := aux.EnsureFreshWithContext(ctx); err != nil {
  46  			return fmt.Errorf("failed to refresh auxiliary token: %w", err)
  47  		}
  48  	}
  49  	return nil
  50  }
  51  
  52  // RefreshWithContext obtains a fresh token for the Service Principal.
  53  func (mt *MultiTenantServicePrincipalToken) RefreshWithContext(ctx context.Context) error {
  54  	if err := mt.PrimaryToken.RefreshWithContext(ctx); err != nil {
  55  		return fmt.Errorf("failed to refresh primary token: %w", err)
  56  	}
  57  	for _, aux := range mt.AuxiliaryTokens {
  58  		if err := aux.RefreshWithContext(ctx); err != nil {
  59  			return fmt.Errorf("failed to refresh auxiliary token: %w", err)
  60  		}
  61  	}
  62  	return nil
  63  }
  64  
  65  // RefreshExchangeWithContext refreshes the token, but for a different resource.
  66  func (mt *MultiTenantServicePrincipalToken) RefreshExchangeWithContext(ctx context.Context, resource string) error {
  67  	if err := mt.PrimaryToken.RefreshExchangeWithContext(ctx, resource); err != nil {
  68  		return fmt.Errorf("failed to refresh primary token: %w", err)
  69  	}
  70  	for _, aux := range mt.AuxiliaryTokens {
  71  		if err := aux.RefreshExchangeWithContext(ctx, resource); err != nil {
  72  			return fmt.Errorf("failed to refresh auxiliary token: %w", err)
  73  		}
  74  	}
  75  	return nil
  76  }
  77