74 lines
2.0 KiB
Go
74 lines
2.0 KiB
Go
package logic
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
modentity "spark-server/internal/module/moderation/entity"
|
|
"spark-server/internal/pkg/errs"
|
|
"spark-server/internal/pkg/reqctx"
|
|
)
|
|
|
|
// Apply records hits and runs account penalties. Call before rejecting send.
|
|
func (s *Service) Apply(ctx context.Context, userID, conversationID int64, in *modentity.ApplyInput) error {
|
|
if in == nil || len(in.Hits) == 0 {
|
|
return nil
|
|
}
|
|
if !s.Ready() {
|
|
return errs.ErrInner
|
|
}
|
|
return s.recordHits(ctx, userID, conversationID, in.Hits)
|
|
}
|
|
|
|
// Enforce runs mute/disable after hits are recorded. Returns ErrContentBlocked when send must stop.
|
|
func (s *Service) Enforce(ctx context.Context, userID int64, res *modentity.ScanResult) error {
|
|
if res == nil {
|
|
return nil
|
|
}
|
|
switch res.Action {
|
|
case modentity.ActionReject, modentity.ActionHide:
|
|
return errs.ErrContentBlocked
|
|
case modentity.ActionMute:
|
|
if s.users == nil || res.MuteSeconds <= 0 {
|
|
return errs.ErrContentBlocked
|
|
}
|
|
until := time.Now().Add(time.Duration(res.MuteSeconds) * time.Second)
|
|
if err := s.users.ExtendSendMutedUntil(ctx, userID, until); err != nil {
|
|
return err
|
|
}
|
|
return errs.ErrContentBlocked
|
|
case modentity.ActionDisable:
|
|
if s.users == nil {
|
|
return errs.ErrContentBlocked
|
|
}
|
|
if err := s.users.DisableAccount(ctx, userID); err != nil {
|
|
return err
|
|
}
|
|
return errs.ErrContentBlocked
|
|
default:
|
|
return nil
|
|
}
|
|
}
|
|
|
|
func (s *Service) recordHits(ctx context.Context, userID, conversationID int64, hits []modentity.HitMatch) error {
|
|
ip := ""
|
|
if rc := reqctx.From(ctx); rc != nil {
|
|
ip = rc.RealIP
|
|
}
|
|
now := time.Now()
|
|
rows := make([]HitRecord, 0, len(hits))
|
|
for i := range hits {
|
|
h := hits[i]
|
|
id, err := s.ids.NextID()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
rows = append(rows, HitRecord{
|
|
ID: id, UserID: userID, ConversationID: conversationID,
|
|
WordID: h.WordID, Category: h.Category, Action: h.Action.Effective(),
|
|
Excerpt: h.Excerpt, RealIP: ip, CreatedAt: now,
|
|
})
|
|
}
|
|
return s.repo.InsertHits(ctx, rows)
|
|
}
|