Skip to content

Commit

Permalink
Merge pull request #139 from OpenTreeHole/sensitive
Browse files Browse the repository at this point in the history
feat: review sensitive check
  • Loading branch information
JingYiJun authored May 23, 2024
2 parents 6a5ec3c + f4be41b commit 6a331b5
Show file tree
Hide file tree
Showing 14 changed files with 932 additions and 45 deletions.
36 changes: 24 additions & 12 deletions common/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,33 @@ import (

// common config
const (
EnvMode = "MODE"
EnvLogLevel = "LOG_LEVEL"
EnvDBType = "DB_TYPE"
EnvDBUrl = "DB_URL"
EnvCacheType = "CACHE_TYPE"
EnvCacheUrl = "CACHE_URL"
EnvMode = "MODE"
EnvLogLevel = "LOG_LEVEL"
EnvDBType = "DB_TYPE"
EnvDBUrl = "DB_URL"
EnvCacheType = "CACHE_TYPE"
EnvCacheUrl = "CACHE_URL"
EnvYiDunBusinessIdText = "YI_DUN_BUSINESS_ID_TEXT"
EnvYiDunBusinessIdImage = "YI_DUN_BUSINESS_ID_IMAGE"
EnvYiDunSecretId = "YI_DUN_SECRET_ID"
EnvYiDunSecretKey = "YI_DUN_SECRET_KEY"
EnvValidImageUrl = "VALID_IMAGE_URL"
EnvUrlHostnameWhitelist = "URL_HOSTNAME_WHITELIST"
)

var defaultConfig = map[string]string{
EnvMode: "dev",
EnvLogLevel: "debug",
EnvDBType: "sqlite",
EnvDBUrl: "file::memory:?cache=shared",
EnvCacheType: "memory",
EnvCacheUrl: "",
EnvMode: "dev",
EnvLogLevel: "debug",
EnvDBType: "sqlite",
EnvDBUrl: "file::memory:?cache=shared",
EnvCacheType: "memory",
EnvCacheUrl: "",
EnvYiDunBusinessIdText: "",
EnvYiDunBusinessIdImage: "",
EnvYiDunSecretId: "",
EnvYiDunSecretKey: "",
EnvValidImageUrl: "",
EnvUrlHostnameWhitelist: "",
}

var GormConfig = &gorm.Config{
Expand Down
9 changes: 9 additions & 0 deletions common/log.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package common

import (
"context"
"log/slog"
"os"
)
Expand All @@ -14,3 +15,11 @@ type mLogger struct {
func (l mLogger) Printf(message string, args ...any) {
l.Info(message, args...)
}

func RequestLog(msg string, TypeName string, Id int64, ans bool) {
Logger.LogAttrs(context.Background(), slog.LevelInfo, msg, slog.String("TypeName", TypeName), slog.Int64("Id", Id), slog.Bool("CheckAnswer", ans))
//Logger.Info().Str("TypeName", TypeName).
// Int64("Id", Id).
// Bool("CheckAnswer", ans).
// Msg(msg)
}
225 changes: 225 additions & 0 deletions common/sensitive/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
package sensitive

import (
"fmt"
"github.com/opentreehole/backend/common"
"github.com/spf13/viper"
"github.com/yidun/yidun-golang-sdk/yidun/service/antispam/image/v5"
"github.com/yidun/yidun-golang-sdk/yidun/service/antispam/image/v5/check"
v5 "github.com/yidun/yidun-golang-sdk/yidun/service/antispam/text"
"github.com/yidun/yidun-golang-sdk/yidun/service/antispam/text/v5/check/sync/single"
"strconv"
"strings"
"time"
)

const (
//TypeHole = "Hole"
//TypeFloor = "Floor"
//TypeTag = "Tag"
TypeImage = "Image"
TypeReview = "Review"
TypeTitle = "Title"
)

var checkTypes = []string{TypeImage, TypeReview, TypeTitle}

type ParamsForCheck struct {
Content string
Id int64
TypeName string
}

type ResponseForCheck struct {
Pass bool
Labels []int
Detail string
}

func CheckSensitive(params ParamsForCheck) (resp *ResponseForCheck, err error) {
images, clearContent, err := findImagesInMarkdownContent(params.Content)
if err != nil {
return nil, err
}
if len(images) != 0 {
for _, img := range images {
ret, err := checkSensitiveImage(ParamsForCheck{
Content: img,
Id: time.Now().UnixNano(),
TypeName: TypeImage,
})
if err != nil {
return nil, err
}
if !ret.Pass {
return ret, nil
}
}
}

contained, reason := containsUnsafeURL(clearContent)
if contained {
return &ResponseForCheck{
Pass: false,
Labels: nil,
Detail: "不允许使用外部链接" + reason,
}, nil
}
params.Content = strings.TrimSpace(removeIDReprInContent(clearContent))
if params.Content == "" {
return &ResponseForCheck{
Pass: true,
Labels: nil,
Detail: "",
}, nil
}

return CheckSensitiveText(params)
}

func CheckSensitiveText(params ParamsForCheck) (resp *ResponseForCheck, err error) {
if !checkType(params) {
return nil, fmt.Errorf("invalid type for sensitive check")
}

request := single.NewTextCheckRequest(viper.GetString(common.EnvYiDunBusinessIdText))
textCheckClient := v5.NewTextClientWithAccessKey(viper.GetString(common.EnvYiDunSecretId), viper.GetString(common.EnvYiDunSecretKey))

request.SetDataID(strconv.FormatInt(params.Id, 10) + "_" + params.TypeName)
request.SetContent(params.Content)
request.SetTimestamp(time.Now().UnixMilli())

response, err := textCheckClient.SyncCheckText(request)
if err != nil {
// 处理错误并打印日志
common.RequestLog(fmt.Sprintf("sync request error:%+v", err.Error()), params.TypeName, params.Id, false)
return &ResponseForCheck{Pass: false}, nil
}

resp = &ResponseForCheck{}
if response.GetCode() == 200 {

if *response.Result.Antispam.Suggestion == 0 {
common.RequestLog("Sensitive text check response code is 200", params.TypeName, params.Id, true)
resp.Pass = true
return
}

common.RequestLog("Sensitive text check response code is 200", params.TypeName, params.Id, false)
resp.Pass = false
var str string
for _, label := range response.Result.Antispam.Labels {
resp.Labels = append(resp.Labels, *label.Label)
// response != nil && response.Result != nil && response.Result.Antispam != nil &&
//if response.Result.Antispam.SecondLabel != nil && response.Result.Antispam.ThirdLabel != nil {
// str := *response.Result.Antispam.SecondLabel + " " + *response.Result.Antispam.ThirdLabel
//}
if label.SubLabels != nil {
for _, subLabel := range label.SubLabels {
if subLabel.Details != nil && subLabel.Details.HitInfos != nil {
for _, hitInfo := range subLabel.Details.HitInfos {
if str == "" {
str = *hitInfo.Value
continue
}
str += "\n" + *hitInfo.Value
}
}
}
}
}
if str == "" {
str = "文本敏感,未知原因"
}
resp.Detail = str
return
}

common.RequestLog("Sensitive text check http response code is not 200", params.TypeName, params.Id, false)
resp.Pass = false
return
}

func checkSensitiveImage(params ParamsForCheck) (resp *ResponseForCheck, err error) {
// 设置易盾内容安全分配的businessId
url := params.Content

request := check.NewImageV5CheckRequest(viper.GetString(common.EnvYiDunBusinessIdImage))

// 实例化一个textClient,入参需要传入易盾内容安全分配的secretId,secretKey
imageCheckClient := image.NewImageClientWithAccessKey(viper.GetString(common.EnvYiDunSecretId), viper.GetString(common.EnvYiDunSecretKey))

imageInst := check.NewImageBeanRequest()
imageInst.SetData(url)
imageInst.SetName(strconv.FormatInt(params.Id, 10) + "_" + params.TypeName)
// 设置图片数据的类型,1:图片URL,2:图片BASE64
imageInst.SetType(1)

imageBeans := []check.ImageBeanRequest{*imageInst}
request.SetImages(imageBeans)

response, err := imageCheckClient.ImageSyncCheck(request)
if err != nil {
// 处理错误并打印日志
common.RequestLog(fmt.Sprintf("sync request error:%+v", err.Error()), params.TypeName, params.Id, false)
// TODO: 通知管理员
return &ResponseForCheck{Pass: false}, nil
}

resp = &ResponseForCheck{}
if response.GetCode() == 200 {
if len(*response.Result) == 0 {
return nil, fmt.Errorf("sensitive image check returns empty response")
}

if *((*response.Result)[0].Antispam.Suggestion) == 0 {
common.RequestLog("Sensitive image check response code is 200", params.TypeName, params.Id, true)
resp.Pass = true
return
}

common.RequestLog("Sensitive image check response code is 200", params.TypeName, params.Id, false)
resp.Pass = false
for _, label := range *((*response.Result)[0].Antispam.Labels) {
resp.Labels = append(resp.Labels, *label.Label)
}
var str string
for _, result := range *response.Result {
if result.Ocr != nil {
if result.Ocr.Details != nil {
for _, detail := range *result.Ocr.Details {
if str == "" {
str = *detail.Content
continue
}
str += "\n" + *detail.Content
}
}
}
if result.Face != nil {
if result.Face.Details != nil {
for _, detail := range *result.Face.Details {
if detail.FaceContents != nil {
for _, faceContent := range *detail.FaceContents {
if str == "" {
str = *faceContent.Name
continue
}
str += "\n" + *faceContent.Name
}
}
}
}
}
}
if str == "" {
str = "图片敏感,未知原因"
}
resp.Detail = str
return
}

common.RequestLog("Sensitive image check http response code is not 200", params.TypeName, params.Id, false)
resp.Pass = false
return
}
Loading

0 comments on commit 6a331b5

Please sign in to comment.