2021-08-19 13:33:56 +00:00
|
|
|
package plugins
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/sha256"
|
|
|
|
"fmt"
|
|
|
|
"strings"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
2024-01-01 16:52:18 +00:00
|
|
|
// TimerType defines an enum of available timer types
|
2021-08-19 13:33:56 +00:00
|
|
|
type TimerType uint8
|
|
|
|
|
2024-01-01 16:52:18 +00:00
|
|
|
// Definitions of supported TimerType values
|
2021-08-19 13:33:56 +00:00
|
|
|
const (
|
|
|
|
TimerTypePermit TimerType = iota
|
|
|
|
TimerTypeCooldown
|
|
|
|
)
|
|
|
|
|
|
|
|
type (
|
2024-01-01 16:52:18 +00:00
|
|
|
// TimerEntry represents a time for the given type in the TimerStore
|
2021-08-19 13:33:56 +00:00
|
|
|
TimerEntry struct {
|
|
|
|
Kind TimerType `json:"kind"`
|
|
|
|
Time time.Time `json:"time"`
|
|
|
|
}
|
|
|
|
|
2024-01-01 16:52:18 +00:00
|
|
|
// TimerStore defines what to expect when interacting with a store
|
2021-08-19 13:33:56 +00:00
|
|
|
TimerStore interface {
|
2022-09-10 11:39:07 +00:00
|
|
|
AddCooldown(tt TimerType, limiter, ruleID string, expiry time.Time) error
|
|
|
|
InCooldown(tt TimerType, limiter, ruleID string) (bool, error)
|
|
|
|
AddPermit(channel, username string) error
|
|
|
|
HasPermit(channel, username string) (bool, error)
|
2021-08-19 13:33:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
testTimerStore struct {
|
|
|
|
timers map[string]time.Time
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
2022-09-10 11:39:07 +00:00
|
|
|
var _ TimerStore = (*testTimerStore)(nil)
|
|
|
|
|
2021-08-19 13:33:56 +00:00
|
|
|
func newTestTimerStore() *testTimerStore { return &testTimerStore{timers: map[string]time.Time{}} }
|
|
|
|
|
|
|
|
// Cooldown timer
|
|
|
|
|
2022-09-10 11:39:07 +00:00
|
|
|
func (t *testTimerStore) AddCooldown(tt TimerType, limiter, ruleID string, expiry time.Time) error {
|
2021-08-19 13:33:56 +00:00
|
|
|
t.timers[t.getCooldownTimerKey(tt, limiter, ruleID)] = expiry
|
2022-09-10 11:39:07 +00:00
|
|
|
return nil
|
2021-08-19 13:33:56 +00:00
|
|
|
}
|
|
|
|
|
2022-09-10 11:39:07 +00:00
|
|
|
func (t *testTimerStore) InCooldown(tt TimerType, limiter, ruleID string) (bool, error) {
|
|
|
|
return t.timers[t.getCooldownTimerKey(tt, limiter, ruleID)].After(time.Now()), nil
|
2021-08-19 13:33:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (testTimerStore) getCooldownTimerKey(tt TimerType, limiter, ruleID string) string {
|
|
|
|
h := sha256.New()
|
|
|
|
fmt.Fprintf(h, "%d:%s:%s", tt, limiter, ruleID)
|
|
|
|
return fmt.Sprintf("sha256:%x", h.Sum(nil))
|
|
|
|
}
|
|
|
|
|
|
|
|
// Permit timer
|
|
|
|
|
2022-09-10 11:39:07 +00:00
|
|
|
func (t *testTimerStore) AddPermit(channel, username string) error {
|
2021-08-19 13:33:56 +00:00
|
|
|
t.timers[t.getPermitTimerKey(channel, username)] = time.Now().Add(time.Minute)
|
2022-09-10 11:39:07 +00:00
|
|
|
return nil
|
2021-08-19 13:33:56 +00:00
|
|
|
}
|
|
|
|
|
2022-09-10 11:39:07 +00:00
|
|
|
func (t *testTimerStore) HasPermit(channel, username string) (bool, error) {
|
|
|
|
return t.timers[t.getPermitTimerKey(channel, username)].After(time.Now()), nil
|
2021-08-19 13:33:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (testTimerStore) getPermitTimerKey(channel, username string) string {
|
|
|
|
h := sha256.New()
|
|
|
|
fmt.Fprintf(h, "%d:%s:%s", TimerTypePermit, channel, strings.ToLower(strings.TrimLeft(username, "@")))
|
|
|
|
return fmt.Sprintf("sha256:%x", h.Sum(nil))
|
|
|
|
}
|