2022-05-09 11:27:37 +00:00
|
|
|
package approle
|
|
|
|
|
|
|
|
import (
|
2022-05-15 15:42:08 +00:00
|
|
|
"context"
|
2022-05-09 11:27:37 +00:00
|
|
|
"encoding/json"
|
2022-05-15 15:42:08 +00:00
|
|
|
"fmt"
|
|
|
|
"net/http"
|
|
|
|
"net/http/httptest"
|
|
|
|
"net/url"
|
2022-05-09 11:27:37 +00:00
|
|
|
"testing"
|
2022-05-15 15:42:08 +00:00
|
|
|
|
|
|
|
vault "github.com/hashicorp/vault/api"
|
2022-05-09 11:27:37 +00:00
|
|
|
)
|
|
|
|
|
2022-05-15 15:42:08 +00:00
|
|
|
func testCAHelper(t *testing.T) (*url.URL, *vault.Client) {
|
|
|
|
t.Helper()
|
|
|
|
|
|
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
switch {
|
|
|
|
case r.RequestURI == "/v1/auth/approle/login":
|
|
|
|
w.WriteHeader(http.StatusOK)
|
|
|
|
fmt.Fprintf(w, `{
|
|
|
|
"auth": {
|
|
|
|
"client_token": "hvs.0000"
|
|
|
|
}
|
|
|
|
}`)
|
|
|
|
case r.RequestURI == "/v1/auth/custom-approle/login":
|
|
|
|
w.WriteHeader(http.StatusOK)
|
|
|
|
fmt.Fprintf(w, `{
|
|
|
|
"auth": {
|
|
|
|
"client_token": "hvs.9999"
|
|
|
|
}
|
|
|
|
}`)
|
|
|
|
default:
|
|
|
|
w.WriteHeader(http.StatusNotFound)
|
|
|
|
fmt.Fprintf(w, `{"error":"not found"}`)
|
|
|
|
}
|
|
|
|
}))
|
|
|
|
t.Cleanup(func() {
|
|
|
|
srv.Close()
|
|
|
|
})
|
|
|
|
u, err := url.Parse(srv.URL)
|
|
|
|
if err != nil {
|
|
|
|
srv.Close()
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
config := vault.DefaultConfig()
|
|
|
|
config.Address = srv.URL
|
2022-05-09 11:27:37 +00:00
|
|
|
|
2022-05-15 15:42:08 +00:00
|
|
|
client, err := vault.NewClient(config)
|
2022-05-09 11:27:37 +00:00
|
|
|
if err != nil {
|
2022-05-15 15:42:08 +00:00
|
|
|
srv.Close()
|
2022-05-09 11:27:37 +00:00
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2022-05-15 15:42:08 +00:00
|
|
|
|
|
|
|
return u, client
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestApprole_LoginMountPaths(t *testing.T) {
|
|
|
|
caURL, _ := testCAHelper(t)
|
|
|
|
|
|
|
|
config := vault.DefaultConfig()
|
|
|
|
config.Address = caURL.String()
|
|
|
|
client, _ := vault.NewClient(config)
|
|
|
|
|
|
|
|
tests := []struct {
|
|
|
|
name string
|
|
|
|
mountPath string
|
|
|
|
token string
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "ok default mount path",
|
|
|
|
mountPath: "",
|
|
|
|
token: "hvs.0000",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "ok explicit mount path",
|
|
|
|
mountPath: "approle",
|
|
|
|
token: "hvs.0000",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "ok custom mount path",
|
|
|
|
mountPath: "custom-approle",
|
|
|
|
token: "hvs.9999",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tt := range tests {
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
method, err := NewApproleAuthMethod(tt.mountPath, json.RawMessage(`{"RoleID":"roleID","SecretID":"secretID","IsWrappingToken":false}`))
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("NewApproleAuthMethod() error = %v", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
secret, err := client.Auth().Login(context.Background(), method)
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("Login() error = %v", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
token, _ := secret.TokenID()
|
|
|
|
if token != tt.token {
|
|
|
|
t.Errorf("Token error got %v, expected %v", token, tt.token)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestApprole_NewApproleAuthMethod(t *testing.T) {
|
|
|
|
tests := []struct {
|
|
|
|
name string
|
|
|
|
mountPath string
|
|
|
|
raw string
|
|
|
|
wantErr bool
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
"ok secret-id string",
|
|
|
|
"",
|
|
|
|
`{"RoleID": "0000-0000-0000-0000", "SecretID": "0000-0000-0000-0000"}`,
|
|
|
|
false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ok secret-id string and wrapped",
|
|
|
|
"",
|
|
|
|
`{"RoleID": "0000-0000-0000-0000", "SecretID": "0000-0000-0000-0000", "isWrappedToken": true}`,
|
|
|
|
false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ok secret-id string and wrapped with custom mountPath",
|
|
|
|
"approle2",
|
|
|
|
`{"RoleID": "0000-0000-0000-0000", "SecretID": "0000-0000-0000-0000", "isWrappedToken": true}`,
|
|
|
|
false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ok secret-id file",
|
|
|
|
"",
|
|
|
|
`{"RoleID": "0000-0000-0000-0000", "SecretIDFile": "./secret-id"}`,
|
|
|
|
false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"ok secret-id env",
|
|
|
|
"",
|
|
|
|
`{"RoleID": "0000-0000-0000-0000", "SecretIDEnv": "VAULT_APPROLE_SECRETID"}`,
|
|
|
|
false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"fail mandatory role-id",
|
|
|
|
"",
|
|
|
|
`{}`,
|
|
|
|
true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"fail mandatory secret-id any",
|
|
|
|
"",
|
|
|
|
`{"RoleID": "0000-0000-0000-0000"}`,
|
|
|
|
true,
|
|
|
|
},
|
2022-05-17 20:13:11 +00:00
|
|
|
{
|
|
|
|
"fail multiple secret-id types id and env",
|
|
|
|
"",
|
|
|
|
`{"RoleID": "0000-0000-0000-0000", "SecretID": "0000-0000-0000-0000", "SecretIDEnv": "VAULT_APPROLE_SECRETID"}`,
|
|
|
|
true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"fail multiple secret-id types id and file",
|
|
|
|
"",
|
|
|
|
`{"RoleID": "0000-0000-0000-0000", "SecretID": "0000-0000-0000-0000", "SecretIDFile": "./secret-id"}`,
|
|
|
|
true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"fail multiple secret-id types env and file",
|
|
|
|
"",
|
|
|
|
`{"RoleID": "0000-0000-0000-0000", "SecretIDFile": "./secret-id", "SecretIDEnv": "VAULT_APPROLE_SECRETID"}`,
|
|
|
|
true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"fail multiple secret-id types all",
|
|
|
|
"",
|
|
|
|
`{"RoleID": "0000-0000-0000-0000", "SecretID": "0000-0000-0000-0000", "SecretIDFile": "./secret-id", "SecretIDEnv": "VAULT_APPROLE_SECRETID"}`,
|
|
|
|
true,
|
|
|
|
},
|
2022-05-15 15:42:08 +00:00
|
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
_, err := NewApproleAuthMethod(tt.mountPath, json.RawMessage(tt.raw))
|
|
|
|
if (err != nil) != tt.wantErr {
|
|
|
|
t.Errorf("Approle.NewApproleAuthMethod() error = %v, wantErr %v", err, tt.wantErr)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
2022-05-09 11:27:37 +00:00
|
|
|
}
|