Help us shape the future of Go! Take the 2026 Go Developer Survey

Source file src/cmd/go/internal/auth/auth_test.go

     1  // Copyright 2018 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package auth
     6  
     7  import (
     8  	"net/http"
     9  	"reflect"
    10  	"testing"
    11  )
    12  
    13  func TestCredentialCache(t *testing.T) {
    14  	testCases := []netrcLine{
    15  		{"api.github.com", "user", "pwd"},
    16  		{"test.host", "user2", "pwd2"},
    17  		{"oneline", "user3", "pwd3"},
    18  		{"hasmacro.too", "user4", "pwd4"},
    19  		{"hasmacro.too", "user5", "pwd5"},
    20  	}
    21  	for _, tc := range testCases {
    22  		want := http.Request{Header: make(http.Header)}
    23  		want.SetBasicAuth(tc.login, tc.password)
    24  		storeCredential(tc.machine, want.Header)
    25  		got := &http.Request{Header: make(http.Header)}
    26  		ok := loadCredential(got, tc.machine)
    27  		if !ok || !reflect.DeepEqual(got.Header, want.Header) {
    28  			t.Errorf("loadCredential(%q):\nhave %q\nwant %q", tc.machine, got.Header, want.Header)
    29  		}
    30  	}
    31  
    32  	// Having stored those credentials, we should be able to look up longer URLs too.
    33  	extraCases := []netrcLine{
    34  		{"https://api.github.com/foo", "user", "pwd"},
    35  		{"https://api.github.com/foo/bar/baz", "user", "pwd"},
    36  		{"https://example.com/abc", "", ""},
    37  		{"https://example.com/?/../api.github.com/", "", ""},
    38  		{"https://example.com/?/../api.github.com", "", ""},
    39  		{"https://example.com/../api.github.com/", "", ""},
    40  		{"https://example.com/../api.github.com", "", ""},
    41  	}
    42  	for _, tc := range extraCases {
    43  		want := http.Request{Header: make(http.Header)}
    44  		if tc.login != "" {
    45  			want.SetBasicAuth(tc.login, tc.password)
    46  		}
    47  		got := &http.Request{Header: make(http.Header)}
    48  		loadCredential(got, tc.machine)
    49  		if !reflect.DeepEqual(got.Header, want.Header) {
    50  			t.Errorf("loadCredential(%q):\nhave %q\nwant %q", tc.machine, got.Header, want.Header)
    51  		}
    52  	}
    53  }
    54  
    55  func TestCredentialCacheDelete(t *testing.T) {
    56  	// Store a credential for api.github.com
    57  	want := http.Request{Header: make(http.Header)}
    58  	want.SetBasicAuth("user", "pwd")
    59  	storeCredential("api.github.com", want.Header)
    60  	got := &http.Request{Header: make(http.Header)}
    61  	ok := loadCredential(got, "api.github.com")
    62  	if !ok || !reflect.DeepEqual(got.Header, want.Header) {
    63  		t.Errorf("parseNetrc:\nhave %q\nwant %q", got.Header, want.Header)
    64  	}
    65  	// Providing an empty header for api.github.com should clear credentials.
    66  	want = http.Request{Header: make(http.Header)}
    67  	storeCredential("api.github.com", want.Header)
    68  	got = &http.Request{Header: make(http.Header)}
    69  	ok = loadCredential(got, "api.github.com")
    70  	if ok {
    71  		t.Errorf("loadCredential:\nhave %q\nwant %q", got.Header, want.Header)
    72  	}
    73  }
    74  
    75  func TestCredentialCacheTrailingSlash(t *testing.T) {
    76  	// Store a credential for api.github.com/foo/bar
    77  	want := http.Request{Header: make(http.Header)}
    78  	want.SetBasicAuth("user", "pwd")
    79  	storeCredential("api.github.com/foo", want.Header)
    80  	got := &http.Request{Header: make(http.Header)}
    81  	ok := loadCredential(got, "api.github.com/foo/bar")
    82  	if !ok || !reflect.DeepEqual(got.Header, want.Header) {
    83  		t.Errorf("parseNetrc:\nhave %q\nwant %q", got.Header, want.Header)
    84  	}
    85  	got2 := &http.Request{Header: make(http.Header)}
    86  	ok = loadCredential(got2, "https://api.github.com/foo/bar/")
    87  	if !ok || !reflect.DeepEqual(got2.Header, want.Header) {
    88  		t.Errorf("parseNetrc:\nhave %q\nwant %q", got2.Header, want.Header)
    89  	}
    90  }
    91  
    92  func TestCredentialCacheHostOnlyMatchesPort(t *testing.T) {
    93  	// A host-only .netrc machine name should match a request to that host
    94  	// regardless of port, and regardless of path.
    95  	want := http.Request{Header: make(http.Header)}
    96  	want.SetBasicAuth("user", "pwd")
    97  	storeCredential("proxy.example.com", want.Header)
    98  
    99  	url := "https://proxy.example.com:8443/mod/info"
   100  	got := &http.Request{Header: make(http.Header)}
   101  	ok := loadCredential(got, url)
   102  	if !ok || !reflect.DeepEqual(got.Header, want.Header) {
   103  		t.Errorf("loadCredential(%q):\nhave %q\nwant %q", url, got.Header, want.Header)
   104  	}
   105  }
   106  
   107  func TestCredentialCacheExplicitPortIsSpecific(t *testing.T) {
   108  	// A machine name with an explicit port should match only that port,
   109  	// not other ports on the same host, and not a bare host-only lookup.
   110  	want := http.Request{Header: make(http.Header)}
   111  	want.SetBasicAuth("user", "pwd")
   112  	storeCredential("example.com:8443", want.Header)
   113  
   114  	url := "https://example.com:8443/mod/info"
   115  	got := &http.Request{Header: make(http.Header)}
   116  	ok := loadCredential(got, url)
   117  	if !ok || !reflect.DeepEqual(got.Header, want.Header) {
   118  		t.Errorf("loadCredential(%q):\nhave %q\nwant %q", url, got.Header, want.Header)
   119  	}
   120  
   121  	url = "https://example.com:9999/mod/info"
   122  	got = &http.Request{Header: make(http.Header)}
   123  	if ok := loadCredential(got, url); ok {
   124  		t.Errorf("loadCredential(%q):\nhave %q\nwant no match", url, got.Header)
   125  	}
   126  
   127  	url = "https://example.com/mod/info"
   128  	got = &http.Request{Header: make(http.Header)}
   129  	if ok := loadCredential(got, url); ok {
   130  		t.Errorf("loadCredential(%q):\nhave %q\nwant no match", url, got.Header)
   131  	}
   132  }
   133  
   134  func TestCredentialCacheURLQuery(t *testing.T) {
   135  	want := http.Request{Header: make(http.Header)}
   136  	want.SetBasicAuth("user", "password")
   137  	storeCredential("example.com/api", want.Header)
   138  
   139  	got := &http.Request{Header: make(http.Header)}
   140  	ok := loadCredential(got, "https://example.com/api?version=1")
   141  	if !ok {
   142  		t.Fatal("loadCredential returned false")
   143  	}
   144  	if !reflect.DeepEqual(got.Header, want.Header) {
   145  		t.Fatalf("got %v, want %v", got.Header, want.Header)
   146  	}
   147  }
   148  

View as plain text