diff --git a/example/plugins/.gitignore b/example/plugins/.gitignore new file mode 100644 index 0000000..5c99c5e --- /dev/null +++ b/example/plugins/.gitignore @@ -0,0 +1,8 @@ +api-call-example/api-call-example +debugger/debugger +dynamic-capture-example/dynamic-capture-example +event-subscriber-example/event-subscriber-example +helloworld/helloworld +restful-example/restful-example +static-capture-example/static-capture-example +upnp/upnp \ No newline at end of file diff --git a/example/plugins/api-call-example/mod/zoraxy_plugin/events/events.go b/example/plugins/api-call-example/mod/zoraxy_plugin/events/events.go new file mode 100644 index 0000000..2bd6536 --- /dev/null +++ b/example/plugins/api-call-example/mod/zoraxy_plugin/events/events.go @@ -0,0 +1,133 @@ +package events + +import ( + "encoding/json" + "fmt" +) + +// EventName represents the type of event +type EventName string + +// EventPayload interface for all event payloads +type EventPayload interface { + // GetName returns the event type + GetName() EventName +} + +// Event represents a system event +type Event struct { + Name EventName `json:"name"` + Timestamp int64 `json:"timestamp"` // Unix timestamp + Data EventPayload `json:"data"` +} + +const ( + // EventBlacklistedIPBlocked is emitted when a blacklisted IP is blocked + EventBlacklistedIPBlocked EventName = "blacklistedIpBlocked" + // EventBlacklistToggled is emitted when the blacklist is toggled for an access rule + EventBlacklistToggled EventName = "blacklistToggled" + // EventAccessRuleCreated is emitted when a new access ruleset is created + EventAccessRuleCreated EventName = "accessRuleCreated" + + // Add more event types as needed +) + +var validEventNames = map[EventName]bool{ + EventBlacklistedIPBlocked: true, + EventBlacklistToggled: true, + EventAccessRuleCreated: true, + // Add more event types as needed + // NOTE: Keep up-to-date with event names specified above +} + +// Check if the event name is valid +func (name EventName) IsValid() bool { + return validEventNames[name] +} + +// BlacklistedIPBlockedEvent represents an event when a blacklisted IP is blocked +type BlacklistedIPBlockedEvent struct { + IP string `json:"ip"` + Comment string `json:"comment"` + RequestedURL string `json:"requested_url"` + Hostname string `json:"hostname"` + UserAgent string `json:"user_agent"` + Method string `json:"method"` +} + +func (e *BlacklistedIPBlockedEvent) GetName() EventName { + return EventBlacklistedIPBlocked +} + +// BlacklistToggledEvent represents an event when the blacklist is disabled for an access rule +type BlacklistToggledEvent struct { + RuleID string `json:"rule_id"` + Enabled bool `json:"enabled"` // Whether the blacklist is enabled or disabled +} + +func (e *BlacklistToggledEvent) GetName() EventName { + return EventBlacklistToggled +} + +// AccessRuleCreatedEvent represents an event when a new access ruleset is created +type AccessRuleCreatedEvent struct { + ID string `json:"id"` + Name string `json:"name"` + Desc string `json:"desc"` + BlacklistEnabled bool `json:"blacklist_enabled"` + WhitelistEnabled bool `json:"whitelist_enabled"` +} + +func (e *AccessRuleCreatedEvent) GetName() EventName { + return EventAccessRuleCreated +} + +// ParseEvent parses a JSON byte slice into an Event struct +func ParseEvent(jsonData []byte, event *Event) error { + // First, determine the event type, and parse shared fields, from the JSON data + var temp struct { + Name EventName `json:"name"` + Timestamp int64 `json:"timestamp"` + } + if err := json.Unmarshal(jsonData, &temp); err != nil { + return err + } + + // Set the event name and timestamp + event.Name = temp.Name + event.Timestamp = temp.Timestamp + + // Now, based on the event type, unmarshal the specific payload + switch temp.Name { + case EventBlacklistedIPBlocked: + type tempData struct { + Data BlacklistedIPBlockedEvent `json:"data"` + } + var payload tempData + if err := json.Unmarshal(jsonData, &payload); err != nil { + return err + } + event.Data = &payload.Data + case EventBlacklistToggled: + type tempData struct { + Data BlacklistToggledEvent `json:"data"` + } + var payload tempData + if err := json.Unmarshal(jsonData, &payload); err != nil { + return err + } + event.Data = &payload.Data + case EventAccessRuleCreated: + type tempData struct { + Data AccessRuleCreatedEvent `json:"data"` + } + var payload tempData + if err := json.Unmarshal(jsonData, &payload); err != nil { + return err + } + event.Data = &payload.Data + default: + return fmt.Errorf("unknown event: %s, %v", temp.Name, jsonData) + } + return nil +} diff --git a/example/plugins/api-call-example/mod/zoraxy_plugin/zoraxy_plugin.go b/example/plugins/api-call-example/mod/zoraxy_plugin/zoraxy_plugin.go index 5398087..761b313 100644 --- a/example/plugins/api-call-example/mod/zoraxy_plugin/zoraxy_plugin.go +++ b/example/plugins/api-call-example/mod/zoraxy_plugin/zoraxy_plugin.go @@ -167,12 +167,12 @@ func RecvConfigureSpec() (*ConfigureSpec, error) { return nil, err } } else { - return nil, fmt.Errorf("No port specified after -configure flag") + return nil, fmt.Errorf("no port specified after -configure flag") } return &configSpec, nil } } - return nil, fmt.Errorf("No -configure flag found") + return nil, fmt.Errorf("no -configure flag found") } /* diff --git a/example/plugins/debugger/mod/zoraxy_plugin/events/events.go b/example/plugins/debugger/mod/zoraxy_plugin/events/events.go new file mode 100644 index 0000000..2bd6536 --- /dev/null +++ b/example/plugins/debugger/mod/zoraxy_plugin/events/events.go @@ -0,0 +1,133 @@ +package events + +import ( + "encoding/json" + "fmt" +) + +// EventName represents the type of event +type EventName string + +// EventPayload interface for all event payloads +type EventPayload interface { + // GetName returns the event type + GetName() EventName +} + +// Event represents a system event +type Event struct { + Name EventName `json:"name"` + Timestamp int64 `json:"timestamp"` // Unix timestamp + Data EventPayload `json:"data"` +} + +const ( + // EventBlacklistedIPBlocked is emitted when a blacklisted IP is blocked + EventBlacklistedIPBlocked EventName = "blacklistedIpBlocked" + // EventBlacklistToggled is emitted when the blacklist is toggled for an access rule + EventBlacklistToggled EventName = "blacklistToggled" + // EventAccessRuleCreated is emitted when a new access ruleset is created + EventAccessRuleCreated EventName = "accessRuleCreated" + + // Add more event types as needed +) + +var validEventNames = map[EventName]bool{ + EventBlacklistedIPBlocked: true, + EventBlacklistToggled: true, + EventAccessRuleCreated: true, + // Add more event types as needed + // NOTE: Keep up-to-date with event names specified above +} + +// Check if the event name is valid +func (name EventName) IsValid() bool { + return validEventNames[name] +} + +// BlacklistedIPBlockedEvent represents an event when a blacklisted IP is blocked +type BlacklistedIPBlockedEvent struct { + IP string `json:"ip"` + Comment string `json:"comment"` + RequestedURL string `json:"requested_url"` + Hostname string `json:"hostname"` + UserAgent string `json:"user_agent"` + Method string `json:"method"` +} + +func (e *BlacklistedIPBlockedEvent) GetName() EventName { + return EventBlacklistedIPBlocked +} + +// BlacklistToggledEvent represents an event when the blacklist is disabled for an access rule +type BlacklistToggledEvent struct { + RuleID string `json:"rule_id"` + Enabled bool `json:"enabled"` // Whether the blacklist is enabled or disabled +} + +func (e *BlacklistToggledEvent) GetName() EventName { + return EventBlacklistToggled +} + +// AccessRuleCreatedEvent represents an event when a new access ruleset is created +type AccessRuleCreatedEvent struct { + ID string `json:"id"` + Name string `json:"name"` + Desc string `json:"desc"` + BlacklistEnabled bool `json:"blacklist_enabled"` + WhitelistEnabled bool `json:"whitelist_enabled"` +} + +func (e *AccessRuleCreatedEvent) GetName() EventName { + return EventAccessRuleCreated +} + +// ParseEvent parses a JSON byte slice into an Event struct +func ParseEvent(jsonData []byte, event *Event) error { + // First, determine the event type, and parse shared fields, from the JSON data + var temp struct { + Name EventName `json:"name"` + Timestamp int64 `json:"timestamp"` + } + if err := json.Unmarshal(jsonData, &temp); err != nil { + return err + } + + // Set the event name and timestamp + event.Name = temp.Name + event.Timestamp = temp.Timestamp + + // Now, based on the event type, unmarshal the specific payload + switch temp.Name { + case EventBlacklistedIPBlocked: + type tempData struct { + Data BlacklistedIPBlockedEvent `json:"data"` + } + var payload tempData + if err := json.Unmarshal(jsonData, &payload); err != nil { + return err + } + event.Data = &payload.Data + case EventBlacklistToggled: + type tempData struct { + Data BlacklistToggledEvent `json:"data"` + } + var payload tempData + if err := json.Unmarshal(jsonData, &payload); err != nil { + return err + } + event.Data = &payload.Data + case EventAccessRuleCreated: + type tempData struct { + Data AccessRuleCreatedEvent `json:"data"` + } + var payload tempData + if err := json.Unmarshal(jsonData, &payload); err != nil { + return err + } + event.Data = &payload.Data + default: + return fmt.Errorf("unknown event: %s, %v", temp.Name, jsonData) + } + return nil +} diff --git a/example/plugins/debugger/mod/zoraxy_plugin/zoraxy_plugin.go b/example/plugins/debugger/mod/zoraxy_plugin/zoraxy_plugin.go index 5398087..761b313 100644 --- a/example/plugins/debugger/mod/zoraxy_plugin/zoraxy_plugin.go +++ b/example/plugins/debugger/mod/zoraxy_plugin/zoraxy_plugin.go @@ -167,12 +167,12 @@ func RecvConfigureSpec() (*ConfigureSpec, error) { return nil, err } } else { - return nil, fmt.Errorf("No port specified after -configure flag") + return nil, fmt.Errorf("no port specified after -configure flag") } return &configSpec, nil } } - return nil, fmt.Errorf("No -configure flag found") + return nil, fmt.Errorf("no -configure flag found") } /* diff --git a/example/plugins/dynamic-capture-example/mod/zoraxy_plugin/events/events.go b/example/plugins/dynamic-capture-example/mod/zoraxy_plugin/events/events.go new file mode 100644 index 0000000..2bd6536 --- /dev/null +++ b/example/plugins/dynamic-capture-example/mod/zoraxy_plugin/events/events.go @@ -0,0 +1,133 @@ +package events + +import ( + "encoding/json" + "fmt" +) + +// EventName represents the type of event +type EventName string + +// EventPayload interface for all event payloads +type EventPayload interface { + // GetName returns the event type + GetName() EventName +} + +// Event represents a system event +type Event struct { + Name EventName `json:"name"` + Timestamp int64 `json:"timestamp"` // Unix timestamp + Data EventPayload `json:"data"` +} + +const ( + // EventBlacklistedIPBlocked is emitted when a blacklisted IP is blocked + EventBlacklistedIPBlocked EventName = "blacklistedIpBlocked" + // EventBlacklistToggled is emitted when the blacklist is toggled for an access rule + EventBlacklistToggled EventName = "blacklistToggled" + // EventAccessRuleCreated is emitted when a new access ruleset is created + EventAccessRuleCreated EventName = "accessRuleCreated" + + // Add more event types as needed +) + +var validEventNames = map[EventName]bool{ + EventBlacklistedIPBlocked: true, + EventBlacklistToggled: true, + EventAccessRuleCreated: true, + // Add more event types as needed + // NOTE: Keep up-to-date with event names specified above +} + +// Check if the event name is valid +func (name EventName) IsValid() bool { + return validEventNames[name] +} + +// BlacklistedIPBlockedEvent represents an event when a blacklisted IP is blocked +type BlacklistedIPBlockedEvent struct { + IP string `json:"ip"` + Comment string `json:"comment"` + RequestedURL string `json:"requested_url"` + Hostname string `json:"hostname"` + UserAgent string `json:"user_agent"` + Method string `json:"method"` +} + +func (e *BlacklistedIPBlockedEvent) GetName() EventName { + return EventBlacklistedIPBlocked +} + +// BlacklistToggledEvent represents an event when the blacklist is disabled for an access rule +type BlacklistToggledEvent struct { + RuleID string `json:"rule_id"` + Enabled bool `json:"enabled"` // Whether the blacklist is enabled or disabled +} + +func (e *BlacklistToggledEvent) GetName() EventName { + return EventBlacklistToggled +} + +// AccessRuleCreatedEvent represents an event when a new access ruleset is created +type AccessRuleCreatedEvent struct { + ID string `json:"id"` + Name string `json:"name"` + Desc string `json:"desc"` + BlacklistEnabled bool `json:"blacklist_enabled"` + WhitelistEnabled bool `json:"whitelist_enabled"` +} + +func (e *AccessRuleCreatedEvent) GetName() EventName { + return EventAccessRuleCreated +} + +// ParseEvent parses a JSON byte slice into an Event struct +func ParseEvent(jsonData []byte, event *Event) error { + // First, determine the event type, and parse shared fields, from the JSON data + var temp struct { + Name EventName `json:"name"` + Timestamp int64 `json:"timestamp"` + } + if err := json.Unmarshal(jsonData, &temp); err != nil { + return err + } + + // Set the event name and timestamp + event.Name = temp.Name + event.Timestamp = temp.Timestamp + + // Now, based on the event type, unmarshal the specific payload + switch temp.Name { + case EventBlacklistedIPBlocked: + type tempData struct { + Data BlacklistedIPBlockedEvent `json:"data"` + } + var payload tempData + if err := json.Unmarshal(jsonData, &payload); err != nil { + return err + } + event.Data = &payload.Data + case EventBlacklistToggled: + type tempData struct { + Data BlacklistToggledEvent `json:"data"` + } + var payload tempData + if err := json.Unmarshal(jsonData, &payload); err != nil { + return err + } + event.Data = &payload.Data + case EventAccessRuleCreated: + type tempData struct { + Data AccessRuleCreatedEvent `json:"data"` + } + var payload tempData + if err := json.Unmarshal(jsonData, &payload); err != nil { + return err + } + event.Data = &payload.Data + default: + return fmt.Errorf("unknown event: %s, %v", temp.Name, jsonData) + } + return nil +} diff --git a/example/plugins/dynamic-capture-example/mod/zoraxy_plugin/zoraxy_plugin.go b/example/plugins/dynamic-capture-example/mod/zoraxy_plugin/zoraxy_plugin.go index 5398087..761b313 100644 --- a/example/plugins/dynamic-capture-example/mod/zoraxy_plugin/zoraxy_plugin.go +++ b/example/plugins/dynamic-capture-example/mod/zoraxy_plugin/zoraxy_plugin.go @@ -167,12 +167,12 @@ func RecvConfigureSpec() (*ConfigureSpec, error) { return nil, err } } else { - return nil, fmt.Errorf("No port specified after -configure flag") + return nil, fmt.Errorf("no port specified after -configure flag") } return &configSpec, nil } } - return nil, fmt.Errorf("No -configure flag found") + return nil, fmt.Errorf("no -configure flag found") } /* diff --git a/example/plugins/event-subscriber-example/main.go b/example/plugins/event-subscriber-example/main.go index 175fc2f..736eeef 100644 --- a/example/plugins/event-subscriber-example/main.go +++ b/example/plugins/event-subscriber-example/main.go @@ -7,6 +7,7 @@ import ( "sync" plugin "aroz.org/zoraxy/event-subscriber-example/mod/zoraxy_plugin" + "aroz.org/zoraxy/event-subscriber-example/mod/zoraxy_plugin/events" ) const ( @@ -38,11 +39,11 @@ func main() { /* Subscriptions Settings */ SubscriptionPath: "/notifyme", - SubscriptionsEvents: map[plugin.EventName]string{ + SubscriptionsEvents: map[string]string{ // for this example, we will subscribe to all events that exist at time of writing - plugin.EventBlacklistedIPBlocked: "This event is triggered when a blacklisted IP is blocked", - plugin.EventBlacklistToggled: "This event is triggered when the blacklist is toggled for an access rule", - plugin.EventAccessRuleCreated: "This event is triggered when a new access ruleset is created", + string(events.EventBlacklistedIPBlocked): "This event is triggered when a blacklisted IP is blocked", + string(events.EventBlacklistToggled): "This event is triggered when the blacklist is toggled for an access rule", + string(events.EventAccessRuleCreated): "This event is triggered when a new access ruleset is created", }, }) diff --git a/example/plugins/event-subscriber-example/mod/zoraxy_plugin/embed_webserver.go b/example/plugins/event-subscriber-example/mod/zoraxy_plugin/embed_webserver.go index b64318f..b68b417 100644 --- a/example/plugins/event-subscriber-example/mod/zoraxy_plugin/embed_webserver.go +++ b/example/plugins/event-subscriber-example/mod/zoraxy_plugin/embed_webserver.go @@ -145,6 +145,24 @@ func (p *PluginUiRouter) RegisterTerminateHandler(termFunc func(), mux *http.Ser }) } +// HandleFunc registers a handler function for the given pattern +// The pattern should start with the handler prefix, e.g. /ui/hello +// If the pattern does not start with the handler prefix, it will be prepended with the handler prefix +func (p *PluginUiRouter) HandleFunc(pattern string, handler func(http.ResponseWriter, *http.Request), mux *http.ServeMux) { + // If mux is nil, use the default ServeMux + if mux == nil { + mux = http.DefaultServeMux + } + + // Make sure the pattern starts with the handler prefix + if !strings.HasPrefix(pattern, p.HandlerPrefix) { + pattern = p.HandlerPrefix + pattern + } + + // Register the handler with the http.ServeMux + mux.HandleFunc(pattern, handler) +} + // Attach the embed UI handler to the target http.ServeMux func (p *PluginUiRouter) AttachHandlerToMux(mux *http.ServeMux) { if mux == nil { diff --git a/example/plugins/event-subscriber-example/mod/zoraxy_plugin/events/events.go b/example/plugins/event-subscriber-example/mod/zoraxy_plugin/events/events.go new file mode 100644 index 0000000..2bd6536 --- /dev/null +++ b/example/plugins/event-subscriber-example/mod/zoraxy_plugin/events/events.go @@ -0,0 +1,133 @@ +package events + +import ( + "encoding/json" + "fmt" +) + +// EventName represents the type of event +type EventName string + +// EventPayload interface for all event payloads +type EventPayload interface { + // GetName returns the event type + GetName() EventName +} + +// Event represents a system event +type Event struct { + Name EventName `json:"name"` + Timestamp int64 `json:"timestamp"` // Unix timestamp + Data EventPayload `json:"data"` +} + +const ( + // EventBlacklistedIPBlocked is emitted when a blacklisted IP is blocked + EventBlacklistedIPBlocked EventName = "blacklistedIpBlocked" + // EventBlacklistToggled is emitted when the blacklist is toggled for an access rule + EventBlacklistToggled EventName = "blacklistToggled" + // EventAccessRuleCreated is emitted when a new access ruleset is created + EventAccessRuleCreated EventName = "accessRuleCreated" + + // Add more event types as needed +) + +var validEventNames = map[EventName]bool{ + EventBlacklistedIPBlocked: true, + EventBlacklistToggled: true, + EventAccessRuleCreated: true, + // Add more event types as needed + // NOTE: Keep up-to-date with event names specified above +} + +// Check if the event name is valid +func (name EventName) IsValid() bool { + return validEventNames[name] +} + +// BlacklistedIPBlockedEvent represents an event when a blacklisted IP is blocked +type BlacklistedIPBlockedEvent struct { + IP string `json:"ip"` + Comment string `json:"comment"` + RequestedURL string `json:"requested_url"` + Hostname string `json:"hostname"` + UserAgent string `json:"user_agent"` + Method string `json:"method"` +} + +func (e *BlacklistedIPBlockedEvent) GetName() EventName { + return EventBlacklistedIPBlocked +} + +// BlacklistToggledEvent represents an event when the blacklist is disabled for an access rule +type BlacklistToggledEvent struct { + RuleID string `json:"rule_id"` + Enabled bool `json:"enabled"` // Whether the blacklist is enabled or disabled +} + +func (e *BlacklistToggledEvent) GetName() EventName { + return EventBlacklistToggled +} + +// AccessRuleCreatedEvent represents an event when a new access ruleset is created +type AccessRuleCreatedEvent struct { + ID string `json:"id"` + Name string `json:"name"` + Desc string `json:"desc"` + BlacklistEnabled bool `json:"blacklist_enabled"` + WhitelistEnabled bool `json:"whitelist_enabled"` +} + +func (e *AccessRuleCreatedEvent) GetName() EventName { + return EventAccessRuleCreated +} + +// ParseEvent parses a JSON byte slice into an Event struct +func ParseEvent(jsonData []byte, event *Event) error { + // First, determine the event type, and parse shared fields, from the JSON data + var temp struct { + Name EventName `json:"name"` + Timestamp int64 `json:"timestamp"` + } + if err := json.Unmarshal(jsonData, &temp); err != nil { + return err + } + + // Set the event name and timestamp + event.Name = temp.Name + event.Timestamp = temp.Timestamp + + // Now, based on the event type, unmarshal the specific payload + switch temp.Name { + case EventBlacklistedIPBlocked: + type tempData struct { + Data BlacklistedIPBlockedEvent `json:"data"` + } + var payload tempData + if err := json.Unmarshal(jsonData, &payload); err != nil { + return err + } + event.Data = &payload.Data + case EventBlacklistToggled: + type tempData struct { + Data BlacklistToggledEvent `json:"data"` + } + var payload tempData + if err := json.Unmarshal(jsonData, &payload); err != nil { + return err + } + event.Data = &payload.Data + case EventAccessRuleCreated: + type tempData struct { + Data AccessRuleCreatedEvent `json:"data"` + } + var payload tempData + if err := json.Unmarshal(jsonData, &payload); err != nil { + return err + } + event.Data = &payload.Data + default: + return fmt.Errorf("unknown event: %s, %v", temp.Name, jsonData) + } + return nil +} diff --git a/example/plugins/event-subscriber-example/mod/zoraxy_plugin/zoraxy_plugin.go b/example/plugins/event-subscriber-example/mod/zoraxy_plugin/zoraxy_plugin.go index 08efe3c..761b313 100644 --- a/example/plugins/event-subscriber-example/mod/zoraxy_plugin/zoraxy_plugin.go +++ b/example/plugins/event-subscriber-example/mod/zoraxy_plugin/zoraxy_plugin.go @@ -102,8 +102,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 /* 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 - 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 + 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[string]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 */ 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 diff --git a/example/plugins/helloworld/mod/zoraxy_plugin/events/events.go b/example/plugins/helloworld/mod/zoraxy_plugin/events/events.go new file mode 100644 index 0000000..2bd6536 --- /dev/null +++ b/example/plugins/helloworld/mod/zoraxy_plugin/events/events.go @@ -0,0 +1,133 @@ +package events + +import ( + "encoding/json" + "fmt" +) + +// EventName represents the type of event +type EventName string + +// EventPayload interface for all event payloads +type EventPayload interface { + // GetName returns the event type + GetName() EventName +} + +// Event represents a system event +type Event struct { + Name EventName `json:"name"` + Timestamp int64 `json:"timestamp"` // Unix timestamp + Data EventPayload `json:"data"` +} + +const ( + // EventBlacklistedIPBlocked is emitted when a blacklisted IP is blocked + EventBlacklistedIPBlocked EventName = "blacklistedIpBlocked" + // EventBlacklistToggled is emitted when the blacklist is toggled for an access rule + EventBlacklistToggled EventName = "blacklistToggled" + // EventAccessRuleCreated is emitted when a new access ruleset is created + EventAccessRuleCreated EventName = "accessRuleCreated" + + // Add more event types as needed +) + +var validEventNames = map[EventName]bool{ + EventBlacklistedIPBlocked: true, + EventBlacklistToggled: true, + EventAccessRuleCreated: true, + // Add more event types as needed + // NOTE: Keep up-to-date with event names specified above +} + +// Check if the event name is valid +func (name EventName) IsValid() bool { + return validEventNames[name] +} + +// BlacklistedIPBlockedEvent represents an event when a blacklisted IP is blocked +type BlacklistedIPBlockedEvent struct { + IP string `json:"ip"` + Comment string `json:"comment"` + RequestedURL string `json:"requested_url"` + Hostname string `json:"hostname"` + UserAgent string `json:"user_agent"` + Method string `json:"method"` +} + +func (e *BlacklistedIPBlockedEvent) GetName() EventName { + return EventBlacklistedIPBlocked +} + +// BlacklistToggledEvent represents an event when the blacklist is disabled for an access rule +type BlacklistToggledEvent struct { + RuleID string `json:"rule_id"` + Enabled bool `json:"enabled"` // Whether the blacklist is enabled or disabled +} + +func (e *BlacklistToggledEvent) GetName() EventName { + return EventBlacklistToggled +} + +// AccessRuleCreatedEvent represents an event when a new access ruleset is created +type AccessRuleCreatedEvent struct { + ID string `json:"id"` + Name string `json:"name"` + Desc string `json:"desc"` + BlacklistEnabled bool `json:"blacklist_enabled"` + WhitelistEnabled bool `json:"whitelist_enabled"` +} + +func (e *AccessRuleCreatedEvent) GetName() EventName { + return EventAccessRuleCreated +} + +// ParseEvent parses a JSON byte slice into an Event struct +func ParseEvent(jsonData []byte, event *Event) error { + // First, determine the event type, and parse shared fields, from the JSON data + var temp struct { + Name EventName `json:"name"` + Timestamp int64 `json:"timestamp"` + } + if err := json.Unmarshal(jsonData, &temp); err != nil { + return err + } + + // Set the event name and timestamp + event.Name = temp.Name + event.Timestamp = temp.Timestamp + + // Now, based on the event type, unmarshal the specific payload + switch temp.Name { + case EventBlacklistedIPBlocked: + type tempData struct { + Data BlacklistedIPBlockedEvent `json:"data"` + } + var payload tempData + if err := json.Unmarshal(jsonData, &payload); err != nil { + return err + } + event.Data = &payload.Data + case EventBlacklistToggled: + type tempData struct { + Data BlacklistToggledEvent `json:"data"` + } + var payload tempData + if err := json.Unmarshal(jsonData, &payload); err != nil { + return err + } + event.Data = &payload.Data + case EventAccessRuleCreated: + type tempData struct { + Data AccessRuleCreatedEvent `json:"data"` + } + var payload tempData + if err := json.Unmarshal(jsonData, &payload); err != nil { + return err + } + event.Data = &payload.Data + default: + return fmt.Errorf("unknown event: %s, %v", temp.Name, jsonData) + } + return nil +} diff --git a/example/plugins/helloworld/mod/zoraxy_plugin/zoraxy_plugin.go b/example/plugins/helloworld/mod/zoraxy_plugin/zoraxy_plugin.go index 5398087..761b313 100644 --- a/example/plugins/helloworld/mod/zoraxy_plugin/zoraxy_plugin.go +++ b/example/plugins/helloworld/mod/zoraxy_plugin/zoraxy_plugin.go @@ -167,12 +167,12 @@ func RecvConfigureSpec() (*ConfigureSpec, error) { return nil, err } } else { - return nil, fmt.Errorf("No port specified after -configure flag") + return nil, fmt.Errorf("no port specified after -configure flag") } return &configSpec, nil } } - return nil, fmt.Errorf("No -configure flag found") + return nil, fmt.Errorf("no -configure flag found") } /* diff --git a/example/plugins/restful-example/mod/zoraxy_plugin/events/events.go b/example/plugins/restful-example/mod/zoraxy_plugin/events/events.go new file mode 100644 index 0000000..2bd6536 --- /dev/null +++ b/example/plugins/restful-example/mod/zoraxy_plugin/events/events.go @@ -0,0 +1,133 @@ +package events + +import ( + "encoding/json" + "fmt" +) + +// EventName represents the type of event +type EventName string + +// EventPayload interface for all event payloads +type EventPayload interface { + // GetName returns the event type + GetName() EventName +} + +// Event represents a system event +type Event struct { + Name EventName `json:"name"` + Timestamp int64 `json:"timestamp"` // Unix timestamp + Data EventPayload `json:"data"` +} + +const ( + // EventBlacklistedIPBlocked is emitted when a blacklisted IP is blocked + EventBlacklistedIPBlocked EventName = "blacklistedIpBlocked" + // EventBlacklistToggled is emitted when the blacklist is toggled for an access rule + EventBlacklistToggled EventName = "blacklistToggled" + // EventAccessRuleCreated is emitted when a new access ruleset is created + EventAccessRuleCreated EventName = "accessRuleCreated" + + // Add more event types as needed +) + +var validEventNames = map[EventName]bool{ + EventBlacklistedIPBlocked: true, + EventBlacklistToggled: true, + EventAccessRuleCreated: true, + // Add more event types as needed + // NOTE: Keep up-to-date with event names specified above +} + +// Check if the event name is valid +func (name EventName) IsValid() bool { + return validEventNames[name] +} + +// BlacklistedIPBlockedEvent represents an event when a blacklisted IP is blocked +type BlacklistedIPBlockedEvent struct { + IP string `json:"ip"` + Comment string `json:"comment"` + RequestedURL string `json:"requested_url"` + Hostname string `json:"hostname"` + UserAgent string `json:"user_agent"` + Method string `json:"method"` +} + +func (e *BlacklistedIPBlockedEvent) GetName() EventName { + return EventBlacklistedIPBlocked +} + +// BlacklistToggledEvent represents an event when the blacklist is disabled for an access rule +type BlacklistToggledEvent struct { + RuleID string `json:"rule_id"` + Enabled bool `json:"enabled"` // Whether the blacklist is enabled or disabled +} + +func (e *BlacklistToggledEvent) GetName() EventName { + return EventBlacklistToggled +} + +// AccessRuleCreatedEvent represents an event when a new access ruleset is created +type AccessRuleCreatedEvent struct { + ID string `json:"id"` + Name string `json:"name"` + Desc string `json:"desc"` + BlacklistEnabled bool `json:"blacklist_enabled"` + WhitelistEnabled bool `json:"whitelist_enabled"` +} + +func (e *AccessRuleCreatedEvent) GetName() EventName { + return EventAccessRuleCreated +} + +// ParseEvent parses a JSON byte slice into an Event struct +func ParseEvent(jsonData []byte, event *Event) error { + // First, determine the event type, and parse shared fields, from the JSON data + var temp struct { + Name EventName `json:"name"` + Timestamp int64 `json:"timestamp"` + } + if err := json.Unmarshal(jsonData, &temp); err != nil { + return err + } + + // Set the event name and timestamp + event.Name = temp.Name + event.Timestamp = temp.Timestamp + + // Now, based on the event type, unmarshal the specific payload + switch temp.Name { + case EventBlacklistedIPBlocked: + type tempData struct { + Data BlacklistedIPBlockedEvent `json:"data"` + } + var payload tempData + if err := json.Unmarshal(jsonData, &payload); err != nil { + return err + } + event.Data = &payload.Data + case EventBlacklistToggled: + type tempData struct { + Data BlacklistToggledEvent `json:"data"` + } + var payload tempData + if err := json.Unmarshal(jsonData, &payload); err != nil { + return err + } + event.Data = &payload.Data + case EventAccessRuleCreated: + type tempData struct { + Data AccessRuleCreatedEvent `json:"data"` + } + var payload tempData + if err := json.Unmarshal(jsonData, &payload); err != nil { + return err + } + event.Data = &payload.Data + default: + return fmt.Errorf("unknown event: %s, %v", temp.Name, jsonData) + } + return nil +} diff --git a/example/plugins/restful-example/mod/zoraxy_plugin/zoraxy_plugin.go b/example/plugins/restful-example/mod/zoraxy_plugin/zoraxy_plugin.go index 5398087..761b313 100644 --- a/example/plugins/restful-example/mod/zoraxy_plugin/zoraxy_plugin.go +++ b/example/plugins/restful-example/mod/zoraxy_plugin/zoraxy_plugin.go @@ -167,12 +167,12 @@ func RecvConfigureSpec() (*ConfigureSpec, error) { return nil, err } } else { - return nil, fmt.Errorf("No port specified after -configure flag") + return nil, fmt.Errorf("no port specified after -configure flag") } return &configSpec, nil } } - return nil, fmt.Errorf("No -configure flag found") + return nil, fmt.Errorf("no -configure flag found") } /* diff --git a/example/plugins/static-capture-example/mod/zoraxy_plugin/events/events.go b/example/plugins/static-capture-example/mod/zoraxy_plugin/events/events.go new file mode 100644 index 0000000..2bd6536 --- /dev/null +++ b/example/plugins/static-capture-example/mod/zoraxy_plugin/events/events.go @@ -0,0 +1,133 @@ +package events + +import ( + "encoding/json" + "fmt" +) + +// EventName represents the type of event +type EventName string + +// EventPayload interface for all event payloads +type EventPayload interface { + // GetName returns the event type + GetName() EventName +} + +// Event represents a system event +type Event struct { + Name EventName `json:"name"` + Timestamp int64 `json:"timestamp"` // Unix timestamp + Data EventPayload `json:"data"` +} + +const ( + // EventBlacklistedIPBlocked is emitted when a blacklisted IP is blocked + EventBlacklistedIPBlocked EventName = "blacklistedIpBlocked" + // EventBlacklistToggled is emitted when the blacklist is toggled for an access rule + EventBlacklistToggled EventName = "blacklistToggled" + // EventAccessRuleCreated is emitted when a new access ruleset is created + EventAccessRuleCreated EventName = "accessRuleCreated" + + // Add more event types as needed +) + +var validEventNames = map[EventName]bool{ + EventBlacklistedIPBlocked: true, + EventBlacklistToggled: true, + EventAccessRuleCreated: true, + // Add more event types as needed + // NOTE: Keep up-to-date with event names specified above +} + +// Check if the event name is valid +func (name EventName) IsValid() bool { + return validEventNames[name] +} + +// BlacklistedIPBlockedEvent represents an event when a blacklisted IP is blocked +type BlacklistedIPBlockedEvent struct { + IP string `json:"ip"` + Comment string `json:"comment"` + RequestedURL string `json:"requested_url"` + Hostname string `json:"hostname"` + UserAgent string `json:"user_agent"` + Method string `json:"method"` +} + +func (e *BlacklistedIPBlockedEvent) GetName() EventName { + return EventBlacklistedIPBlocked +} + +// BlacklistToggledEvent represents an event when the blacklist is disabled for an access rule +type BlacklistToggledEvent struct { + RuleID string `json:"rule_id"` + Enabled bool `json:"enabled"` // Whether the blacklist is enabled or disabled +} + +func (e *BlacklistToggledEvent) GetName() EventName { + return EventBlacklistToggled +} + +// AccessRuleCreatedEvent represents an event when a new access ruleset is created +type AccessRuleCreatedEvent struct { + ID string `json:"id"` + Name string `json:"name"` + Desc string `json:"desc"` + BlacklistEnabled bool `json:"blacklist_enabled"` + WhitelistEnabled bool `json:"whitelist_enabled"` +} + +func (e *AccessRuleCreatedEvent) GetName() EventName { + return EventAccessRuleCreated +} + +// ParseEvent parses a JSON byte slice into an Event struct +func ParseEvent(jsonData []byte, event *Event) error { + // First, determine the event type, and parse shared fields, from the JSON data + var temp struct { + Name EventName `json:"name"` + Timestamp int64 `json:"timestamp"` + } + if err := json.Unmarshal(jsonData, &temp); err != nil { + return err + } + + // Set the event name and timestamp + event.Name = temp.Name + event.Timestamp = temp.Timestamp + + // Now, based on the event type, unmarshal the specific payload + switch temp.Name { + case EventBlacklistedIPBlocked: + type tempData struct { + Data BlacklistedIPBlockedEvent `json:"data"` + } + var payload tempData + if err := json.Unmarshal(jsonData, &payload); err != nil { + return err + } + event.Data = &payload.Data + case EventBlacklistToggled: + type tempData struct { + Data BlacklistToggledEvent `json:"data"` + } + var payload tempData + if err := json.Unmarshal(jsonData, &payload); err != nil { + return err + } + event.Data = &payload.Data + case EventAccessRuleCreated: + type tempData struct { + Data AccessRuleCreatedEvent `json:"data"` + } + var payload tempData + if err := json.Unmarshal(jsonData, &payload); err != nil { + return err + } + event.Data = &payload.Data + default: + return fmt.Errorf("unknown event: %s, %v", temp.Name, jsonData) + } + return nil +} diff --git a/example/plugins/static-capture-example/mod/zoraxy_plugin/zoraxy_plugin.go b/example/plugins/static-capture-example/mod/zoraxy_plugin/zoraxy_plugin.go index 5398087..761b313 100644 --- a/example/plugins/static-capture-example/mod/zoraxy_plugin/zoraxy_plugin.go +++ b/example/plugins/static-capture-example/mod/zoraxy_plugin/zoraxy_plugin.go @@ -167,12 +167,12 @@ func RecvConfigureSpec() (*ConfigureSpec, error) { return nil, err } } else { - return nil, fmt.Errorf("No port specified after -configure flag") + return nil, fmt.Errorf("no port specified after -configure flag") } return &configSpec, nil } } - return nil, fmt.Errorf("No -configure flag found") + return nil, fmt.Errorf("no -configure flag found") } /* diff --git a/example/plugins/upnp/mod/zoraxy_plugin/events/events.go b/example/plugins/upnp/mod/zoraxy_plugin/events/events.go new file mode 100644 index 0000000..2bd6536 --- /dev/null +++ b/example/plugins/upnp/mod/zoraxy_plugin/events/events.go @@ -0,0 +1,133 @@ +package events + +import ( + "encoding/json" + "fmt" +) + +// EventName represents the type of event +type EventName string + +// EventPayload interface for all event payloads +type EventPayload interface { + // GetName returns the event type + GetName() EventName +} + +// Event represents a system event +type Event struct { + Name EventName `json:"name"` + Timestamp int64 `json:"timestamp"` // Unix timestamp + Data EventPayload `json:"data"` +} + +const ( + // EventBlacklistedIPBlocked is emitted when a blacklisted IP is blocked + EventBlacklistedIPBlocked EventName = "blacklistedIpBlocked" + // EventBlacklistToggled is emitted when the blacklist is toggled for an access rule + EventBlacklistToggled EventName = "blacklistToggled" + // EventAccessRuleCreated is emitted when a new access ruleset is created + EventAccessRuleCreated EventName = "accessRuleCreated" + + // Add more event types as needed +) + +var validEventNames = map[EventName]bool{ + EventBlacklistedIPBlocked: true, + EventBlacklistToggled: true, + EventAccessRuleCreated: true, + // Add more event types as needed + // NOTE: Keep up-to-date with event names specified above +} + +// Check if the event name is valid +func (name EventName) IsValid() bool { + return validEventNames[name] +} + +// BlacklistedIPBlockedEvent represents an event when a blacklisted IP is blocked +type BlacklistedIPBlockedEvent struct { + IP string `json:"ip"` + Comment string `json:"comment"` + RequestedURL string `json:"requested_url"` + Hostname string `json:"hostname"` + UserAgent string `json:"user_agent"` + Method string `json:"method"` +} + +func (e *BlacklistedIPBlockedEvent) GetName() EventName { + return EventBlacklistedIPBlocked +} + +// BlacklistToggledEvent represents an event when the blacklist is disabled for an access rule +type BlacklistToggledEvent struct { + RuleID string `json:"rule_id"` + Enabled bool `json:"enabled"` // Whether the blacklist is enabled or disabled +} + +func (e *BlacklistToggledEvent) GetName() EventName { + return EventBlacklistToggled +} + +// AccessRuleCreatedEvent represents an event when a new access ruleset is created +type AccessRuleCreatedEvent struct { + ID string `json:"id"` + Name string `json:"name"` + Desc string `json:"desc"` + BlacklistEnabled bool `json:"blacklist_enabled"` + WhitelistEnabled bool `json:"whitelist_enabled"` +} + +func (e *AccessRuleCreatedEvent) GetName() EventName { + return EventAccessRuleCreated +} + +// ParseEvent parses a JSON byte slice into an Event struct +func ParseEvent(jsonData []byte, event *Event) error { + // First, determine the event type, and parse shared fields, from the JSON data + var temp struct { + Name EventName `json:"name"` + Timestamp int64 `json:"timestamp"` + } + if err := json.Unmarshal(jsonData, &temp); err != nil { + return err + } + + // Set the event name and timestamp + event.Name = temp.Name + event.Timestamp = temp.Timestamp + + // Now, based on the event type, unmarshal the specific payload + switch temp.Name { + case EventBlacklistedIPBlocked: + type tempData struct { + Data BlacklistedIPBlockedEvent `json:"data"` + } + var payload tempData + if err := json.Unmarshal(jsonData, &payload); err != nil { + return err + } + event.Data = &payload.Data + case EventBlacklistToggled: + type tempData struct { + Data BlacklistToggledEvent `json:"data"` + } + var payload tempData + if err := json.Unmarshal(jsonData, &payload); err != nil { + return err + } + event.Data = &payload.Data + case EventAccessRuleCreated: + type tempData struct { + Data AccessRuleCreatedEvent `json:"data"` + } + var payload tempData + if err := json.Unmarshal(jsonData, &payload); err != nil { + return err + } + event.Data = &payload.Data + default: + return fmt.Errorf("unknown event: %s, %v", temp.Name, jsonData) + } + return nil +} diff --git a/example/plugins/upnp/mod/zoraxy_plugin/zoraxy_plugin.go b/example/plugins/upnp/mod/zoraxy_plugin/zoraxy_plugin.go index 5398087..761b313 100644 --- a/example/plugins/upnp/mod/zoraxy_plugin/zoraxy_plugin.go +++ b/example/plugins/upnp/mod/zoraxy_plugin/zoraxy_plugin.go @@ -167,12 +167,12 @@ func RecvConfigureSpec() (*ConfigureSpec, error) { return nil, err } } else { - return nil, fmt.Errorf("No port specified after -configure flag") + return nil, fmt.Errorf("no port specified after -configure flag") } return &configSpec, nil } } - return nil, fmt.Errorf("No -configure flag found") + return nil, fmt.Errorf("no -configure flag found") } /*