]>
Commit | Line | Data |
---|---|---|
d9bc63a1 JH |
1 | package mobius |
2 | ||
3 | import ( | |
fd740bc4 | 4 | "fmt" |
d9bc63a1 JH |
5 | "gopkg.in/yaml.v3" |
6 | "os" | |
7 | "path/filepath" | |
8 | "sync" | |
9 | "time" | |
10 | ) | |
11 | ||
12 | type BanFile struct { | |
13 | banList map[string]*time.Time | |
14 | filePath string | |
15 | ||
16 | sync.Mutex | |
17 | } | |
18 | ||
19 | func NewBanFile(path string) (*BanFile, error) { | |
20 | bf := &BanFile{ | |
21 | filePath: path, | |
22 | banList: make(map[string]*time.Time), | |
23 | } | |
24 | ||
25 | err := bf.Load() | |
fd740bc4 JH |
26 | if err != nil { |
27 | return nil, fmt.Errorf("load ban file: %w", err) | |
28 | } | |
d9bc63a1 | 29 | |
fd740bc4 | 30 | return bf, nil |
d9bc63a1 JH |
31 | } |
32 | ||
33 | func (bf *BanFile) Load() error { | |
34 | bf.Lock() | |
35 | defer bf.Unlock() | |
36 | ||
37 | bf.banList = make(map[string]*time.Time) | |
38 | ||
39 | fh, err := os.Open(bf.filePath) | |
fd740bc4 JH |
40 | if os.IsNotExist(err) { |
41 | return nil | |
42 | } | |
d9bc63a1 | 43 | if err != nil { |
fd740bc4 | 44 | return fmt.Errorf("open file: %v", err) |
d9bc63a1 JH |
45 | } |
46 | defer fh.Close() | |
47 | ||
fd740bc4 | 48 | err = yaml.NewDecoder(fh).Decode(&bf.banList) |
d9bc63a1 | 49 | if err != nil { |
fd740bc4 | 50 | return fmt.Errorf("decode yaml: %v", err) |
d9bc63a1 JH |
51 | } |
52 | ||
53 | return nil | |
54 | } | |
55 | ||
56 | func (bf *BanFile) Add(ip string, until *time.Time) error { | |
57 | bf.Lock() | |
58 | defer bf.Unlock() | |
59 | ||
60 | bf.banList[ip] = until | |
61 | ||
62 | out, err := yaml.Marshal(bf.banList) | |
63 | if err != nil { | |
fd740bc4 | 64 | return fmt.Errorf("marshal yaml: %v", err) |
d9bc63a1 JH |
65 | } |
66 | ||
fd740bc4 JH |
67 | err = os.WriteFile(filepath.Join(bf.filePath), out, 0644) |
68 | if err != nil { | |
69 | return fmt.Errorf("write file: %v", err) | |
70 | } | |
71 | ||
72 | return nil | |
d9bc63a1 JH |
73 | } |
74 | ||
75 | func (bf *BanFile) IsBanned(ip string) (bool, *time.Time) { | |
76 | bf.Lock() | |
77 | defer bf.Unlock() | |
78 | ||
79 | if until, ok := bf.banList[ip]; ok { | |
80 | return true, until | |
81 | } | |
82 | ||
83 | return false, nil | |
84 | } |