github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/internal/domain/onetimetoken/token.go (about)

     1  package onetimetoken
     2  
     3  import (
     4  	"context"
     5  	"encoding/base64"
     6  	"encoding/json"
     7  	"fmt"
     8  	"net/http"
     9  	"net/url"
    10  	"strings"
    11  
    12  	"github.com/kyma-incubator/compass/components/director/pkg/graphql"
    13  	"github.com/kyma-incubator/compass/components/director/pkg/header"
    14  	"github.com/kyma-incubator/compass/components/director/pkg/log"
    15  	"github.com/pkg/errors"
    16  	"github.com/tidwall/gjson"
    17  )
    18  
    19  func raw(obj *graphql.TokenWithURL) (*string, error) {
    20  	rawJSON, err := json.Marshal(obj)
    21  	if err != nil {
    22  		return nil, errors.Wrap(err, "while marshalling object to JSON")
    23  	}
    24  
    25  	rawJSONStr := string(rawJSON)
    26  
    27  	return &rawJSONStr, nil
    28  }
    29  
    30  func rawEncoded(obj *graphql.TokenWithURL) (*string, error) {
    31  	rawJSON, err := json.Marshal(obj)
    32  	if err != nil {
    33  		return nil, errors.Wrap(err, "while marshalling object to JSON")
    34  	}
    35  
    36  	rawBaseEncoded := base64.StdEncoding.EncodeToString(rawJSON)
    37  
    38  	return &rawBaseEncoded, nil
    39  }
    40  
    41  func legacyConnectorURLWithToken(legacyConnectorURL, token string) (string, error) {
    42  	if strings.Contains(token, legacyConnectorURL) {
    43  		return token, nil
    44  	}
    45  	url, err := url.Parse(legacyConnectorURL)
    46  	if err != nil {
    47  		return "", errors.Wrapf(err, "while parsing string (%s) as the URL", legacyConnectorURL)
    48  	}
    49  
    50  	if url.RawQuery != "" {
    51  		url.RawQuery += "&"
    52  	}
    53  
    54  	token = extractToken(token)
    55  
    56  	url.RawQuery += fmt.Sprintf("token=%s", token)
    57  	return url.String(), nil
    58  }
    59  
    60  func tokenSuggestionEnabled(ctx context.Context, suggestTokenHeaderKey string) bool {
    61  	reqHeaders, ok := ctx.Value(header.ContextKey).(http.Header)
    62  	if !ok || reqHeaders.Get(suggestTokenHeaderKey) != "true" {
    63  		return false
    64  	}
    65  
    66  	log.C(ctx).Infof("Token suggestion is required by client")
    67  	return true
    68  }
    69  
    70  // extractToken tries to extract the original one-time token from the provided token in case it is a suggested one - base64 encoded raw token response,
    71  // where the token is part of a base64 encoded json, or a legacy url, which contains the original token as a query parameter.
    72  // If none of those cases is correct, or if any error occurs while checking, the provided token is returned as is.
    73  func extractToken(currentToken string) string {
    74  	// already encoded
    75  	if rawEncoded, err := base64.StdEncoding.DecodeString(currentToken); err == nil {
    76  		if token := gjson.GetBytes(rawEncoded, "token").String(); token != "" {
    77  			return token
    78  		}
    79  	}
    80  
    81  	// is in form of a legacy connector url
    82  	legacyURL, err := url.Parse(currentToken)
    83  	if err != nil {
    84  		return currentToken
    85  	}
    86  	if token := legacyURL.Query().Get("token"); token != "" {
    87  		return token
    88  	}
    89  
    90  	return currentToken
    91  }