124 lines
3.9 KiB
Go
124 lines
3.9 KiB
Go
package api
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"net"
|
|
"os"
|
|
"testing"
|
|
|
|
"git.julianfamily.org/keepassgo/internal/apitokens"
|
|
"git.julianfamily.org/keepassgo/internal/grpcaddr"
|
|
"git.julianfamily.org/keepassgo/internal/passwords"
|
|
"git.julianfamily.org/keepassgo/internal/session"
|
|
"git.julianfamily.org/keepassgo/internal/vault"
|
|
keepassgov1 "git.julianfamily.org/keepassgo/proto/keepassgo/v1"
|
|
"google.golang.org/grpc"
|
|
"google.golang.org/grpc/credentials/insecure"
|
|
)
|
|
|
|
func TestStartHostServesVaultLifecycleAndSyncsSessionState(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
lifecycle := &session.Manager{}
|
|
if err := lifecycle.Create(vault.Model{
|
|
Entries: []vault.Entry{
|
|
testAPITokenEntry(t,
|
|
apitokens.PolicyRule{
|
|
Effect: apitokens.EffectAllow,
|
|
Operation: apitokens.OperationManageVault,
|
|
Resource: apitokens.Resource{
|
|
Kind: apitokens.ResourceGroup,
|
|
Path: []string{"Root"},
|
|
},
|
|
},
|
|
),
|
|
{ID: "entry-1", Title: "Vault Console", Path: []string{"Root", "Internet"}},
|
|
},
|
|
}, vault.MasterKey{Password: "correct horse battery staple"}); err != nil {
|
|
t.Fatalf("Create() error = %v", err)
|
|
}
|
|
|
|
host, err := StartHost("127.0.0.1:0", lifecycle, passwords.DefaultProfiles(), nil, func() bool { return true })
|
|
if err != nil {
|
|
t.Fatalf("StartHost() error = %v", err)
|
|
}
|
|
defer func() { _ = host.Stop() }()
|
|
|
|
network, endpoint, err := grpcaddr.Parse(host.Address())
|
|
if err != nil {
|
|
t.Fatalf("Parse(host.Address()) error = %v", err)
|
|
}
|
|
conn, err := grpc.NewClient("passthrough:///"+host.Address(),
|
|
grpc.WithTransportCredentials(insecure.NewCredentials()),
|
|
grpc.WithContextDialer(func(context.Context, string) (net.Conn, error) {
|
|
return net.Dial(network, endpoint)
|
|
}),
|
|
)
|
|
if err != nil {
|
|
t.Fatalf("grpc.NewClient() error = %v", err)
|
|
}
|
|
defer func() { _ = conn.Close() }()
|
|
|
|
client := keepassgov1.NewVaultServiceClient(conn)
|
|
statusResp, err := client.GetSessionStatus(tokenContext(defaultTestTokenSecret), &keepassgov1.GetSessionStatusRequest{})
|
|
if err != nil {
|
|
t.Fatalf("GetSessionStatus() error = %v", err)
|
|
}
|
|
if statusResp.Locked {
|
|
t.Fatal("GetSessionStatus().Locked = true, want false")
|
|
}
|
|
if !statusResp.Dirty {
|
|
t.Fatal("GetSessionStatus().Dirty = false, want true from dirty provider")
|
|
}
|
|
|
|
if err := lifecycle.Lock(); err != nil {
|
|
t.Fatalf("Lock() error = %v", err)
|
|
}
|
|
if err := host.SyncFromLifecycle(); err != nil {
|
|
t.Fatalf("SyncFromLifecycle() after lock error = %v", err)
|
|
}
|
|
|
|
statusResp, err = client.GetSessionStatus(tokenContext(defaultTestTokenSecret), &keepassgov1.GetSessionStatusRequest{})
|
|
if err != nil {
|
|
t.Fatalf("GetSessionStatus() after lock error = %v", err)
|
|
}
|
|
if !statusResp.Locked {
|
|
t.Fatal("GetSessionStatus().Locked = false, want true after lifecycle lock")
|
|
}
|
|
}
|
|
|
|
func TestStartHostServesOverUnixSocket(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
socketDir := t.TempDir()
|
|
socketPath := socketDir + "/keepassgo.sock"
|
|
lifecycle := &session.Manager{}
|
|
if err := lifecycle.Create(vault.Model{
|
|
Entries: []vault.Entry{
|
|
testAPITokenEntry(t,
|
|
apitokens.PolicyRule{Effect: apitokens.EffectAllow, Operation: apitokens.OperationManageVault, Resource: apitokens.Resource{Kind: apitokens.ResourceGroup, Path: []string{"Root"}}},
|
|
),
|
|
},
|
|
}, vault.MasterKey{Password: "correct horse battery staple"}); err != nil {
|
|
t.Fatalf("Create() error = %v", err)
|
|
}
|
|
|
|
host, err := StartHost("unix://"+socketPath, lifecycle, passwords.DefaultProfiles(), nil, func() bool { return false })
|
|
if err != nil {
|
|
t.Fatalf("StartHost() error = %v", err)
|
|
}
|
|
if got := host.Address(); got != "unix://"+socketPath {
|
|
t.Fatalf("host.Address() = %q, want %q", got, "unix://"+socketPath)
|
|
}
|
|
if _, err := os.Stat(socketPath); err != nil {
|
|
t.Fatalf("Stat(socketPath) error = %v", err)
|
|
}
|
|
if err := host.Stop(); err != nil {
|
|
t.Fatalf("Stop() error = %v", err)
|
|
}
|
|
if _, err := os.Stat(socketPath); !errors.Is(err, os.ErrNotExist) {
|
|
t.Fatalf("socket exists after Stop(), err = %v, want not-exist", err)
|
|
}
|
|
}
|