|
@@ -41,6 +41,10 @@ import (
|
|
"github.com/drakkan/sftpgo/v2/internal/vfs"
|
|
"github.com/drakkan/sftpgo/v2/internal/vfs"
|
|
)
|
|
)
|
|
|
|
|
|
|
|
+const (
|
|
|
|
+ ipBlockedEventName = "IP Blocked"
|
|
|
|
+)
|
|
|
|
+
|
|
var (
|
|
var (
|
|
// eventManager handle the supported event rules actions
|
|
// eventManager handle the supported event rules actions
|
|
eventManager eventRulesContainer
|
|
eventManager eventRulesContainer
|
|
@@ -71,11 +75,12 @@ func init() {
|
|
// eventRulesContainer stores event rules by trigger
|
|
// eventRulesContainer stores event rules by trigger
|
|
type eventRulesContainer struct {
|
|
type eventRulesContainer struct {
|
|
sync.RWMutex
|
|
sync.RWMutex
|
|
|
|
+ lastLoad int64
|
|
FsEvents []dataprovider.EventRule
|
|
FsEvents []dataprovider.EventRule
|
|
ProviderEvents []dataprovider.EventRule
|
|
ProviderEvents []dataprovider.EventRule
|
|
Schedules []dataprovider.EventRule
|
|
Schedules []dataprovider.EventRule
|
|
|
|
+ IPBlockedEvents []dataprovider.EventRule
|
|
schedulesMapping map[string][]cron.EntryID
|
|
schedulesMapping map[string][]cron.EntryID
|
|
- lastLoad int64
|
|
|
|
concurrencyGuard chan struct{}
|
|
concurrencyGuard chan struct{}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -124,6 +129,15 @@ func (r *eventRulesContainer) removeRuleInternal(name string) {
|
|
return
|
|
return
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ for idx := range r.IPBlockedEvents {
|
|
|
|
+ if r.IPBlockedEvents[idx].Name == name {
|
|
|
|
+ lastIdx := len(r.IPBlockedEvents) - 1
|
|
|
|
+ r.IPBlockedEvents[idx] = r.IPBlockedEvents[lastIdx]
|
|
|
|
+ r.IPBlockedEvents = r.IPBlockedEvents[:lastIdx]
|
|
|
|
+ eventManagerLog(logger.LevelDebug, "removed rule %q from IP blocked events", name)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ }
|
|
for idx := range r.Schedules {
|
|
for idx := range r.Schedules {
|
|
if r.Schedules[idx].Name == name {
|
|
if r.Schedules[idx].Name == name {
|
|
if schedules, ok := r.schedulesMapping[name]; ok {
|
|
if schedules, ok := r.schedulesMapping[name]; ok {
|
|
@@ -160,6 +174,9 @@ func (r *eventRulesContainer) addUpdateRuleInternal(rule dataprovider.EventRule)
|
|
case dataprovider.EventTriggerProviderEvent:
|
|
case dataprovider.EventTriggerProviderEvent:
|
|
r.ProviderEvents = append(r.ProviderEvents, rule)
|
|
r.ProviderEvents = append(r.ProviderEvents, rule)
|
|
eventManagerLog(logger.LevelDebug, "added rule %q to provider events", rule.Name)
|
|
eventManagerLog(logger.LevelDebug, "added rule %q to provider events", rule.Name)
|
|
|
|
+ case dataprovider.EventTriggerIPBlocked:
|
|
|
|
+ r.IPBlockedEvents = append(r.IPBlockedEvents, rule)
|
|
|
|
+ eventManagerLog(logger.LevelDebug, "added rule %q to IP blocked events", rule.Name)
|
|
case dataprovider.EventTriggerSchedule:
|
|
case dataprovider.EventTriggerSchedule:
|
|
for _, schedule := range rule.Conditions.Schedules {
|
|
for _, schedule := range rule.Conditions.Schedules {
|
|
cronSpec := schedule.GetCronSpec()
|
|
cronSpec := schedule.GetCronSpec()
|
|
@@ -200,8 +217,8 @@ func (r *eventRulesContainer) loadRules() {
|
|
r.addUpdateRuleInternal(rule)
|
|
r.addUpdateRuleInternal(rule)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- eventManagerLog(logger.LevelDebug, "event rules updated, fs events: %d, provider events: %d, schedules: %d",
|
|
|
|
- len(r.FsEvents), len(r.ProviderEvents), len(r.Schedules))
|
|
|
|
|
|
+ eventManagerLog(logger.LevelDebug, "event rules updated, fs events: %d, provider events: %d, schedules: %d, ip blocked events: %d",
|
|
|
|
+ len(r.FsEvents), len(r.ProviderEvents), len(r.Schedules), len(r.IPBlockedEvents))
|
|
|
|
|
|
r.setLastLoadTime(modTime)
|
|
r.setLastLoadTime(modTime)
|
|
}
|
|
}
|
|
@@ -323,6 +340,28 @@ func (r *eventRulesContainer) handleProviderEvent(params EventParams) {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+func (r *eventRulesContainer) handleIPBlockedEvent(params EventParams) {
|
|
|
|
+ r.RLock()
|
|
|
|
+ defer r.RUnlock()
|
|
|
|
+
|
|
|
|
+ if len(r.IPBlockedEvents) == 0 {
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ var rules []dataprovider.EventRule
|
|
|
|
+ for _, rule := range r.IPBlockedEvents {
|
|
|
|
+ if err := rule.CheckActionsConsistency(""); err == nil {
|
|
|
|
+ rules = append(rules, rule)
|
|
|
|
+ } else {
|
|
|
|
+ eventManagerLog(logger.LevelWarn, "rule %q skipped: %v, event %q",
|
|
|
|
+ rule.Name, err, params.Event)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if len(rules) > 0 {
|
|
|
|
+ go executeAsyncRulesActions(rules, params)
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
// EventParams defines the supported event parameters
|
|
// EventParams defines the supported event parameters
|
|
type EventParams struct {
|
|
type EventParams struct {
|
|
Name string
|
|
Name string
|