Why: collaborative KeePass use needs one arbiter of "who wrote last" that never sees a master password, plus access control that follows an org chart. What: stdlib-only Go server. Metadata is a single JSON document with one writer and atomic commit; KDBX payloads are versioned blobs on disk. Access comes from a group tree where a grant on a group reaches every member below it. Login is password+TOTP, invite links, or OIDC through a browser-approved device flow. Pushes carry If-Match and are arbitrated by a per-database merge strategy (server-wins by default). Updates are pushed to clients over SSE. Proved: go test ./internal/... covers RFC 6238 vectors, ACL inheritance and isolation, store rollback, blob pruning, every push verdict, and an end-to-end HTTP pass over login, conflict, force, read-only grants, invite redemption, TOTP enrolment, device login and the event stream.
43 lines
950 B
Go
43 lines
950 B
Go
package blob
|
|
|
|
import "testing"
|
|
|
|
func TestPutGetIsIdempotentAndVersioned(t *testing.T) {
|
|
s, err := Open(t.TempDir())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := s.Put("db", 1, []byte("v1")); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := s.Put("db", 1, []byte("v1")); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := s.Put("db", 2, []byte("v2")); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
got, err := s.Get("db", 1)
|
|
if err != nil || string(got) != "v1" {
|
|
t.Fatalf("get v1 = %q, %v", got, err)
|
|
}
|
|
if vs := s.Versions("db"); len(vs) != 2 || vs[0] != 1 || vs[1] != 2 {
|
|
t.Fatalf("versions = %v", vs)
|
|
}
|
|
}
|
|
|
|
func TestPruneKeepsNewest(t *testing.T) {
|
|
s, _ := Open(t.TempDir())
|
|
for i := int64(1); i <= KeepVersions+5; i++ {
|
|
if err := s.Put("db", i, []byte{byte(i)}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
if err := s.Prune("db"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
vs := s.Versions("db")
|
|
if len(vs) != KeepVersions || vs[0] != 6 {
|
|
t.Fatalf("after prune = %v", vs)
|
|
}
|
|
}
|