- commit
- 0aca966a569138bd3e705a7f9931fa95a1a348f3
- parent
- 3b648ecfc76b2d06f78f37d22375dbcf5834813f
- author
- Dami <dami.etoile@gmail.com>
| M | internal/ | 2 | +- |
| A | internal/ | 24 | ++++++++++++++++++++++++ |
| A | internal/ | 27 | +++++++++++++++++++++++++++ |
| M | internal/ | 12 | +++++++++++- |
@@ -159,7 +159,7 @@ func warnPolicy(c *Config) {
159159 c.Warnings = append(c.Warnings, "policy.lease: legacy lease imported disabled; explicit owner mapping required")160160 } else if key == "owner" {161161 c.Warnings = append(c.Warnings, "policy.owner: never imported; tenant owner must be assigned by the operator")162- } 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") {162+ } 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")) {163163 c.Warnings = append(c.Warnings, "policy."+key+": removed from self-hosted runtime")164164 }165165 }@@ -0,0 +1,24 @@
1+package configport2+3+import (4+ "testing"5+6+ "github.com/FelineStateMachine/tinyrelay/internal/policy"7+)8+9+func TestImportFileLimits(t *testing.T) {10+ doc, err := Parse([]byte(`{"format":"bind.ws/relay-config/2","policy":{"fileLimits":{"maxFileBytes":1024,"userStorageBytes":4096}}}`))11+ if err != nil {12+ t.Fatal(err)13+ }14+ if len(doc.Warnings) != 0 {15+ t.Fatalf("file limits should be portable: %v", doc.Warnings)16+ }17+ got, err := finalPolicy(policy.Defaults("owner"), doc, "")18+ if err != nil {19+ t.Fatal(err)20+ }21+ if got.FileLimits.MaxFileBytes != 1024 || got.FileLimits.UserStorageBytes != 4096 {22+ t.Fatalf("file limits lost during import: %+v", got.FileLimits)23+ }24+}@@ -0,0 +1,27 @@
1+package policy2+3+import (4+ "encoding/json"5+ "testing"6+)7+8+func TestFileLimitsPatchAndValidation(t *testing.T) {9+ p := Defaults("owner")10+ p.FileLimits = FileLimits{MaxFileBytes: 1024, UserStorageBytes: 4096}11+ updated, err := Patch(p, map[string]json.RawMessage{"fileLimits": json.RawMessage(`{"maxFileBytes":2048}`)})12+ if err != nil {13+ t.Fatal(err)14+ }15+ if updated.FileLimits.MaxFileBytes != 2048 || updated.FileLimits.UserStorageBytes != 4096 {16+ t.Fatalf("partial limit patch lost settings: %+v", updated.FileLimits)17+ }18+ for _, patch := range []string{`{"maxFileBytes":-1}`, `{"userStorageBytes":-1}`} {19+ if _, err := Patch(p, map[string]json.RawMessage{"fileLimits": json.RawMessage(patch)}); err == nil {20+ t.Fatalf("accepted negative limit: %s", patch)21+ }22+ }23+ updated, err = Patch(p, map[string]json.RawMessage{"fileLimits": json.RawMessage(`{"maxFileBytes":0,"userStorageBytes":0}`)})24+ if err != nil || updated.FileLimits != (FileLimits{}) {25+ t.Fatalf("zero should disable limits: %+v, %v", updated.FileLimits, err)26+ }27+}@@ -62,6 +62,12 @@ type Inbox struct {
6262 Targeted bool `json:"targeted"`6363 }6464 65+// FileLimits controls a tenant's file storage allowances. Zero is unlimited.66+type FileLimits struct {67+ MaxFileBytes int64 `json:"maxFileBytes"`68+ UserStorageBytes int64 `json:"userStorageBytes"`69+}70+6571 type CustomHost struct {6672 Host string `json:"host"`6773 ID string `json:"id"`@@ -109,6 +115,7 @@ type Policy struct {
109115 Features Features `json:"features"`110116 PushCallbacks []string `json:"pushCallbacks"`111117 PrivatePeers []string `json:"privatePeers,omitempty"`118+ FileLimits FileLimits `json:"fileLimits"`112119 LetteredNips bool `json:"letteredNips"`113120 Delivery Delivery `json:"delivery"`114121 Inbox Inbox `json:"inbox"`@@ -126,6 +133,9 @@ func Defaults(owner string) Policy {
126133 }127134 128135 func Validate(p Policy) error {136+ if p.FileLimits.MaxFileBytes < 0 || p.FileLimits.UserStorageBytes < 0 {137+ return errors.New("fileLimits: byte allowances cannot be negative")138+ }129139 if p.Writes != "open" && p.Writes != "allowlist" && p.Writes != "wot" && p.Writes != "owner" {130140 return fmt.Errorf("writes: invalid rule %q", p.Writes)131141 }@@ -203,7 +213,7 @@ func Patch(cur Policy, raw map[string]json.RawMessage) (Policy, error) {
203213 if _, ok := merged[key]; !ok {204214 continue205215 }206- if key == "features" || key == "notify" || key == "memberInvites" || key == "delivery" || key == "inbox" {216+ if key == "features" || key == "notify" || key == "memberInvites" || key == "delivery" || key == "inbox" || key == "fileLimits" {207217 var patchMap, currentMap map[string]json.RawMessage208218 if json.Unmarshal(value, &patchMap) == nil && json.Unmarshal(merged[key], ¤tMap) == nil {209219 if key == "features" {