...

Source file src/github.com/go-kivik/kivik/v4/couchdb/chttp/proxyauth_test.go

Documentation: github.com/go-kivik/kivik/v4/couchdb/chttp

     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  }
   180  

View as plain text