Stop auth commands from modifying global config file (#5378)
This commit is contained in:
parent
6fa8e4299c
commit
8dbd07212c
9 changed files with 58 additions and 10 deletions
|
|
@ -26,6 +26,7 @@ var (
|
||||||
type iconfig interface {
|
type iconfig interface {
|
||||||
Set(string, string, string) error
|
Set(string, string, string) error
|
||||||
Write() error
|
Write() error
|
||||||
|
WriteHosts() error
|
||||||
}
|
}
|
||||||
|
|
||||||
func AuthFlowWithConfig(cfg iconfig, IO *iostreams.IOStreams, hostname, notice string, additionalScopes []string, isInteractive bool) (string, error) {
|
func AuthFlowWithConfig(cfg iconfig, IO *iostreams.IOStreams, hostname, notice string, additionalScopes []string, isInteractive bool) (string, error) {
|
||||||
|
|
@ -46,7 +47,7 @@ func AuthFlowWithConfig(cfg iconfig, IO *iostreams.IOStreams, hostname, notice s
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
return token, cfg.Write()
|
return token, cfg.WriteHosts()
|
||||||
}
|
}
|
||||||
|
|
||||||
func authFlow(oauthHost string, IO *iostreams.IOStreams, notice string, additionalScopes []string, isInteractive bool) (string, string, error) {
|
func authFlow(oauthHost string, IO *iostreams.IOStreams, notice string, additionalScopes []string, isInteractive bool) (string, string, error) {
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"runtime"
|
"runtime"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/MakeNowJust/heredoc"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
@ -269,6 +270,31 @@ func Test_configFile_Write_toDisk(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_configFile_WriteHosts_toDisk(t *testing.T) {
|
||||||
|
configDir := filepath.Join(t.TempDir(), ".config", "gh")
|
||||||
|
_ = os.MkdirAll(configDir, 0755)
|
||||||
|
os.Setenv(GH_CONFIG_DIR, configDir)
|
||||||
|
defer os.Unsetenv(GH_CONFIG_DIR)
|
||||||
|
|
||||||
|
cfg := NewFromString(heredoc.Doc(`
|
||||||
|
hosts:
|
||||||
|
github.com:
|
||||||
|
user: monalisa
|
||||||
|
oauth_token: TOKEN
|
||||||
|
`))
|
||||||
|
err := cfg.WriteHosts()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedConfig := "github.com:\n user: monalisa\n oauth_token: TOKEN\n"
|
||||||
|
actualConfig, err := ioutil.ReadFile(filepath.Join(configDir, "hosts.yml"))
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, expectedConfig, string(actualConfig))
|
||||||
|
_, nonExistErr := os.Stat(filepath.Join(configDir, "config.yml"))
|
||||||
|
assert.Error(t, nonExistErr)
|
||||||
|
}
|
||||||
|
|
||||||
func Test_autoMigrateConfigDir_noMigration_notExist(t *testing.T) {
|
func Test_autoMigrateConfigDir_noMigration_notExist(t *testing.T) {
|
||||||
homeDir := t.TempDir()
|
homeDir := t.TempDir()
|
||||||
migrateDir := t.TempDir()
|
migrateDir := t.TempDir()
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ type Config interface {
|
||||||
Aliases() (*AliasConfig, error)
|
Aliases() (*AliasConfig, error)
|
||||||
CheckWriteable(string, string) error
|
CheckWriteable(string, string) error
|
||||||
Write() error
|
Write() error
|
||||||
|
WriteHosts() error
|
||||||
}
|
}
|
||||||
|
|
||||||
type ConfigOption struct {
|
type ConfigOption struct {
|
||||||
|
|
|
||||||
|
|
@ -135,13 +135,10 @@ func (c *fileConfig) CheckWriteable(hostname, key string) error {
|
||||||
|
|
||||||
func (c *fileConfig) Write() error {
|
func (c *fileConfig) Write() error {
|
||||||
mainData := yaml.Node{Kind: yaml.MappingNode}
|
mainData := yaml.Node{Kind: yaml.MappingNode}
|
||||||
hostsData := yaml.Node{Kind: yaml.MappingNode}
|
|
||||||
|
|
||||||
nodes := c.documentRoot.Content[0].Content
|
nodes := c.documentRoot.Content[0].Content
|
||||||
for i := 0; i < len(nodes)-1; i += 2 {
|
for i := 0; i < len(nodes)-1; i += 2 {
|
||||||
if nodes[i].Value == "hosts" {
|
if nodes[i].Value != "hosts" {
|
||||||
hostsData.Content = append(hostsData.Content, nodes[i+1].Content...)
|
|
||||||
} else {
|
|
||||||
mainData.Content = append(mainData.Content, nodes[i], nodes[i+1])
|
mainData.Content = append(mainData.Content, nodes[i], nodes[i+1])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -151,12 +148,26 @@ func (c *fileConfig) Write() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
filename := ConfigFile()
|
err = WriteConfigFile(ConfigFile(), yamlNormalize(mainBytes))
|
||||||
err = WriteConfigFile(filename, yamlNormalize(mainBytes))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return c.WriteHosts()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the hosts config file only, so as to allow logging in when the main
|
||||||
|
// config file is not writable.
|
||||||
|
func (c *fileConfig) WriteHosts() error {
|
||||||
|
hostsData := yaml.Node{Kind: yaml.MappingNode}
|
||||||
|
|
||||||
|
nodes := c.documentRoot.Content[0].Content
|
||||||
|
for i := 0; i < len(nodes)-1; i += 2 {
|
||||||
|
if nodes[i].Value == "hosts" {
|
||||||
|
hostsData.Content = append(hostsData.Content, nodes[i+1].Content...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
hostsBytes, err := yaml.Marshal(&hostsData)
|
hostsBytes, err := yaml.Marshal(&hostsData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,10 @@ func (c ConfigStub) Write() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c ConfigStub) WriteHosts() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (c ConfigStub) DefaultHost() (string, error) {
|
func (c ConfigStub) DefaultHost() (string, error) {
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -161,7 +161,7 @@ func loginRun(opts *LoginOptions) error {
|
||||||
return fmt.Errorf("error validating token: %w", err)
|
return fmt.Errorf("error validating token: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return cfg.Write()
|
return cfg.WriteHosts()
|
||||||
}
|
}
|
||||||
|
|
||||||
existingToken, _ := cfg.Get(hostname, "oauth_token")
|
existingToken, _ := cfg.Get(hostname, "oauth_token")
|
||||||
|
|
|
||||||
|
|
@ -151,7 +151,7 @@ func logoutRun(opts *LogoutOptions) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg.UnsetHost(hostname)
|
cfg.UnsetHost(hostname)
|
||||||
err = cfg.Write()
|
err = cfg.WriteHosts()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to write config, authentication configuration not updated: %w", err)
|
return fmt.Errorf("failed to write config, authentication configuration not updated: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ type iconfig interface {
|
||||||
Get(string, string) (string, error)
|
Get(string, string) (string, error)
|
||||||
Set(string, string, string) error
|
Set(string, string, string) error
|
||||||
Write() error
|
Write() error
|
||||||
|
WriteHosts() error
|
||||||
}
|
}
|
||||||
|
|
||||||
type LoginOptions struct {
|
type LoginOptions struct {
|
||||||
|
|
@ -173,7 +174,7 @@ func Login(opts *LoginOptions) error {
|
||||||
fmt.Fprintf(opts.IO.ErrOut, "%s Configured git protocol\n", cs.SuccessIcon())
|
fmt.Fprintf(opts.IO.ErrOut, "%s Configured git protocol\n", cs.SuccessIcon())
|
||||||
}
|
}
|
||||||
|
|
||||||
err := cfg.Write()
|
err := cfg.WriteHosts()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,10 @@ func (c tinyConfig) Write() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c tinyConfig) WriteHosts() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func TestLogin_ssh(t *testing.T) {
|
func TestLogin_ssh(t *testing.T) {
|
||||||
dir := t.TempDir()
|
dir := t.TempDir()
|
||||||
io, _, stdout, stderr := iostreams.Test()
|
io, _, stdout, stderr := iostreams.Test()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue