github.com/secman-team/gh-api@v1.8.2/pkg/cmd/ssh-key/add/add.go (about)

     1  package add
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"io"
     7  	"net/http"
     8  	"os"
     9  
    10  	"github.com/secman-team/gh-api/core/config"
    11  	"github.com/secman-team/gh-api/pkg/cmdutil"
    12  	"github.com/secman-team/gh-api/pkg/iostreams"
    13  	"github.com/spf13/cobra"
    14  )
    15  
    16  type AddOptions struct {
    17  	IO         *iostreams.IOStreams
    18  	Config     func() (config.Config, error)
    19  	HTTPClient func() (*http.Client, error)
    20  
    21  	KeyFile string
    22  	Title   string
    23  }
    24  
    25  func NewCmdAdd(f *cmdutil.Factory, runF func(*AddOptions) error) *cobra.Command {
    26  	opts := &AddOptions{
    27  		HTTPClient: f.HttpClient,
    28  		Config:     f.Config,
    29  		IO:         f.IOStreams,
    30  	}
    31  
    32  	cmd := &cobra.Command{
    33  		Use:   "add [<key-file>]",
    34  		Short: "Add an SSH key to your GitHub account",
    35  		Args:  cobra.MaximumNArgs(1),
    36  		RunE: func(cmd *cobra.Command, args []string) error {
    37  			if len(args) == 0 {
    38  				if opts.IO.IsStdoutTTY() && opts.IO.IsStdinTTY() {
    39  					return &cmdutil.FlagError{Err: errors.New("public key file missing")}
    40  				}
    41  				opts.KeyFile = "-"
    42  			} else {
    43  				opts.KeyFile = args[0]
    44  			}
    45  
    46  			if runF != nil {
    47  				return runF(opts)
    48  			}
    49  			return runAdd(opts)
    50  		},
    51  	}
    52  
    53  	cmd.Flags().StringVarP(&opts.Title, "title", "t", "", "Title for the new key")
    54  	return cmd
    55  }
    56  
    57  func runAdd(opts *AddOptions) error {
    58  	httpClient, err := opts.HTTPClient()
    59  	if err != nil {
    60  		return err
    61  	}
    62  
    63  	var keyReader io.Reader
    64  	if opts.KeyFile == "-" {
    65  		keyReader = opts.IO.In
    66  		defer opts.IO.In.Close()
    67  	} else {
    68  		f, err := os.Open(opts.KeyFile)
    69  		if err != nil {
    70  			return err
    71  		}
    72  		defer f.Close()
    73  		keyReader = f
    74  	}
    75  
    76  	cfg, err := opts.Config()
    77  	if err != nil {
    78  		return err
    79  	}
    80  
    81  	hostname, err := cfg.DefaultHost()
    82  	if err != nil {
    83  		return err
    84  	}
    85  
    86  	err = SSHKeyUpload(httpClient, hostname, keyReader, opts.Title)
    87  	if err != nil {
    88  		if errors.Is(err, scopesError) {
    89  			cs := opts.IO.ColorScheme()
    90  			fmt.Fprint(opts.IO.ErrOut, "Error: insufficient OAuth scopes to list SSH keys\n")
    91  			fmt.Fprintf(opts.IO.ErrOut, "Run the following to grant scopes: %s\n", cs.Bold("gh auth refresh -s write:public_key"))
    92  			return cmdutil.SilentError
    93  		}
    94  		return err
    95  	}
    96  
    97  	if opts.IO.IsStdoutTTY() {
    98  		cs := opts.IO.ColorScheme()
    99  		fmt.Fprintf(opts.IO.ErrOut, "%s Public key added to your account\n", cs.SuccessIcon())
   100  	}
   101  	return nil
   102  }