Remove cookie authentication.

This commit is contained in:
Jeff Mitchell
2015-08-21 17:36:19 -07:00
parent 3da9f81bdd
commit f1a301922d
20 changed files with 185 additions and 336 deletions

View File

@@ -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

View File

@@ -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))

View File

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

View File

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

View File

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

View File

@@ -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

View File

@@ -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)

View File

@@ -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)
}

View File

@@ -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,

View File

@@ -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

View File

@@ -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{}{}

View File

@@ -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{}{

View File

@@ -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,
})

View File

@@ -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)
}

View File

@@ -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{}{

View File

@@ -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{}{

View File

@@ -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),
})

View File

@@ -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{}{

View File

@@ -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",
})

View File

@@ -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)
}