github.com/jenkins-x/jx/v2@v2.1.155/pkg/gits/credentialhelper/git_credential.go (about)

     1  package credentialhelper
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"net/url"
     7  	"reflect"
     8  	"strings"
     9  
    10  	"github.com/jenkins-x/jx/v2/pkg/util"
    11  	"github.com/pkg/errors"
    12  )
    13  
    14  // GitCredential represents the different parts of a git credential URL
    15  // See also https://git-scm.com/docs/git-credential
    16  type GitCredential struct {
    17  	Protocol string
    18  	Host     string
    19  	Path     string
    20  	Username string
    21  	Password string
    22  }
    23  
    24  // CreateGitCredential creates a CreateGitCredential instance from a slice of strings where each element is a key/value pair
    25  // separated by '='.
    26  func CreateGitCredential(lines []string) (GitCredential, error) {
    27  	var credential GitCredential
    28  
    29  	if lines == nil {
    30  		return credential, errors.New("no data lines provided")
    31  	}
    32  
    33  	fieldMap, err := util.ExtractKeyValuePairs(lines, "=")
    34  	if err != nil {
    35  		return credential, errors.Wrap(err, "unable to extract git credential parameters")
    36  	}
    37  
    38  	data, err := json.Marshal(fieldMap)
    39  	if err != nil {
    40  		return GitCredential{}, errors.Wrapf(err, "unable to marshal git credential data")
    41  	}
    42  
    43  	err = json.Unmarshal(data, &credential)
    44  	if err != nil {
    45  		return GitCredential{}, errors.Wrapf(err, "unable unmarshal git credential data")
    46  	}
    47  
    48  	return credential, nil
    49  }
    50  
    51  // CreateGitCredentialFromURL creates a CreateGitCredential instance from a URL and optional username and password.
    52  func CreateGitCredentialFromURL(gitURL string, username string, password string) (GitCredential, error) {
    53  	var credential GitCredential
    54  
    55  	if gitURL == "" {
    56  		return credential, errors.New("url cannot be empty")
    57  	}
    58  
    59  	u, err := url.Parse(gitURL)
    60  	if err != nil {
    61  		return credential, errors.Wrapf(err, "unable to parse URL %s", gitURL)
    62  	}
    63  
    64  	credential.Protocol = u.Scheme
    65  	credential.Host = u.Host
    66  	credential.Path = u.Path
    67  	if username != "" {
    68  		credential.Username = username
    69  	}
    70  
    71  	if password != "" {
    72  		credential.Password = password
    73  	}
    74  
    75  	return credential, nil
    76  }
    77  
    78  // String returns a string representation of this instance according to the expected format of git credential helpers.
    79  // See also https://git-scm.com/docs/git-credential
    80  func (g *GitCredential) String() string {
    81  	answer := ""
    82  
    83  	value := reflect.ValueOf(g).Elem()
    84  	typeOfT := value.Type()
    85  
    86  	for i := 0; i < value.NumField(); i++ {
    87  		field := value.Field(i)
    88  		answer = answer + fmt.Sprintf("%s=%v\n", strings.ToLower(typeOfT.Field(i).Name), field.Interface())
    89  	}
    90  
    91  	answer = answer + "\n"
    92  
    93  	return answer
    94  }
    95  
    96  // Clone clones this GitCredential instance
    97  func (g *GitCredential) Clone() GitCredential {
    98  	clone := GitCredential{}
    99  
   100  	value := reflect.ValueOf(g).Elem()
   101  	typeOfT := value.Type()
   102  	for i := 0; i < value.NumField(); i++ {
   103  		field := value.Field(i)
   104  		value := field.String()
   105  		v := reflect.ValueOf(&clone).Elem().FieldByName(typeOfT.Field(i).Name)
   106  		v.SetString(value)
   107  	}
   108  
   109  	return clone
   110  }
   111  
   112  // URL returns a URL from the data of this instance. If not enough information exist an error is returned
   113  func (g *GitCredential) URL() (url.URL, error) {
   114  	urlAsString := g.Protocol + "://" + g.Host
   115  	if g.Path != "" {
   116  		urlAsString = urlAsString + "/" + g.Path
   117  	}
   118  	u, err := url.Parse(urlAsString)
   119  	if err != nil {
   120  		return url.URL{}, errors.Wrap(err, "unable to construct URL")
   121  	}
   122  
   123  	u.User = url.UserPassword(g.Username, g.Password)
   124  	return *u, nil
   125  }