1
2
3
4
5
6
7
8
9
10
11
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