20251209
This commit is contained in:
30
archive/bbs-go/server/internal/spam/captcha_strategy.go
Normal file
30
archive/bbs-go/server/internal/spam/captcha_strategy.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package spam
|
||||
|
||||
import (
|
||||
"bbs-go/internal/models"
|
||||
"bbs-go/internal/pkg/errs"
|
||||
"bbs-go/internal/services"
|
||||
|
||||
"github.com/dchest/captcha"
|
||||
)
|
||||
|
||||
type CaptchaStrategy struct{}
|
||||
|
||||
func (CaptchaStrategy) Name() string {
|
||||
return "CaptchaStrategy"
|
||||
}
|
||||
|
||||
func (CaptchaStrategy) CheckTopic(user *models.User, form models.CreateTopicForm) error {
|
||||
if services.SysConfigService.GetConfig().TopicCaptcha && !captcha.VerifyString(form.CaptchaId, form.CaptchaCode) {
|
||||
return errs.CaptchaError
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (CaptchaStrategy) CheckArticle(user *models.User, form models.CreateArticleForm) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (CaptchaStrategy) CheckComment(user *models.User, form models.CreateCommentForm) error {
|
||||
return nil
|
||||
}
|
||||
34
archive/bbs-go/server/internal/spam/email_verify_strategy.go
Normal file
34
archive/bbs-go/server/internal/spam/email_verify_strategy.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package spam
|
||||
|
||||
import (
|
||||
"bbs-go/internal/models"
|
||||
"bbs-go/internal/pkg/errs"
|
||||
"bbs-go/internal/services"
|
||||
)
|
||||
|
||||
type EmailVerifyStrategy struct{}
|
||||
|
||||
func (EmailVerifyStrategy) Name() string {
|
||||
return "EmailVerifyStrategy"
|
||||
}
|
||||
|
||||
func (EmailVerifyStrategy) CheckTopic(user *models.User, form models.CreateTopicForm) error {
|
||||
if services.SysConfigService.IsCreateTopicEmailVerified() && !user.EmailVerified {
|
||||
return errs.EmailNotVerified
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (EmailVerifyStrategy) CheckArticle(user *models.User, form models.CreateArticleForm) error {
|
||||
if services.SysConfigService.IsCreateArticleEmailVerified() && !user.EmailVerified {
|
||||
return errs.EmailNotVerified
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (EmailVerifyStrategy) CheckComment(user *models.User, form models.CreateCommentForm) error {
|
||||
if services.SysConfigService.IsCreateCommentEmailVerified() && !user.EmailVerified {
|
||||
return errs.EmailNotVerified
|
||||
}
|
||||
return nil
|
||||
}
|
||||
105
archive/bbs-go/server/internal/spam/post_frequency_strategy.go
Normal file
105
archive/bbs-go/server/internal/spam/post_frequency_strategy.go
Normal file
@@ -0,0 +1,105 @@
|
||||
package spam
|
||||
|
||||
import (
|
||||
"bbs-go/internal/models"
|
||||
"bbs-go/internal/repositories"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/mlogclub/simple/common/dates"
|
||||
"github.com/mlogclub/simple/sqls"
|
||||
)
|
||||
|
||||
// PostFrequencyStrategy 发表频率限制
|
||||
type PostFrequencyStrategy struct{}
|
||||
|
||||
func (PostFrequencyStrategy) Name() string {
|
||||
return "PostFrequencyStrategy"
|
||||
}
|
||||
|
||||
func (PostFrequencyStrategy) CheckTopic(user *models.User, topic models.CreateTopicForm) error {
|
||||
// 注册时间超过24小时
|
||||
if user.CreateTime < dates.Timestamp(time.Now().Add(-time.Hour*24)) {
|
||||
return nil
|
||||
}
|
||||
var (
|
||||
maxCountInTenMinutes int64 = 1 // 十分钟内最高发帖数量
|
||||
maxCountInOneHour int64 = 2 // 一小时内最高发帖量
|
||||
maxCountInOneDay int64 = 3 // 一天内最高发帖量
|
||||
)
|
||||
|
||||
if repositories.TopicRepository.Count(sqls.DB(), sqls.NewCnd().Eq("user_id", user.Id).
|
||||
Gt("create_time", dates.Timestamp(time.Now().Add(-time.Hour*24)))) >= maxCountInOneDay {
|
||||
return errors.New("发表太快了,请休息一会儿")
|
||||
}
|
||||
|
||||
if repositories.TopicRepository.Count(sqls.DB(), sqls.NewCnd().Eq("user_id", user.Id).
|
||||
Gt("create_time", dates.Timestamp(time.Now().Add(-time.Hour)))) >= maxCountInOneHour {
|
||||
return errors.New("发表太快了,请休息一会儿")
|
||||
}
|
||||
|
||||
if repositories.TopicRepository.Count(sqls.DB(), sqls.NewCnd().Eq("user_id", user.Id).
|
||||
Gt("create_time", dates.Timestamp(time.Now().Add(-time.Minute*10)))) >= maxCountInTenMinutes {
|
||||
return errors.New("发表太快了,请休息一会儿")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s PostFrequencyStrategy) CheckArticle(user *models.User, form models.CreateArticleForm) error {
|
||||
// 注册时间超过24小时
|
||||
if user.CreateTime < dates.Timestamp(time.Now().Add(-time.Hour*24)) {
|
||||
return nil
|
||||
}
|
||||
var (
|
||||
maxCountInTenMinutes int64 = 1 // 十分钟内最高发帖数量
|
||||
maxCountInOneHour int64 = 2 // 一小时内最高发帖量
|
||||
maxCountInOneDay int64 = 3 // 一天内最高发帖量
|
||||
)
|
||||
|
||||
if repositories.ArticleRepository.Count(sqls.DB(), sqls.NewCnd().Eq("user_id", user.Id).
|
||||
Gt("create_time", dates.Timestamp(time.Now().Add(-time.Hour*24)))) >= maxCountInOneDay {
|
||||
return errors.New("发表太快了,请休息一会儿")
|
||||
}
|
||||
|
||||
if repositories.ArticleRepository.Count(sqls.DB(), sqls.NewCnd().Eq("user_id", user.Id).
|
||||
Gt("create_time", dates.Timestamp(time.Now().Add(-time.Hour)))) >= maxCountInOneHour {
|
||||
return errors.New("发表太快了,请休息一会儿")
|
||||
}
|
||||
|
||||
if repositories.ArticleRepository.Count(sqls.DB(), sqls.NewCnd().Eq("user_id", user.Id).
|
||||
Gt("create_time", dates.Timestamp(time.Now().Add(-time.Minute*10)))) >= maxCountInTenMinutes {
|
||||
return errors.New("发表太快了,请休息一会儿")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s PostFrequencyStrategy) CheckComment(user *models.User, form models.CreateCommentForm) error {
|
||||
// 注册时间超过24小时
|
||||
if user.CreateTime < dates.Timestamp(time.Now().Add(-time.Hour*24)) {
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
maxCountInTenMinutes int64 = 1 // 十分钟内最高发帖数量
|
||||
maxCountInOneHour int64 = 1 // 一小时内最高发帖量
|
||||
maxCountInOneDay int64 = 1 // 一天内最高发帖量
|
||||
)
|
||||
|
||||
if repositories.CommentRepository.Count(sqls.DB(), sqls.NewCnd().Eq("user_id", user.Id).
|
||||
Gt("create_time", dates.Timestamp(time.Now().Add(-time.Hour*24)))) >= maxCountInOneDay {
|
||||
return errors.New("发表太快了,请休息一会儿")
|
||||
}
|
||||
|
||||
if repositories.CommentRepository.Count(sqls.DB(), sqls.NewCnd().Eq("user_id", user.Id).
|
||||
Gt("create_time", dates.Timestamp(time.Now().Add(-time.Hour)))) >= maxCountInOneHour {
|
||||
return errors.New("发表太快了,请休息一会儿")
|
||||
}
|
||||
|
||||
if repositories.CommentRepository.Count(sqls.DB(), sqls.NewCnd().Eq("user_id", user.Id).
|
||||
Gt("create_time", dates.Timestamp(time.Now().Add(-time.Minute*10)))) >= maxCountInTenMinutes {
|
||||
return errors.New("发表太快了,请休息一会儿")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
53
archive/bbs-go/server/internal/spam/spam.go
Normal file
53
archive/bbs-go/server/internal/spam/spam.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package spam
|
||||
|
||||
import (
|
||||
"bbs-go/internal/models"
|
||||
"log/slog"
|
||||
)
|
||||
|
||||
var strategies []Strategy
|
||||
|
||||
func init() {
|
||||
strategies = append(strategies, &EmailVerifyStrategy{})
|
||||
strategies = append(strategies, &CaptchaStrategy{})
|
||||
// strategies = append(strategies, &PostFrequencyStrategy{})
|
||||
}
|
||||
|
||||
func CheckTopic(user *models.User, form models.CreateTopicForm) error {
|
||||
if len(strategies) == 0 {
|
||||
return nil
|
||||
}
|
||||
for _, strategy := range strategies {
|
||||
if err := strategy.CheckTopic(user, form); err != nil {
|
||||
slog.Warn("[Topic]命中策略", slog.Any("strategy", strategy.Name()), slog.Any("userId", user.Id))
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func CheckArticle(user *models.User, form models.CreateArticleForm) error {
|
||||
if len(strategies) == 0 {
|
||||
return nil
|
||||
}
|
||||
for _, strategy := range strategies {
|
||||
if err := strategy.CheckArticle(user, form); err != nil {
|
||||
slog.Warn("[Article]命中策略", slog.Any("strategy", strategy.Name()), slog.Any("userId", user.Id))
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func CheckComment(user *models.User, form models.CreateCommentForm) error {
|
||||
if len(strategies) == 0 {
|
||||
return nil
|
||||
}
|
||||
for _, strategy := range strategies {
|
||||
if err := strategy.CheckComment(user, form); err != nil {
|
||||
slog.Warn("[Comment]命中策略", slog.Any("strategy", strategy.Name()), slog.Any("userId", user.Id))
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
14
archive/bbs-go/server/internal/spam/strategy.go
Normal file
14
archive/bbs-go/server/internal/spam/strategy.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package spam
|
||||
|
||||
import "bbs-go/internal/models"
|
||||
|
||||
type Strategy interface {
|
||||
// Name 策略名称
|
||||
Name() string
|
||||
// CheckTopic 检查话题
|
||||
CheckTopic(user *models.User, form models.CreateTopicForm) error
|
||||
// CheckArticle 检查文章
|
||||
CheckArticle(user *models.User, form models.CreateArticleForm) error
|
||||
// CheckComment 检查评论
|
||||
CheckComment(user *models.User, form models.CreateCommentForm) error
|
||||
}
|
||||
Reference in New Issue
Block a user