fix: SendBan and AllowStranger setting not taking effect

This commit is contained in:
tt
2025-06-23 13:57:37 +08:00
parent 9213c5d309
commit 398c6a077d
8 changed files with 77 additions and 58 deletions

View File

@@ -5,6 +5,7 @@ wsAddr: "ws://0.0.0.0:5200" # websocket ws 监听地址
rootDir: "./wukongimdata/1" # 数据存储目录
pprofOn: true
stress: true # 是否开启压力测试模式
# whitelistOffOfPerson: false
intranet:
tcpAddr: "127.0.0.1:5100" # 内网tcp地址
logger:

View File

@@ -78,8 +78,8 @@ func (ch *channel) channelCreateOrUpdate(c *wkhttp.Context) {
return
}
if req.ChannelType == wkproto.ChannelTypePerson {
c.ResponseError(errors.New("不支持个人频道!"))
if req.ChannelType == wkproto.ChannelTypePerson && len(req.Subscribers) > 0 {
c.ResponseError(errors.New("不支持个人频道添加订阅者"))
return
}
@@ -1270,7 +1270,6 @@ func (ch *channel) addOrUpdateChannel(channelInfo wkdb.ChannelInfo) error {
if err != nil && err != wkdb.ErrNotFound {
return err
}
if wkdb.IsEmptyChannelInfo(existChannel) {
err = service.Store.AddChannelInfo(channelInfo)
if err != nil {

View File

@@ -206,7 +206,7 @@ func (h *Handler) requestAllowSend(from, to string) (wkproto.ReasonCode, error)
return wkproto.ReasonSystemError, err
}
if options.G.IsLocalNode(leaderNode.Id) {
return h.allowSend(from, to)
return service.AllowSendForPerson(from, to)
}
resp, err := h.client.RequestAllowSendForPerson(leaderNode.Id, from, to)
@@ -221,40 +221,3 @@ func (h *Handler) requestAllowSend(from, to string) (wkproto.ReasonCode, error)
}
return wkproto.ReasonCode(resp.Status), nil
}
func (h *Handler) allowSend(from, to string) (wkproto.ReasonCode, error) {
// 查询接收者的频道信息
toChannelInfo, err := service.Store.GetChannel(to, wkproto.ChannelTypePerson)
if err != nil {
h.Error("GetChannel error", zap.Error(err), zap.String("to", to))
return wkproto.ReasonSystemError, err
}
// 频道禁止发送消息,则返回禁止发送消息
if toChannelInfo.SendBan {
return wkproto.ReasonSendBan, nil
}
// 判断是否是黑名单内
isDenylist, err := service.Store.ExistDenylist(to, wkproto.ChannelTypePerson, from)
if err != nil {
h.Error("ExistDenylist error", zap.String("from", from), zap.String("to", to), zap.Error(err))
return wkproto.ReasonSystemError, err
}
if isDenylist {
return wkproto.ReasonInBlacklist, nil
}
// 判断是否在白名单内
if !toChannelInfo.AllowStranger && !options.G.WhitelistOffOfPerson {
isAllowlist, err := service.Store.ExistAllowlist(to, wkproto.ChannelTypePerson, from)
if err != nil {
h.Error("ExistAllowlist error", zap.Error(err))
return wkproto.ReasonSystemError, err
}
if !isAllowlist {
return wkproto.ReasonNotInWhitelist, nil
}
}
return wkproto.ReasonSuccess, nil
}

View File

@@ -19,6 +19,12 @@ type ICommonService interface {
// 判断单聊是否允许发送消息
func AllowSendForPerson(from, to string) (wkproto.ReasonCode, error) {
// 查询接收者的频道信息
toChannelInfo, err := Store.GetChannel(to, wkproto.ChannelTypePerson)
if err != nil {
wklog.Error("GetChannel error", zap.Error(err), zap.String("to", to))
return wkproto.ReasonSystemError, err
}
// 判断是否是黑名单内
isDenylist, err := Store.ExistDenylist(to, wkproto.ChannelTypePerson, from)
if err != nil {
@@ -29,7 +35,7 @@ func AllowSendForPerson(from, to string) (wkproto.ReasonCode, error) {
return wkproto.ReasonInBlacklist, nil
}
if !options.G.WhitelistOffOfPerson {
if !toChannelInfo.AllowStranger && !options.G.WhitelistOffOfPerson {
// 判断是否在白名单内
isAllowlist, err := Store.ExistAllowlist(to, wkproto.ChannelTypePerson, from)
if err != nil {

View File

@@ -38,7 +38,7 @@ func (h *Handler) handleOnSend(event *eventbus.Event) {
event.Track.Record(track.PositionUserOnSend)
conn := event.Conn
from := conn.Uid
sendPacket := event.Frame.(*wkproto.SendPacket)
channelId := sendPacket.ChannelID
channelType := sendPacket.ChannelType
@@ -52,7 +52,7 @@ func (h *Handler) handleOnSend(event *eventbus.Event) {
"onSend",
zap.Int64("messageId", event.MessageId),
zap.Uint64("messageSeq", event.MessageSeq),
zap.String("from", event.Conn.Uid),
zap.String("from", from),
zap.String("deviceId", event.Conn.DeviceId),
zap.String("deviceFlag", event.Conn.DeviceFlag.String()),
zap.Int64("connId", event.Conn.ConnId),
@@ -61,6 +61,33 @@ func (h *Handler) handleOnSend(event *eventbus.Event) {
)
}
reasonCode, err := h.checkGlobalSendPermission(from)
if err != nil {
h.Error("checkGlobalSendPermission error", zap.Error(err), zap.String("uid", from))
sendack := &wkproto.SendackPacket{
Framer: sendPacket.Framer,
MessageID: event.MessageId,
ClientSeq: sendPacket.ClientSeq,
ClientMsgNo: sendPacket.ClientMsgNo,
ReasonCode: wkproto.ReasonSystemError,
}
eventbus.User.ConnWrite(event.ReqId, conn, sendack)
return
}
if reasonCode != wkproto.ReasonSuccess {
h.Warn("checkGlobalSendPermission failed", zap.String("uid", from), zap.String("reasonCode", reasonCode.String()))
sendack := &wkproto.SendackPacket{
Framer: sendPacket.Framer,
MessageID: event.MessageId,
ClientSeq: sendPacket.ClientSeq,
ClientMsgNo: sendPacket.ClientMsgNo,
ReasonCode: reasonCode,
}
eventbus.User.ConnWrite(event.ReqId, conn, sendack)
return
}
// 根据配置决定是否解密消息
if !options.G.DisableEncryption && !conn.IsJsonRpc {
newPayload, err := h.decryptPayload(sendPacket, conn)
@@ -113,6 +140,18 @@ func (h *Handler) handleOnSend(event *eventbus.Event) {
}
// 检查发送者全局权限
func (h *Handler) checkGlobalSendPermission(from string) (wkproto.ReasonCode, error) {
channelInfo, err := service.Store.GetChannel(from, wkproto.ChannelTypePerson)
if err != nil {
return wkproto.ReasonSystemError, err
}
if channelInfo.SendBan {
return wkproto.ReasonSendBan, nil
}
return wkproto.ReasonSuccess, nil
}
func (h *Handler) pluginInvokeSend(sendPacket *wkproto.SendPacket, event *eventbus.Event) (wkproto.ReasonCode, error) {
plugins := service.PluginManager.Plugins(types.PluginSend)

View File

@@ -225,7 +225,9 @@ func NewCMDWithVersion(cmdType CMDType, data []byte, version CmdVersion) *CMD {
}
func (c *CMD) Marshal() ([]byte, error) {
c.version = 1
if c.version == 0 {
c.version = 1
}
enc := wkproto.NewEncoder()
defer enc.End()
enc.WriteUint16(c.version.Uint16())
@@ -853,6 +855,10 @@ func EncodeChannelInfo(c wkdb.ChannelInfo, version CmdVersion) ([]byte, error) {
if version > 0 {
enc.WriteString(c.Webhook)
}
if version > 2 {
enc.WriteUint8(wkutil.BoolToUint8(c.AllowStranger))
enc.WriteUint8(wkutil.BoolToUint8(c.SendBan))
}
return enc.Bytes(), nil
}
@@ -908,6 +914,19 @@ func (c *CMD) DecodeChannelInfo() (wkdb.ChannelInfo, error) {
}
}
if c.version > 2 {
var allowStranger uint8
if allowStranger, err = dec.Uint8(); err != nil {
return channelInfo, err
}
var sendBan uint8
if sendBan, err = dec.Uint8(); err != nil {
return channelInfo, err
}
channelInfo.AllowStranger = wkutil.Uint8ToBool(allowStranger)
channelInfo.SendBan = wkutil.Uint8ToBool(sendBan)
}
return channelInfo, err
}

View File

@@ -4,7 +4,7 @@ type CmdVersion uint16
const (
// CmdVersionChannelInfo is the version of the command that contains channel info
CmdVersionChannelInfo CmdVersion = 2
CmdVersionChannelInfo CmdVersion = 3
)
func (c CmdVersion) Uint16() uint16 {

View File

@@ -672,16 +672,8 @@ func (wk *wukongDB) getConversationsBatch(uid string, ids []uint64) ([]Conversat
// 先尝试从缓存获取部分数据
conversations := make([]Conversation, 0, len(ids))
missingIds := make([]uint64, 0)
// 检查缓存中已有的会话
for _, id := range ids {
// 这里需要通过ID查找会话但缓存是按 uid:channelId:channelType 索引的
// 所以我们还是需要从数据库查询,但可以批量缓存结果
missingIds = append(missingIds, id)
}
if len(missingIds) == 0 {
if len(ids) == 0 {
return conversations, nil
}
@@ -690,11 +682,11 @@ func (wk *wukongDB) getConversationsBatch(uid string, ids []uint64) ([]Conversat
var err error
// 如果ID数量较少使用优化的多范围查询
if len(missingIds) <= 10 {
dbConversations, err = wk.getConversationsBatchOptimized(uid, missingIds)
if len(ids) <= 10 {
dbConversations, err = wk.getConversationsBatchOptimized(uid, ids)
} else {
// ID数量较多时使用全表扫描+过滤的方式
dbConversations, err = wk.getConversationsBatchFiltered(uid, missingIds)
dbConversations, err = wk.getConversationsBatchFiltered(uid, ids)
}
if err != nil {