Introduce Rate-Limiting

Ratelimits a user for 30mins if they send more than 20 requests in a minute, also a schema change

Signed-off-by: baalajimaestro <me@baalajimaestro.me>
This commit is contained in:
baalajimaestro 2022-04-10 23:24:48 +05:30
parent 04f6bc054b
commit 5bf33a49ea
Signed by: baalajimaestro
GPG key ID: F93C394FE9BBAFD5
3 changed files with 35 additions and 11 deletions

View file

@ -1,5 +1,5 @@
import telebot import telebot
import std/[asyncdispatch, logging, options, strutils, random, with, os] import std/[asyncdispatch, logging, options, strutils, random, with, os, tables, times, sequtils]
import norm/[model, sqlite] import norm/[model, sqlite]
type type
@ -11,17 +11,38 @@ type
type type
BannedUsers* = ref object of Model BannedUsers* = ref object of Model
userid*: string userid*: int64
bantime*: float
bantype*: string
var RateLimiter = initTable[int64, seq[float]]()
let AdminID = getEnv("ADMIN_ID").split(",")
func NewCensoredData*(ftype = ""; fhash = ""; fileid = ""; caption = ""): func NewCensoredData*(ftype = ""; fhash = ""; fileid = ""; caption = ""):
CensoredData = CensoredData(ftype: ftype, fhash: fhash, fileid: fileid, caption: caption) CensoredData = CensoredData(ftype: ftype, fhash: fhash, fileid: fileid, caption: caption)
func NewBannedUsers*(userid = ""): func NewBannedUsers*(userid = int64(0), bantime = 0.0, bantype = ""):
BannedUsers = BannedUsers(userid: userid) BannedUsers = BannedUsers(userid: userid, bantime: bantime, bantype: bantype)
let dbConn* = sqlite.open("censordata.db", "", "", "") let dbConn* = sqlite.open("censordata.db", "", "", "")
proc ManageRateLimit(): void=
for i in RateLimiter.keys().toSeq():
if RateLimiter[i][^1] - RateLimiter[i][0] >= 60:
RateLimiter.del(i)
elif len(RateLimiter[i]) >= 20:
var BannedUser = NewBannedUsers(i, epochTime(), "auto")
RateLimiter.del(i)
with dbConn:
insert BannedUser
if dbConn.exists(BannedUsers, "bantype = ? and ? - bantime >= 1800", "auto", epochTime()):
var TempData = @[NewBannedUsers()]
dbConn.select(TempData, "bantype = ? and ? - bantime >= 1800", "auto", epochTime())
for i in TempData:
var e = i
dbConn.delete(e)
dbConn.createTables(NewCensoredData()) dbConn.createTables(NewCensoredData())
dbConn.createTables(NewBannedUsers()) dbConn.createTables(NewBannedUsers())
@ -35,18 +56,21 @@ proc generate_hash(): string=
result[i] = sample(charset) result[i] = sample(charset)
return result return result
const API_KEY = getEnv("TELEGRAM_TOKEN")
proc updateHandler(b: Telebot, u: Update): Future[bool] {.async, gcsafe.} = proc updateHandler(b: Telebot, u: Update): Future[bool] {.async, gcsafe.} =
let response = u.message.get let response = u.message.get
ManageRateLimit()
if not dbConn.exists(BannedUsers, "userid = ?", response.chat.id): if not dbConn.exists(BannedUsers, "userid = ?", response.chat.id):
if RateLimiter.contains(response.chat.id):
RateLimiter[response.chat.id].insert(epochTime())
else:
RateLimiter[response.chat.id] = @[epochTime()]
if response.text.isSome: if response.text.isSome:
let message = response.text.get let message = response.text.get
if message == "/start": if message == "/start":
discard await b.sendMessage(response.chat.id, "Hey, To create a censored post, you can share any album, video, photo, gif, sticker, etc. The messages could then be forwarded to any chat for them to view") discard await b.sendMessage(response.chat.id, "Hey, To create a censored post, you can share any album, video, photo, gif, sticker, etc. The messages could then be forwarded to any chat for them to view")
elif message.contains("/ban"): elif message.contains("/ban"):
let user = message.split(" ") let user = message.split(" ")
var BannedUser = NewBannedUsers(user[1]) var BannedUser = NewBannedUsers(int64(parseInt(user[1])), epochTime(), "permanent")
with dbConn: with dbConn:
insert BannedUser insert BannedUser
discard await b.sendMessage(response.chat.id, "Banned!") discard await b.sendMessage(response.chat.id, "Banned!")
@ -104,6 +128,6 @@ proc updateHandler(b: Telebot, u: Update): Future[bool] {.async, gcsafe.} =
discard await b.sendMessage(response.chat.id, "Censored --> " & "tg://resolve?domain=botbotbotnotabot&start=" & filehash) discard await b.sendMessage(response.chat.id, "Censored --> " & "tg://resolve?domain=botbotbotnotabot&start=" & filehash)
let bot = newTeleBot(API_KEY) let bot = newTeleBot(getEnv("TELEGRAM_TOKEN"))
bot.onUpdate(updateHandler) bot.onUpdate(updateHandler)
bot.poll(timeout=300) bot.poll(timeout=300)