github.com/IBM-Cloud/bluemix-go@v0.0.0-20240314082800-4e02a69b84b2/authentication/uaa.go (about)

     1  package authentication
     2  
     3  import (
     4  	"encoding/base64"
     5  	"fmt"
     6  
     7  	bluemix "github.com/IBM-Cloud/bluemix-go"
     8  	"github.com/IBM-Cloud/bluemix-go/bmxerror"
     9  	"github.com/IBM-Cloud/bluemix-go/rest"
    10  )
    11  
    12  //UAAError ...
    13  type UAAError struct {
    14  	ErrorCode   string `json:"error"`
    15  	Description string `json:"error_description"`
    16  }
    17  
    18  //UAATokenResponse ...
    19  type UAATokenResponse struct {
    20  	AccessToken  string `json:"access_token"`
    21  	TokenType    string `json:"token_type"`
    22  	RefreshToken string `json:"refresh_token"`
    23  }
    24  
    25  //UAARepository ...
    26  type UAARepository struct {
    27  	config   *bluemix.Config
    28  	client   *rest.Client
    29  	endpoint string
    30  }
    31  
    32  //NewUAARepository ...
    33  func NewUAARepository(config *bluemix.Config, client *rest.Client) (*UAARepository, error) {
    34  	var endpoint string
    35  
    36  	if config.TokenProviderEndpoint != nil {
    37  		endpoint = *config.TokenProviderEndpoint
    38  	} else {
    39  		var err error
    40  		endpoint, err = config.EndpointLocator.UAAEndpoint()
    41  		if err != nil {
    42  			return nil, err
    43  		}
    44  	}
    45  	return &UAARepository{
    46  		config:   config,
    47  		client:   client,
    48  		endpoint: endpoint,
    49  	}, nil
    50  }
    51  
    52  //AuthenticatePassword ...
    53  func (auth *UAARepository) AuthenticatePassword(username string, password string) error {
    54  	return auth.getToken(map[string]string{
    55  		"grant_type": "password",
    56  		"username":   username,
    57  		"password":   password,
    58  	})
    59  }
    60  
    61  //AuthenticateSSO ...
    62  func (auth *UAARepository) AuthenticateSSO(passcode string) error {
    63  	return auth.getToken(map[string]string{
    64  		"grant_type": "password",
    65  		"passcode":   passcode,
    66  	})
    67  }
    68  
    69  //AuthenticateAPIKey ...
    70  func (auth *UAARepository) AuthenticateAPIKey(apiKey string) error {
    71  	return auth.AuthenticatePassword("apikey", apiKey)
    72  }
    73  
    74  //RefreshToken ...
    75  func (auth *UAARepository) RefreshToken() (string, error) {
    76  	err := auth.getToken(map[string]string{
    77  		"grant_type":    "refresh_token",
    78  		"refresh_token": auth.config.UAARefreshToken,
    79  	})
    80  	if err != nil {
    81  		return "", err
    82  	}
    83  
    84  	return auth.config.UAAAccessToken, nil
    85  }
    86  
    87  //GetPasscode ...
    88  func (auth *UAARepository) GetPasscode() (string, error) {
    89  	return "", nil
    90  }
    91  
    92  func (auth *UAARepository) getToken(data map[string]string) error {
    93  	request := rest.PostRequest(auth.endpoint+"/oauth/token").
    94  		Set("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte("cf:"))).
    95  		Field("scope", "")
    96  
    97  	for k, v := range data {
    98  		request.Field(k, v)
    99  	}
   100  
   101  	var tokens UAATokenResponse
   102  	var apiErr UAAError
   103  
   104  	resp, err := auth.client.Do(request, &tokens, &apiErr)
   105  	if err != nil {
   106  		return err
   107  	}
   108  	if apiErr.ErrorCode != "" {
   109  		if apiErr.ErrorCode == "invalid-token" {
   110  			return bmxerror.NewInvalidTokenError(apiErr.Description)
   111  		}
   112  		return bmxerror.NewRequestFailure(apiErr.ErrorCode, apiErr.Description, resp.StatusCode)
   113  	}
   114  
   115  	auth.config.UAAAccessToken = fmt.Sprintf("%s %s", tokens.TokenType, tokens.AccessToken)
   116  	auth.config.UAARefreshToken = tokens.RefreshToken
   117  	return nil
   118  }