github.com/adevinta/maiao@v0.0.0-20240318133227-b6f9656b5e07/pkg/credentials/keyring.go (about)

     1  package credentials
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"fmt"
     7  	"os"
     8  
     9  	"github.com/99designs/keyring"
    10  	"github.com/manifoldco/promptui"
    11  )
    12  
    13  type Keyring struct {
    14  	kr keyring.Keyring
    15  }
    16  
    17  var _ CredentialGetter = &Keyring{}
    18  
    19  func (k Keyring) CredentialForHost(h string) (*Credentials, error) {
    20  	secretKey := fmt.Sprintf("%s-credentials", h)
    21  	v, err := k.kr.Get(secretKey)
    22  	creds := &Credentials{}
    23  	if err == nil {
    24  		err = json.NewDecoder(bytes.NewReader(v.Data)).Decode(creds)
    25  		if err != nil {
    26  			return nil, err
    27  		}
    28  	}
    29  
    30  	if err == keyring.ErrKeyNotFound {
    31  		prompt := promptui.Prompt{
    32  			Label:  fmt.Sprintf("username for %s", h),
    33  			Stdin:  os.Stdin,
    34  			Stdout: os.Stdout,
    35  		}
    36  		creds.Username, err = prompt.Run()
    37  		if err != nil {
    38  			return nil, err
    39  		}
    40  		prompt = promptui.Prompt{
    41  			Label:  fmt.Sprintf("password for %s (usually your Personal Access Token)", h),
    42  			Mask:   '*',
    43  			Stdin:  os.Stdin,
    44  			Stdout: os.Stdout,
    45  		}
    46  		creds.Password, err = prompt.Run()
    47  		if err != nil {
    48  			return nil, err
    49  		}
    50  		d := bytes.NewBuffer(nil)
    51  		err = json.NewEncoder(d).Encode(creds)
    52  		if err != nil {
    53  			return creds, nil
    54  		}
    55  		err = k.kr.Set(keyring.Item{
    56  			Key:         secretKey,
    57  			Label:       h,
    58  			Description: fmt.Sprintf("json encoded user/password to access %s", h),
    59  			Data:        d.Bytes(),
    60  		})
    61  		if err != nil {
    62  			return creds, nil
    63  		}
    64  	}
    65  	if err != nil {
    66  		return nil, err
    67  	}
    68  
    69  	return creds, nil
    70  }
    71  
    72  func NewKeyring(cfg keyring.Config) (CredentialGetter, error) {
    73  	kr, err := keyring.Open(cfg)
    74  	if err != nil {
    75  		return nil, err
    76  	}
    77  	return &Keyring{kr: kr}, nil
    78  }
    79  
    80  func MustNewKeyring(cfg keyring.Config) CredentialGetter {
    81  	c, err := NewKeyring(cfg)
    82  	if err != nil {
    83  		panic(err)
    84  	}
    85  	return c
    86  }