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

     1  package credentialhelper
     2  
     3  import (
     4  	"bufio"
     5  	"fmt"
     6  	"io"
     7  
     8  	"github.com/pkg/errors"
     9  )
    10  
    11  // GitCredentialsHelper is used to implement the git credential helper algorithm.
    12  // See also https://git-scm.com/docs/git-credential.
    13  type GitCredentialsHelper struct {
    14  	in               io.Reader
    15  	out              io.Writer
    16  	knownCredentials []GitCredential
    17  }
    18  
    19  // CreateGitCredentialsHelper creates an instance of a git credential helper. It needs to get passed the handles to read
    20  // the git credential data as well as write the response to. It also gets the list og known credentials.
    21  func CreateGitCredentialsHelper(in io.Reader, out io.Writer, credentials []GitCredential) (*GitCredentialsHelper, error) {
    22  	if in == nil {
    23  		return nil, errors.New("in parameter cannot be nil")
    24  	}
    25  
    26  	if out == nil {
    27  		return nil, errors.New("out parameter cannot be nil")
    28  	}
    29  
    30  	if credentials == nil {
    31  		return nil, errors.New("credentials parameter cannot be nil")
    32  	}
    33  
    34  	return &GitCredentialsHelper{
    35  		in:               in,
    36  		out:              out,
    37  		knownCredentials: credentials,
    38  	}, nil
    39  }
    40  
    41  // Run executes the specified git credential helper operation which must be one of get, store or erase.
    42  // NOTE: Currently only get is implemented.
    43  func (h *GitCredentialsHelper) Run(op string) error {
    44  	var err error
    45  
    46  	switch op {
    47  	case "get":
    48  		err = h.Get()
    49  	case "store":
    50  		// not yet implemented (HF)
    51  		fmt.Println("")
    52  	case "erase":
    53  		// not yet implemented (HF)
    54  		fmt.Println("")
    55  	default:
    56  		err = errors.Errorf("invalid git credential operation '%s'", op)
    57  	}
    58  
    59  	return err
    60  }
    61  
    62  // Get implements the get operation of the git credential helper protocol. It reads the authentication query from
    63  // the reader of this instance and writes the response to the writer (usually this will be stdout and stdin).
    64  func (h *GitCredentialsHelper) Get() error {
    65  	var data []string
    66  	scanner := bufio.NewScanner(h.in)
    67  	for scanner.Scan() {
    68  		data = append(data, scanner.Text())
    69  	}
    70  
    71  	if scanner.Err() != nil {
    72  		return errors.Wrap(scanner.Err(), "unable to read input from stdin")
    73  	}
    74  
    75  	gitCredential, err := CreateGitCredential(data)
    76  	if err != nil {
    77  		return errors.Wrap(scanner.Err(), "unable to create GitCredential struct")
    78  	}
    79  
    80  	answer := h.Fill(gitCredential)
    81  
    82  	_, err = fmt.Fprintf(h.out, answer.String())
    83  	if err != nil {
    84  		return errors.Wrap(err, "unable to write response to stdin")
    85  	}
    86  
    87  	return nil
    88  }
    89  
    90  // Fill creates a GitCredential instance based on a git credential helper request which represented by the passed queryCredential instance.
    91  // If there is no auth information available an empty credential instance is returned
    92  func (h *GitCredentialsHelper) Fill(queryCredential GitCredential) GitCredential {
    93  	for _, authCredential := range h.knownCredentials {
    94  		if queryCredential.Protocol != authCredential.Protocol {
    95  			continue
    96  		}
    97  
    98  		if queryCredential.Host != authCredential.Host {
    99  			continue
   100  		}
   101  
   102  		if queryCredential.Path != authCredential.Path {
   103  			continue
   104  		}
   105  
   106  		answer := authCredential.Clone()
   107  		return answer
   108  	}
   109  
   110  	return GitCredential{}
   111  }