68 lines
1.9 KiB
Go
68 lines
1.9 KiB
Go
package factory
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"net/http"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/cli/cli/api"
|
|
"github.com/cli/cli/internal/config"
|
|
"github.com/cli/cli/internal/ghinstance"
|
|
"github.com/cli/cli/pkg/iostreams"
|
|
)
|
|
|
|
// generic authenticated HTTP client for commands
|
|
func httpClient(io *iostreams.IOStreams, cfg config.Config, appVersion string, setAccept bool) *http.Client {
|
|
var opts []api.ClientOption
|
|
if verbose := os.Getenv("DEBUG"); verbose != "" {
|
|
logTraffic := strings.Contains(verbose, "api")
|
|
opts = append(opts, api.VerboseLog(io.ErrOut, logTraffic, io.IsStderrTTY()))
|
|
}
|
|
|
|
opts = append(opts,
|
|
api.AddHeader("User-Agent", fmt.Sprintf("GitHub CLI %s", appVersion)),
|
|
api.AddHeaderFunc("Authorization", func(req *http.Request) (string, error) {
|
|
if token := os.Getenv("GITHUB_TOKEN"); token != "" {
|
|
return fmt.Sprintf("token %s", token), nil
|
|
}
|
|
|
|
hostname := ghinstance.NormalizeHostname(req.URL.Hostname())
|
|
token, err := cfg.Get(hostname, "oauth_token")
|
|
if token == "" {
|
|
var notFound *config.NotFoundError
|
|
// TODO: check if stdout is TTY too
|
|
if errors.As(err, ¬Found) && io.IsStdinTTY() {
|
|
// interactive OAuth flow
|
|
token, err = config.AuthFlowWithConfig(cfg, hostname, "Notice: authentication required", nil)
|
|
}
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
if token == "" {
|
|
// TODO: instruct user how to manually authenticate
|
|
return "", fmt.Errorf("authentication required for %s", hostname)
|
|
}
|
|
}
|
|
|
|
return fmt.Sprintf("token %s", token), nil
|
|
}),
|
|
)
|
|
|
|
if setAccept {
|
|
opts = append(opts,
|
|
api.AddHeaderFunc("Accept", func(req *http.Request) (string, error) {
|
|
// antiope-preview: Checks
|
|
accept := "application/vnd.github.antiope-preview+json"
|
|
if ghinstance.IsEnterprise(req.URL.Hostname()) {
|
|
// shadow-cat-preview: Draft pull requests
|
|
accept += ", application/vnd.github.shadow-cat-preview"
|
|
}
|
|
return accept, nil
|
|
}),
|
|
)
|
|
}
|
|
|
|
return api.NewHTTPClient(opts...)
|
|
}
|