add askismet, comment spam prevention

This commit is contained in:
BennyThink
2021-12-09 20:07:20 +08:00
parent d1e8bca0e6
commit cf9fc350ba
4 changed files with 45 additions and 9 deletions

View File

@@ -15,4 +15,5 @@ filetype==1.0.7
requests[socks]
tqdm==4.61.1
retry==0.9.2
pymysql
pymysql
git+https://github.com/tgbot-collection/python-akismet

View File

@@ -37,7 +37,7 @@ from database import (AnnouncementResource, BlacklistResource, CaptchaResource,
NameResource, NotificationResource, OtherResource, Redis,
ResourceLatestResource, ResourceResource, TopResource,
UserEmailResource, UserResource)
from utils import send_mail, ts_date
from utils import check_spam, send_mail, ts_date
lib_path = pathlib.Path(__file__).parent.parent.joinpath("yyetsbot").resolve().as_posix()
sys.path.append(lib_path)
@@ -62,6 +62,11 @@ class Mongo:
if data:
return True
def is_user_blocked(self, username: str) -> str:
r = self.db["users"].find_one({"username": username, "status.disable": True})
if r:
return r["status"]["reason"]
class FakeMongoResource:
pass
@@ -206,6 +211,21 @@ class CommentMongoResource(CommentResource, Mongo):
def add_comment(self, captcha: str, captcha_id: int, content: str, resource_id: int,
ip: str, username: str, browser: str, parent_comment_id=None) -> dict:
returned = {"status_code": 0, "message": ""}
# check if this user is blocked
reason = self.is_user_blocked(username)
if reason:
return {"status_code": HTTPStatus.FORBIDDEN, "message": reason}
if check_spam(ip, browser, username, content) != 0:
inserted_id = self.db["spam"].insert_one({
"username": username,
"ip": ip,
"date": ts_date(),
"browser": browser,
"content": content,
"resource_id": resource_id
}).inserted_id
return {"status_code": HTTPStatus.FORBIDDEN, "message": f"possible spam, reference id: {inserted_id}"}
user_group = self.db["users"].find_one(
{"username": username},
projection={"group": True, "_id": False}

View File

@@ -20,10 +20,10 @@ from tornado.log import enable_pretty_logging
from handler import (AnnouncementHandler, BlacklistHandler, CaptchaHandler,
CategoryHandler, CommentChildHandler, CommentHandler,
CommentNewestHandler, CommentReactionHandler,
DBDumpHandler, DoubanHandler,
DoubanReportHandler, GrafanaIndexHandler,
GrafanaQueryHandler, GrafanaSearchHandler, IndexHandler,
LikeHandler, MetricsHandler, NameHandler, NotFoundHandler,
DBDumpHandler, DoubanHandler, DoubanReportHandler,
GrafanaIndexHandler, GrafanaQueryHandler,
GrafanaSearchHandler, IndexHandler, LikeHandler,
MetricsHandler, NameHandler, NotFoundHandler,
NotificationHandler, ResourceHandler,
ResourceLatestHandler, TopHandler, UserEmailHandler,
UserHandler)

View File

@@ -7,6 +7,7 @@
__author__ = "Benny <benny.think@gmail.com>"
import contextlib
import os
import smtplib
import time
@@ -14,12 +15,13 @@ from email.header import Header
from email.mime.text import MIMEText
from email.utils import formataddr, parseaddr
from akismet import Akismet
def ts_date(ts=None):
return time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(ts))
def _format_addr(s):
name, addr = parseaddr(s)
return formataddr((Header(name, 'utf-8').encode(), addr))
@@ -38,13 +40,26 @@ def send_mail(to: str, subject: str, body: str):
msg['Subject'] = Header(subject, 'utf-8').encode()
if port == "1025":
server = smtplib.SMTP(host, port)
server = smtplib.SMTP(host, int(port))
else:
server = smtplib.SMTP_SSL(host, port)
server = smtplib.SMTP_SSL(host, int(port))
server.login(user, password)
server.sendmail(from_addr, [to], msg.as_string())
server.quit()
def check_spam(ip, ua, author, content) -> int:
# 0 means okay
token = os.getenv("askismet")
if token:
with contextlib.suppress(Exception):
akismet = Akismet(token, blog="https://yyets.dmesg.app/")
return akismet.check(ip, ua, comment_author=author, blog_lang="zh_cn",
comment_type="comment",
comment_content=content)
return 0
if __name__ == '__main__':
send_mail("benny.think@gmail.com", "subj", 'aaaa<br>bbb')