• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Civil / tg-simple-regex-antispam / 13070263183

31 Jan 2025 09:45AM UTC coverage: 0.0%. Remained the same
13070263183

Pull #5

github

Civil
Refactor and improve bot

 * Fixed small bug in forward action
 * package statefulFilters renamed to chains
 * generic badgerdb interface
 * add filter that counts repeated messages
 * add filter that checks if message is a story
 * add filter that checks if message was marked as spam
Pull Request #5: some improvements

0 of 1422 new or added lines in 20 files covered. (0.0%)

21 existing lines in 3 files now uncovered.

0 of 3756 relevant lines covered (0.0%)

0.0 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/bannedDB/db.go
1
package bannedDB
2

3
import (
4
        "bytes"
5
        "fmt"
6
        "strconv"
7

8
        "github.com/mymmrac/telego"
9

10
        "github.com/dgraph-io/badger/v4"
11
        "go.uber.org/zap"
12

13
        "github.com/Civil/tg-simple-regex-antispam/constants"
14
        "github.com/Civil/tg-simple-regex-antispam/filters/interfaces"
15
        badgerHelper "github.com/Civil/tg-simple-regex-antispam/helper/badger"
16
        "github.com/Civil/tg-simple-regex-antispam/helper/badger/badgerOpts"
17
        "github.com/Civil/tg-simple-regex-antispam/helper/stateful"
18
        "github.com/Civil/tg-simple-regex-antispam/helper/tg"
19
)
20

21
type BannedDB struct {
22
        logger   *zap.Logger
23
        stateDir string
24
        db       *badger.DB
25

26
        statefulFilters []interfaces.StatefulFilter
27

28
        tg.TGHaveAdminCommands
29
}
30

UNCOV
31
func New(logger *zap.Logger, config map[string]any) (BanDB, error) {
×
UNCOV
32
        stateDirI, ok := config["state_dir"]
×
33
        if !ok {
×
NEW
34
                return nil, constants.ErrRequiresStateDir
×
35
        }
×
36
        stateDir, ok := stateDirI.(string)
×
37
        if !ok {
×
NEW
38
                return nil, constants.ErrStateDirNotString
×
39
        }
×
40

41
        badgerDB, err := badger.Open(badgerOpts.GetBadgerOptions(logger, "bannedDB", stateDir))
×
42
        if err != nil {
×
43
                return nil, err
×
44
        }
×
45

46
        db := &BannedDB{
×
47
                logger:              logger.With(zap.String("banDB", "bannedDB")),
×
48
                stateDir:            stateDir,
×
49
                db:                  badgerDB,
×
50
                TGHaveAdminCommands: tg.TGHaveAdminCommands{},
×
51
        }
×
52
        db.TGHaveAdminCommands.Handlers = map[string]tg.AdminCMDHandlerFunc{
×
53
                "list":     db.listCmd,
×
54
                "unban":    db.unbanCmd,
×
55
                "bannodel": db.bannodelCmd,
×
56
                "ban":      db.banCmd,
×
57
                "help":     db.helpCmd,
×
58
        }
×
59
        return db, nil
×
60
}
61

62
func (r *BannedDB) BanUser(userID int64) error {
×
63
        return r.db.Update(
×
64
                func(txn *badger.Txn) error {
×
65
                        return txn.Set(badgerHelper.UserIDToKey(userID), []byte("1"))
×
66
                })
×
67
}
68

69
func (r *BannedDB) SetStatefulFilters(filters []interfaces.StatefulFilter) {
×
70
        r.statefulFilters = filters
×
71
}
×
72

73
func (r *BannedDB) UnbanUser(userID int64) error {
×
74
        err := r.db.Update(
×
75
                func(txn *badger.Txn) error {
×
76
                        return txn.Delete(badgerHelper.UserIDToKey(userID))
×
77
                })
×
78
        if err != nil {
×
79
                return err
×
80
        }
×
81
        if r.statefulFilters != nil {
×
82
                for _, filter := range r.statefulFilters {
×
83
                        err = filter.UnbanUser(userID)
×
84
                        if err != nil {
×
85
                                r.logger.Error("failed to remove state from filter",
×
86
                                        zap.Int64("userID", userID),
×
87
                                        zap.String("filter", filter.GetName()),
×
88
                                        zap.Error(err),
×
89
                                )
×
90
                        }
×
91
                }
92
        }
93
        return nil
×
94
}
95

96
func (r *BannedDB) IsBanned(userID int64) bool {
×
97
        var exists bool
×
98
        err := r.db.View(
×
99
                func(tx *badger.Txn) error {
×
100
                        key := badgerHelper.UserIDToKey(userID)
×
101
                        if val, err := tx.Get(key); err != nil {
×
102
                                return err
×
103
                        } else if val != nil {
×
104
                                exists = true
×
105
                        }
×
106
                        return nil
×
107
                })
108
        if err != nil {
×
109
                return false
×
110
        }
×
111
        return exists
×
112
}
113

114
func (r *BannedDB) ListUserIDs() ([]int64, error) {
×
115
        var userIDs []int64
×
116
        err := r.db.View(
×
117
                func(tx *badger.Txn) error {
×
118
                        opts := badger.DefaultIteratorOptions
×
119
                        opts.PrefetchValues = false
×
120
                        it := tx.NewIterator(opts)
×
121
                        defer it.Close()
×
122

×
123
                        for it.Rewind(); it.Valid(); it.Next() {
×
124
                                item := it.Item()
×
125
                                key := item.Key()
×
126
                                userID, err := badgerHelper.KeyToUserID(key)
×
127
                                if err != nil {
×
128
                                        return err
×
129
                                }
×
130
                                userIDs = append(userIDs, userID)
×
131
                        }
132
                        return nil
×
133

134
                })
135
        return userIDs, err
×
136
}
137

138
func (r *BannedDB) LoadState() error {
×
139
        return nil
×
140
}
×
141

142
func (r *BannedDB) SaveState() error {
×
143
        return r.db.Sync()
×
144
}
×
145

146
func (r *BannedDB) Close() error {
×
147
        return r.db.Close()
×
148
}
×
149

150
func (r *BannedDB) TGAdminPrefix() string {
×
151
        return "bandb"
×
152
}
×
153

154
func (r *BannedDB) listCmd(logger *zap.Logger, bot *telego.Bot, message *telego.Message, tokens []string) error {
×
155
        list, err := r.ListUserIDs()
×
156
        if err != nil {
×
157
                logger.Error("failed to list banned users", zap.Error(err))
×
158
                return err
×
159
        }
×
160
        buf := bytes.NewBuffer([]byte{})
×
161
        buf.WriteString("Banned users:\n")
×
162
        for _, userID := range list {
×
163
                buf.WriteString(fmt.Sprintf("%v\n", userID))
×
164
        }
×
165
        err = tg.SendMessage(bot, message.Chat.ChatID(), &message.MessageID, buf.String())
×
166
        if err != nil {
×
167
                logger.Error("failed to send message", zap.Error(err))
×
168
        }
×
169
        return err
×
170
}
171

172
func (r *BannedDB) unbanCmd(logger *zap.Logger, bot *telego.Bot, message *telego.Message, tokens []string) error {
×
173
        if len(tokens) < 1 {
×
174
                logger.Warn("invalid command", zap.Strings("tokens", tokens))
×
175
                return stateful.ErrNotSupported
×
176
        }
×
177
        userID := tokens[0]
×
178
        userIDInt, err := strconv.ParseInt(userID, 10, 64)
×
179
        if err != nil {
×
180
                logger.Warn("invalid user id", zap.Strings("tokens", tokens), zap.Error(err))
×
181
                return stateful.ErrUserIDInvalid
×
182
        }
×
183
        err = r.UnbanUser(userIDInt)
×
184
        if err != nil {
×
185
                logger.Error("failed to unban user", zap.String("userID", userID), zap.Error(err))
×
186
                _ = tg.SendMessage(bot, message.Chat.ChatID(), &message.MessageID,
×
187
                        fmt.Sprintf("cannot unban user: %s",
×
188
                                err.Error()))
×
189
                return err
×
190
        }
×
191

192
        return tg.SendMessage(bot, message.Chat.ChatID(), &message.MessageID,
×
193
                fmt.Sprintf("user %v unbanned", userIDInt))
×
194
}
195

196
func (r *BannedDB) bannodelCmd(logger *zap.Logger, bot *telego.Bot, message *telego.Message, tokens []string) error {
×
197
        return r.ban(logger, bot, message, tokens, false)
×
198
}
×
199

200
func (r *BannedDB) banCmd(logger *zap.Logger, bot *telego.Bot, message *telego.Message, tokens []string) error {
×
201
        return r.ban(logger, bot, message, tokens, true)
×
202
}
×
203

204
func (r *BannedDB) ban(logger *zap.Logger, bot *telego.Bot, message *telego.Message, tokens []string, deleteAll bool) error {
×
205
        if len(tokens) < 1 {
×
206
                logger.Warn("invalid command", zap.Strings("tokens", tokens))
×
207
                return stateful.ErrInvalidCommand
×
208
        }
×
209
        userID := tokens[0]
×
210
        userIDInt, err := strconv.ParseInt(userID, 10, 64)
×
211
        if err != nil {
×
212
                logger.Warn("invalid user id", zap.Strings("tokens", tokens), zap.Error(err))
×
213
                return err
×
214
        }
×
215
        err = r.BanUser(userIDInt)
×
216
        if err != nil {
×
217
                logger.Error("failed to add user to bandb", zap.String("userID", userID), zap.Error(err))
×
218
                _ = tg.SendMessage(bot, message.Chat.ChatID(), &message.MessageID,
×
219
                        fmt.Sprintf("cannot ban user: %s",
×
220
                                err.Error()))
×
221
                return err
×
222
        }
×
223
        err = tg.BanUser(bot, message.Chat.ChatID(), userIDInt, deleteAll)
×
224
        if err != nil {
×
225
                logger.Error("failed to ban user in telegram", zap.Error(err))
×
226
                return err
×
227
        }
×
228
        return tg.SendMessage(bot, message.Chat.ChatID(), &message.MessageID,
×
229
                fmt.Sprintf("user %v banned", userIDInt))
×
230
}
231

232
func (r *BannedDB) helpCmd(logger *zap.Logger, bot *telego.Bot, message *telego.Message, _ []string) error {
×
233
        buf := bytes.NewBuffer([]byte{})
×
234
        buf.WriteString("Available commands:\n")
×
235
        buf.WriteString(" - `list` - list all banned users (IDs only)\n")
×
236
        buf.WriteString(" - `ban` - ban user by ID and delete all messages\n")
×
237
        buf.WriteString(" - `banNoDel` - ban user by ID but keep all messages\n")
×
238
        buf.WriteString(" - `unban` - unban user by ID\n")
×
239
        buf.WriteString(" - `help` - this help\n")
×
240

×
241
        err := tg.SendMarkdownMessage(bot, message.Chat.ChatID(), &message.MessageID, buf.String())
×
242
        if err != nil {
×
243
                logger.Error("failed to send message", zap.Error(err))
×
244
        }
×
245
        return err
×
246
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc