github.com/go-kivik/kivik/v4@v4.3.2/couchdb/chttp/proxyauth_test.go (about) 1 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 2 // use this file except in compliance with the License. You may obtain a copy of 3 // the License at 4 // 5 // http://www.apache.org/licenses/LICENSE-2.0 6 // 7 // Unless required by applicable law or agreed to in writing, software 8 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 // License for the specific language governing permissions and limitations under 11 // the License. 12 13 package chttp 14 15 import ( 16 "net/http" 17 "net/http/httptest" 18 "testing" 19 20 "gitlab.com/flimzy/testy" 21 22 "github.com/go-kivik/kivik/v4/internal/nettest" 23 ) 24 25 const ( 26 rolesTest = "users,admins" 27 secretTest = "abc123" 28 tokenTest = "adedb8d002eb53a52faba80e82cb1fc6d57bca74" 29 usernameTest = "bob" 30 ) 31 32 func TestProxyAuthRoundTrip(t *testing.T) { 33 type rtTest struct { 34 name string 35 auth *proxyAuth 36 req *http.Request 37 expected *http.Response 38 cleanup func() 39 } 40 tests := []rtTest{ 41 { 42 name: "Provided transport", 43 req: httptest.NewRequest("GET", "/", nil), 44 auth: &proxyAuth{ 45 Username: usernameTest, 46 Secret: secretTest, 47 Roles: []string{"users", "admins"}, 48 transport: customTransport(func(req *http.Request) (*http.Response, error) { 49 username := req.Header.Get("X-Auth-CouchDB-UserName") 50 if username != usernameTest { 51 t.Errorf("Unexpected X-Auth-CouchDB-UserName value: %s", username) 52 } 53 54 roles := req.Header.Get("X-Auth-CouchDB-Roles") 55 if roles != rolesTest { 56 t.Errorf("Unexpected X-Auth-CouchDB-Roles value: %s", roles) 57 } 58 59 token := req.Header.Get("X-Auth-CouchDB-Token") 60 if token != tokenTest { 61 t.Errorf("Unexpected X-Auth-CouchDB-Token value: %s", token) 62 } 63 64 return &http.Response{StatusCode: 200}, nil 65 }), 66 }, 67 expected: &http.Response{StatusCode: 200}, 68 }, 69 { 70 name: "Secret is an empty string", 71 req: httptest.NewRequest("GET", "/", nil), 72 auth: &proxyAuth{ 73 Username: usernameTest, 74 Secret: "", 75 Roles: []string{"users", "admins"}, 76 transport: customTransport(func(req *http.Request) (*http.Response, error) { 77 token := req.Header.Get("X-Auth-CouchDB-Token") 78 if token != "" { 79 t.Error("Setting secret to an empty string did not unset the X-Auth-CouchDB-Token header") 80 } 81 82 return &http.Response{StatusCode: 200}, nil 83 }), 84 }, 85 expected: &http.Response{StatusCode: 200}, 86 }, 87 { 88 name: "Overridden header names", 89 req: httptest.NewRequest("GET", "/", nil), 90 auth: &proxyAuth{ 91 Username: usernameTest, 92 Secret: secretTest, 93 Roles: []string{"users", "admins"}, 94 Headers: http.Header{ 95 "X-Auth-Couchdb-Token": []string{"moo"}, 96 "X-Auth-Couchdb-Username": []string{"cow"}, 97 "X-Auth-Couchdb-Roles": []string{"bovine"}, 98 }, 99 transport: customTransport(func(req *http.Request) (*http.Response, error) { 100 username := req.Header.Get("Cow") 101 if username != usernameTest { 102 t.Error("Username header override failed") 103 } 104 105 roles := req.Header.Get("Bovine") 106 if roles != rolesTest { 107 t.Error("Roles header override failed") 108 } 109 110 token := req.Header.Get("Moo") 111 if token != tokenTest { 112 t.Error("Token header override failed") 113 } 114 115 return &http.Response{StatusCode: 200}, nil 116 }), 117 }, 118 expected: &http.Response{StatusCode: 200}, 119 }, 120 func() rtTest { 121 h := func(w http.ResponseWriter, r *http.Request) { 122 username := r.Header.Get("X-Auth-CouchDB-UserName") 123 if username != usernameTest { 124 t.Errorf("Unexpected X-Auth-CouchDB-UserName value: %s", username) 125 } 126 127 roles := r.Header.Get("X-Auth-CouchDB-Roles") 128 if roles != rolesTest { 129 t.Errorf("Unexpected X-Auth-CouchDB-Roles value: %s", roles) 130 } 131 132 token := r.Header.Get("X-Auth-CouchDB-Token") 133 if token != tokenTest { 134 t.Errorf("Unexpected X-Auth-CouchDB-Token value: %s", token) 135 } 136 137 w.Header().Set("Date", "Wed, 01 Nov 2017 19:32:41 GMT") 138 w.Header().Set("Content-Type", "application/json") 139 } 140 s := nettest.NewHTTPTestServer(t, http.HandlerFunc(h)) 141 return rtTest{ 142 name: "default transport", 143 auth: &proxyAuth{ 144 Username: usernameTest, 145 Secret: secretTest, 146 Roles: []string{"users", "admins"}, 147 transport: http.DefaultTransport, 148 }, 149 req: httptest.NewRequest("GET", s.URL, nil), 150 expected: &http.Response{ 151 Status: "200 OK", 152 StatusCode: 200, 153 Proto: "HTTP/1.1", 154 ProtoMajor: 1, 155 ProtoMinor: 1, 156 Header: http.Header{ 157 "Content-Length": {"0"}, 158 "Content-Type": {"application/json"}, 159 "Date": {"Wed, 01 Nov 2017 19:32:41 GMT"}, 160 }, 161 }, 162 cleanup: func() { s.Close() }, 163 } 164 }(), 165 } 166 for _, test := range tests { 167 t.Run(test.name, func(t *testing.T) { 168 res, err := test.auth.RoundTrip(test.req) 169 if err != nil { 170 t.Fatal(err) 171 } 172 res.Body = nil 173 res.Request = nil 174 if d := testy.DiffInterface(test.expected, res); d != nil { 175 t.Error(d) 176 } 177 }) 178 } 179 }