feat: enforce tenant content moderation
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
package moderation
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/mozillazg/go-pinyin"
|
||||
"github.com/tinode/chat/server/store/types"
|
||||
)
|
||||
|
||||
func matchLocalWords(text, scene string, words *types.SensitiveWordSet) *ProviderResult {
|
||||
normalized := strings.ToLower(strings.TrimSpace(text))
|
||||
if normalized == "" || words == nil {
|
||||
return nil
|
||||
}
|
||||
for _, rule := range words.Items {
|
||||
if rule == nil || strings.TrimSpace(rule.Word) == "" || !sceneEnabled(rule.Scenes, scene) {
|
||||
continue
|
||||
}
|
||||
matched := false
|
||||
switch strings.ToLower(strings.TrimSpace(rule.MatchType)) {
|
||||
case "exact":
|
||||
matched = normalized == strings.ToLower(strings.TrimSpace(rule.Word))
|
||||
case "regex":
|
||||
pattern, err := regexp.Compile(rule.Word)
|
||||
matched = err == nil && pattern.MatchString(text)
|
||||
case "pinyin":
|
||||
args := pinyin.NewArgs()
|
||||
args.Style = pinyin.Normal
|
||||
textPinyin := strings.Join(pinyin.LazyConvert(text, &args), "")
|
||||
wordPinyin := strings.Join(pinyin.LazyConvert(rule.Word, &args), "")
|
||||
if wordPinyin == "" {
|
||||
wordPinyin = strings.ToLower(strings.TrimSpace(rule.Word))
|
||||
}
|
||||
matched = wordPinyin != "" && strings.Contains(strings.ToLower(textPinyin), strings.ToLower(wordPinyin))
|
||||
default:
|
||||
matched = strings.Contains(normalized, strings.ToLower(strings.TrimSpace(rule.Word)))
|
||||
}
|
||||
if matched {
|
||||
return &ProviderResult{RiskLevel: normalizedRisk(rule.RiskLevel), RiskLabels: []string{"local_sensitive_word"}, Summary: normalizedAction(rule.Action)}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func sceneEnabled(scenes []string, scene string) bool {
|
||||
if len(scenes) == 0 {
|
||||
return true
|
||||
}
|
||||
for _, value := range scenes {
|
||||
if value == "*" || value == scene {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func normalizedRisk(value string) string {
|
||||
switch strings.ToLower(strings.TrimSpace(value)) {
|
||||
case "high", "medium", "low":
|
||||
return strings.ToLower(strings.TrimSpace(value))
|
||||
default:
|
||||
return "none"
|
||||
}
|
||||
}
|
||||
|
||||
func normalizedAction(value string) string {
|
||||
switch strings.ToLower(strings.TrimSpace(value)) {
|
||||
case ActionBlock, ActionAuditOnly:
|
||||
return strings.ToLower(strings.TrimSpace(value))
|
||||
default:
|
||||
return ActionAllow
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user