tinyrelayfile
tinyrelay/internal/daemon/room_attachments_test.go/

internal/daemon/room_attachments_test.go raw
1package daemon
2
3import (
4 "context"
5 "encoding/json"
6 "strings"
7 "testing"
8 "time"
9
10 "github.com/FelineStateMachine/tinyrelay/internal/blob"
11 "github.com/FelineStateMachine/tinyrelay/internal/event"
12)
13
14func TestRoomAttachmentAccessFollowsMembership(t *testing.T) {
15 h := newRoomHarness(t)
16 ctx := context.Background()
17 h.must("alice", event.KIND_CREATE_GROUP, [][]string{{"h", "secret"}, {"closed"}}, "")
18 entry, err := h.tenant.blobs.Put(ctx, blob.PutOptions{Reader: strings.NewReader("room secret"), Type: "text/plain", Uploader: h.keys["alice"]})
19 if err != nil {
20 t.Fatal(err)
21 }
22 room, err := h.tenant.community.Room(ctx, "secret")
23 if err != nil {
24 t.Fatal(err)
25 }
26 if _, err := h.tenant.store.DB().ExecContext(ctx, "INSERT INTO room_attachments(room_id,room_event_id,sha256,filename,created_at) VALUES(?,?,?,?,unixepoch())", "secret", room.EventID, entry.SHA256, "secret.txt"); err != nil {
27 t.Fatal(err)
28 }
29 if err := h.tenant.roomAttachmentAccess(ctx, h.keys["stranger"], entry.SHA256); err == nil {
30 t.Fatal("nonmember can read room attachment")
31 }
32 if err := h.tenant.roomAttachmentAccess(ctx, h.keys["owner"], entry.SHA256); err != nil {
33 t.Fatalf("member cannot read room attachment: %v", err)
34 }
35}
36
37func TestGenericBlobRemainsUnscoped(t *testing.T) {
38 h := newRoomHarness(t)
39 entry, err := h.tenant.blobs.Put(context.Background(), blob.PutOptions{Reader: strings.NewReader("public"), Type: "text/plain", Uploader: h.keys["alice"]})
40 if err != nil {
41 t.Fatal(err)
42 }
43 if err := h.tenant.roomAttachmentAccess(context.Background(), "", entry.SHA256); err != nil {
44 t.Fatalf("generic blob unexpectedly scoped: %v", err)
45 }
46}
47
48func TestRoomAttachmentAgentGrantAndStorageLimits(t *testing.T) {
49 _, tenant := testTenant(t)
50 ctx := context.Background()
51 owner := tenant.Policy().Owner
52 agent, _ := event.PublicKey(testAgentSecret)
53 now := time.Now().Unix()
54 if err := publishAs(t, tenant, agentGrantEvent(t, agent, now, now+3600, []string{"k", "9"}, []string{"h", "main"})); err != nil {
55 t.Fatal(err)
56 }
57 input := roomAttachmentInput{Body: []byte("generated attachment"), Type: "text/plain"}
58 if _, err := tenant.storeRoomAttachment(ctx, agent, "main", input); err != nil {
59 t.Fatalf("active agent upload: %v", err)
60 }
61 if _, err := tenant.Execute(ctx, owner, "pauseagent", []json.RawMessage{rawJSON(agent)}); err != nil {
62 t.Fatal(err)
63 }
64 if _, err := tenant.storeRoomAttachment(ctx, agent, "main", input); err == nil {
65 t.Fatal("paused agent uploaded")
66 }
67 if _, err := tenant.Execute(ctx, owner, "revokeagent", []json.RawMessage{rawJSON(agent)}); err != nil {
68 t.Fatal(err)
69 }
70 if _, err := tenant.storeRoomAttachment(ctx, agent, "main", input); err == nil {
71 t.Fatal("revoked agent uploaded")
72 }
73 if _, err := tenant.Execute(ctx, owner, "setpolicy", []json.RawMessage{rawJSON(map[string]any{"fileLimits": map[string]any{"maxFileBytes": 4}})}); err != nil {
74 t.Fatal(err)
75 }
76 if _, err := tenant.storeRoomAttachment(ctx, owner, "main", input); err == nil {
77 t.Fatal("room upload bypassed file limit")
78 }
79}
80
81func TestRoomAttachmentCannotPrivatizeExistingUnscopedBlob(t *testing.T) {
82 h := newRoomHarness(t)
83 entry, err := h.tenant.blobs.Put(h.ctx, blob.PutOptions{Reader: strings.NewReader("shared bytes"), Type: "text/plain", Uploader: h.keys["alice"]})
84 if err != nil {
85 t.Fatal(err)
86 }
87 if _, err := h.tenant.storeRoomAttachment(h.ctx, h.keys["bob"], "main", roomAttachmentInput{Body: []byte("shared bytes"), Type: "text/plain"}); err == nil || !strings.HasPrefix(err.Error(), "conflict:") {
88 t.Fatalf("existing public blob should conflict: %v", err)
89 }
90 scopes, err := h.tenant.roomAttachmentRooms(h.ctx, entry.SHA256)
91 if err != nil || len(scopes) != 0 {
92 t.Fatalf("conflicted upload changed visibility: %v %v", scopes, err)
93 }
94 var claims int
95 if err := h.tenant.store.DB().QueryRowContext(h.ctx, "SELECT COUNT(*) FROM blob_claims WHERE sha256=? AND uploader=?", entry.SHA256, h.keys["bob"]).Scan(&claims); err != nil || claims != 0 {
96 t.Fatalf("conflicted upload left a claim: %d %v", claims, err)
97 }
98}

About

ownerc01503e8035f
visibilitypublic
headd730679639bf

Maintainers

  • c01503e8035f owner
  • ba1b5beed5b5 agent hermes

Clone

  • https://012.run/npub1cq2s86qrtadf36eqq3epm38wmhdynrrcwxf84eldk3f94dkv7ttsrulrz5/tinyrelay.git

Refs