package policy import ( "context" "encoding/json" "os" "path/filepath" "strings" "testing" "time" "lol.mleku.dev/chk" "next.orly.dev/pkg/crypto/p256k" "next.orly.dev/pkg/encoders/event" "next.orly.dev/pkg/encoders/hex" "next.orly.dev/pkg/encoders/tag" ) // Helper function to create int64 pointer func int64Ptr(i int64) *int64 { return &i } // Helper function to generate a keypair for testing func generateTestKeypair(t *testing.T) (signer *p256k.Signer, pubkey []byte) { signer = &p256k.Signer{} if err := signer.Generate(); chk.E(err) { t.Fatalf("Failed to generate test keypair: %v", err) } pubkey = signer.Pub() return } // Helper function to generate a keypair for benchmarks func generateTestKeypairB(b *testing.B) (signer *p256k.Signer, pubkey []byte) { signer = &p256k.Signer{} if err := signer.Generate(); chk.E(err) { b.Fatalf("Failed to generate test keypair: %v", err) } pubkey = signer.Pub() return } // Helper function to create a real test event with proper signing func createTestEvent(t *testing.T, signer *p256k.Signer, content string, kind uint16) *event.E { ev := event.New() ev.CreatedAt = time.Now().Unix() ev.Kind = kind ev.Content = []byte(content) ev.Tags = tag.NewS() // Sign the event properly if err := ev.Sign(signer); chk.E(err) { t.Fatalf("Failed to sign test event: %v", err) } return ev } // Helper function to create a test event with a specific pubkey (for unauthorized tests) func createTestEventWithPubkey(t *testing.T, signer *p256k.Signer, content string, kind uint16) *event.E { ev := event.New() ev.CreatedAt = time.Now().Unix() ev.Kind = kind ev.Content = []byte(content) ev.Tags = tag.NewS() // Sign the event properly if err := ev.Sign(signer); chk.E(err) { t.Fatalf("Failed to sign test event: %v", err) } return ev } // Helper function to add p tag with hex-encoded pubkey to event func addPTag(ev *event.E, pubkey []byte) { pTag := tag.NewFromAny("p", hex.Enc(pubkey)) ev.Tags.Append(pTag) } // Helper function to add other tags to event func addTag(ev *event.E, key, value string) { tagItem := tag.NewFromAny(key, value) ev.Tags.Append(tagItem) } func TestNew(t *testing.T) { tests := []struct { name string policyJSON []byte expectError bool expectRules int }{ { name: "empty JSON", policyJSON: []byte("{}"), expectError: false, expectRules: 0, }, { name: "valid policy JSON", policyJSON: []byte(`{"kind":{"whitelist":[1,3,5]},"rules":{"1":{"description":"test"}}}`), expectError: false, expectRules: 1, }, { name: "invalid JSON", policyJSON: []byte(`{"invalid": json}`), expectError: true, expectRules: 0, }, { name: "nil JSON", policyJSON: nil, expectError: false, expectRules: 0, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { policy, err := New(tt.policyJSON) if tt.expectError { if err == nil { t.Errorf("Expected error but got none") } return } if err != nil { t.Errorf("Unexpected error: %v", err) return } if policy == nil { t.Errorf("Expected policy but got nil") return } if len(policy.Rules) != tt.expectRules { t.Errorf("Expected %d rules, got %d", tt.expectRules, len(policy.Rules)) } }) } } func TestCheckKindsPolicy(t *testing.T) { tests := []struct { name string policy *P kind uint16 expected bool }{ { name: "no whitelist or blacklist - allow all", policy: &P{ Kind: Kinds{}, }, kind: 1, expected: true, }, { name: "whitelist - kind allowed", policy: &P{ Kind: Kinds{ Whitelist: []int{1, 3, 5}, }, }, kind: 1, expected: true, }, { name: "whitelist - kind not allowed", policy: &P{ Kind: Kinds{ Whitelist: []int{1, 3, 5}, }, }, kind: 2, expected: false, }, { name: "blacklist - kind not blacklisted", policy: &P{ Kind: Kinds{ Blacklist: []int{2, 4, 6}, }, }, kind: 1, expected: true, }, { name: "blacklist - kind blacklisted", policy: &P{ Kind: Kinds{ Blacklist: []int{2, 4, 6}, }, }, kind: 2, expected: false, }, { name: "whitelist overrides blacklist", policy: &P{ Kind: Kinds{ Whitelist: []int{1, 3, 5}, Blacklist: []int{1, 2, 3}, }, }, kind: 1, expected: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { result := tt.policy.checkKindsPolicy(tt.kind) if result != tt.expected { t.Errorf("Expected %v, got %v", tt.expected, result) } }) } } func TestCheckRulePolicy(t *testing.T) { // Generate real keypairs for testing eventSigner, eventPubkey := generateTestKeypair(t) _, pTagPubkey := generateTestKeypair(t) _, unauthorizedPubkey := generateTestKeypair(t) // Create real test event with proper signing testEvent := createTestEvent(t, eventSigner, "test content", 1) // Add p tag with hex-encoded pubkey addPTag(testEvent, pTagPubkey) addTag(testEvent, "expiration", "1234567890") tests := []struct { name string access string event *event.E rule Rule loggedInPubkey []byte expected bool }{ { name: "write access - no restrictions", access: "write", event: testEvent, rule: Rule{ Description: "no restrictions", }, loggedInPubkey: eventPubkey, expected: true, }, { name: "write access - pubkey allowed", access: "write", event: testEvent, rule: Rule{ Description: "pubkey allowed", WriteAllow: []string{hex.Enc(testEvent.Pubkey)}, }, loggedInPubkey: eventPubkey, expected: true, }, { name: "write access - pubkey not allowed", access: "write", event: testEvent, rule: Rule{ Description: "pubkey not allowed", WriteAllow: []string{hex.Enc(pTagPubkey)}, // Different pubkey }, loggedInPubkey: eventPubkey, expected: false, }, { name: "size limit - within limit", access: "write", event: testEvent, rule: Rule{ Description: "size limit", SizeLimit: int64Ptr(10000), }, loggedInPubkey: eventPubkey, expected: true, }, { name: "size limit - exceeds limit", access: "write", event: testEvent, rule: Rule{ Description: "size limit exceeded", SizeLimit: int64Ptr(10), }, loggedInPubkey: eventPubkey, expected: false, }, { name: "content limit - within limit", access: "write", event: testEvent, rule: Rule{ Description: "content limit", ContentLimit: int64Ptr(1000), }, loggedInPubkey: eventPubkey, expected: true, }, { name: "content limit - exceeds limit", access: "write", event: testEvent, rule: Rule{ Description: "content limit exceeded", ContentLimit: int64Ptr(5), }, loggedInPubkey: eventPubkey, expected: false, }, { name: "required tags - has required tag", access: "write", event: testEvent, rule: Rule{ Description: "required tags", MustHaveTags: []string{"p"}, }, loggedInPubkey: eventPubkey, expected: true, }, { name: "required tags - missing required tag", access: "write", event: testEvent, rule: Rule{ Description: "required tags missing", MustHaveTags: []string{"e"}, }, loggedInPubkey: eventPubkey, expected: false, }, { name: "privileged - event authored by logged in user", access: "write", event: testEvent, rule: Rule{ Description: "privileged event", Privileged: true, }, loggedInPubkey: testEvent.Pubkey, expected: true, }, { name: "privileged - event contains logged in user in p tag", access: "write", event: testEvent, rule: Rule{ Description: "privileged event with p tag", Privileged: true, }, loggedInPubkey: pTagPubkey, expected: true, }, { name: "privileged - not authenticated", access: "write", event: testEvent, rule: Rule{ Description: "privileged event not authenticated", Privileged: true, }, loggedInPubkey: nil, expected: false, }, { name: "privileged - authenticated but not authorized (different pubkey, not in p tags)", access: "write", event: testEvent, rule: Rule{ Description: "privileged event unauthorized user", Privileged: true, }, loggedInPubkey: unauthorizedPubkey, expected: false, }, { name: "privileged read - event authored by logged in user", access: "read", event: testEvent, rule: Rule{ Description: "privileged event read access", Privileged: true, }, loggedInPubkey: testEvent.Pubkey, expected: true, }, { name: "privileged read - event contains logged in user in p tag", access: "read", event: testEvent, rule: Rule{ Description: "privileged event read access with p tag", Privileged: true, }, loggedInPubkey: pTagPubkey, expected: true, }, { name: "privileged read - not authenticated", access: "read", event: testEvent, rule: Rule{ Description: "privileged event read access not authenticated", Privileged: true, }, loggedInPubkey: nil, expected: false, }, { name: "privileged read - authenticated but not authorized (different pubkey, not in p tags)", access: "read", event: testEvent, rule: Rule{ Description: "privileged event read access unauthorized user", Privileged: true, }, loggedInPubkey: unauthorizedPubkey, expected: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { policy := &P{} result, err := policy.checkRulePolicy(tt.access, tt.event, tt.rule, tt.loggedInPubkey) if err != nil { t.Errorf("Unexpected error: %v", err) return } if result != tt.expected { t.Errorf("Expected %v, got %v", tt.expected, result) } }) } } func TestCheckPolicy(t *testing.T) { // Generate real keypair for testing eventSigner, eventPubkey := generateTestKeypair(t) // Create real test event with proper signing testEvent := createTestEvent(t, eventSigner, "test content", 1) tests := []struct { name string access string event *event.E policy *P loggedInPubkey []byte ipAddress string expected bool expectError bool }{ { name: "no policy rules - allow", access: "write", event: testEvent, policy: &P{ Kind: Kinds{}, Rules: map[int]Rule{}, }, loggedInPubkey: eventPubkey, ipAddress: "127.0.0.1", expected: true, expectError: false, }, { name: "kinds policy blocks - deny", access: "write", event: testEvent, policy: &P{ Kind: Kinds{ Whitelist: []int{3, 5}, }, Rules: map[int]Rule{}, }, loggedInPubkey: eventPubkey, ipAddress: "127.0.0.1", expected: false, expectError: false, }, { name: "rule blocks - deny", access: "write", event: testEvent, policy: &P{ Kind: Kinds{}, Rules: map[int]Rule{ 1: { Description: "block test", WriteDeny: []string{hex.Enc(testEvent.Pubkey)}, }, }, }, loggedInPubkey: eventPubkey, ipAddress: "127.0.0.1", expected: false, expectError: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { result, err := tt.policy.CheckPolicy(tt.access, tt.event, tt.loggedInPubkey, tt.ipAddress) if tt.expectError { if err == nil { t.Errorf("Expected error but got none") } return } if err != nil { t.Errorf("Unexpected error: %v", err) return } if result != tt.expected { t.Errorf("Expected %v, got %v", tt.expected, result) } }) } } func TestLoadFromFile(t *testing.T) { // Create temporary directory tempDir := t.TempDir() configPath := filepath.Join(tempDir, "policy.json") tests := []struct { name string configData string expectError bool expectRules int }{ { name: "valid policy file", configData: `{"kind":{"whitelist":[1,3,5]},"rules":{"1":{"description":"test"}}}`, expectError: false, expectRules: 1, }, { name: "empty policy file", configData: `{}`, expectError: false, expectRules: 0, }, { name: "invalid JSON", configData: `{"invalid": json}`, expectError: true, expectRules: 0, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // Write test config file if tt.configData != "" { err := os.WriteFile(configPath, []byte(tt.configData), 0644) if err != nil { t.Fatalf("Failed to write test config file: %v", err) } } policy := &P{} err := policy.LoadFromFile(configPath) if tt.expectError { if err == nil { t.Errorf("Expected error but got none") } return } if err != nil { t.Errorf("Unexpected error: %v", err) return } if len(policy.Rules) != tt.expectRules { t.Errorf("Expected %d rules, got %d", tt.expectRules, len(policy.Rules)) } }) } // Test file not found t.Run("file not found", func(t *testing.T) { policy := &P{} err := policy.LoadFromFile("/nonexistent/policy.json") if err == nil { t.Errorf("Expected error for nonexistent file but got none") } }) } func TestPolicyEventSerialization(t *testing.T) { // Generate real keypair for testing eventSigner, eventPubkey := generateTestKeypair(t) // Create real test event with proper signing testEvent := createTestEvent(t, eventSigner, "test content", 1) // Create policy event policyEvent := &PolicyEvent{ E: testEvent, LoggedInPubkey: hex.Enc(eventPubkey), IPAddress: "127.0.0.1", } // Test JSON serialization jsonData, err := json.Marshal(policyEvent) if err != nil { t.Fatalf("Failed to marshal policy event: %v", err) } // Verify the JSON contains expected fields jsonStr := string(jsonData) t.Logf("Generated JSON: %s", jsonStr) if !strings.Contains(jsonStr, hex.Enc(eventPubkey)) { t.Error("JSON should contain logged_in_pubkey field") } if !strings.Contains(jsonStr, "127.0.0.1") { t.Error("JSON should contain ip_address field") } if !strings.Contains(jsonStr, hex.Enc(testEvent.ID)) { t.Error("JSON should contain event id field (hex encoded)") } // Test with nil event nilPolicyEvent := &PolicyEvent{ E: nil, LoggedInPubkey: "test-logged-in-pubkey", IPAddress: "127.0.0.1", } jsonData2, err := json.Marshal(nilPolicyEvent) if err != nil { t.Fatalf("Failed to marshal nil policy event: %v", err) } jsonStr2 := string(jsonData2) if !strings.Contains(jsonStr2, "test-logged-in-pubkey") { t.Error("JSON should contain logged_in_pubkey field even with nil event") } if !strings.Contains(jsonStr2, "127.0.0.1") { t.Error("JSON should contain ip_address field even with nil event") } } func TestPolicyResponseSerialization(t *testing.T) { // Test JSON serialization response := &PolicyResponse{ ID: "test-id", Action: "accept", Msg: "test message", } jsonData, err := json.Marshal(response) if err != nil { t.Fatalf("Failed to marshal policy response: %v", err) } // Test JSON deserialization var deserializedResponse PolicyResponse err = json.Unmarshal(jsonData, &deserializedResponse) if err != nil { t.Fatalf("Failed to unmarshal policy response: %v", err) } // Verify fields if deserializedResponse.ID != response.ID { t.Errorf("Expected ID %s, got %s", response.ID, deserializedResponse.ID) } if deserializedResponse.Action != response.Action { t.Errorf("Expected Action %s, got %s", response.Action, deserializedResponse.Action) } if deserializedResponse.Msg != response.Msg { t.Errorf("Expected Msg %s, got %s", response.Msg, deserializedResponse.Msg) } } func TestNewWithManager(t *testing.T) { ctx := context.Background() appName := "test-app" enabled := true policy := NewWithManager(ctx, appName, enabled) if policy == nil { t.Fatal("Expected policy but got nil") } if policy.Manager == nil { t.Fatal("Expected policy manager but got nil") } if !policy.Manager.IsEnabled() { t.Error("Expected policy manager to be enabled") } if policy.Manager.IsRunning() { t.Error("Expected policy manager to not be running initially") } } func TestPolicyManagerLifecycle(t *testing.T) { // Test basic manager initialization without script execution ctx, cancel := context.WithCancel(context.Background()) defer cancel() manager := &PolicyManager{ ctx: ctx, cancel: cancel, configDir: "/tmp", scriptPath: "/tmp/policy.sh", enabled: true, responseChan: make(chan PolicyResponse, 100), } // Test manager state if !manager.IsEnabled() { t.Error("Expected policy manager to be enabled") } if manager.IsRunning() { t.Error("Expected policy manager to not be running initially") } // Test starting with non-existent script (should fail gracefully) err := manager.StartPolicy() if err == nil { t.Error("Expected error when starting policy with non-existent script") } // Test stopping when not running (should fail gracefully) err = manager.StopPolicy() if err == nil { t.Error("Expected error when stopping policy that's not running") } } func TestPolicyManagerProcessEvent(t *testing.T) { // Test processing event when manager is not running (should fail gracefully) ctx, cancel := context.WithCancel(context.Background()) defer cancel() manager := &PolicyManager{ ctx: ctx, cancel: cancel, configDir: "/tmp", scriptPath: "/tmp/policy.sh", enabled: true, responseChan: make(chan PolicyResponse, 100), } // Generate real keypair for testing eventSigner, eventPubkey := generateTestKeypair(t) // Create real test event with proper signing testEvent := createTestEvent(t, eventSigner, "test content", 1) // Create policy event policyEvent := &PolicyEvent{ E: testEvent, LoggedInPubkey: hex.Enc(eventPubkey), IPAddress: "127.0.0.1", } // Process event when not running (should fail gracefully) _, err := manager.ProcessEvent(policyEvent) if err == nil { t.Error("Expected error when processing event with non-running policy manager") } } func TestEdgeCasesEmptyPolicy(t *testing.T) { policy := &P{} // Generate real keypair for testing eventSigner, eventPubkey := generateTestKeypair(t) // Create real test event with proper signing testEvent := createTestEvent(t, eventSigner, "test content", 1) // Should allow all events when policy is empty allowed, err := policy.CheckPolicy("write", testEvent, eventPubkey, "127.0.0.1") if err != nil { t.Errorf("Unexpected error: %v", err) } if !allowed { t.Error("Expected event to be allowed with empty policy") } } func TestEdgeCasesNilEvent(t *testing.T) { policy := &P{} // Should handle nil event gracefully allowed, err := policy.CheckPolicy("write", nil, []byte("test-pubkey"), "127.0.0.1") if err == nil { t.Error("Expected error when event is nil") } if allowed { t.Error("Expected event to be blocked when nil") } // Verify the error message if err != nil && !strings.Contains(err.Error(), "event cannot be nil") { t.Errorf("Expected error message to contain 'event cannot be nil', got: %v", err) } } func TestEdgeCasesLargeEvent(t *testing.T) { // Create large content largeContent := strings.Repeat("a", 100000) // 100KB content policy := &P{ Kind: Kinds{}, Rules: map[int]Rule{ 1: { Description: "size limit test", SizeLimit: int64Ptr(50000), // 50KB limit ContentLimit: int64Ptr(10000), // 10KB content limit }, }, } // Generate real keypair for testing eventSigner, eventPubkey := generateTestKeypair(t) // Create real test event with large content testEvent := createTestEvent(t, eventSigner, largeContent, 1) // Should block large event allowed, err := policy.CheckPolicy("write", testEvent, eventPubkey, "127.0.0.1") if err != nil { t.Errorf("Unexpected error: %v", err) } if allowed { t.Error("Expected large event to be blocked") } } func TestEdgeCasesWhitelistBlacklistConflict(t *testing.T) { policy := &P{ Kind: Kinds{ Whitelist: []int{1, 3, 5}, Blacklist: []int{1, 2, 3}, // Overlap with whitelist }, } // Test kind in both whitelist and blacklist - whitelist should win allowed := policy.checkKindsPolicy(1) if !allowed { t.Error("Expected whitelist to override blacklist") } // Test kind in blacklist but not whitelist allowed = policy.checkKindsPolicy(2) if allowed { t.Error("Expected kind in blacklist but not whitelist to be blocked") } // Test kind in whitelist but not blacklist allowed = policy.checkKindsPolicy(5) if !allowed { t.Error("Expected kind in whitelist to be allowed") } } func TestEdgeCasesManagerWithInvalidScript(t *testing.T) { // Create temporary directory tempDir := t.TempDir() scriptPath := filepath.Join(tempDir, "policy.sh") // Create invalid script (not executable, wrong shebang, etc.) scriptContent := `invalid script content` err := os.WriteFile(scriptPath, []byte(scriptContent), 0644) // Not executable if err != nil { t.Fatalf("Failed to create invalid script: %v", err) } ctx := context.Background() manager := &PolicyManager{ ctx: ctx, configDir: tempDir, scriptPath: scriptPath, enabled: true, responseChan: make(chan PolicyResponse, 100), } // Should fail to start with invalid script err = manager.StartPolicy() if err == nil { t.Error("Expected error when starting policy with invalid script") } } func TestEdgeCasesManagerDoubleStart(t *testing.T) { // Test double start without actually starting (simpler test) ctx := context.Background() manager := &PolicyManager{ ctx: ctx, configDir: "/tmp", scriptPath: "/tmp/policy.sh", enabled: true, responseChan: make(chan PolicyResponse, 100), } // Try to start with non-existent script - should fail err := manager.StartPolicy() if err == nil { t.Error("Expected error when starting policy manager with non-existent script") } // Try to start again - should still fail err = manager.StartPolicy() if err == nil { t.Error("Expected error when starting policy manager twice") } } func TestCheckGlobalRulePolicy(t *testing.T) { // Generate real keypairs for testing eventSigner, eventPubkey := generateTestKeypair(t) _, loggedInPubkey := generateTestKeypair(t) tests := []struct { name string globalRule Rule event *event.E loggedInPubkey []byte expected bool }{ { name: "global rule with write allow - event allowed", globalRule: Rule{ WriteAllow: []string{hex.Enc(eventPubkey)}, }, event: createTestEvent(t, eventSigner, "test content", 1), loggedInPubkey: loggedInPubkey, expected: true, }, { name: "global rule with write deny - event denied", globalRule: Rule{ WriteDeny: []string{hex.Enc(eventPubkey)}, }, event: createTestEvent(t, eventSigner, "test content", 1), loggedInPubkey: loggedInPubkey, expected: false, }, { name: "global rule with size limit - event too large", globalRule: Rule{ SizeLimit: func() *int64 { v := int64(10); return &v }(), }, event: createTestEvent(t, eventSigner, "this is a very long content that exceeds the size limit", 1), loggedInPubkey: loggedInPubkey, expected: false, }, { name: "global rule with max age of event - event too old", globalRule: Rule{ MaxAgeOfEvent: func() *int64 { v := int64(3600); return &v }(), // 1 hour }, event: func() *event.E { ev := createTestEvent(t, eventSigner, "test content", 1) ev.CreatedAt = time.Now().Unix() - 7200 // 2 hours ago return ev }(), loggedInPubkey: loggedInPubkey, expected: false, }, { name: "global rule with max age event in future - event too far in future", globalRule: Rule{ MaxAgeEventInFuture: func() *int64 { v := int64(3600); return &v }(), // 1 hour }, event: func() *event.E { ev := createTestEvent(t, eventSigner, "test content", 1) ev.CreatedAt = time.Now().Unix() + 7200 // 2 hours in future return ev }(), loggedInPubkey: loggedInPubkey, expected: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { policy := &P{ Global: tt.globalRule, } result := policy.checkGlobalRulePolicy("write", tt.event, tt.loggedInPubkey) if result != tt.expected { t.Errorf("Expected %v, got %v", tt.expected, result) } }) } } func TestCheckPolicyWithGlobalRule(t *testing.T) { // Generate real keypairs for testing eventSigner, eventPubkey := generateTestKeypair(t) _, loggedInPubkey := generateTestKeypair(t) // Test that global rule is applied first policy := &P{ Global: Rule{ WriteDeny: []string{hex.Enc(eventPubkey)}, // Deny event pubkey globally }, Kind: Kinds{ Whitelist: []int{1}, // Allow kind 1 }, Rules: map[int]Rule{ 1: { WriteAllow: []string{hex.Enc(eventPubkey)}, // Allow event pubkey for kind 1 }, }, } event := createTestEvent(t, eventSigner, "test content", 1) // Global rule should deny this event even though kind-specific rule would allow it allowed, err := policy.CheckPolicy("write", event, loggedInPubkey, "127.0.0.1") if err != nil { t.Fatalf("CheckPolicy failed: %v", err) } if allowed { t.Error("Expected event to be denied by global rule, but it was allowed") } } func TestMaxAgeChecks(t *testing.T) { // Generate real keypairs for testing eventSigner, _ := generateTestKeypair(t) _, loggedInPubkey := generateTestKeypair(t) tests := []struct { name string rule Rule event *event.E loggedInPubkey []byte expected bool }{ { name: "max age of event - event within allowed age", rule: Rule{ MaxAgeOfEvent: func() *int64 { v := int64(3600); return &v }(), // 1 hour }, event: func() *event.E { ev := createTestEvent(t, eventSigner, "test content", 1) ev.CreatedAt = time.Now().Unix() - 1800 // 30 minutes ago return ev }(), loggedInPubkey: loggedInPubkey, expected: true, }, { name: "max age of event - event too old", rule: Rule{ MaxAgeOfEvent: func() *int64 { v := int64(3600); return &v }(), // 1 hour }, event: func() *event.E { ev := createTestEvent(t, eventSigner, "test content", 1) ev.CreatedAt = time.Now().Unix() - 7200 // 2 hours ago return ev }(), loggedInPubkey: loggedInPubkey, expected: false, }, { name: "max age event in future - event within allowed future time", rule: Rule{ MaxAgeEventInFuture: func() *int64 { v := int64(3600); return &v }(), // 1 hour }, event: func() *event.E { ev := createTestEvent(t, eventSigner, "test content", 1) ev.CreatedAt = time.Now().Unix() + 1800 // 30 minutes in future return ev }(), loggedInPubkey: loggedInPubkey, expected: true, }, { name: "max age event in future - event too far in future", rule: Rule{ MaxAgeEventInFuture: func() *int64 { v := int64(3600); return &v }(), // 1 hour }, event: func() *event.E { ev := createTestEvent(t, eventSigner, "test content", 1) ev.CreatedAt = time.Now().Unix() + 7200 // 2 hours in future return ev }(), loggedInPubkey: loggedInPubkey, expected: false, }, { name: "both age checks - event within both limits", rule: Rule{ MaxAgeOfEvent: func() *int64 { v := int64(3600); return &v }(), // 1 hour MaxAgeEventInFuture: func() *int64 { v := int64(1800); return &v }(), // 30 minutes }, event: func() *event.E { ev := createTestEvent(t, eventSigner, "test content", 1) ev.CreatedAt = time.Now().Unix() + 900 // 15 minutes in future return ev }(), loggedInPubkey: loggedInPubkey, expected: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { policy := &P{} allowed, err := policy.checkRulePolicy("write", tt.event, tt.rule, tt.loggedInPubkey) if err != nil { t.Fatalf("checkRulePolicy failed: %v", err) } if allowed != tt.expected { t.Errorf("Expected %v, got %v", tt.expected, allowed) } }) } } func TestScriptPolicyDisabledFallsBackToDefault(t *testing.T) { // Generate real keypair for testing eventSigner, eventPubkey := generateTestKeypair(t) // Create a policy with a script rule but policy is disabled, default policy is "allow" policy := &P{ DefaultPolicy: "allow", Rules: map[int]Rule{ 1: { Description: "script rule", Script: "policy.sh", }, }, Manager: &PolicyManager{ enabled: false, // Policy is disabled isRunning: false, }, } // Create real test event with proper signing testEvent := createTestEvent(t, eventSigner, "test content", 1) // Should allow the event when policy is disabled (falls back to default "allow") allowed, err := policy.CheckPolicy("write", testEvent, eventPubkey, "127.0.0.1") if err != nil { t.Errorf("Unexpected error: %v", err) } if !allowed { t.Error("Expected event to be allowed when policy is disabled (should fall back to default policy 'allow')") } // Test with default policy "deny" policy.DefaultPolicy = "deny" allowed2, err2 := policy.CheckPolicy("write", testEvent, eventPubkey, "127.0.0.1") if err2 != nil { t.Errorf("Unexpected error: %v", err2) } if allowed2 { t.Error("Expected event to be denied when policy is disabled and default policy is 'deny'") } } func TestDefaultPolicyAllow(t *testing.T) { // Generate real keypair for testing eventSigner, eventPubkey := generateTestKeypair(t) // Test default policy "allow" behavior policy := &P{ DefaultPolicy: "allow", Kind: Kinds{}, Rules: map[int]Rule{}, // No specific rules } // Create real test event with proper signing testEvent := createTestEvent(t, eventSigner, "test content", 1) // Should allow the event with default policy "allow" allowed, err := policy.CheckPolicy("write", testEvent, eventPubkey, "127.0.0.1") if err != nil { t.Errorf("Unexpected error: %v", err) } if !allowed { t.Error("Expected event to be allowed with default_policy 'allow'") } } func TestDefaultPolicyDeny(t *testing.T) { // Generate real keypair for testing eventSigner, eventPubkey := generateTestKeypair(t) // Test default policy "deny" behavior policy := &P{ DefaultPolicy: "deny", Kind: Kinds{}, Rules: map[int]Rule{}, // No specific rules } // Create real test event with proper signing testEvent := createTestEvent(t, eventSigner, "test content", 1) // Should deny the event with default policy "deny" allowed, err := policy.CheckPolicy("write", testEvent, eventPubkey, "127.0.0.1") if err != nil { t.Errorf("Unexpected error: %v", err) } if allowed { t.Error("Expected event to be denied with default_policy 'deny'") } } func TestDefaultPolicyEmpty(t *testing.T) { // Generate real keypair for testing eventSigner, eventPubkey := generateTestKeypair(t) // Test empty default policy (should default to "allow") policy := &P{ DefaultPolicy: "", Kind: Kinds{}, Rules: map[int]Rule{}, // No specific rules } // Create real test event with proper signing testEvent := createTestEvent(t, eventSigner, "test content", 1) // Should allow the event with empty default policy (defaults to "allow") allowed, err := policy.CheckPolicy("write", testEvent, eventPubkey, "127.0.0.1") if err != nil { t.Errorf("Unexpected error: %v", err) } if !allowed { t.Error("Expected event to be allowed with empty default_policy (should default to 'allow')") } } func TestDefaultPolicyInvalid(t *testing.T) { // Generate real keypair for testing eventSigner, eventPubkey := generateTestKeypair(t) // Test invalid default policy (should default to "allow") policy := &P{ DefaultPolicy: "invalid", Kind: Kinds{}, Rules: map[int]Rule{}, // No specific rules } // Create real test event with proper signing testEvent := createTestEvent(t, eventSigner, "test content", 1) // Should allow the event with invalid default policy (defaults to "allow") allowed, err := policy.CheckPolicy("write", testEvent, eventPubkey, "127.0.0.1") if err != nil { t.Errorf("Unexpected error: %v", err) } if !allowed { t.Error("Expected event to be allowed with invalid default_policy (should default to 'allow')") } } func TestDefaultPolicyWithSpecificRule(t *testing.T) { // Generate real keypair for testing eventSigner, eventPubkey := generateTestKeypair(t) // Test that specific rules override default policy policy := &P{ DefaultPolicy: "deny", // Default is deny Kind: Kinds{}, Rules: map[int]Rule{ 1: { Description: "allow kind 1", WriteAllow: []string{}, // Allow all for kind 1 }, }, } // Create real test event with proper signing for kind 1 (has specific rule) testEvent := createTestEvent(t, eventSigner, "test content", 1) // Should allow the event because specific rule allows it, despite default policy being "deny" allowed, err := policy.CheckPolicy("write", testEvent, eventPubkey, "127.0.0.1") if err != nil { t.Errorf("Unexpected error: %v", err) } if !allowed { t.Error("Expected event to be allowed by specific rule, despite default_policy 'deny'") } // Create real test event with proper signing for kind 2 (no specific rule exists) testEvent2 := createTestEvent(t, eventSigner, "test content", 2) // Should deny the event because no specific rule and default policy is "deny" allowed2, err2 := policy.CheckPolicy("write", testEvent2, eventPubkey, "127.0.0.1") if err2 != nil { t.Errorf("Unexpected error: %v", err2) } if allowed2 { t.Error("Expected event to be denied with default_policy 'deny' for kind without specific rule") } } func TestNewPolicyDefaultsToAllow(t *testing.T) { // Test that New() function sets default policy to "allow" policy, err := New([]byte(`{}`)) if err != nil { t.Fatalf("Failed to create policy: %v", err) } if policy.DefaultPolicy != "allow" { t.Errorf("Expected default policy to be 'allow', got '%s'", policy.DefaultPolicy) } } func TestNewPolicyWithDefaultPolicyJSON(t *testing.T) { // Test loading default policy from JSON jsonConfig := `{"default_policy": "deny"}` policy, err := New([]byte(jsonConfig)) if err != nil { t.Fatalf("Failed to create policy: %v", err) } if policy.DefaultPolicy != "deny" { t.Errorf("Expected default policy to be 'deny', got '%s'", policy.DefaultPolicy) } } func TestScriptProcessingDisabledFallsBackToDefault(t *testing.T) { // Generate real keypair for testing eventSigner, eventPubkey := generateTestKeypair(t) // Test that when policy is disabled, it falls back to default policy policy := &P{ DefaultPolicy: "allow", Rules: map[int]Rule{ 1: { Description: "script rule", Script: "policy.sh", }, }, Manager: &PolicyManager{ enabled: false, // Policy is disabled isRunning: false, }, } // Create real test event with proper signing testEvent := createTestEvent(t, eventSigner, "test content", 1) // Should allow the event when policy is disabled (falls back to default "allow") allowed, err := policy.checkScriptPolicy("write", testEvent, "policy.sh", eventPubkey, "127.0.0.1") if err != nil { t.Errorf("Unexpected error: %v", err) } if !allowed { t.Error("Expected event to be allowed when policy is disabled (should fall back to default policy 'allow')") } // Test with default policy "deny" policy.DefaultPolicy = "deny" allowed2, err2 := policy.checkScriptPolicy("write", testEvent, "policy.sh", eventPubkey, "127.0.0.1") if err2 != nil { t.Errorf("Unexpected error: %v", err2) } if allowed2 { t.Error("Expected event to be denied when policy is disabled and default policy is 'deny'") } } func TestDefaultPolicyLogicWithRules(t *testing.T) { // Generate real keypairs for testing testSigner, _ := generateTestKeypair(t) deniedSigner, deniedPubkey := generateTestKeypair(t) _, loggedInPubkey := generateTestKeypair(t) // Test that default policy logic works correctly with rules // Test 1: default_policy "deny" - should only allow if rule explicitly allows policy1 := &P{ DefaultPolicy: "deny", Kind: Kinds{ Whitelist: []int{1, 2, 3}, // Allow kinds 1, 2, 3 }, Rules: map[int]Rule{ 1: { Description: "allow all for kind 1", WriteAllow: []string{}, // Empty means allow all }, 2: { Description: "deny specific pubkey for kind 2", WriteDeny: []string{hex.Enc(deniedPubkey)}, }, // No rule for kind 3 }, } // Kind 1: has rule that allows all - should be allowed event1 := createTestEvent(t, testSigner, "content", 1) allowed1, err1 := policy1.CheckPolicy("write", event1, loggedInPubkey, "127.0.0.1") if err1 != nil { t.Errorf("Unexpected error for kind 1: %v", err1) } if !allowed1 { t.Error("Expected kind 1 to be allowed (rule allows all)") } // Kind 2: has rule that denies specific pubkey - should be allowed for other pubkeys event2 := createTestEvent(t, testSigner, "content", 2) allowed2, err2 := policy1.CheckPolicy("write", event2, loggedInPubkey, "127.0.0.1") if err2 != nil { t.Errorf("Unexpected error for kind 2: %v", err2) } if !allowed2 { t.Error("Expected kind 2 to be allowed for non-denied pubkey") } // Kind 2: denied pubkey should be denied event2Denied := createTestEvent(t, deniedSigner, "content", 2) allowed2Denied, err2Denied := policy1.CheckPolicy("write", event2Denied, loggedInPubkey, "127.0.0.1") if err2Denied != nil { t.Errorf("Unexpected error for kind 2 denied: %v", err2Denied) } if allowed2Denied { t.Error("Expected kind 2 to be denied for denied pubkey") } // Kind 3: whitelisted but no rule - should follow default policy (deny) event3 := createTestEvent(t, testSigner, "content", 3) allowed3, err3 := policy1.CheckPolicy("write", event3, loggedInPubkey, "127.0.0.1") if err3 != nil { t.Errorf("Unexpected error for kind 3: %v", err3) } if allowed3 { t.Error("Expected kind 3 to be denied (no rule, default policy is deny)") } // Test 2: default_policy "allow" - should allow unless rule explicitly denies policy2 := &P{ DefaultPolicy: "allow", Kind: Kinds{ Whitelist: []int{1, 2, 3}, // Allow kinds 1, 2, 3 }, Rules: map[int]Rule{ 1: { Description: "deny specific pubkey for kind 1", WriteDeny: []string{hex.Enc(deniedPubkey)}, }, // No rules for kind 2, 3 }, } // Kind 1: has rule that denies specific pubkey - should be allowed for other pubkeys event1Allow := createTestEvent(t, testSigner, "content", 1) allowed1Allow, err1Allow := policy2.CheckPolicy("write", event1Allow, loggedInPubkey, "127.0.0.1") if err1Allow != nil { t.Errorf("Unexpected error for kind 1 allow: %v", err1Allow) } if !allowed1Allow { t.Error("Expected kind 1 to be allowed for non-denied pubkey") } // Kind 1: denied pubkey should be denied event1Deny := createTestEvent(t, deniedSigner, "content", 1) allowed1Deny, err1Deny := policy2.CheckPolicy("write", event1Deny, loggedInPubkey, "127.0.0.1") if err1Deny != nil { t.Errorf("Unexpected error for kind 1 deny: %v", err1Deny) } if allowed1Deny { t.Error("Expected kind 1 to be denied for denied pubkey") } // Kind 2: whitelisted but no rule - should follow default policy (allow) event2Allow := createTestEvent(t, testSigner, "content", 2) allowed2Allow, err2Allow := policy2.CheckPolicy("write", event2Allow, loggedInPubkey, "127.0.0.1") if err2Allow != nil { t.Errorf("Unexpected error for kind 2 allow: %v", err2Allow) } if !allowed2Allow { t.Error("Expected kind 2 to be allowed (no rule, default policy is allow)") } } func TestPolicyFilterProcessing(t *testing.T) { // Test policy filter processing using the provided filter JSON specification filterJSON := []byte(`{ "kind": { "whitelist": [4678, 10306, 30520, 30919] }, "rules": { "4678": { "description": "Zenotp message events", "script": "/home/orly/.config/ORLY/validate4678.js", "privileged": true }, "10306": { "description": "End user whitelist changes", "read_allow": [ "04eeb1ed409c0b9205e722f8bf1780f553b61876ef323aff16c9f80a9d8ee9f5" ], "privileged": true }, "30520": { "description": "Zenotp events", "write_allow": [ "04eeb1ed409c0b9205e722f8bf1780f553b61876ef323aff16c9f80a9d8ee9f5" ], "privileged": true }, "30919": { "description": "Zenotp events", "write_allow": [ "04eeb1ed409c0b9205e722f8bf1780f553b61876ef323aff16c9f80a9d8ee9f5" ], "privileged": true } } }`) // Create policy from JSON policy, err := New(filterJSON) if err != nil { t.Fatalf("Failed to create policy from JSON: %v", err) } // Verify whitelist is set correctly if len(policy.Kind.Whitelist) != 4 { t.Errorf("Expected whitelist to have 4 kinds, got %d", len(policy.Kind.Whitelist)) } expectedKinds := map[int]bool{4678: true, 10306: true, 30520: true, 30919: true} for _, kind := range policy.Kind.Whitelist { if !expectedKinds[kind] { t.Errorf("Unexpected kind in whitelist: %d", kind) } } // Verify rules are loaded correctly if len(policy.Rules) != 4 { t.Errorf("Expected 4 rules, got %d", len(policy.Rules)) } // Verify rule 4678 (script-based) rule4678, ok := policy.Rules[4678] if !ok { t.Fatal("Rule 4678 not found") } if rule4678.Description != "Zenotp message events" { t.Errorf("Expected description 'Zenotp message events', got '%s'", rule4678.Description) } if rule4678.Script != "/home/orly/.config/ORLY/validate4678.js" { t.Errorf("Expected script path '/home/orly/.config/ORLY/validate4678.js', got '%s'", rule4678.Script) } if !rule4678.Privileged { t.Error("Expected rule 4678 to be privileged") } // Verify rule 10306 (read_allow) rule10306, ok := policy.Rules[10306] if !ok { t.Fatal("Rule 10306 not found") } if rule10306.Description != "End user whitelist changes" { t.Errorf("Expected description 'End user whitelist changes', got '%s'", rule10306.Description) } if len(rule10306.ReadAllow) != 1 { t.Errorf("Expected 1 read_allow pubkey, got %d", len(rule10306.ReadAllow)) } if rule10306.ReadAllow[0] != "04eeb1ed409c0b9205e722f8bf1780f553b61876ef323aff16c9f80a9d8ee9f5" { t.Errorf("Expected read_allow pubkey '04eeb1ed409c0b9205e722f8bf1780f553b61876ef323aff16c9f80a9d8ee9f5', got '%s'", rule10306.ReadAllow[0]) } if !rule10306.Privileged { t.Error("Expected rule 10306 to be privileged") } // Verify rule 30520 (write_allow) rule30520, ok := policy.Rules[30520] if !ok { t.Fatal("Rule 30520 not found") } if rule30520.Description != "Zenotp events" { t.Errorf("Expected description 'Zenotp events', got '%s'", rule30520.Description) } if len(rule30520.WriteAllow) != 1 { t.Errorf("Expected 1 write_allow pubkey, got %d", len(rule30520.WriteAllow)) } if rule30520.WriteAllow[0] != "04eeb1ed409c0b9205e722f8bf1780f553b61876ef323aff16c9f80a9d8ee9f5" { t.Errorf("Expected write_allow pubkey '04eeb1ed409c0b9205e722f8bf1780f553b61876ef323aff16c9f80a9d8ee9f5', got '%s'", rule30520.WriteAllow[0]) } if !rule30520.Privileged { t.Error("Expected rule 30520 to be privileged") } // Verify rule 30919 (write_allow) rule30919, ok := policy.Rules[30919] if !ok { t.Fatal("Rule 30919 not found") } if rule30919.Description != "Zenotp events" { t.Errorf("Expected description 'Zenotp events', got '%s'", rule30919.Description) } if len(rule30919.WriteAllow) != 1 { t.Errorf("Expected 1 write_allow pubkey, got %d", len(rule30919.WriteAllow)) } if rule30919.WriteAllow[0] != "04eeb1ed409c0b9205e722f8bf1780f553b61876ef323aff16c9f80a9d8ee9f5" { t.Errorf("Expected write_allow pubkey '04eeb1ed409c0b9205e722f8bf1780f553b61876ef323aff16c9f80a9d8ee9f5', got '%s'", rule30919.WriteAllow[0]) } if !rule30919.Privileged { t.Error("Expected rule 30919 to be privileged") } // Test kind whitelist filtering t.Run("kind whitelist filtering", func(t *testing.T) { eventSigner, eventPubkey := generateTestKeypair(t) _, loggedInPubkey := generateTestKeypair(t) // Test whitelisted kind (should pass kind check, but may fail other checks) whitelistedEvent := createTestEvent(t, eventSigner, "test content", 4678) addPTag(whitelistedEvent, loggedInPubkey) allowed, err := policy.CheckPolicy("write", whitelistedEvent, loggedInPubkey, "127.0.0.1") if err != nil { t.Errorf("Unexpected error: %v", err) } // Should be allowed because script isn't running (falls back to default "allow") // and privileged check passes (loggedInPubkey is in p tag) if !allowed { t.Error("Expected whitelisted kind to be allowed when script not running and privileged check passes") } // Test non-whitelisted kind (should be denied) nonWhitelistedEvent := createTestEvent(t, eventSigner, "test content", 1) allowed, err = policy.CheckPolicy("write", nonWhitelistedEvent, eventPubkey, "127.0.0.1") if err != nil { t.Errorf("Unexpected error: %v", err) } if allowed { t.Error("Expected non-whitelisted kind to be denied") } }) // Test read access for kind 10306 t.Run("read access for kind 10306", func(t *testing.T) { allowedPubkeyHex := "04eeb1ed409c0b9205e722f8bf1780f553b61876ef323aff16c9f80a9d8ee9f5" allowedPubkeyBytes, err := hex.Dec(allowedPubkeyHex) if err != nil { t.Fatalf("Failed to decode allowed pubkey: %v", err) } // Create event with allowed pubkey using a temporary signer // Note: We can't actually sign with just the pubkey, so we'll create the event // with a random signer and then manually set the pubkey for testing tempSigner, _ := generateTestKeypair(t) event10306 := createTestEvent(t, tempSigner, "test content", 10306) event10306.Pubkey = allowedPubkeyBytes // Re-sign won't work without private key, but policy checks use the pubkey field // So we'll test with the pubkey set correctly // Test read access with allowed pubkey (logged in user matches event pubkey) allowed, err := policy.CheckPolicy("read", event10306, allowedPubkeyBytes, "127.0.0.1") if err != nil { t.Errorf("Unexpected error: %v", err) } if !allowed { t.Error("Expected event to be allowed for read access with allowed pubkey") } // Test read access with non-allowed pubkey _, unauthorizedPubkey := generateTestKeypair(t) allowed, err = policy.CheckPolicy("read", event10306, unauthorizedPubkey, "127.0.0.1") if err != nil { t.Errorf("Unexpected error: %v", err) } if allowed { t.Error("Expected event to be denied for read access with non-allowed pubkey") } // Test read access without authentication (privileged check) allowed, err = policy.CheckPolicy("read", event10306, nil, "127.0.0.1") if err != nil { t.Errorf("Unexpected error: %v", err) } if allowed { t.Error("Expected event to be denied for read access without authentication (privileged)") } }) // Test write access for kind 30520 t.Run("write access for kind 30520", func(t *testing.T) { allowedPubkeyHex := "04eeb1ed409c0b9205e722f8bf1780f553b61876ef323aff16c9f80a9d8ee9f5" allowedPubkeyBytes, err := hex.Dec(allowedPubkeyHex) if err != nil { t.Fatalf("Failed to decode allowed pubkey: %v", err) } // Create event with allowed pubkey using a temporary signer // We'll set the pubkey manually for testing since we don't have the private key tempSigner, _ := generateTestKeypair(t) event30520 := createTestEvent(t, tempSigner, "test content", 30520) event30520.Pubkey = allowedPubkeyBytes // Test write access with allowed pubkey (event pubkey matches write_allow) allowed, err := policy.CheckPolicy("write", event30520, allowedPubkeyBytes, "127.0.0.1") if err != nil { t.Errorf("Unexpected error: %v", err) } if !allowed { t.Error("Expected event to be allowed for write access with allowed pubkey") } // Test write access with non-allowed pubkey unauthorizedSigner, unauthorizedPubkey := generateTestKeypair(t) unauthorizedEvent := createTestEvent(t, unauthorizedSigner, "test content", 30520) allowed, err = policy.CheckPolicy("write", unauthorizedEvent, unauthorizedPubkey, "127.0.0.1") if err != nil { t.Errorf("Unexpected error: %v", err) } if allowed { t.Error("Expected event to be denied for write access with non-allowed pubkey") } // Test write access without authentication (privileged check) allowed, err = policy.CheckPolicy("write", event30520, nil, "127.0.0.1") if err != nil { t.Errorf("Unexpected error: %v", err) } if allowed { t.Error("Expected event to be denied for write access without authentication (privileged)") } }) // Test write access for kind 30919 t.Run("write access for kind 30919", func(t *testing.T) { allowedPubkeyHex := "04eeb1ed409c0b9205e722f8bf1780f553b61876ef323aff16c9f80a9d8ee9f5" allowedPubkeyBytes, err := hex.Dec(allowedPubkeyHex) if err != nil { t.Fatalf("Failed to decode allowed pubkey: %v", err) } // Create event with allowed pubkey using a temporary signer // We'll set the pubkey manually for testing since we don't have the private key tempSigner, _ := generateTestKeypair(t) event30919 := createTestEvent(t, tempSigner, "test content", 30919) event30919.Pubkey = allowedPubkeyBytes // Test write access with allowed pubkey (event pubkey matches write_allow) allowed, err := policy.CheckPolicy("write", event30919, allowedPubkeyBytes, "127.0.0.1") if err != nil { t.Errorf("Unexpected error: %v", err) } if !allowed { t.Error("Expected event to be allowed for write access with allowed pubkey") } // Test write access with non-allowed pubkey unauthorizedSigner, unauthorizedPubkey := generateTestKeypair(t) unauthorizedEvent := createTestEvent(t, unauthorizedSigner, "test content", 30919) allowed, err = policy.CheckPolicy("write", unauthorizedEvent, unauthorizedPubkey, "127.0.0.1") if err != nil { t.Errorf("Unexpected error: %v", err) } if allowed { t.Error("Expected event to be denied for write access with non-allowed pubkey") } // Test write access without authentication (privileged check) allowed, err = policy.CheckPolicy("write", event30919, nil, "127.0.0.1") if err != nil { t.Errorf("Unexpected error: %v", err) } if allowed { t.Error("Expected event to be denied for write access without authentication (privileged)") } }) // Test privileged flag behavior with p tags t.Run("privileged flag with p tags", func(t *testing.T) { eventSigner, _ := generateTestKeypair(t) _, loggedInPubkey := generateTestKeypair(t) allowedPubkeyHex := "04eeb1ed409c0b9205e722f8bf1780f553b61876ef323aff16c9f80a9d8ee9f5" allowedPubkeyBytes, err := hex.Dec(allowedPubkeyHex) if err != nil { t.Fatalf("Failed to decode allowed pubkey: %v", err) } // Create event with allowed pubkey and logged-in pubkey in p tag event30520 := createTestEvent(t, eventSigner, "test content", 30520) event30520.Pubkey = allowedPubkeyBytes addPTag(event30520, loggedInPubkey) // Test that event is allowed when logged-in pubkey is in p tag (privileged) // and event pubkey matches write_allow allowed, err := policy.CheckPolicy("write", event30520, loggedInPubkey, "127.0.0.1") if err != nil { t.Errorf("Unexpected error: %v", err) } if !allowed { t.Error("Expected event to be allowed when event pubkey matches write_allow and logged-in pubkey is in p tag") } // Test that event is denied when logged-in pubkey is not in p tag and doesn't match event pubkey event30520NoPTag := createTestEvent(t, eventSigner, "test content", 30520) event30520NoPTag.Pubkey = allowedPubkeyBytes allowed, err = policy.CheckPolicy("write", event30520NoPTag, loggedInPubkey, "127.0.0.1") if err != nil { t.Errorf("Unexpected error: %v", err) } if allowed { t.Error("Expected event to be denied when logged-in pubkey is not in p tag (privileged check fails)") } }) // Test script-based rule (kind 4678) t.Run("script-based rule for kind 4678", func(t *testing.T) { eventSigner, _ := generateTestKeypair(t) _, loggedInPubkey := generateTestKeypair(t) event4678 := createTestEvent(t, eventSigner, "test content", 4678) addPTag(event4678, loggedInPubkey) // Test with script not running (should fall back to default policy) allowed, err := policy.CheckPolicy("write", event4678, loggedInPubkey, "127.0.0.1") if err != nil { t.Errorf("Unexpected error: %v", err) } // Should allow because default policy is "allow" and script is not running // and privileged check passes (loggedInPubkey is in p tag) if !allowed { t.Error("Expected event to be allowed when script is not running (falls back to default 'allow') and privileged check passes") } // Test without authentication (privileged check should fail) allowed, err = policy.CheckPolicy("write", event4678, nil, "127.0.0.1") if err != nil { t.Errorf("Unexpected error: %v", err) } // Should be denied because privileged check fails without authentication // The privileged check happens in checkRulePolicy before script check // So it should be denied even though script is not running if allowed { t.Error("Expected event to be denied without authentication (privileged check)") } }) }