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 }