From f1a301922d293e269dfeecffe4ed594cab83788c Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Fri, 21 Aug 2015 17:36:19 -0700 Subject: [PATCH] Remove cookie authentication. --- api/client.go | 89 ++++++++++++++--------------------------- api/client_test.go | 74 +--------------------------------- api/request.go | 17 +++++--- api/ssh_agent.go | 19 +++++++++ command/meta.go | 18 +++++++++ http/handler.go | 9 ----- http/help_test.go | 6 +-- http/http_test.go | 51 +++++++++++++++++++---- http/logical.go | 23 +---------- http/logical_test.go | 45 ++++++--------------- http/sys_audit_test.go | 17 +++----- http/sys_auth_test.go | 22 +++------- http/sys_init_test.go | 2 +- http/sys_lease_test.go | 15 +++---- http/sys_mount_test.go | 33 +++++---------- http/sys_policy_test.go | 27 ++++--------- http/sys_rekey_test.go | 17 ++++---- http/sys_rotate_test.go | 8 +--- http/sys_seal_test.go | 8 ++-- http/testing.go | 21 ---------- 20 files changed, 185 insertions(+), 336 deletions(-) diff --git a/api/client.go b/api/client.go index 6fa30e323c..5026548e45 100644 --- a/api/client.go +++ b/api/client.go @@ -4,15 +4,11 @@ import ( "errors" "fmt" "net/http" - "net/http/cookiejar" "net/url" "os" "strings" - "time" ) -const AuthCookieName = "token" - var ( errRedirect = errors.New("redirect") ) @@ -25,11 +21,8 @@ type Config struct { // HttpClient. Address string - // HttpClient is the HTTP client to use. http.DefaultClient will be - // used if not specified. The HTTP client must have the cookie jar set - // to be able to store cookies, otherwise authentication (login) will - // not work properly. If the jar is nil, a default empty cookie jar - // will be set. + // HttpClient is the HTTP client to use, which will currently always be + // http.DefaultClient. This is used to control redirect behavior. HttpClient *http.Client } @@ -41,7 +34,25 @@ type Config struct { func DefaultConfig() *Config { config := &Config{ Address: "https://127.0.0.1:8200", - HttpClient: &http.Client{}, + HttpClient: http.DefaultClient, + } + + // From https://github.com/michiwend/gomusicbrainz/pull/4/files + defaultRedirectLimit := 30 + + config.HttpClient.CheckRedirect = func(req *http.Request, via []*http.Request) error { + if len(via) > defaultRedirectLimit { + return fmt.Errorf("%d consecutive requests(redirects)", len(via)) + } + if len(via) == 0 { + // No redirects + return nil + } + // mutate the subsequent redirect requests with the first Header + if token := via[0].Header.Get("X-Vault-Token"); len(token) != 0 { + req.Header.Set("X-Vault-Token", token) + } + return nil } if addr := os.Getenv("VAULT_ADDR"); addr != "" { @@ -56,6 +67,7 @@ func DefaultConfig() *Config { type Client struct { addr *url.URL config *Config + token string } // NewClient returns a new client for the given configuration. @@ -69,24 +81,6 @@ func NewClient(c *Config) (*Client, error) { return nil, err } - if c.HttpClient == nil { - c.HttpClient = http.DefaultClient - } - - // Make a copy of the HTTP client so we can configure it without - // affecting the original - // - // If no cookie jar is set on the client, we set a default empty - // cookie jar. - if c.HttpClient.Jar == nil { - jar, err := cookiejar.New(&cookiejar.Options{}) - if err != nil { - return nil, err - } - - c.HttpClient.Jar = jar - } - // Ensure redirects are not automatically followed c.HttpClient.CheckRedirect = func(req *http.Request, via []*http.Request) error { return errRedirect @@ -107,55 +101,36 @@ func NewClient(c *Config) (*Client, error) { // Token returns the access token being used by this client. It will // return the empty string if there is no token set. func (c *Client) Token() string { - r := c.NewRequest("GET", "/") - for _, cookie := range c.config.HttpClient.Jar.Cookies(r.URL) { - if cookie.Name == AuthCookieName { - return cookie.Value - } - } - - return "" + return c.token } // SetToken sets the token directly. This won't perform any auth // verification, it simply sets the cookie properly for future requests. func (c *Client) SetToken(v string) { - r := c.NewRequest("GET", "/") - c.config.HttpClient.Jar.SetCookies(r.URL, []*http.Cookie{ - &http.Cookie{ - Name: AuthCookieName, - Value: v, - Path: "/", - Expires: time.Now().Add(365 * 24 * time.Hour), - }, - }) + c.token = v } // ClearToken deletes the token cookie if it is set or does nothing otherwise. func (c *Client) ClearToken() { - r := c.NewRequest("GET", "/") - c.config.HttpClient.Jar.SetCookies(r.URL, []*http.Cookie{ - &http.Cookie{ - Name: AuthCookieName, - Value: "", - Expires: time.Now().Add(-1 * time.Hour), - }, - }) + c.token = "" } // NewRequest creates a new raw request object to query the Vault server // configured for this client. This is an advanced method and generally // doesn't need to be called externally. func (c *Client) NewRequest(method, path string) *Request { - return &Request{ + req := &Request{ Method: method, URL: &url.URL{ Scheme: c.addr.Scheme, Host: c.addr.Host, Path: path, }, - Params: make(map[string][]string), + ClientToken: c.token, + Params: make(map[string][]string), } + + return req } // RawRequest performs the raw request given. This request may be against @@ -208,10 +183,6 @@ START: return result, fmt.Errorf("redirect would cause protocol downgrade") } - // Copy the cookies so that our client auth transfers - cookies := c.config.HttpClient.Jar.Cookies(r.URL) - c.config.HttpClient.Jar.SetCookies(respLoc, cookies) - // Update the request r.URL = respLoc diff --git a/api/client_test.go b/api/client_test.go index 18a018fe01..af360a640b 100644 --- a/api/client_test.go +++ b/api/client_test.go @@ -6,7 +6,6 @@ import ( "net/http" "os" "testing" - "time" ) func init() { @@ -39,13 +38,7 @@ func TestDefaultConfig_envvar(t *testing.T) { func TestClientToken(t *testing.T) { tokenValue := "foo" - handler := func(w http.ResponseWriter, req *http.Request) { - http.SetCookie(w, &http.Cookie{ - Name: AuthCookieName, - Value: tokenValue, - Expires: time.Now().Add(time.Hour), - }) - } + handler := func(w http.ResponseWriter, req *http.Request) {} config, ln := testHTTPServer(t, http.HandlerFunc(handler)) defer ln.Close() @@ -55,15 +48,7 @@ func TestClientToken(t *testing.T) { t.Fatalf("err: %s", err) } - // Should have no token initially - if v := client.Token(); v != "" { - t.Fatalf("bad: %s", v) - } - - // Do a raw "/" request to set the cookie - if _, err := client.RawRequest(client.NewRequest("GET", "/")); err != nil { - t.Fatalf("err: %s", err) - } + client.SetToken(tokenValue) // Verify the token is set if v := client.Token(); v != tokenValue { @@ -77,63 +62,8 @@ func TestClientToken(t *testing.T) { } } -func TestClientSetToken(t *testing.T) { - var tokenValue string - handler := func(w http.ResponseWriter, req *http.Request) { - cookie, err := req.Cookie(AuthCookieName) - if err != nil { - t.Fatalf("err: %s", err) - } - - tokenValue = cookie.Value - } - - config, ln := testHTTPServer(t, http.HandlerFunc(handler)) - defer ln.Close() - - client, err := NewClient(config) - if err != nil { - t.Fatalf("err: %s", err) - } - - // Should have no token initially - if v := client.Token(); v != "" { - t.Fatalf("bad: %s", v) - } - - // Set the cookie manually - client.SetToken("foo") - - // Do a raw "/" request to get the cookie - if _, err := client.RawRequest(client.NewRequest("GET", "/")); err != nil { - t.Fatalf("err: %s", err) - } - - // Verify the token is set - if v := client.Token(); v != "foo" { - t.Fatalf("bad: %s", v) - } - if v := tokenValue; v != "foo" { - t.Fatalf("bad: %s", v) - } - - client.ClearToken() - - if v := client.Token(); v != "" { - t.Fatalf("bad: %s", v) - } -} - func TestClientRedirect(t *testing.T) { primary := func(w http.ResponseWriter, req *http.Request) { - cookie, err := req.Cookie(AuthCookieName) - if err != nil { - t.Fatalf("err: %s", err) - } - if cookie.Value != "foo" { - t.Fatalf("Bad: %#v", cookie) - } - w.Write([]byte("test")) } config, ln := testHTTPServer(t, http.HandlerFunc(primary)) diff --git a/api/request.go b/api/request.go index b8ac95504b..f44deff832 100644 --- a/api/request.go +++ b/api/request.go @@ -11,12 +11,13 @@ import ( // Request is a raw request configuration structure used to initiate // API requests to the Vault server. type Request struct { - Method string - URL *url.URL - Params url.Values - Obj interface{} - Body io.Reader - BodySize int64 + Method string + URL *url.URL + Params url.Values + ClientToken string + Obj interface{} + Body io.Reader + BodySize int64 } // SetJSONBody is used to set a request body that is a JSON-encoded value. @@ -57,5 +58,9 @@ func (r *Request) ToHTTP() (*http.Request, error) { req.URL.Host = r.URL.Host req.Host = r.URL.Host + if len(r.ClientToken) != 0 { + req.Header.Set("X-Vault-Token", r.ClientToken) + } + return req, nil } diff --git a/api/ssh_agent.go b/api/ssh_agent.go index 5b559020c6..2a0ddb9f5d 100644 --- a/api/ssh_agent.go +++ b/api/ssh_agent.go @@ -78,6 +78,25 @@ func (c *SSHAgentConfig) TLSClient(certPool *x509.CertPool) *http.Client { TLSClientConfig: tlsConfig, TLSHandshakeTimeout: 10 * time.Second, } + + // From https://github.com/michiwend/gomusicbrainz/pull/4/files + defaultRedirectLimit := 30 + + client.CheckRedirect = func(req *http.Request, via []*http.Request) error { + if len(via) > defaultRedirectLimit { + return fmt.Errorf("%d consecutive requests(redirects)", len(via)) + } + if len(via) == 0 { + // No redirects + return nil + } + // mutate the subsequent redirect requests with the first Header + if token := via[0].Header.Get("X-Vault-Token"); len(token) != 0 { + req.Header.Set("X-Vault-Token", token) + } + return nil + } + return &client } diff --git a/command/meta.go b/command/meta.go index 94c70c6f11..103c0bff40 100644 --- a/command/meta.go +++ b/command/meta.go @@ -135,6 +135,24 @@ func (m *Meta) Client() (*api.Client, error) { TLSHandshakeTimeout: 10 * time.Second, } + // From https://github.com/michiwend/gomusicbrainz/pull/4/files + defaultRedirectLimit := 30 + + client.CheckRedirect = func(req *http.Request, via []*http.Request) error { + if len(via) > defaultRedirectLimit { + return fmt.Errorf("%d consecutive requests(redirects)", len(via)) + } + if len(via) == 0 { + // No redirects + return nil + } + // mutate the subsequent redirect requests with the first Header + if token := via[0].Header.Get("X-Vault-Token"); len(token) != 0 { + req.Header.Set("X-Vault-Token", token) + } + return nil + } + config.HttpClient = &client } diff --git a/http/handler.go b/http/handler.go index b082c8d309..2d71bddaea 100644 --- a/http/handler.go +++ b/http/handler.go @@ -11,9 +11,6 @@ import ( "github.com/hashicorp/vault/vault" ) -// AuthCookieName is the name of the cookie containing the token. -const AuthCookieName = "token" - // AuthHeaderName is the name of the header containing the token. const AuthHeaderName = "X-Vault-Token" @@ -135,12 +132,6 @@ func respondStandby(core *vault.Core, w http.ResponseWriter, reqURL *url.URL) { // requestAuth adds the token to the logical.Request if it exists. func requestAuth(r *http.Request, req *logical.Request) *logical.Request { - // Attach the cookie value as the token if we have it - cookie, err := r.Cookie(AuthCookieName) - if err == nil { - req.ClientToken = cookie.Value - } - // Attach the header value if we have it if v := r.Header.Get(AuthHeaderName); v != "" { req.ClientToken = v diff --git a/http/help_test.go b/http/help_test.go index 2f225e4f91..cc3879b36f 100644 --- a/http/help_test.go +++ b/http/help_test.go @@ -1,7 +1,6 @@ package http import ( - "net/http" "testing" "github.com/hashicorp/vault/vault" @@ -13,10 +12,7 @@ func TestHelp(t *testing.T) { defer ln.Close() TestServerAuth(t, addr, token) - resp, err := http.Get(addr + "/v1/sys/mounts?help=1") - if err != nil { - t.Fatalf("err: %s", err) - } + resp := testHttpGet(t, token, addr+"/v1/sys/mounts?help=1") var actual map[string]interface{} testResponseStatus(t, resp, 200) diff --git a/http/http_test.go b/http/http_test.go index c5cbd30e6d..e8b0aa9752 100644 --- a/http/http_test.go +++ b/http/http_test.go @@ -3,24 +3,30 @@ package http import ( "bytes" "encoding/json" + "fmt" "io" "net/http" "testing" ) -func testHttpDelete(t *testing.T, addr string) *http.Response { - return testHttpData(t, "DELETE", addr, nil) +func testHttpGet(t *testing.T, token string, addr string) *http.Response { + t.Logf("Token is %s", token) + return testHttpData(t, "GET", token, addr, nil) } -func testHttpPost(t *testing.T, addr string, body interface{}) *http.Response { - return testHttpData(t, "POST", addr, body) +func testHttpDelete(t *testing.T, token string, addr string) *http.Response { + return testHttpData(t, "DELETE", token, addr, nil) } -func testHttpPut(t *testing.T, addr string, body interface{}) *http.Response { - return testHttpData(t, "PUT", addr, body) +func testHttpPost(t *testing.T, token string, addr string, body interface{}) *http.Response { + return testHttpData(t, "POST", token, addr, body) } -func testHttpData(t *testing.T, method string, addr string, body interface{}) *http.Response { +func testHttpPut(t *testing.T, token string, addr string, body interface{}) *http.Response { + return testHttpData(t, "PUT", token, addr, body) +} + +func testHttpData(t *testing.T, method string, token string, addr string, body interface{}) *http.Response { bodyReader := new(bytes.Buffer) if body != nil { enc := json.NewEncoder(bodyReader) @@ -35,7 +41,36 @@ func testHttpData(t *testing.T, method string, addr string, body interface{}) *h } req.Header.Set("Content-Type", "application/json") - resp, err := http.DefaultClient.Do(req) + + if len(token) != 0 { + t.Logf("Setting token %s", token) + req.Header.Set("X-Vault-Token", token) + } else { + t.Log("No token set") + } + t.Logf("Request in http_test.go: %#v", req) + + client := http.DefaultClient + + // From https://github.com/michiwend/gomusicbrainz/pull/4/files + defaultRedirectLimit := 30 + + client.CheckRedirect = func(req *http.Request, via []*http.Request) error { + if len(via) > defaultRedirectLimit { + return fmt.Errorf("%d consecutive requests(redirects)", len(via)) + } + if len(via) == 0 { + // No redirects + return nil + } + // mutate the subsequent redirect requests with the first Header + if token := via[0].Header.Get("X-Vault-Token"); len(token) != 0 { + req.Header.Set("X-Vault-Token", token) + } + return nil + } + + resp, err := client.Do(req) if err != nil { t.Fatalf("err: %s", err) } diff --git a/http/logical.go b/http/logical.go index 36b91dadd2..f5fa2326c4 100644 --- a/http/logical.go +++ b/http/logical.go @@ -5,7 +5,6 @@ import ( "net" "net/http" "strings" - "time" "github.com/hashicorp/vault/logical" "github.com/hashicorp/vault/vault" @@ -104,27 +103,9 @@ func respondLogical(w http.ResponseWriter, r *http.Request, path string, dataOnl logicalResp.LeaseDuration = int(resp.Secret.TTL.Seconds()) } - // If we have authentication information, then set the cookie - // and setup the result structure. + // If we have authentication information, then + // set up the result structure. if resp.Auth != nil { - expireDuration := 365 * 24 * time.Hour - if logicalResp.LeaseDuration != 0 { - expireDuration = - time.Duration(logicalResp.LeaseDuration) * time.Second - } - - // Do not set the token as the auth cookie if the endpoint - // is the token store. Otherwise, attempting to create a token - // will cause the client to be authenticated as that token. - if !strings.HasPrefix(path, "auth/token/") { - http.SetCookie(w, &http.Cookie{ - Name: AuthCookieName, - Value: resp.Auth.ClientToken, - Path: "/", - Expires: time.Now().UTC().Add(expireDuration), - }) - } - logicalResp.Auth = &Auth{ ClientToken: resp.Auth.ClientToken, Policies: resp.Auth.Policies, diff --git a/http/logical_test.go b/http/logical_test.go index 1c454e96bd..154b22b0a9 100644 --- a/http/logical_test.go +++ b/http/logical_test.go @@ -3,7 +3,6 @@ package http import ( "bytes" "io" - "net/http" "reflect" "testing" "time" @@ -19,16 +18,13 @@ func TestLogical(t *testing.T) { TestServerAuth(t, addr, token) // WRITE - resp := testHttpPut(t, addr+"/v1/secret/foo", map[string]interface{}{ + resp := testHttpPut(t, token, addr+"/v1/secret/foo", map[string]interface{}{ "data": "bar", }) testResponseStatus(t, resp, 204) // READ - resp, err := http.Get(addr + "/v1/secret/foo") - if err != nil { - t.Fatalf("err: %s", err) - } + resp = testHttpGet(t, token, addr+"/v1/secret/foo") var actual map[string]interface{} expected := map[string]interface{}{ @@ -47,13 +43,10 @@ func TestLogical(t *testing.T) { } // DELETE - resp = testHttpDelete(t, addr+"/v1/secret/foo") + resp = testHttpDelete(t, token, addr+"/v1/secret/foo") testResponseStatus(t, resp, 204) - resp, err = http.Get(addr + "/v1/secret/foo") - if err != nil { - t.Fatalf("err: %s", err) - } + resp = testHttpGet(t, token, addr+"/v1/secret/foo") testResponseStatus(t, resp, 404) } @@ -63,10 +56,7 @@ func TestLogical_noExist(t *testing.T) { defer ln.Close() TestServerAuth(t, addr, token) - resp, err := http.Get(addr + "/v1/secret/foo") - if err != nil { - t.Fatalf("err: %s", err) - } + resp := testHttpGet(t, token, addr+"/v1/secret/foo") testResponseStatus(t, resp, 404) } @@ -111,17 +101,13 @@ func TestLogical_StandbyRedirect(t *testing.T) { TestServerAuth(t, addr1, root) // WRITE to STANDBY - resp := testHttpPut(t, addr2+"/v1/secret/foo", map[string]interface{}{ + resp := testHttpPut(t, root, addr2+"/v1/secret/foo", map[string]interface{}{ "data": "bar", }) testResponseStatus(t, resp, 307) //// READ to standby - resp, err = http.Get(addr2 + "/v1/auth/token/lookup-self") - if err != nil { - t.Fatalf("err: %s", err) - } - + resp = testHttpGet(t, root, addr2+"/v1/auth/token/lookup-self") var actual map[string]interface{} expected := map[string]interface{}{ "renewable": false, @@ -136,6 +122,7 @@ func TestLogical_StandbyRedirect(t *testing.T) { }, "auth": nil, } + testResponseStatus(t, resp, 200) testResponseBody(t, resp, &actual) delete(actual, "lease_id") @@ -144,7 +131,7 @@ func TestLogical_StandbyRedirect(t *testing.T) { } //// DELETE to standby - resp = testHttpDelete(t, addr2+"/v1/secret/foo") + resp = testHttpDelete(t, root, addr2+"/v1/secret/foo") testResponseStatus(t, resp, 307) } @@ -155,7 +142,7 @@ func TestLogical_CreateToken(t *testing.T) { TestServerAuth(t, addr, token) // WRITE - resp := testHttpPut(t, addr+"/v1/auth/token/create", map[string]interface{}{ + resp := testHttpPut(t, token, addr+"/v1/auth/token/create", map[string]interface{}{ "data": "bar", }) @@ -178,11 +165,6 @@ func TestLogical_CreateToken(t *testing.T) { if !reflect.DeepEqual(actual, expected) { t.Fatalf("bad: %#v %#v", actual, expected) } - - // Should not get auth cookie - if cookies := resp.Cookies(); len(cookies) != 0 { - t.Fatalf("should not get cookies: %#v", cookies) - } } func TestLogical_RawHTTP(t *testing.T) { @@ -191,16 +173,13 @@ func TestLogical_RawHTTP(t *testing.T) { defer ln.Close() TestServerAuth(t, addr, token) - resp := testHttpPost(t, addr+"/v1/sys/mounts/foo", map[string]interface{}{ + resp := testHttpPost(t, token, addr+"/v1/sys/mounts/foo", map[string]interface{}{ "type": "http", }) testResponseStatus(t, resp, 204) // Get the raw response - resp, err := http.Get(addr + "/v1/foo/raw") - if err != nil { - t.Fatalf("err: %s", err) - } + resp = testHttpGet(t, token, addr+"/v1/foo/raw") testResponseStatus(t, resp, 200) // Test the headers diff --git a/http/sys_audit_test.go b/http/sys_audit_test.go index 2f84c40bec..f67af78f7d 100644 --- a/http/sys_audit_test.go +++ b/http/sys_audit_test.go @@ -1,7 +1,6 @@ package http import ( - "net/http" "reflect" "testing" @@ -14,15 +13,12 @@ func TestSysAudit(t *testing.T) { defer ln.Close() TestServerAuth(t, addr, token) - resp := testHttpPost(t, addr+"/v1/sys/audit/noop", map[string]interface{}{ + resp := testHttpPost(t, token, addr+"/v1/sys/audit/noop", map[string]interface{}{ "type": "noop", }) testResponseStatus(t, resp, 204) - resp, err := http.Get(addr + "/v1/sys/audit") - if err != nil { - t.Fatalf("err: %s", err) - } + resp = testHttpGet(t, token, addr+"/v1/sys/audit") var actual map[string]interface{} expected := map[string]interface{}{ @@ -45,18 +41,15 @@ func TestSysDisableAudit(t *testing.T) { defer ln.Close() TestServerAuth(t, addr, token) - resp := testHttpPost(t, addr+"/v1/sys/audit/foo", map[string]interface{}{ + resp := testHttpPost(t, token, addr+"/v1/sys/audit/foo", map[string]interface{}{ "type": "noop", }) testResponseStatus(t, resp, 204) - resp = testHttpDelete(t, addr+"/v1/sys/audit/foo") + resp = testHttpDelete(t, token, addr+"/v1/sys/audit/foo") testResponseStatus(t, resp, 204) - resp, err := http.Get(addr + "/v1/sys/audit") - if err != nil { - t.Fatalf("err: %s", err) - } + resp = testHttpGet(t, token, addr+"/v1/sys/audit") var actual map[string]interface{} expected := map[string]interface{}{} diff --git a/http/sys_auth_test.go b/http/sys_auth_test.go index 22046051d8..cac1daa370 100644 --- a/http/sys_auth_test.go +++ b/http/sys_auth_test.go @@ -1,7 +1,6 @@ package http import ( - "net/http" "reflect" "testing" @@ -14,10 +13,7 @@ func TestSysAuth(t *testing.T) { defer ln.Close() TestServerAuth(t, addr, token) - resp, err := http.Get(addr + "/v1/sys/auth") - if err != nil { - t.Fatalf("err: %s", err) - } + resp := testHttpGet(t, token, addr+"/v1/sys/auth") var actual map[string]interface{} expected := map[string]interface{}{ @@ -39,16 +35,13 @@ func TestSysEnableAuth(t *testing.T) { defer ln.Close() TestServerAuth(t, addr, token) - resp := testHttpPost(t, addr+"/v1/sys/auth/foo", map[string]interface{}{ + resp := testHttpPost(t, token, addr+"/v1/sys/auth/foo", map[string]interface{}{ "type": "noop", "description": "foo", }) testResponseStatus(t, resp, 204) - resp, err := http.Get(addr + "/v1/sys/auth") - if err != nil { - t.Fatalf("err: %s", err) - } + resp = testHttpGet(t, token, addr+"/v1/sys/auth") var actual map[string]interface{} expected := map[string]interface{}{ @@ -74,19 +67,16 @@ func TestSysDisableAuth(t *testing.T) { defer ln.Close() TestServerAuth(t, addr, token) - resp := testHttpPost(t, addr+"/v1/sys/auth/foo", map[string]interface{}{ + resp := testHttpPost(t, token, addr+"/v1/sys/auth/foo", map[string]interface{}{ "type": "noop", "description": "foo", }) testResponseStatus(t, resp, 204) - resp = testHttpDelete(t, addr+"/v1/sys/auth/foo") + resp = testHttpDelete(t, token, addr+"/v1/sys/auth/foo") testResponseStatus(t, resp, 204) - resp, err := http.Get(addr + "/v1/sys/auth") - if err != nil { - t.Fatalf("err: %s", err) - } + resp = testHttpGet(t, token, addr+"/v1/sys/auth") var actual map[string]interface{} expected := map[string]interface{}{ diff --git a/http/sys_init_test.go b/http/sys_init_test.go index 6fa20a5d8f..b3dec904dc 100644 --- a/http/sys_init_test.go +++ b/http/sys_init_test.go @@ -58,7 +58,7 @@ func TestSysInit_put(t *testing.T) { ln, addr := TestServer(t, core) defer ln.Close() - resp := testHttpPut(t, addr+"/v1/sys/init", map[string]interface{}{ + resp := testHttpPut(t, "", addr+"/v1/sys/init", map[string]interface{}{ "secret_shares": 5, "secret_threshold": 3, }) diff --git a/http/sys_lease_test.go b/http/sys_lease_test.go index 0be16677b9..72c7af23a7 100644 --- a/http/sys_lease_test.go +++ b/http/sys_lease_test.go @@ -2,7 +2,6 @@ package http import ( "encoding/json" - "net/http" "testing" "github.com/hashicorp/vault/vault" @@ -15,18 +14,14 @@ func TestSysRenew(t *testing.T) { TestServerAuth(t, addr, token) // write secret - resp := testHttpPut(t, addr+"/v1/secret/foo", map[string]interface{}{ + resp := testHttpPut(t, token, addr+"/v1/secret/foo", map[string]interface{}{ "data": "bar", "lease": "1h", }) testResponseStatus(t, resp, 204) // read secret - resp, err := http.Get(addr + "/v1/secret/foo") - if err != nil { - t.Fatalf("err: %s", err) - } - + resp = testHttpGet(t, token, addr+"/v1/secret/foo") var result struct { LeaseId string `json:"lease_id"` } @@ -35,7 +30,7 @@ func TestSysRenew(t *testing.T) { t.Fatalf("bad: %s", err) } - resp = testHttpPut(t, addr+"/v1/sys/renew/"+result.LeaseId, nil) + resp = testHttpPut(t, token, addr+"/v1/sys/renew/"+result.LeaseId, nil) testResponseStatus(t, resp, 200) } @@ -45,7 +40,7 @@ func TestSysRevoke(t *testing.T) { defer ln.Close() TestServerAuth(t, addr, token) - resp := testHttpPut(t, addr+"/v1/sys/revoke/secret/foo/1234", nil) + resp := testHttpPut(t, token, addr+"/v1/sys/revoke/secret/foo/1234", nil) testResponseStatus(t, resp, 204) } @@ -55,6 +50,6 @@ func TestSysRevokePrefix(t *testing.T) { defer ln.Close() TestServerAuth(t, addr, token) - resp := testHttpPut(t, addr+"/v1/sys/revoke-prefix/secret/foo/1234", nil) + resp := testHttpPut(t, token, addr+"/v1/sys/revoke-prefix/secret/foo/1234", nil) testResponseStatus(t, resp, 204) } diff --git a/http/sys_mount_test.go b/http/sys_mount_test.go index 9e7a943405..1f41837524 100644 --- a/http/sys_mount_test.go +++ b/http/sys_mount_test.go @@ -1,7 +1,6 @@ package http import ( - "net/http" "reflect" "testing" @@ -14,10 +13,7 @@ func TestSysMounts(t *testing.T) { defer ln.Close() TestServerAuth(t, addr, token) - resp, err := http.Get(addr + "/v1/sys/mounts") - if err != nil { - t.Fatalf("err: %s", err) - } + resp := testHttpGet(t, token, addr+"/v1/sys/mounts") var actual map[string]interface{} expected := map[string]interface{}{ @@ -43,16 +39,13 @@ func TestSysMount(t *testing.T) { defer ln.Close() TestServerAuth(t, addr, token) - resp := testHttpPost(t, addr+"/v1/sys/mounts/foo", map[string]interface{}{ + resp := testHttpPost(t, token, addr+"/v1/sys/mounts/foo", map[string]interface{}{ "type": "generic", "description": "foo", }) testResponseStatus(t, resp, 204) - resp, err := http.Get(addr + "/v1/sys/mounts") - if err != nil { - t.Fatalf("err: %s", err) - } + resp = testHttpGet(t, token, addr+"/v1/sys/mounts") var actual map[string]interface{} expected := map[string]interface{}{ @@ -82,7 +75,7 @@ func TestSysMount_put(t *testing.T) { defer ln.Close() TestServerAuth(t, addr, token) - resp := testHttpPut(t, addr+"/v1/sys/mounts/foo", map[string]interface{}{ + resp := testHttpPut(t, token, addr+"/v1/sys/mounts/foo", map[string]interface{}{ "type": "generic", "description": "foo", }) @@ -98,22 +91,19 @@ func TestSysRemount(t *testing.T) { defer ln.Close() TestServerAuth(t, addr, token) - resp := testHttpPost(t, addr+"/v1/sys/mounts/foo", map[string]interface{}{ + resp := testHttpPost(t, token, addr+"/v1/sys/mounts/foo", map[string]interface{}{ "type": "generic", "description": "foo", }) testResponseStatus(t, resp, 204) - resp = testHttpPost(t, addr+"/v1/sys/remount", map[string]interface{}{ + resp = testHttpPost(t, token, addr+"/v1/sys/remount", map[string]interface{}{ "from": "foo", "to": "bar", }) testResponseStatus(t, resp, 204) - resp, err := http.Get(addr + "/v1/sys/mounts") - if err != nil { - t.Fatalf("err: %s", err) - } + resp = testHttpGet(t, token, addr+"/v1/sys/mounts") var actual map[string]interface{} expected := map[string]interface{}{ @@ -143,19 +133,16 @@ func TestSysUnmount(t *testing.T) { defer ln.Close() TestServerAuth(t, addr, token) - resp := testHttpPost(t, addr+"/v1/sys/mounts/foo", map[string]interface{}{ + resp := testHttpPost(t, token, addr+"/v1/sys/mounts/foo", map[string]interface{}{ "type": "generic", "description": "foo", }) testResponseStatus(t, resp, 204) - resp = testHttpDelete(t, addr+"/v1/sys/mounts/foo") + resp = testHttpDelete(t, token, addr+"/v1/sys/mounts/foo") testResponseStatus(t, resp, 204) - resp, err := http.Get(addr + "/v1/sys/mounts") - if err != nil { - t.Fatalf("err: %s", err) - } + resp = testHttpGet(t, token, addr+"/v1/sys/mounts") var actual map[string]interface{} expected := map[string]interface{}{ diff --git a/http/sys_policy_test.go b/http/sys_policy_test.go index 7c28876e32..788f358f17 100644 --- a/http/sys_policy_test.go +++ b/http/sys_policy_test.go @@ -1,7 +1,6 @@ package http import ( - "net/http" "reflect" "testing" @@ -14,10 +13,7 @@ func TestSysPolicies(t *testing.T) { defer ln.Close() TestServerAuth(t, addr, token) - resp, err := http.Get(addr + "/v1/sys/policy") - if err != nil { - t.Fatalf("err: %s", err) - } + resp := testHttpGet(t, token, addr+"/v1/sys/policy") var actual map[string]interface{} expected := map[string]interface{}{ @@ -36,10 +32,7 @@ func TestSysReadPolicy(t *testing.T) { defer ln.Close() TestServerAuth(t, addr, token) - resp, err := http.Get(addr + "/v1/sys/policy/root") - if err != nil { - t.Fatalf("err: %s", err) - } + resp := testHttpGet(t, token, addr+"/v1/sys/policy/root") var actual map[string]interface{} expected := map[string]interface{}{ @@ -59,15 +52,12 @@ func TestSysWritePolicy(t *testing.T) { defer ln.Close() TestServerAuth(t, addr, token) - resp := testHttpPost(t, addr+"/v1/sys/policy/foo", map[string]interface{}{ + resp := testHttpPost(t, token, addr+"/v1/sys/policy/foo", map[string]interface{}{ "rules": ``, }) testResponseStatus(t, resp, 204) - resp, err := http.Get(addr + "/v1/sys/policy") - if err != nil { - t.Fatalf("err: %s", err) - } + resp = testHttpGet(t, token, addr+"/v1/sys/policy") var actual map[string]interface{} expected := map[string]interface{}{ @@ -86,18 +76,15 @@ func TestSysDeletePolicy(t *testing.T) { defer ln.Close() TestServerAuth(t, addr, token) - resp := testHttpPost(t, addr+"/v1/sys/policy/foo", map[string]interface{}{ + resp := testHttpPost(t, token, addr+"/v1/sys/policy/foo", map[string]interface{}{ "rules": ``, }) testResponseStatus(t, resp, 204) - resp = testHttpDelete(t, addr+"/v1/sys/policy/foo") + resp = testHttpDelete(t, token, addr+"/v1/sys/policy/foo") testResponseStatus(t, resp, 204) - resp, err := http.Get(addr + "/v1/sys/policy") - if err != nil { - t.Fatalf("err: %s", err) - } + resp = testHttpGet(t, token, addr+"/v1/sys/policy") var actual map[string]interface{} expected := map[string]interface{}{ diff --git a/http/sys_rekey_test.go b/http/sys_rekey_test.go index 9b1ed57de3..d930801419 100644 --- a/http/sys_rekey_test.go +++ b/http/sys_rekey_test.go @@ -41,16 +41,13 @@ func TestSysRekeyInit_Setup(t *testing.T) { defer ln.Close() TestServerAuth(t, addr, token) - resp := testHttpPut(t, addr+"/v1/sys/rekey/init", map[string]interface{}{ + resp := testHttpPut(t, token, addr+"/v1/sys/rekey/init", map[string]interface{}{ "secret_shares": 5, "secret_threshold": 3, }) testResponseStatus(t, resp, 204) - resp, err := http.Get(addr + "/v1/sys/rekey/init") - if err != nil { - t.Fatalf("err: %s", err) - } + resp = testHttpGet(t, token, addr+"/v1/sys/rekey/init") var actual map[string]interface{} expected := map[string]interface{}{ @@ -73,13 +70,13 @@ func TestSysRekeyInit_Cancel(t *testing.T) { defer ln.Close() TestServerAuth(t, addr, token) - resp := testHttpPut(t, addr+"/v1/sys/rekey/init", map[string]interface{}{ + resp := testHttpPut(t, token, addr+"/v1/sys/rekey/init", map[string]interface{}{ "secret_shares": 5, "secret_threshold": 3, }) testResponseStatus(t, resp, 204) - resp = testHttpDelete(t, addr+"/v1/sys/rekey/init") + resp = testHttpDelete(t, token, addr+"/v1/sys/rekey/init") testResponseStatus(t, resp, 204) resp, err := http.Get(addr + "/v1/sys/rekey/init") @@ -108,7 +105,7 @@ func TestSysRekey_badKey(t *testing.T) { defer ln.Close() TestServerAuth(t, addr, token) - resp := testHttpPut(t, addr+"/v1/sys/rekey/update", map[string]interface{}{ + resp := testHttpPut(t, token, addr+"/v1/sys/rekey/update", map[string]interface{}{ "key": "0123", }) testResponseStatus(t, resp, 400) @@ -120,13 +117,13 @@ func TestSysRekey_Update(t *testing.T) { defer ln.Close() TestServerAuth(t, addr, token) - resp := testHttpPut(t, addr+"/v1/sys/rekey/init", map[string]interface{}{ + resp := testHttpPut(t, token, addr+"/v1/sys/rekey/init", map[string]interface{}{ "secret_shares": 5, "secret_threshold": 3, }) testResponseStatus(t, resp, 204) - resp = testHttpPut(t, addr+"/v1/sys/rekey/update", map[string]interface{}{ + resp = testHttpPut(t, token, addr+"/v1/sys/rekey/update", map[string]interface{}{ "key": hex.EncodeToString(master), }) diff --git a/http/sys_rotate_test.go b/http/sys_rotate_test.go index d47a170e48..ce6afb27b5 100644 --- a/http/sys_rotate_test.go +++ b/http/sys_rotate_test.go @@ -1,7 +1,6 @@ package http import ( - "net/http" "reflect" "testing" @@ -14,13 +13,10 @@ func TestSysRotate(t *testing.T) { defer ln.Close() TestServerAuth(t, addr, token) - resp := testHttpPost(t, addr+"/v1/sys/rotate", map[string]interface{}{}) + resp := testHttpPost(t, token, addr+"/v1/sys/rotate", map[string]interface{}{}) testResponseStatus(t, resp, 204) - resp, err := http.Get(addr + "/v1/sys/key-status") - if err != nil { - t.Fatalf("err: %s", err) - } + resp = testHttpGet(t, token, addr+"/v1/sys/key-status") var actual map[string]interface{} expected := map[string]interface{}{ diff --git a/http/sys_seal_test.go b/http/sys_seal_test.go index 7a26d48851..d403ae1e70 100644 --- a/http/sys_seal_test.go +++ b/http/sys_seal_test.go @@ -52,7 +52,7 @@ func TestSysSeal(t *testing.T) { defer ln.Close() TestServerAuth(t, addr, token) - resp := testHttpPut(t, addr+"/v1/sys/seal", nil) + resp := testHttpPut(t, token, addr+"/v1/sys/seal", nil) testResponseStatus(t, resp, 204) check, err := core.Sealed() @@ -70,7 +70,7 @@ func TestSysSeal_unsealed(t *testing.T) { defer ln.Close() TestServerAuth(t, addr, token) - resp := testHttpPut(t, addr+"/v1/sys/seal", nil) + resp := testHttpPut(t, token, addr+"/v1/sys/seal", nil) testResponseStatus(t, resp, 204) check, err := core.Sealed() @@ -88,7 +88,7 @@ func TestSysUnseal(t *testing.T) { ln, addr := TestServer(t, core) defer ln.Close() - resp := testHttpPut(t, addr+"/v1/sys/unseal", map[string]interface{}{ + resp := testHttpPut(t, "", addr+"/v1/sys/unseal", map[string]interface{}{ "key": hex.EncodeToString(key), }) @@ -112,7 +112,7 @@ func TestSysUnseal_badKey(t *testing.T) { ln, addr := TestServer(t, core) defer ln.Close() - resp := testHttpPut(t, addr+"/v1/sys/unseal", map[string]interface{}{ + resp := testHttpPut(t, "", addr+"/v1/sys/unseal", map[string]interface{}{ "key": "0123", }) diff --git a/http/testing.go b/http/testing.go index 5c6f980032..bda4819d4b 100644 --- a/http/testing.go +++ b/http/testing.go @@ -4,9 +4,7 @@ import ( "fmt" "net" "net/http" - "net/http/cookiejar" "testing" - "time" "github.com/hashicorp/vault/vault" ) @@ -48,30 +46,11 @@ func TestServer(t *testing.T, core *vault.Core) (net.Listener, string) { } func TestServerAuth(t *testing.T, addr string, token string) { - // If no cookie jar is set on the default HTTP client, then setup the jar - if http.DefaultClient.Jar == nil { - jar, err := cookiejar.New(&cookiejar.Options{}) - if err != nil { - t.Fatalf("err: %s", err) - } - - http.DefaultClient.Jar = jar - } - - // Get the internal path so that we set the cookie if _, err := http.Get(addr + "/_test/auth?token=" + token); err != nil { t.Fatalf("error authenticating: %s", err) } } func testHandleAuth(w http.ResponseWriter, req *http.Request) { - token := req.URL.Query().Get("token") - http.SetCookie(w, &http.Cookie{ - Name: AuthCookieName, - Value: token, - Path: "/", - Expires: time.Now().UTC().Add(1 * time.Hour), - }) - respondOk(w, nil) }