| 1 | package tinygit |
| 2 | |
| 3 | import ( |
| 4 | "context" |
| 5 | "path/filepath" |
| 6 | "strings" |
| 7 | "testing" |
| 8 | |
| 9 | "github.com/FelineStateMachine/tinyrelay/internal/event" |
| 10 | "github.com/FelineStateMachine/tinyrelay/internal/policy" |
| 11 | "github.com/FelineStateMachine/tinyrelay/internal/storage" |
| 12 | ) |
| 13 | |
| 14 | func TestArchiveAnnouncementRequiresOptInWhenServiceConfigured(t *testing.T) { |
| 15 | root := t.TempDir() |
| 16 | store, err := storage.Open(context.Background(), filepath.Join(root, "relay.db" )) |
| 17 | if err != nil { |
| 18 | t.Fatal(err) |
| 19 | } |
| 20 | defer store.Close() |
| 21 | secret := strings.Repeat("0" , 63) + "1" |
| 22 | makeEvent := func() event.Event { |
| 23 | e := event.Event{Kind: 30617, CreatedAt: 1, Tags: [][]string{{"d" , "archive" }}} |
| 24 | if err := event.Sign(&e, secret); err != nil { |
| 25 | t.Fatal(err) |
| 26 | } |
| 27 | return e |
| 28 | } |
| 29 | for name, p := range map[string]policy.Policy{ |
| 30 | "disabled" : {}, |
| 31 | "enabled" : {Features: policy.Features{Grasp02: true, Grasp05: true}}, |
| 32 | } { |
| 33 | t.Run(name, func(t *testing.T) { |
| 34 | g, err := New(Config{Store: tinyStore(store), Root: filepath.Join(root, name), PublicURL: "https://relay.example" , Policy: func() Policy { return fromInternalPolicy(p) }}) |
| 35 | if err != nil { |
| 36 | t.Fatal(err) |
| 37 | } |
| 38 | _, err = g.Validate(context.Background(), makeEvent()) |
| 39 | if name == "disabled" && err == nil { |
| 40 | t.Fatal("archive announcement accepted while GRASP-05 is disabled" ) |
| 41 | } |
| 42 | if name == "enabled" && err != nil { |
| 43 | t.Fatalf("archive announcement rejected: %v" , err) |
| 44 | } |
| 45 | }) |
| 46 | } |
| 47 | } |
| 48 | |
| 49 | func TestArchiveAdmissionRecognizesServiceAndMaintainerExceptions(t *testing.T) { |
| 50 | root := t.TempDir() |
| 51 | store, err := storage.Open(context.Background(), filepath.Join(root, "relay.db" )) |
| 52 | if err != nil { |
| 53 | t.Fatal(err) |
| 54 | } |
| 55 | defer store.Close() |
| 56 | ownerSecret := strings.Repeat("0" , 63) + "1" |
| 57 | maintainerSecret := strings.Repeat("0" , 63) + "2" |
| 58 | _, _ = event.PublicKey(ownerSecret) |
| 59 | maintainer, _ := event.PublicKey(maintainerSecret) |
| 60 | p := policy.Policy{Features: policy.Features{Grasp02: true, Grasp05: true}} |
| 61 | g, err := New(Config{Store: tinyStore(store), Root: filepath.Join(root, "git" ), PublicURL: "https://relay.example" , Policy: func() Policy { return fromInternalPolicy(p) }, Authorize: func(context.Context, Event, Repository) error { return nil }}) |
| 62 | if err != nil { |
| 63 | t.Fatal(err) |
| 64 | } |
| 65 | ownerAnnouncement := event.Event{Kind: 30617, CreatedAt: 1, Tags: [][]string{{"d" , "repo" }, {"clone" , "https://relay.example/repo.git" }, {"relays" , "wss://relay.example" }, {"maintainers" , maintainer}}} |
| 66 | if err := event.Sign(&ownerAnnouncement, ownerSecret); err != nil { |
| 67 | t.Fatal(err) |
| 68 | } |
| 69 | if err := g.Publish(context.Background(), ownerAnnouncement); err != nil { |
| 70 | t.Fatal(err) |
| 71 | } |
| 72 | maintainerAnnouncement := event.Event{Kind: 30617, CreatedAt: 2, Tags: [][]string{{"d" , "repo" }}} |
| 73 | if err := event.Sign(&maintainerAnnouncement, maintainerSecret); err != nil { |
| 74 | t.Fatal(err) |
| 75 | } |
| 76 | if _, err := g.Validate(context.Background(), maintainerAnnouncement); err != nil { |
| 77 | t.Fatalf("recognized maintainer archive announcement rejected: %v" , err) |
| 78 | } |
| 79 | wrong := event.Event{Kind: 30617, CreatedAt: 3, Tags: [][]string{{"d" , "other" }, {"clone" , "https://elsewhere.example/other.git" }, {"relays" , "wss://elsewhere.example" }}} |
| 80 | if err := event.Sign(&wrong, ownerSecret); err != nil { |
| 81 | t.Fatal(err) |
| 82 | } |
| 83 | if _, err := g.Validate(context.Background(), wrong); err == nil { |
| 84 | t.Fatal("announcement naming another service was accepted" ) |
| 85 | } |
| 86 | } |