tinyrelaycommit

Commit 0aca966a5691

browse files at this commit | history

1diff --git a/internal/configport/configport.go b/internal/configport/configport.go
2index e0dc5bf..68d89a4 100644
3--- a/internal/configport/configport.go
4+++ b/internal/configport/configport.go
5@@ -159,7 +159,7 @@ func warnPolicy(c *Config) {
6 c.Warnings = append(c.Warnings, "policy.lease: legacy lease imported disabled; explicit owner mapping required")
7 } else if key == "owner" {
8 c.Warnings = append(c.Warnings, "policy.owner: never imported; tenant owner must be assigned by the operator")
9- } else if key == "succession" || key == "customHosts" || key == "fuel" || strings.Contains(strings.ToLower(key), "limit") || strings.HasPrefix(strings.ToLower(key), "free") || strings.HasPrefix(strings.ToLower(key), "sats") {
10+ } else if key != "fileLimits" && (key == "succession" || key == "customHosts" || key == "fuel" || strings.Contains(strings.ToLower(key), "limit") || strings.HasPrefix(strings.ToLower(key), "free") || strings.HasPrefix(strings.ToLower(key), "sats")) {
11 c.Warnings = append(c.Warnings, "policy."+key+": removed from self-hosted runtime")
12 }
13 }
14diff --git a/internal/configport/file_limits_test.go b/internal/configport/file_limits_test.go
15new file mode 100644
16index 0000000..6a154f2
17--- /dev/null
18+++ b/internal/configport/file_limits_test.go
19@@ -0,0 +1,24 @@
20+package configport
21+
22+import (
23+ "testing"
24+
25+ "github.com/FelineStateMachine/tinyrelay/internal/policy"
26+)
27+
28+func TestImportFileLimits(t *testing.T) {
29+ doc, err := Parse([]byte(`{"format":"bind.ws/relay-config/2","policy":{"fileLimits":{"maxFileBytes":1024,"userStorageBytes":4096}}}`))
30+ if err != nil {
31+ t.Fatal(err)
32+ }
33+ if len(doc.Warnings) != 0 {
34+ t.Fatalf("file limits should be portable: %v", doc.Warnings)
35+ }
36+ got, err := finalPolicy(policy.Defaults("owner"), doc, "")
37+ if err != nil {
38+ t.Fatal(err)
39+ }
40+ if got.FileLimits.MaxFileBytes != 1024 || got.FileLimits.UserStorageBytes != 4096 {
41+ t.Fatalf("file limits lost during import: %+v", got.FileLimits)
42+ }
43+}
44diff --git a/internal/policy/file_limits_test.go b/internal/policy/file_limits_test.go
45new file mode 100644
46index 0000000..0bb2027
47--- /dev/null
48+++ b/internal/policy/file_limits_test.go
49@@ -0,0 +1,27 @@
50+package policy
51+
52+import (
53+ "encoding/json"
54+ "testing"
55+)
56+
57+func TestFileLimitsPatchAndValidation(t *testing.T) {
58+ p := Defaults("owner")
59+ p.FileLimits = FileLimits{MaxFileBytes: 1024, UserStorageBytes: 4096}
60+ updated, err := Patch(p, map[string]json.RawMessage{"fileLimits": json.RawMessage(`{"maxFileBytes":2048}`)})
61+ if err != nil {
62+ t.Fatal(err)
63+ }
64+ if updated.FileLimits.MaxFileBytes != 2048 || updated.FileLimits.UserStorageBytes != 4096 {
65+ t.Fatalf("partial limit patch lost settings: %+v", updated.FileLimits)
66+ }
67+ for _, patch := range []string{`{"maxFileBytes":-1}`, `{"userStorageBytes":-1}`} {
68+ if _, err := Patch(p, map[string]json.RawMessage{"fileLimits": json.RawMessage(patch)}); err == nil {
69+ t.Fatalf("accepted negative limit: %s", patch)
70+ }
71+ }
72+ updated, err = Patch(p, map[string]json.RawMessage{"fileLimits": json.RawMessage(`{"maxFileBytes":0,"userStorageBytes":0}`)})
73+ if err != nil || updated.FileLimits != (FileLimits{}) {
74+ t.Fatalf("zero should disable limits: %+v, %v", updated.FileLimits, err)
75+ }
76+}
77diff --git a/internal/policy/policy.go b/internal/policy/policy.go
78index 1bc0f8c..49599ad 100644
79--- a/internal/policy/policy.go
80+++ b/internal/policy/policy.go
81@@ -62,6 +62,12 @@ type Inbox struct {
82 Targeted bool `json:"targeted"`
83 }
84
85+// FileLimits controls a tenant's file storage allowances. Zero is unlimited.
86+type FileLimits struct {
87+ MaxFileBytes int64 `json:"maxFileBytes"`
88+ UserStorageBytes int64 `json:"userStorageBytes"`
89+}
90+
91 type CustomHost struct {
92 Host string `json:"host"`
93 ID string `json:"id"`
94@@ -109,6 +115,7 @@ type Policy struct {
95 Features Features `json:"features"`
96 PushCallbacks []string `json:"pushCallbacks"`
97 PrivatePeers []string `json:"privatePeers,omitempty"`
98+ FileLimits FileLimits `json:"fileLimits"`
99 LetteredNips bool `json:"letteredNips"`
100 Delivery Delivery `json:"delivery"`
101 Inbox Inbox `json:"inbox"`
102@@ -126,6 +133,9 @@ func Defaults(owner string) Policy {
103 }
104
105 func Validate(p Policy) error {
106+ if p.FileLimits.MaxFileBytes < 0 || p.FileLimits.UserStorageBytes < 0 {
107+ return errors.New("fileLimits: byte allowances cannot be negative")
108+ }
109 if p.Writes != "open" && p.Writes != "allowlist" && p.Writes != "wot" && p.Writes != "owner" {
110 return fmt.Errorf("writes: invalid rule %q", p.Writes)
111 }
112@@ -203,7 +213,7 @@ func Patch(cur Policy, raw map[string]json.RawMessage) (Policy, error) {
113 if _, ok := merged[key]; !ok {
114 continue
115 }
116- if key == "features" || key == "notify" || key == "memberInvites" || key == "delivery" || key == "inbox" {
117+ if key == "features" || key == "notify" || key == "memberInvites" || key == "delivery" || key == "inbox" || key == "fileLimits" {
118 var patchMap, currentMap map[string]json.RawMessage
119 if json.Unmarshal(value, &patchMap) == nil && json.Unmarshal(merged[key], &currentMap) == nil {
120 if key == "features" {

About

ownerc01503e8035f
visibilitypublic
head0aca966a5691

Maintainers

  • c01503e8035f owner
  • ba1b5beed5b5 agent hermes

Clone

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

Refs