refactor: move event types into own submodule

This commit is contained in:
Anthony Rubick
2025-08-31 21:27:45 -05:00
parent f45d5f46b4
commit 22d2a0c6ca
8 changed files with 44 additions and 40 deletions

View File

@@ -11,7 +11,7 @@ import (
"imuslab.com/zoraxy/mod/access" "imuslab.com/zoraxy/mod/access"
"imuslab.com/zoraxy/mod/eventsystem" "imuslab.com/zoraxy/mod/eventsystem"
"imuslab.com/zoraxy/mod/plugins/zoraxy_plugin" "imuslab.com/zoraxy/mod/plugins/zoraxy_plugin/events"
"imuslab.com/zoraxy/mod/utils" "imuslab.com/zoraxy/mod/utils"
) )
@@ -101,7 +101,7 @@ func handleCreateAccessRule(w http.ResponseWriter, r *http.Request) {
// emit an event for the new access rule creation // emit an event for the new access rule creation
eventsystem.Publisher.Emit( eventsystem.Publisher.Emit(
&zoraxy_plugin.AccessRuleCreatedEvent{ &events.AccessRuleCreatedEvent{
ID: ruleUUID, ID: ruleUUID,
Name: ruleName, Name: ruleName,
Desc: ruleDesc, Desc: ruleDesc,
@@ -372,7 +372,7 @@ func handleBlacklistEnable(w http.ResponseWriter, r *http.Request) {
return return
} }
eventsystem.Publisher.Emit(&zoraxy_plugin.BlacklistToggledEvent{ eventsystem.Publisher.Emit(&events.BlacklistToggledEvent{
RuleID: ruleID, RuleID: ruleID,
Enabled: rule.BlacklistEnabled, Enabled: rule.BlacklistEnabled,
}) })

View File

@@ -8,7 +8,7 @@ import (
"imuslab.com/zoraxy/mod/access" "imuslab.com/zoraxy/mod/access"
"imuslab.com/zoraxy/mod/eventsystem" "imuslab.com/zoraxy/mod/eventsystem"
"imuslab.com/zoraxy/mod/netutils" "imuslab.com/zoraxy/mod/netutils"
"imuslab.com/zoraxy/mod/plugins/zoraxy_plugin" "imuslab.com/zoraxy/mod/plugins/zoraxy_plugin/events"
) )
// Handle access check (blacklist / whitelist), return true if request is handled (aka blocked) // Handle access check (blacklist / whitelist), return true if request is handled (aka blocked)
@@ -52,7 +52,7 @@ func accessRequestBlocked(accessRule *access.AccessRule, templateDirectory strin
comment = "blacklisted" comment = "blacklisted"
} }
eventsystem.Publisher.Emit( eventsystem.Publisher.Emit(
&zoraxy_plugin.BlacklistedIPBlockedEvent{ &events.BlacklistedIPBlockedEvent{
IP: clientIpAddr, IP: clientIpAddr,
Comment: comment, Comment: comment,
RequestedURL: r.URL.String(), RequestedURL: r.URL.String(),

View File

@@ -6,21 +6,22 @@ import (
"imuslab.com/zoraxy/mod/info/logger" "imuslab.com/zoraxy/mod/info/logger"
// "imuslab.com/zoraxy/mod/plugins" // "imuslab.com/zoraxy/mod/plugins"
zoraxyPlugin "imuslab.com/zoraxy/mod/plugins/zoraxy_plugin"
"imuslab.com/zoraxy/mod/plugins/zoraxy_plugin/events"
) )
type ListenerID string type ListenerID string
type Listener interface { type Listener interface {
Notify(event zoraxyPlugin.Event) error Notify(event events.Event) error
GetID() ListenerID GetID() ListenerID
} }
// eventManager manages event subscriptions and dispatching events to listeners // eventManager manages event subscriptions and dispatching events to listeners
type eventManager struct { type eventManager struct {
subscriptions map[zoraxyPlugin.EventName][]ListenerID // EventType -> []Subscriber, tracks which events each listener is subscribed to subscriptions map[events.EventName][]ListenerID // EventType -> []Subscriber, tracks which events each listener is subscribed to
subscribers map[ListenerID]Listener // ListenerID -> Listener, tracks all registered listeners subscribers map[ListenerID]Listener // ListenerID -> Listener, tracks all registered listeners
logger *logger.Logger // Logger for the event manager logger *logger.Logger // Logger for the event manager
mutex sync.RWMutex // Mutex for concurrent access mutex sync.RWMutex // Mutex for concurrent access
} }
var ( var (
@@ -33,7 +34,7 @@ var (
func InitEventSystem(logger *logger.Logger) { func InitEventSystem(logger *logger.Logger) {
once.Do(func() { once.Do(func() {
Publisher = &eventManager{ Publisher = &eventManager{
subscriptions: make(map[zoraxyPlugin.EventName][]ListenerID), subscriptions: make(map[events.EventName][]ListenerID),
subscribers: make(map[ListenerID]Listener), subscribers: make(map[ListenerID]Listener),
logger: logger, logger: logger,
} }
@@ -41,7 +42,7 @@ func InitEventSystem(logger *logger.Logger) {
} }
// RegisterSubscriberToEvent adds a listener to the subscription list for an event type // RegisterSubscriberToEvent adds a listener to the subscription list for an event type
func (em *eventManager) RegisterSubscriberToEvent(subscriber Listener, eventType zoraxyPlugin.EventName) error { func (em *eventManager) RegisterSubscriberToEvent(subscriber Listener, eventType events.EventName) error {
em.mutex.Lock() em.mutex.Lock()
defer em.mutex.Unlock() defer em.mutex.Unlock()
@@ -86,7 +87,7 @@ func (em *eventManager) UnregisterSubscriber(listenerID ListenerID) error {
} }
// Emit dispatches an event to all subscribed listeners // Emit dispatches an event to all subscribed listeners
func (em *eventManager) Emit(payload zoraxyPlugin.EventPayload) error { func (em *eventManager) Emit(payload events.EventPayload) error {
eventName := payload.GetName() eventName := payload.GetName()
em.mutex.RLock() em.mutex.RLock()
@@ -98,7 +99,7 @@ func (em *eventManager) Emit(payload zoraxyPlugin.EventPayload) error {
} }
// Create the event // Create the event
event := zoraxyPlugin.Event{ event := events.Event{
Name: eventName, Name: eventName,
Timestamp: time.Now().Unix(), Timestamp: time.Now().Unix(),
Data: payload, Data: payload,

View File

@@ -6,14 +6,14 @@ import (
"testing" "testing"
"time" "time"
"imuslab.com/zoraxy/mod/plugins/zoraxy_plugin" "imuslab.com/zoraxy/mod/plugins/zoraxy_plugin/events"
) )
// Test (de)serialization of events // Test (de)serialization of events
func TestEventDeSerialization(t *testing.T) { func TestEventDeSerialization(t *testing.T) {
type SerializationTest struct { type SerializationTest struct {
name string name string
event zoraxy_plugin.Event event events.Event
expectedJson string expectedJson string
} }
@@ -22,10 +22,10 @@ func TestEventDeSerialization(t *testing.T) {
tests := []SerializationTest{ tests := []SerializationTest{
{ {
name: "BlacklistedIPBlocked", name: "BlacklistedIPBlocked",
event: zoraxy_plugin.Event{ event: events.Event{
Name: zoraxy_plugin.EventBlacklistedIPBlocked, Name: events.EventBlacklistedIPBlocked,
Timestamp: timestamp, Timestamp: timestamp,
Data: &zoraxy_plugin.BlacklistedIPBlockedEvent{ Data: &events.BlacklistedIPBlockedEvent{
IP: "192.168.1.1", IP: "192.168.1.1",
Comment: "Test comment", Comment: "Test comment",
RequestedURL: "http://example.com", RequestedURL: "http://example.com",
@@ -38,10 +38,10 @@ func TestEventDeSerialization(t *testing.T) {
}, },
{ {
name: "BlacklistToggled", name: "BlacklistToggled",
event: zoraxy_plugin.Event{ event: events.Event{
Name: zoraxy_plugin.EventBlacklistToggled, Name: events.EventBlacklistToggled,
Timestamp: timestamp, Timestamp: timestamp,
Data: &zoraxy_plugin.BlacklistToggledEvent{ Data: &events.BlacklistToggledEvent{
RuleID: "rule123", RuleID: "rule123",
Enabled: true, Enabled: true,
}, },
@@ -50,10 +50,10 @@ func TestEventDeSerialization(t *testing.T) {
}, },
{ {
name: "AccessRuleCreated", name: "AccessRuleCreated",
event: zoraxy_plugin.Event{ event: events.Event{
Name: zoraxy_plugin.EventAccessRuleCreated, Name: events.EventAccessRuleCreated,
Timestamp: timestamp, Timestamp: timestamp,
Data: &zoraxy_plugin.AccessRuleCreatedEvent{ Data: &events.AccessRuleCreatedEvent{
ID: "rule456", ID: "rule456",
Name: "New Access Rule", Name: "New Access Rule",
Desc: "A dummy access rule", Desc: "A dummy access rule",
@@ -79,8 +79,8 @@ func TestEventDeSerialization(t *testing.T) {
} }
// Deserialize the JSON back into an event // Deserialize the JSON back into an event
var deserializedEvent zoraxy_plugin.Event var deserializedEvent events.Event
if err := zoraxy_plugin.ParseEvent(jsonData, &deserializedEvent); err != nil { if err := events.ParseEvent(jsonData, &deserializedEvent); err != nil {
t.Fatalf("Failed to parse event: %v", err) t.Fatalf("Failed to parse event: %v", err)
} }
@@ -90,18 +90,18 @@ func TestEventDeSerialization(t *testing.T) {
} }
switch data := deserializedEvent.Data.(type) { switch data := deserializedEvent.Data.(type) {
case *zoraxy_plugin.BlacklistedIPBlockedEvent: case *events.BlacklistedIPBlockedEvent:
originalData, ok := test.event.Data.(*zoraxy_plugin.BlacklistedIPBlockedEvent) originalData, ok := test.event.Data.(*events.BlacklistedIPBlockedEvent)
if !ok || *data != *originalData { if !ok || *data != *originalData {
t.Fatalf("Deserialized BlacklistedIPBlockedEvent does not match original.\nGot: %+v\nWant: %+v", data, originalData) t.Fatalf("Deserialized BlacklistedIPBlockedEvent does not match original.\nGot: %+v\nWant: %+v", data, originalData)
} }
case *zoraxy_plugin.AccessRuleCreatedEvent: case *events.AccessRuleCreatedEvent:
originalData, ok := test.event.Data.(*zoraxy_plugin.AccessRuleCreatedEvent) originalData, ok := test.event.Data.(*events.AccessRuleCreatedEvent)
if !ok || *data != *originalData { if !ok || *data != *originalData {
t.Fatalf("Deserialized AccessRuleCreatedEvent does not match original.\nGot: %+v\nWant: %+v", data, originalData) t.Fatalf("Deserialized AccessRuleCreatedEvent does not match original.\nGot: %+v\nWant: %+v", data, originalData)
} }
case *zoraxy_plugin.BlacklistToggledEvent: case *events.BlacklistToggledEvent:
originalData, ok := test.event.Data.(*zoraxy_plugin.BlacklistToggledEvent) originalData, ok := test.event.Data.(*events.BlacklistToggledEvent)
if !ok || *data != *originalData { if !ok || *data != *originalData {
t.Fatalf("Deserialized BlacklistToggledEvent does not match original.\nGot: %+v\nWant: %+v", data, originalData) t.Fatalf("Deserialized BlacklistToggledEvent does not match original.\nGot: %+v\nWant: %+v", data, originalData)
} }

View File

@@ -12,7 +12,7 @@ import (
"time" "time"
"imuslab.com/zoraxy/mod/eventsystem" "imuslab.com/zoraxy/mod/eventsystem"
zoraxyPlugin "imuslab.com/zoraxy/mod/plugins/zoraxy_plugin" "imuslab.com/zoraxy/mod/plugins/zoraxy_plugin/events"
) )
func (p *Plugin) GetID() eventsystem.ListenerID { func (p *Plugin) GetID() eventsystem.ListenerID {
@@ -20,7 +20,7 @@ func (p *Plugin) GetID() eventsystem.ListenerID {
} }
// Send an event to the plugin // Send an event to the plugin
func (p *Plugin) Notify(event zoraxyPlugin.Event) error { func (p *Plugin) Notify(event events.Event) error {
// Handle the event notification // Handle the event notification
if !p.Enabled || p.AssignedPort == 0 { if !p.Enabled || p.AssignedPort == 0 {
return fmt.Errorf("plugin %s is not running", p.Spec.ID) return fmt.Errorf("plugin %s is not running", p.Spec.ID)

View File

@@ -16,6 +16,7 @@ import (
"imuslab.com/zoraxy/mod/dynamicproxy/dpcore" "imuslab.com/zoraxy/mod/dynamicproxy/dpcore"
"imuslab.com/zoraxy/mod/eventsystem" "imuslab.com/zoraxy/mod/eventsystem"
zoraxyPlugin "imuslab.com/zoraxy/mod/plugins/zoraxy_plugin" zoraxyPlugin "imuslab.com/zoraxy/mod/plugins/zoraxy_plugin"
"imuslab.com/zoraxy/mod/plugins/zoraxy_plugin/events"
) )
func (m *Manager) StartPlugin(pluginID string) error { func (m *Manager) StartPlugin(pluginID string) error {
@@ -155,7 +156,7 @@ func (m *Manager) StartPlugin(pluginID string) error {
// Register event subscriptions // Register event subscriptions
if thisPlugin.Spec.SubscriptionsEvents != nil { if thisPlugin.Spec.SubscriptionsEvents != nil {
for eventName := range thisPlugin.Spec.SubscriptionsEvents { for eventName := range thisPlugin.Spec.SubscriptionsEvents {
eventType := zoraxyPlugin.EventName(eventName) eventType := events.EventName(eventName)
err := eventsystem.Publisher.RegisterSubscriberToEvent(thisPlugin, eventType) err := eventsystem.Publisher.RegisterSubscriberToEvent(thisPlugin, eventType)
if err != nil { if err != nil {
m.Log("Failed to subscribe plugin "+thisPlugin.Spec.Name+" to event "+string(eventName), err) m.Log("Failed to subscribe plugin "+thisPlugin.Spec.Name+" to event "+string(eventName), err)

View File

@@ -1,4 +1,4 @@
package zoraxy_plugin package events
import ( import (
"encoding/json" "encoding/json"

View File

@@ -5,6 +5,8 @@ import (
"fmt" "fmt"
"os" "os"
"strings" "strings"
"imuslab.com/zoraxy/mod/plugins/zoraxy_plugin/events"
) )
/* /*
@@ -102,8 +104,8 @@ type IntroSpect struct {
UIPath string `json:"ui_path"` //UI path of your plugin (e.g. /ui), will proxy the whole subpath tree to Zoraxy Web UI as plugin UI UIPath string `json:"ui_path"` //UI path of your plugin (e.g. /ui), will proxy the whole subpath tree to Zoraxy Web UI as plugin UI
/* Subscriptions Settings */ /* Subscriptions Settings */
SubscriptionPath string `json:"subscription_path"` //Subscription event path of your plugin (e.g. /notifyme), a POST request with SubscriptionEvent as body will be sent to this path when the event is triggered SubscriptionPath string `json:"subscription_path"` //Subscription event path of your plugin (e.g. /notifyme), a POST request with SubscriptionEvent as body will be sent to this path when the event is triggered
SubscriptionsEvents map[EventName]string `json:"subscriptions_events"` //Subscriptions events of your plugin, paired with comments describing how the event is used, see Zoraxy documentation for more details SubscriptionsEvents map[events.EventName]string `json:"subscriptions_events"` //Subscriptions events of your plugin, paired with comments describing how the event is used, see Zoraxy documentation for more details
/* API Access Control */ /* API Access Control */
PermittedAPIEndpoints []PermittedAPIEndpoint `json:"permitted_api_endpoints"` //List of API endpoints this plugin can access, and a description of why the plugin needs to access this endpoint PermittedAPIEndpoints []PermittedAPIEndpoint `json:"permitted_api_endpoints"` //List of API endpoints this plugin can access, and a description of why the plugin needs to access this endpoint