You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
135 lines
3.8 KiB
135 lines
3.8 KiB
package main |
|
|
|
import ( |
|
"context" |
|
"flag" |
|
"fmt" |
|
"time" |
|
|
|
"lol.mleku.dev/chk" |
|
"lol.mleku.dev/log" |
|
"next.orly.dev/pkg/encoders/event" |
|
"next.orly.dev/pkg/encoders/filter" |
|
"next.orly.dev/pkg/encoders/kind" |
|
"next.orly.dev/pkg/encoders/tag" |
|
"next.orly.dev/pkg/interfaces/signer/p8k" |
|
"next.orly.dev/pkg/protocol/ws" |
|
) |
|
|
|
func main() { |
|
var err error |
|
url := flag.String("url", "ws://127.0.0.1:3334", "relay websocket URL") |
|
timeout := flag.Duration("timeout", 20*time.Second, "operation timeout") |
|
testType := flag.String("type", "event", "test type: 'event' for write control, 'req' for read control, 'both' for both") |
|
eventKind := flag.Int("kind", 4678, "event kind to test") |
|
flag.Parse() |
|
|
|
// Connect to relay |
|
var rl *ws.Client |
|
if rl, err = ws.RelayConnect(context.Background(), *url); chk.E(err) { |
|
log.E.F("connect error: %v", err) |
|
return |
|
} |
|
defer rl.Close() |
|
|
|
// Create signer |
|
var signer *p8k.Signer |
|
if signer, err = p8k.New(); chk.E(err) { |
|
log.E.F("signer create error: %v", err) |
|
return |
|
} |
|
if err = signer.Generate(); chk.E(err) { |
|
log.E.F("signer generate error: %v", err) |
|
return |
|
} |
|
|
|
// Perform tests based on type |
|
switch *testType { |
|
case "event": |
|
testEventWrite(rl, signer, *eventKind, *timeout) |
|
case "req": |
|
testReqRead(rl, signer, *eventKind, *timeout) |
|
case "both": |
|
log.I.Ln("Testing EVENT (write control)...") |
|
testEventWrite(rl, signer, *eventKind, *timeout) |
|
log.I.Ln("\nTesting REQ (read control)...") |
|
testReqRead(rl, signer, *eventKind, *timeout) |
|
default: |
|
log.E.F("invalid test type: %s (must be 'event', 'req', or 'both')", *testType) |
|
} |
|
} |
|
|
|
func testEventWrite(rl *ws.Client, signer *p8k.Signer, eventKind int, timeout time.Duration) { |
|
ev := &event.E{ |
|
CreatedAt: time.Now().Unix(), |
|
Kind: uint16(eventKind), |
|
Tags: tag.NewS(), |
|
Content: []byte("policy test: expect rejection for write"), |
|
} |
|
if err := ev.Sign(signer); chk.E(err) { |
|
log.E.F("sign error: %v", err) |
|
return |
|
} |
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), timeout) |
|
defer cancel() |
|
|
|
if err := rl.Publish(ctx, ev); err != nil { |
|
// Expected path if policy rejects: client returns error with reason (from OK false) |
|
fmt.Println("EVENT policy reject:", err) |
|
return |
|
} |
|
|
|
log.I.Ln("EVENT publish result: accepted") |
|
fmt.Println("EVENT ACCEPT") |
|
} |
|
|
|
func testReqRead(rl *ws.Client, signer *p8k.Signer, eventKind int, timeout time.Duration) { |
|
// First, publish a test event to the relay that we'll try to query |
|
testEvent := &event.E{ |
|
CreatedAt: time.Now().Unix(), |
|
Kind: uint16(eventKind), |
|
Tags: tag.NewS(), |
|
Content: []byte("policy test: event for read control test"), |
|
} |
|
if err := testEvent.Sign(signer); chk.E(err) { |
|
log.E.F("sign error: %v", err) |
|
return |
|
} |
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), timeout) |
|
defer cancel() |
|
|
|
// Try to publish the test event first (ignore errors if policy rejects) |
|
_ = rl.Publish(ctx, testEvent) |
|
log.I.F("published test event kind %d for read testing", eventKind) |
|
|
|
// Now try to query for events of this kind |
|
limit := uint(10) |
|
f := &filter.F{ |
|
Kinds: kind.FromIntSlice([]int{eventKind}), |
|
Limit: &limit, |
|
} |
|
|
|
ctx2, cancel2 := context.WithTimeout(context.Background(), timeout) |
|
defer cancel2() |
|
|
|
events, err := rl.QuerySync(ctx2, f) |
|
if chk.E(err) { |
|
log.E.F("query error: %v", err) |
|
fmt.Println("REQ query error:", err) |
|
return |
|
} |
|
|
|
// Check if we got the expected events |
|
if len(events) == 0 { |
|
// Could mean policy filtered it out, or it wasn't stored |
|
fmt.Println("REQ policy reject: no events returned (filtered by read policy)") |
|
log.I.F("REQ result: no events of kind %d returned (policy filtered or not stored)", eventKind) |
|
return |
|
} |
|
|
|
// Events were returned - read access allowed |
|
fmt.Printf("REQ ACCEPT: %d events returned\n", len(events)) |
|
log.I.F("REQ result: %d events of kind %d returned", len(events), eventKind) |
|
}
|
|
|