From 70721836b685fa3c45b93f2bd34350a03b18d0e1 Mon Sep 17 00:00:00 2001 From: icey-yu <1186114839@qq.com> Date: Fri, 14 Feb 2025 12:11:11 +0800 Subject: [PATCH] feat: msg filter and search system account --- config/webhooks.yml | 16 +++------ go.mod | 6 +++- go.sum | 1 + internal/rpc/msg/filter.go | 46 +++++++++++++++++++------ internal/rpc/user/user.go | 26 ++++++++++---- pkg/common/config/config.go | 12 +++---- pkg/common/storage/controller/user.go | 11 ++++-- pkg/common/storage/database/mgo/user.go | 7 +++- pkg/common/storage/database/user.go | 4 ++- 9 files changed, 87 insertions(+), 42 deletions(-) diff --git a/config/webhooks.yml b/config/webhooks.yml index 854d2dc2c..41c60e7e2 100644 --- a/config/webhooks.yml +++ b/config/webhooks.yml @@ -3,14 +3,7 @@ beforeSendSingleMsg: enable: false timeout: 5 failedContinue: true - # Only the contentType in allowedTypes will send the callback. - # Supports two formats: a single type or a range. The range is defined by the lower and upper bounds connected with a hyphen ("-"). - # e.g. allowedTypes: [1, 100, 200-500, 600-700] means that only contentType within the range - # {1, 100} ∪ [200, 500] ∪ [600, 700] will be allowed through the filter. - # If not set, all contentType messages will through this filter. - allowedTypes: [] # Only the contentType not in deniedTypes will send the callback. - # Supports two formats, same as allowedTypes. # If not set, all contentType messages will through this filter. deniedTypes: [] beforeUpdateUserInfoEx: @@ -23,31 +16,30 @@ afterUpdateUserInfoEx: afterSendSingleMsg: enable: false timeout: 5 - # Only the senID/recvID specified in attentionIds will send the callback + # Only the recvID specified in attentionIds will send the callback # if not set, all user messages will be callback attentionIds: [] # See beforeSendSingleMsg comment. - allowedTypes: [] deniedTypes: [] beforeSendGroupMsg: enable: false timeout: 5 failedContinue: true # See beforeSendSingleMsg comment. - allowedTypes: [] deniedTypes: [] beforeMsgModify: enable: false timeout: 5 failedContinue: true # See beforeSendSingleMsg comment. - allowedTypes: [] deniedTypes: [] afterSendGroupMsg: enable: false timeout: 5 + # Only the recvID specified in attentionIds will send the callback + # if not set, all user messages will be callback + attentionIds: [] # See beforeSendSingleMsg comment. - allowedTypes: [] deniedTypes: [] afterUserOnline: enable: false diff --git a/go.mod b/go.mod index fd188e978..2bff5e9d6 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/gorilla/websocket v1.5.1 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 github.com/mitchellh/mapstructure v1.5.0 - github.com/openimsdk/protocol v0.0.72-alpha.71 + github.com/openimsdk/protocol v0.0.72-alpha.72 github.com/openimsdk/tools v0.0.50-alpha.70 github.com/pkg/errors v0.9.1 // indirect github.com/prometheus/client_golang v1.18.0 @@ -219,3 +219,7 @@ require ( golang.org/x/crypto v0.27.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect ) + +replace ( + github.com/openimsdk/protocol v0.0.72-alpha.72 => C:\App\Project\protocol +) \ No newline at end of file diff --git a/go.sum b/go.sum index 4f3431133..e97c8655b 100644 --- a/go.sum +++ b/go.sum @@ -349,6 +349,7 @@ github.com/openimsdk/gomake v0.0.15-alpha.2 h1:5Q8yl8ezy2yx+q8/ucU/t4kJnDfCzNOrk github.com/openimsdk/gomake v0.0.15-alpha.2/go.mod h1:PndCozNc2IsQIciyn9mvEblYWZwJmAI+06z94EY+csI= github.com/openimsdk/protocol v0.0.72-alpha.71 h1:R3utzOlqepaJWTAmnfJi4ccUM/XIoFasSyjQMOipM70= github.com/openimsdk/protocol v0.0.72-alpha.71/go.mod h1:WF7EuE55vQvpyUAzDXcqg+B+446xQyEba0X35lTINmw= +github.com/openimsdk/protocol v0.0.72-alpha.72/go.mod h1:WF7EuE55vQvpyUAzDXcqg+B+446xQyEba0X35lTINmw= github.com/openimsdk/tools v0.0.50-alpha.70 h1:pyqWkJzXbELWU9KKAsWkj3g0flJYNsDTcjR5SLFQAZU= github.com/openimsdk/tools v0.0.50-alpha.70/go.mod h1:B+oqV0zdewN7OiEHYJm+hW+8/Te7B8tHHgD8rK5ZLZk= github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= diff --git a/internal/rpc/msg/filter.go b/internal/rpc/msg/filter.go index ed1a488f1..36511ec7b 100644 --- a/internal/rpc/msg/filter.go +++ b/internal/rpc/msg/filter.go @@ -1,11 +1,13 @@ package msg import ( + "strconv" + "strings" + "github.com/openimsdk/open-im-server/v3/pkg/common/config" + "github.com/openimsdk/protocol/constant" pbchat "github.com/openimsdk/protocol/msg" "github.com/openimsdk/tools/utils/datautil" - "strconv" - "strings" ) const ( @@ -13,28 +15,50 @@ const ( ) func filterAfterMsg(msg *pbchat.SendMsgReq, after *config.AfterConfig) bool { - return filterMsg(msg, after.AttentionIds, after.AllowedTypes, after.DeniedTypes) + return filterMsg(msg, after.AttentionIds, after.DeniedTypes) } func filterBeforeMsg(msg *pbchat.SendMsgReq, before *config.BeforeConfig) bool { - return filterMsg(msg, nil, before.AllowedTypes, before.DeniedTypes) + return filterMsg(msg, nil, before.DeniedTypes) } -func filterMsg(msg *pbchat.SendMsgReq, attentionIds, allowedTypes, deniedTypes []string) bool { +func filterMsg(msg *pbchat.SendMsgReq, attentionIds []string, deniedTypes []int32) bool { // According to the attentionIds configuration, only some users are sent - if len(attentionIds) != 0 && !datautil.Contains([]string{msg.MsgData.SendID, msg.MsgData.RecvID}, attentionIds...) { + if len(attentionIds) != 0 && !datautil.Contain(msg.MsgData.RecvID, attentionIds...) { return false } - if len(allowedTypes) != 0 && !isInInterval(msg.MsgData.ContentType, allowedTypes) { + + if defaultDeniedTypes(msg.MsgData.ContentType) { return false } - if len(deniedTypes) != 0 && isInInterval(msg.MsgData.ContentType, deniedTypes) { + + if len(deniedTypes) != 0 && datautil.Contain(msg.MsgData.ContentType, deniedTypes...) { return false } + //if len(allowedTypes) != 0 && !isInInterval(msg.MsgData.ContentType, allowedTypes) { + // return false + //} + //if len(deniedTypes) != 0 && isInInterval(msg.MsgData.ContentType, deniedTypes) { + // return false + //} return true } -func isInInterval(contentType int32, interval []string) bool { +func defaultDeniedTypes(contentType int32) bool { + if contentType >= constant.NotificationBegin && contentType <= constant.NotificationEnd { + return true + } + if contentType == constant.Typing { + return true + } + return false +} + +// isInInterval if data is in interval +// Supports two formats: a single type or a range. The range is defined by the lower and upper bounds connected with a hyphen ("-") +// e.g. [1, 100, 200-500, 600-700] means that only data within the range +// {1, 100} ∪ [200, 500] ∪ [600, 700] will return true. +func isInInterval(data int32, interval []string) bool { for _, v := range interval { if strings.Contains(v, separator) { // is interval @@ -50,7 +74,7 @@ func isInInterval(contentType int32, interval []string) bool { if err != nil { continue } - if datautil.BetweenEq(int(contentType), bottom, top) { + if datautil.BetweenEq(int(data), bottom, top) { return true } } else { @@ -58,7 +82,7 @@ func isInInterval(contentType int32, interval []string) bool { if err != nil { continue } - if int(contentType) == iv { + if int(data) == iv { return true } } diff --git a/internal/rpc/user/user.go b/internal/rpc/user/user.go index 15e93a988..6f1ab1149 100644 --- a/internal/rpc/user/user.go +++ b/internal/rpc/user/user.go @@ -566,7 +566,7 @@ func (s *userServer) SearchNotificationAccount(ctx context.Context, req *pbuser. } // Convert users to response format - resp := s.userModelToResp(users, req.Pagination) + resp := s.userModelToResp(users, req.Pagination, req.AppManagerLevel) if resp.Total != 0 { return resp, nil } @@ -576,17 +576,24 @@ func (s *userServer) SearchNotificationAccount(ctx context.Context, req *pbuser. if err != nil { return nil, err } - resp = s.userModelToResp(users, req.Pagination) + resp = s.userModelToResp(users, req.Pagination, req.AppManagerLevel) return resp, nil } // If no keyword, find users with notification settings - users, err = s.db.FindNotification(ctx, constant.AppNotificationAdmin) - if err != nil { - return nil, err + if req.AppManagerLevel != nil { + users, err = s.db.FindNotification(ctx, *req.AppManagerLevel) + if err != nil { + return nil, err + } + } else { + users, err = s.db.FindSystemAccount(ctx) + if err != nil { + return nil, err + } } - resp := s.userModelToResp(users, req.Pagination) + resp := s.userModelToResp(users, req.Pagination, req.AppManagerLevel) return resp, nil } @@ -625,11 +632,16 @@ func (s *userServer) genUserID() string { return string(data) } -func (s *userServer) userModelToResp(users []*tablerelation.User, pagination pagination.Pagination) *pbuser.SearchNotificationAccountResp { +func (s *userServer) userModelToResp(users []*tablerelation.User, pagination pagination.Pagination, appManagerLevel *int32) *pbuser.SearchNotificationAccountResp { accounts := make([]*pbuser.NotificationAccountInfo, 0) var total int64 for _, v := range users { if v.AppMangerLevel >= constant.AppNotificationAdmin && !datautil.Contain(v.UserID, s.config.Share.IMAdminUserID...) { + if appManagerLevel != nil { + if v.AppMangerLevel != *appManagerLevel { + continue + } + } temp := &pbuser.NotificationAccountInfo{ UserID: v.UserID, FaceURL: v.FaceURL, diff --git a/pkg/common/config/config.go b/pkg/common/config/config.go index 1b9121b7a..ffce7c153 100644 --- a/pkg/common/config/config.go +++ b/pkg/common/config/config.go @@ -364,19 +364,17 @@ type Redis struct { } type BeforeConfig struct { - Enable bool `mapstructure:"enable"` - Timeout int `mapstructure:"timeout"` - FailedContinue bool `mapstructure:"failedContinue"` - AllowedTypes []string `mapstructure:"allowedTypes"` - DeniedTypes []string `mapstructure:"deniedTypes"` + Enable bool `mapstructure:"enable"` + Timeout int `mapstructure:"timeout"` + FailedContinue bool `mapstructure:"failedContinue"` + DeniedTypes []int32 `mapstructure:"deniedTypes"` } type AfterConfig struct { Enable bool `mapstructure:"enable"` Timeout int `mapstructure:"timeout"` AttentionIds []string `mapstructure:"attentionIds"` - AllowedTypes []string `mapstructure:"allowedTypes"` - DeniedTypes []string `mapstructure:"deniedTypes"` + DeniedTypes []int32 `mapstructure:"deniedTypes"` } type Share struct { diff --git a/pkg/common/storage/controller/user.go b/pkg/common/storage/controller/user.go index 3f34481a3..e58f42ca5 100644 --- a/pkg/common/storage/controller/user.go +++ b/pkg/common/storage/controller/user.go @@ -20,6 +20,7 @@ import ( "github.com/openimsdk/open-im-server/v3/pkg/common/storage/database" "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" + "github.com/openimsdk/protocol/constant" "github.com/openimsdk/tools/db/pagination" "github.com/openimsdk/tools/db/tx" "github.com/openimsdk/tools/utils/datautil" @@ -37,8 +38,10 @@ type UserDatabase interface { Find(ctx context.Context, userIDs []string) (users []*model.User, err error) // Find userInfo By Nickname FindByNickname(ctx context.Context, nickname string) (users []*model.User, err error) - // Find notificationAccounts - FindNotification(ctx context.Context, level int64) (users []*model.User, err error) + // FindNotification find system account by level + FindNotification(ctx context.Context, level int32) (users []*model.User, err error) + // FindSystemAccount find all system account + FindSystemAccount(ctx context.Context) (users []*model.User, err error) // Create Insert multiple external guarantees that the userID is not repeated and does not exist in the storage Create(ctx context.Context, users []*model.User) (err error) // UpdateByMap update (zero value) external guarantee userID exists @@ -139,6 +142,10 @@ func (u *userDatabase) FindNotification(ctx context.Context, level int64) (users return u.userDB.TakeNotification(ctx, level) } +func (u *userDatabase) FindSystemAccount(ctx context.Context) (users []*model.User, err error) { + return u.userDB.TakeGTEAppManagerLevel(ctx, constant.AppNotificationAdmin) +} + // Create Insert multiple external guarantees that the userID is not repeated and does not exist in the storage. func (u *userDatabase) Create(ctx context.Context, users []*model.User) (err error) { return u.tx.Transaction(ctx, func(ctx context.Context) error { diff --git a/pkg/common/storage/database/mgo/user.go b/pkg/common/storage/database/mgo/user.go index ee92b7554..a08765baf 100644 --- a/pkg/common/storage/database/mgo/user.go +++ b/pkg/common/storage/database/mgo/user.go @@ -16,9 +16,10 @@ package mgo import ( "context" + "time" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/database" "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" - "time" "github.com/openimsdk/protocol/user" "github.com/openimsdk/tools/db/mongoutil" @@ -71,6 +72,10 @@ func (u *UserMgo) TakeNotification(ctx context.Context, level int64) (user []*mo return mongoutil.Find[*model.User](ctx, u.coll, bson.M{"app_manger_level": level}) } +func (u *UserMgo) TakeGTEAppManagerLevel(ctx context.Context, level int64) (user []*model.User, err error) { + return mongoutil.Find[*model.User](ctx, u.coll, bson.M{"app_manager_level": bson.M{"$gte": level}}) +} + func (u *UserMgo) TakeByNickname(ctx context.Context, nickname string) (user []*model.User, err error) { return mongoutil.Find[*model.User](ctx, u.coll, bson.M{"nickname": nickname}) } diff --git a/pkg/common/storage/database/user.go b/pkg/common/storage/database/user.go index 4ddc8285f..c597424b9 100644 --- a/pkg/common/storage/database/user.go +++ b/pkg/common/storage/database/user.go @@ -16,10 +16,11 @@ package database import ( "context" + "time" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "github.com/openimsdk/protocol/user" "github.com/openimsdk/tools/db/pagination" - "time" ) type User interface { @@ -28,6 +29,7 @@ type User interface { Find(ctx context.Context, userIDs []string) (users []*model.User, err error) Take(ctx context.Context, userID string) (user *model.User, err error) TakeNotification(ctx context.Context, level int64) (user []*model.User, err error) + TakeGTEAppManagerLevel(ctx context.Context, level int64) (user []*model.User, err error) TakeByNickname(ctx context.Context, nickname string) (user []*model.User, err error) Page(ctx context.Context, pagination pagination.Pagination) (count int64, users []*model.User, err error) PageFindUser(ctx context.Context, level1 int64, level2 int64, pagination pagination.Pagination) (count int64, users []*model.User, err error)