github.com/cli/cli@v1.14.1-0.20210902173923-1af6a669e342/internal/config/from_env_test.go (about)

     1  package config
     2  
     3  import (
     4  	"os"
     5  	"testing"
     6  
     7  	"github.com/MakeNowJust/heredoc"
     8  	"github.com/stretchr/testify/assert"
     9  )
    10  
    11  func TestInheritEnv(t *testing.T) {
    12  	orig_GITHUB_TOKEN := os.Getenv("GITHUB_TOKEN")
    13  	orig_GITHUB_ENTERPRISE_TOKEN := os.Getenv("GITHUB_ENTERPRISE_TOKEN")
    14  	orig_GH_TOKEN := os.Getenv("GH_TOKEN")
    15  	orig_GH_ENTERPRISE_TOKEN := os.Getenv("GH_ENTERPRISE_TOKEN")
    16  	orig_AppData := os.Getenv("AppData")
    17  	t.Cleanup(func() {
    18  		os.Setenv("GITHUB_TOKEN", orig_GITHUB_TOKEN)
    19  		os.Setenv("GITHUB_ENTERPRISE_TOKEN", orig_GITHUB_ENTERPRISE_TOKEN)
    20  		os.Setenv("GH_TOKEN", orig_GH_TOKEN)
    21  		os.Setenv("GH_ENTERPRISE_TOKEN", orig_GH_ENTERPRISE_TOKEN)
    22  		os.Setenv("AppData", orig_AppData)
    23  	})
    24  
    25  	type wants struct {
    26  		hosts     []string
    27  		token     string
    28  		source    string
    29  		writeable bool
    30  	}
    31  
    32  	tests := []struct {
    33  		name                    string
    34  		baseConfig              string
    35  		GITHUB_TOKEN            string
    36  		GITHUB_ENTERPRISE_TOKEN string
    37  		GH_TOKEN                string
    38  		GH_ENTERPRISE_TOKEN     string
    39  		hostname                string
    40  		wants                   wants
    41  	}{
    42  		{
    43  			name:       "blank",
    44  			baseConfig: ``,
    45  			hostname:   "github.com",
    46  			wants: wants{
    47  				hosts:     []string{},
    48  				token:     "",
    49  				source:    ".config.gh.config.yml",
    50  				writeable: true,
    51  			},
    52  		},
    53  		{
    54  			name:         "GITHUB_TOKEN over blank config",
    55  			baseConfig:   ``,
    56  			GITHUB_TOKEN: "OTOKEN",
    57  			hostname:     "github.com",
    58  			wants: wants{
    59  				hosts:     []string{"github.com"},
    60  				token:     "OTOKEN",
    61  				source:    "GITHUB_TOKEN",
    62  				writeable: false,
    63  			},
    64  		},
    65  		{
    66  			name:       "GH_TOKEN over blank config",
    67  			baseConfig: ``,
    68  			GH_TOKEN:   "OTOKEN",
    69  			hostname:   "github.com",
    70  			wants: wants{
    71  				hosts:     []string{"github.com"},
    72  				token:     "OTOKEN",
    73  				source:    "GH_TOKEN",
    74  				writeable: false,
    75  			},
    76  		},
    77  		{
    78  			name:         "GITHUB_TOKEN not applicable to GHE",
    79  			baseConfig:   ``,
    80  			GITHUB_TOKEN: "OTOKEN",
    81  			hostname:     "example.org",
    82  			wants: wants{
    83  				hosts:     []string{"github.com"},
    84  				token:     "",
    85  				source:    ".config.gh.config.yml",
    86  				writeable: true,
    87  			},
    88  		},
    89  		{
    90  			name:       "GH_TOKEN not applicable to GHE",
    91  			baseConfig: ``,
    92  			GH_TOKEN:   "OTOKEN",
    93  			hostname:   "example.org",
    94  			wants: wants{
    95  				hosts:     []string{"github.com"},
    96  				token:     "",
    97  				source:    ".config.gh.config.yml",
    98  				writeable: true,
    99  			},
   100  		},
   101  		{
   102  			name:                    "GITHUB_ENTERPRISE_TOKEN over blank config",
   103  			baseConfig:              ``,
   104  			GITHUB_ENTERPRISE_TOKEN: "ENTOKEN",
   105  			hostname:                "example.org",
   106  			wants: wants{
   107  				hosts:     []string{},
   108  				token:     "ENTOKEN",
   109  				source:    "GITHUB_ENTERPRISE_TOKEN",
   110  				writeable: false,
   111  			},
   112  		},
   113  		{
   114  			name:                "GH_ENTERPRISE_TOKEN over blank config",
   115  			baseConfig:          ``,
   116  			GH_ENTERPRISE_TOKEN: "ENTOKEN",
   117  			hostname:            "example.org",
   118  			wants: wants{
   119  				hosts:     []string{},
   120  				token:     "ENTOKEN",
   121  				source:    "GH_ENTERPRISE_TOKEN",
   122  				writeable: false,
   123  			},
   124  		},
   125  		{
   126  			name: "token from file",
   127  			baseConfig: heredoc.Doc(`
   128  			hosts:
   129  			  github.com:
   130  			    oauth_token: OTOKEN
   131  			`),
   132  			hostname: "github.com",
   133  			wants: wants{
   134  				hosts:     []string{"github.com"},
   135  				token:     "OTOKEN",
   136  				source:    ".config.gh.hosts.yml",
   137  				writeable: true,
   138  			},
   139  		},
   140  		{
   141  			name: "GITHUB_TOKEN shadows token from file",
   142  			baseConfig: heredoc.Doc(`
   143  			hosts:
   144  			  github.com:
   145  			    oauth_token: OTOKEN
   146  			`),
   147  			GITHUB_TOKEN: "ENVTOKEN",
   148  			hostname:     "github.com",
   149  			wants: wants{
   150  				hosts:     []string{"github.com"},
   151  				token:     "ENVTOKEN",
   152  				source:    "GITHUB_TOKEN",
   153  				writeable: false,
   154  			},
   155  		},
   156  		{
   157  			name: "GH_TOKEN shadows token from file",
   158  			baseConfig: heredoc.Doc(`
   159  			hosts:
   160  			  github.com:
   161  			    oauth_token: OTOKEN
   162  			`),
   163  			GH_TOKEN: "ENVTOKEN",
   164  			hostname: "github.com",
   165  			wants: wants{
   166  				hosts:     []string{"github.com"},
   167  				token:     "ENVTOKEN",
   168  				source:    "GH_TOKEN",
   169  				writeable: false,
   170  			},
   171  		},
   172  		{
   173  			name: "GITHUB_ENTERPRISE_TOKEN shadows token from file",
   174  			baseConfig: heredoc.Doc(`
   175  			hosts:
   176  			  example.org:
   177  			    oauth_token: OTOKEN
   178  			`),
   179  			GITHUB_ENTERPRISE_TOKEN: "ENVTOKEN",
   180  			hostname:                "example.org",
   181  			wants: wants{
   182  				hosts:     []string{"example.org"},
   183  				token:     "ENVTOKEN",
   184  				source:    "GITHUB_ENTERPRISE_TOKEN",
   185  				writeable: false,
   186  			},
   187  		},
   188  		{
   189  			name: "GH_ENTERPRISE_TOKEN shadows token from file",
   190  			baseConfig: heredoc.Doc(`
   191  			hosts:
   192  			  example.org:
   193  			    oauth_token: OTOKEN
   194  			`),
   195  			GH_ENTERPRISE_TOKEN: "ENVTOKEN",
   196  			hostname:            "example.org",
   197  			wants: wants{
   198  				hosts:     []string{"example.org"},
   199  				token:     "ENVTOKEN",
   200  				source:    "GH_ENTERPRISE_TOKEN",
   201  				writeable: false,
   202  			},
   203  		},
   204  		{
   205  			name:         "GH_TOKEN shadows token from GITHUB_TOKEN",
   206  			baseConfig:   ``,
   207  			GH_TOKEN:     "GHTOKEN",
   208  			GITHUB_TOKEN: "GITHUBTOKEN",
   209  			hostname:     "github.com",
   210  			wants: wants{
   211  				hosts:     []string{"github.com"},
   212  				token:     "GHTOKEN",
   213  				source:    "GH_TOKEN",
   214  				writeable: false,
   215  			},
   216  		},
   217  		{
   218  			name:                    "GH_ENTERPRISE_TOKEN shadows token from GITHUB_ENTERPRISE_TOKEN",
   219  			baseConfig:              ``,
   220  			GH_ENTERPRISE_TOKEN:     "GHTOKEN",
   221  			GITHUB_ENTERPRISE_TOKEN: "GITHUBTOKEN",
   222  			hostname:                "example.org",
   223  			wants: wants{
   224  				hosts:     []string{},
   225  				token:     "GHTOKEN",
   226  				source:    "GH_ENTERPRISE_TOKEN",
   227  				writeable: false,
   228  			},
   229  		},
   230  		{
   231  			name: "GITHUB_TOKEN adds host entry",
   232  			baseConfig: heredoc.Doc(`
   233  			hosts:
   234  			  example.org:
   235  			    oauth_token: OTOKEN
   236  			`),
   237  			GITHUB_TOKEN: "ENVTOKEN",
   238  			hostname:     "github.com",
   239  			wants: wants{
   240  				hosts:     []string{"github.com", "example.org"},
   241  				token:     "ENVTOKEN",
   242  				source:    "GITHUB_TOKEN",
   243  				writeable: false,
   244  			},
   245  		},
   246  		{
   247  			name: "GH_TOKEN adds host entry",
   248  			baseConfig: heredoc.Doc(`
   249  			hosts:
   250  			  example.org:
   251  			    oauth_token: OTOKEN
   252  			`),
   253  			GH_TOKEN: "ENVTOKEN",
   254  			hostname: "github.com",
   255  			wants: wants{
   256  				hosts:     []string{"github.com", "example.org"},
   257  				token:     "ENVTOKEN",
   258  				source:    "GH_TOKEN",
   259  				writeable: false,
   260  			},
   261  		},
   262  	}
   263  	for _, tt := range tests {
   264  		t.Run(tt.name, func(t *testing.T) {
   265  			os.Setenv("GITHUB_TOKEN", tt.GITHUB_TOKEN)
   266  			os.Setenv("GITHUB_ENTERPRISE_TOKEN", tt.GITHUB_ENTERPRISE_TOKEN)
   267  			os.Setenv("GH_TOKEN", tt.GH_TOKEN)
   268  			os.Setenv("GH_ENTERPRISE_TOKEN", tt.GH_ENTERPRISE_TOKEN)
   269  			os.Setenv("AppData", "")
   270  
   271  			baseCfg := NewFromString(tt.baseConfig)
   272  			cfg := InheritEnv(baseCfg)
   273  
   274  			hosts, _ := cfg.Hosts()
   275  			assert.Equal(t, tt.wants.hosts, hosts)
   276  
   277  			val, source, _ := cfg.GetWithSource(tt.hostname, "oauth_token")
   278  			assert.Equal(t, tt.wants.token, val)
   279  			assert.Regexp(t, tt.wants.source, source)
   280  
   281  			val, _ = cfg.Get(tt.hostname, "oauth_token")
   282  			assert.Equal(t, tt.wants.token, val)
   283  
   284  			err := cfg.CheckWriteable(tt.hostname, "oauth_token")
   285  			if tt.wants.writeable != (err == nil) {
   286  				t.Errorf("CheckWriteable() = %v, wants %v", err, tt.wants.writeable)
   287  			}
   288  		})
   289  	}
   290  }
   291  
   292  func TestAuthTokenProvidedFromEnv(t *testing.T) {
   293  	orig_GITHUB_TOKEN := os.Getenv("GITHUB_TOKEN")
   294  	orig_GITHUB_ENTERPRISE_TOKEN := os.Getenv("GITHUB_ENTERPRISE_TOKEN")
   295  	orig_GH_TOKEN := os.Getenv("GH_TOKEN")
   296  	orig_GH_ENTERPRISE_TOKEN := os.Getenv("GH_ENTERPRISE_TOKEN")
   297  	t.Cleanup(func() {
   298  		os.Setenv("GITHUB_TOKEN", orig_GITHUB_TOKEN)
   299  		os.Setenv("GITHUB_ENTERPRISE_TOKEN", orig_GITHUB_ENTERPRISE_TOKEN)
   300  		os.Setenv("GH_TOKEN", orig_GH_TOKEN)
   301  		os.Setenv("GH_ENTERPRISE_TOKEN", orig_GH_ENTERPRISE_TOKEN)
   302  	})
   303  
   304  	tests := []struct {
   305  		name                    string
   306  		GITHUB_TOKEN            string
   307  		GITHUB_ENTERPRISE_TOKEN string
   308  		GH_TOKEN                string
   309  		GH_ENTERPRISE_TOKEN     string
   310  		provided                bool
   311  	}{
   312  		{
   313  			name:     "no env tokens",
   314  			provided: false,
   315  		},
   316  		{
   317  			name:     "GH_TOKEN",
   318  			GH_TOKEN: "TOKEN",
   319  			provided: true,
   320  		},
   321  		{
   322  			name:         "GITHUB_TOKEN",
   323  			GITHUB_TOKEN: "TOKEN",
   324  			provided:     true,
   325  		},
   326  		{
   327  			name:                "GH_ENTERPRISE_TOKEN",
   328  			GH_ENTERPRISE_TOKEN: "TOKEN",
   329  			provided:            true,
   330  		},
   331  		{
   332  			name:                    "GITHUB_ENTERPRISE_TOKEN",
   333  			GITHUB_ENTERPRISE_TOKEN: "TOKEN",
   334  			provided:                true,
   335  		},
   336  	}
   337  
   338  	for _, tt := range tests {
   339  		t.Run(tt.name, func(t *testing.T) {
   340  			os.Setenv("GITHUB_TOKEN", tt.GITHUB_TOKEN)
   341  			os.Setenv("GITHUB_ENTERPRISE_TOKEN", tt.GITHUB_ENTERPRISE_TOKEN)
   342  			os.Setenv("GH_TOKEN", tt.GH_TOKEN)
   343  			os.Setenv("GH_ENTERPRISE_TOKEN", tt.GH_ENTERPRISE_TOKEN)
   344  			assert.Equal(t, tt.provided, AuthTokenProvidedFromEnv())
   345  		})
   346  	}
   347  }