mirror of
https://github.com/openimsdk/open-im-server.git
synced 2026-05-12 21:16:00 +08:00
Merge remote-tracking branch 'origin/main' into v3.8-js-sdk-only
# Conflicts: # go.mod # go.sum # pkg/common/storage/controller/auth.go
This commit is contained in:
@@ -198,6 +198,13 @@ func newGinRouter(disCov discovery.SvcDiscoveryRegistry, config *Config) *gin.En
|
||||
objectGroup.POST("/initiate_form_data", t.InitiateFormData)
|
||||
objectGroup.POST("/complete_form_data", t.CompleteFormData)
|
||||
objectGroup.GET("/*name", t.ObjectRedirect)
|
||||
|
||||
applicationGroup := r.Group("application")
|
||||
applicationGroup.POST("/add_version", t.AddApplicationVersion)
|
||||
applicationGroup.POST("/update_version", t.UpdateApplicationVersion)
|
||||
applicationGroup.POST("/delete_version", t.DeleteApplicationVersion)
|
||||
applicationGroup.POST("/latest_version", t.LatestApplicationVersion)
|
||||
applicationGroup.POST("/page_versions", t.PageApplicationVersion)
|
||||
}
|
||||
// Message
|
||||
msgGroup := r.Group("/msg")
|
||||
@@ -290,4 +297,6 @@ func GinParseToken(authRPC *rpcclient.Auth) gin.HandlerFunc {
|
||||
var Whitelist = []string{
|
||||
"/auth/get_admin_token",
|
||||
"/auth/parse_token",
|
||||
"/application/latest_version",
|
||||
"/application/page_versions",
|
||||
}
|
||||
|
||||
@@ -170,3 +170,23 @@ func (o *ThirdApi) SearchLogs(c *gin.Context) {
|
||||
func (o *ThirdApi) GetPrometheus(c *gin.Context) {
|
||||
c.Redirect(http.StatusFound, o.GrafanaUrl)
|
||||
}
|
||||
|
||||
func (o *ThirdApi) LatestApplicationVersion(c *gin.Context) {
|
||||
a2r.Call(third.ThirdClient.LatestApplicationVersion, o.Client, c)
|
||||
}
|
||||
|
||||
func (o *ThirdApi) AddApplicationVersion(c *gin.Context) {
|
||||
a2r.Call(third.ThirdClient.AddApplicationVersion, o.Client, c)
|
||||
}
|
||||
|
||||
func (o *ThirdApi) UpdateApplicationVersion(c *gin.Context) {
|
||||
a2r.Call(third.ThirdClient.UpdateApplicationVersion, o.Client, c)
|
||||
}
|
||||
|
||||
func (o *ThirdApi) DeleteApplicationVersion(c *gin.Context) {
|
||||
a2r.Call(third.ThirdClient.DeleteApplicationVersion, o.Client, c)
|
||||
}
|
||||
|
||||
func (o *ThirdApi) PageApplicationVersion(c *gin.Context) {
|
||||
a2r.Call(third.ThirdClient.PageApplicationVersion, o.Client, c)
|
||||
}
|
||||
|
||||
@@ -1,17 +1,3 @@
|
||||
// Copyright © 2023 OpenIM. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package msggateway
|
||||
|
||||
import (
|
||||
@@ -212,7 +198,6 @@ func (ws *WsServer) sendUserOnlineInfoToOtherNode(ctx context.Context, client *C
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
wg := errgroup.Group{}
|
||||
wg.SetLimit(concurrentRequest)
|
||||
|
||||
@@ -321,8 +306,32 @@ func (ws *WsServer) KickUserConn(client *Client) error {
|
||||
}
|
||||
|
||||
func (ws *WsServer) multiTerminalLoginChecker(clientOK bool, oldClients []*Client, newClient *Client) {
|
||||
switch ws.msgGatewayConfig.Share.MultiLoginPolicy {
|
||||
kickTokenFunc := func(kickClients []*Client) {
|
||||
var kickTokens []string
|
||||
ws.clients.DeleteClients(newClient.UserID, kickClients)
|
||||
for _, c := range kickClients {
|
||||
kickTokens = append(kickTokens, c.token)
|
||||
err := c.KickOnlineMessage()
|
||||
if err != nil {
|
||||
log.ZWarn(c.ctx, "KickOnlineMessage", err)
|
||||
}
|
||||
}
|
||||
ctx := mcontext.WithMustInfoCtx(
|
||||
[]string{newClient.ctx.GetOperationID(), newClient.ctx.GetUserID(),
|
||||
constant.PlatformIDToName(newClient.PlatformID), newClient.ctx.GetConnID()},
|
||||
)
|
||||
if _, err := ws.authClient.KickTokens(ctx, kickTokens); err != nil {
|
||||
log.ZWarn(newClient.ctx, "kickTokens err", err)
|
||||
}
|
||||
}
|
||||
|
||||
switch ws.msgGatewayConfig.Share.MultiLogin.Policy {
|
||||
case constant.DefalutNotKick:
|
||||
case constant.WebAndOther:
|
||||
if constant.PlatformIDToClass(newClient.PlatformID) == constant.WebPlatformStr {
|
||||
return
|
||||
}
|
||||
fallthrough
|
||||
case constant.PCAndOther:
|
||||
if constant.PlatformIDToClass(newClient.PlatformID) == constant.TerminalPC {
|
||||
return
|
||||
@@ -347,6 +356,35 @@ func (ws *WsServer) multiTerminalLoginChecker(clientOK bool, oldClients []*Clien
|
||||
log.ZWarn(newClient.ctx, "InvalidateToken err", err, "userID", newClient.UserID,
|
||||
"platformID", newClient.PlatformID)
|
||||
}
|
||||
case constant.PcMobileAndWeb:
|
||||
clients, ok := ws.clients.GetAll(newClient.UserID)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
var (
|
||||
kickClients []*Client
|
||||
)
|
||||
for _, client := range clients {
|
||||
if constant.PlatformIDToClass(client.PlatformID) == constant.PlatformIDToClass(newClient.PlatformID) {
|
||||
kickClients = append(kickClients, client)
|
||||
}
|
||||
}
|
||||
kickTokenFunc(kickClients)
|
||||
|
||||
case constant.SingleTerminalLogin:
|
||||
clients, ok := ws.clients.GetAll(newClient.UserID)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
var (
|
||||
kickClients []*Client
|
||||
)
|
||||
for _, client := range clients {
|
||||
kickClients = append(kickClients, client)
|
||||
}
|
||||
kickTokenFunc(kickClients)
|
||||
case constant.Customize:
|
||||
// todo
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,10 +23,13 @@ import (
|
||||
"github.com/openimsdk/open-im-server/v3/internal/push/offlinepush/options"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache"
|
||||
"github.com/openimsdk/tools/log"
|
||||
"github.com/openimsdk/tools/mcontext"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
geTUI = "geTui"
|
||||
geTUI = "getui"
|
||||
firebase = "fcm"
|
||||
jPush = "jpush"
|
||||
)
|
||||
@@ -38,6 +41,7 @@ type OfflinePusher interface {
|
||||
|
||||
func NewOfflinePusher(pushConf *config.Push, cache cache.ThirdCache, fcmConfigPath string) (OfflinePusher, error) {
|
||||
var offlinePusher OfflinePusher
|
||||
pushConf.Enable = strings.ToLower(pushConf.Enable)
|
||||
switch pushConf.Enable {
|
||||
case geTUI:
|
||||
offlinePusher = getui.NewClient(pushConf, cache)
|
||||
@@ -47,6 +51,7 @@ func NewOfflinePusher(pushConf *config.Push, cache cache.ThirdCache, fcmConfigPa
|
||||
offlinePusher = jpush.NewClient(pushConf)
|
||||
default:
|
||||
offlinePusher = dummy.NewClient()
|
||||
log.ZWarn(mcontext.WithMustInfoCtx([]string{"push start", "admin", "admin", ""}), "Unknown push config", nil)
|
||||
}
|
||||
return offlinePusher, nil
|
||||
}
|
||||
|
||||
@@ -55,6 +55,9 @@ func (o *OfflinePushConsumerHandler) handleMsg2OfflinePush(ctx context.Context,
|
||||
log.ZError(ctx, "offline push msg is empty", errs.New("offlinePushMsg is empty"), "userIDs", offlinePushMsg.UserIDs, "msg", offlinePushMsg.MsgData)
|
||||
return
|
||||
}
|
||||
if offlinePushMsg.MsgData.Status == constant.MsgStatusSending {
|
||||
offlinePushMsg.MsgData.Status = constant.MsgStatusSendSuccess
|
||||
}
|
||||
log.ZInfo(ctx, "receive to OfflinePush MQ", "userIDs", offlinePushMsg.UserIDs, "msg", offlinePushMsg.MsgData)
|
||||
|
||||
err := o.offlinePushMsg(ctx, offlinePushMsg.MsgData, offlinePushMsg.UserIDs)
|
||||
|
||||
@@ -194,6 +194,9 @@ func (c *ConsumerHandler) shouldPushOffline(_ context.Context, msg *sdkws.MsgDat
|
||||
}
|
||||
|
||||
func (c *ConsumerHandler) GetConnsAndOnlinePush(ctx context.Context, msg *sdkws.MsgData, pushToUserIDs []string) ([]*msggateway.SingleMsgToUserResults, error) {
|
||||
if msg != nil && msg.Status == constant.MsgStatusSending {
|
||||
msg.Status = constant.MsgStatusSendSuccess
|
||||
}
|
||||
onlineUserIDs, offlineUserIDs, err := c.onlineCache.GetUsersOnline(ctx, pushToUserIDs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -65,7 +65,7 @@ func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryReg
|
||||
redis2.NewTokenCacheModel(rdb, config.RpcConfig.TokenPolicy.Expire),
|
||||
config.Share.Secret,
|
||||
config.RpcConfig.TokenPolicy.Expire,
|
||||
config.Share.MultiLoginPolicy,
|
||||
config.Share.MultiLogin,
|
||||
),
|
||||
config: config,
|
||||
})
|
||||
@@ -230,3 +230,10 @@ func (s *authServer) InvalidateToken(ctx context.Context, req *pbauth.Invalidate
|
||||
}
|
||||
return &pbauth.InvalidateTokenResp{}, nil
|
||||
}
|
||||
|
||||
func (s *authServer) KickTokens(ctx context.Context, req *pbauth.KickTokensReq) (*pbauth.KickTokensResp, error) {
|
||||
if err := s.authDatabase.BatchSetTokenMapByUidPid(ctx, req.Tokens); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &pbauth.KickTokensResp{}, nil
|
||||
}
|
||||
|
||||
+80
-24
@@ -465,7 +465,7 @@ func (g *groupServer) InviteUserToGroup(ctx context.Context, req *pbgroup.Invite
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = g.notification.MemberEnterNotification(ctx, req.GroupID, req.InvitedUserIDs...); err != nil {
|
||||
if err = g.notification.GroupApplicationAgreeMemberEnterNotification(ctx, req.GroupID, opUserID, req.InvitedUserIDs...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &pbgroup.InviteUserToGroupResp{}, nil
|
||||
@@ -1180,36 +1180,53 @@ func (g *groupServer) TransferGroupOwner(ctx context.Context, req *pbgroup.Trans
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if group.Status == constant.GroupStatusDismissed {
|
||||
return nil, servererrs.ErrDismissedAlready.Wrap()
|
||||
}
|
||||
|
||||
if req.OldOwnerUserID == req.NewOwnerUserID {
|
||||
return nil, errs.ErrArgs.WrapMsg("OldOwnerUserID == NewOwnerUserID")
|
||||
}
|
||||
|
||||
members, err := g.db.FindGroupMembers(ctx, req.GroupID, []string{req.OldOwnerUserID, req.NewOwnerUserID})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := g.PopulateGroupMember(ctx, members...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
memberMap := datautil.SliceToMap(members, func(e *model.GroupMember) string { return e.UserID })
|
||||
if ids := datautil.Single([]string{req.OldOwnerUserID, req.NewOwnerUserID}, datautil.Keys(memberMap)); len(ids) > 0 {
|
||||
return nil, errs.ErrArgs.WrapMsg("user not in group " + strings.Join(ids, ","))
|
||||
}
|
||||
|
||||
oldOwner := memberMap[req.OldOwnerUserID]
|
||||
if oldOwner == nil {
|
||||
return nil, errs.ErrArgs.WrapMsg("OldOwnerUserID not in group " + req.NewOwnerUserID)
|
||||
}
|
||||
|
||||
newOwner := memberMap[req.NewOwnerUserID]
|
||||
if newOwner == nil {
|
||||
return nil, errs.ErrArgs.WrapMsg("NewOwnerUser not in group " + req.NewOwnerUserID)
|
||||
}
|
||||
|
||||
if !authverify.IsAppManagerUid(ctx, g.config.Share.IMAdminUserID) {
|
||||
if !(mcontext.GetOpUserID(ctx) == oldOwner.UserID && oldOwner.RoleLevel == constant.GroupOwner) {
|
||||
return nil, errs.ErrNoPermission.WrapMsg("no permission transfer group owner")
|
||||
}
|
||||
}
|
||||
|
||||
if newOwner.MuteEndTime != time.Unix(0, 0) {
|
||||
if _, err := g.CancelMuteGroupMember(ctx, &pbgroup.CancelMuteGroupMemberReq{
|
||||
GroupID: group.GroupID,
|
||||
UserID: req.NewOwnerUserID}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if err := g.db.TransferGroupOwner(ctx, req.GroupID, req.OldOwnerUserID, req.NewOwnerUserID, newOwner.RoleLevel); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1217,6 +1234,7 @@ func (g *groupServer) TransferGroupOwner(ctx context.Context, req *pbgroup.Trans
|
||||
g.webhookAfterTransferGroupOwner(ctx, &g.config.WebhooksConfig.AfterTransferGroupOwner, req)
|
||||
|
||||
g.notification.GroupOwnerTransferredNotification(ctx, req)
|
||||
|
||||
return &pbgroup.TransferGroupOwnerResp{}, nil
|
||||
}
|
||||
|
||||
@@ -1425,32 +1443,38 @@ func (g *groupServer) CancelMuteGroupMember(ctx context.Context, req *pbgroup.Ca
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := g.PopulateGroupMember(ctx, member); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !authverify.IsAppManagerUid(ctx, g.config.Share.IMAdminUserID) {
|
||||
opMember, err := g.db.TakeGroupMember(ctx, req.GroupID, mcontext.GetOpUserID(ctx))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch member.RoleLevel {
|
||||
case constant.GroupOwner:
|
||||
return nil, errs.ErrNoPermission.WrapMsg("set group owner mute")
|
||||
return nil, errs.ErrNoPermission.WrapMsg("Can not set group owner unmute")
|
||||
case constant.GroupAdmin:
|
||||
if opMember.RoleLevel != constant.GroupOwner {
|
||||
return nil, errs.ErrNoPermission.WrapMsg("set group admin mute")
|
||||
return nil, errs.ErrNoPermission.WrapMsg("Can not set group admin unmute")
|
||||
}
|
||||
case constant.GroupOrdinaryUsers:
|
||||
if !(opMember.RoleLevel == constant.GroupAdmin || opMember.RoleLevel == constant.GroupOwner) {
|
||||
return nil, errs.ErrNoPermission.WrapMsg("set group ordinary users mute")
|
||||
return nil, errs.ErrNoPermission.WrapMsg("Can not set group ordinary users unmute")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data := UpdateGroupMemberMutedTimeMap(time.Unix(0, 0))
|
||||
if err := g.db.UpdateGroupMember(ctx, member.GroupID, member.UserID, data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
g.notification.GroupMemberCancelMutedNotification(ctx, req.GroupID, req.UserID)
|
||||
|
||||
return &pbgroup.CancelMuteGroupMemberResp{}, nil
|
||||
}
|
||||
|
||||
@@ -1526,29 +1550,61 @@ func (g *groupServer) SetGroupMemberInfo(ctx context.Context, req *pbgroup.SetGr
|
||||
case 0:
|
||||
if !isAppManagerUid {
|
||||
roleLevel := dbMembers[opUserIndex].RoleLevel
|
||||
if roleLevel != constant.GroupOwner {
|
||||
switch roleLevel {
|
||||
case constant.GroupAdmin:
|
||||
for _, member := range dbMembers {
|
||||
if member.RoleLevel == constant.GroupOwner {
|
||||
return nil, errs.ErrNoPermission.WrapMsg("admin can not change group owner")
|
||||
}
|
||||
if member.RoleLevel == constant.GroupAdmin && member.UserID != opUserID {
|
||||
return nil, errs.ErrNoPermission.WrapMsg("admin can not change other group admin")
|
||||
}
|
||||
var (
|
||||
dbSelf = &model.GroupMember{}
|
||||
reqSelf *pbgroup.SetGroupMemberInfo
|
||||
)
|
||||
switch roleLevel {
|
||||
case constant.GroupOwner:
|
||||
for _, member := range dbMembers {
|
||||
if member.UserID == opUserID {
|
||||
dbSelf = member
|
||||
break
|
||||
}
|
||||
case constant.GroupOrdinaryUsers:
|
||||
for _, member := range dbMembers {
|
||||
if !(member.RoleLevel == constant.GroupOrdinaryUsers && member.UserID == opUserID) {
|
||||
return nil, errs.ErrNoPermission.WrapMsg("ordinary users can not change other role level")
|
||||
}
|
||||
}
|
||||
case constant.GroupAdmin:
|
||||
for _, member := range dbMembers {
|
||||
if member.UserID == opUserID {
|
||||
dbSelf = member
|
||||
}
|
||||
default:
|
||||
for _, member := range dbMembers {
|
||||
if member.RoleLevel >= roleLevel {
|
||||
return nil, errs.ErrNoPermission.WrapMsg("can not change higher role level")
|
||||
}
|
||||
if member.RoleLevel == constant.GroupOwner {
|
||||
return nil, errs.ErrNoPermission.WrapMsg("admin can not change group owner")
|
||||
}
|
||||
if member.RoleLevel == constant.GroupAdmin && member.UserID != opUserID {
|
||||
return nil, errs.ErrNoPermission.WrapMsg("admin can not change other group admin")
|
||||
}
|
||||
}
|
||||
case constant.GroupOrdinaryUsers:
|
||||
for _, member := range dbMembers {
|
||||
if member.UserID == opUserID {
|
||||
dbSelf = member
|
||||
}
|
||||
if !(member.RoleLevel == constant.GroupOrdinaryUsers && member.UserID == opUserID) {
|
||||
return nil, errs.ErrNoPermission.WrapMsg("ordinary users can not change other role level")
|
||||
}
|
||||
}
|
||||
default:
|
||||
for _, member := range dbMembers {
|
||||
if member.UserID == opUserID {
|
||||
dbSelf = member
|
||||
}
|
||||
if member.RoleLevel >= roleLevel {
|
||||
return nil, errs.ErrNoPermission.WrapMsg("can not change higher role level")
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, member := range req.Members {
|
||||
if member.UserID == opUserID {
|
||||
reqSelf = member
|
||||
break
|
||||
}
|
||||
}
|
||||
if reqSelf != nil && reqSelf.RoleLevel != nil {
|
||||
if reqSelf.RoleLevel.GetValue() > dbSelf.RoleLevel {
|
||||
return nil, errs.ErrNoPermission.WrapMsg("can not improve role level by self")
|
||||
}
|
||||
if roleLevel == constant.GroupOwner {
|
||||
return nil, errs.ErrArgs.WrapMsg("group owner can not change own role level") // Prevent the absence of a group owner
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ import (
|
||||
"github.com/openimsdk/tools/utils/datautil"
|
||||
"github.com/openimsdk/tools/utils/stringutil"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"time"
|
||||
)
|
||||
|
||||
// GroupApplicationReceiver
|
||||
@@ -572,8 +573,51 @@ func (g *GroupNotificationSender) GroupApplicationAgreeMemberEnterNotification(c
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *GroupNotificationSender) MemberEnterNotification(ctx context.Context, groupID string, entrantUserID ...string) error {
|
||||
return g.GroupApplicationAgreeMemberEnterNotification(ctx, groupID, "", entrantUserID...)
|
||||
func (g *GroupNotificationSender) MemberEnterNotification(ctx context.Context, groupID string, entrantUserID string) error {
|
||||
var err error
|
||||
defer func() {
|
||||
if err != nil {
|
||||
log.ZError(ctx, stringutil.GetFuncName(1)+" failed", err)
|
||||
}
|
||||
}()
|
||||
|
||||
if !g.config.RpcConfig.EnableHistoryForNewMembers {
|
||||
conversationID := msgprocessor.GetConversationIDBySessionType(constant.ReadGroupChatType, groupID)
|
||||
maxSeq, err := g.msgRpcClient.GetConversationMaxSeq(ctx, conversationID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = g.msgRpcClient.SetUserConversationsMinSeq(ctx, &msg.SetUserConversationsMinSeqReq{
|
||||
UserIDs: []string{entrantUserID},
|
||||
ConversationID: conversationID,
|
||||
Seq: maxSeq,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := g.conversationRpcClient.GroupChatFirstCreateConversation(ctx, groupID, []string{entrantUserID}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var group *sdkws.GroupInfo
|
||||
group, err = g.getGroupInfo(ctx, groupID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
user, err := g.getGroupMember(ctx, groupID, entrantUserID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tips := &sdkws.MemberEnterTips{
|
||||
Group: group,
|
||||
EntrantUser: user,
|
||||
OperationTime: time.Now().UnixMilli(),
|
||||
}
|
||||
g.setVersion(ctx, &tips.GroupMemberVersion, &tips.GroupMemberVersionID, database.GroupMemberVersionName, tips.Group.GroupID)
|
||||
g.Notification(ctx, mcontext.GetOpUserID(ctx), group.GroupID, constant.MemberEnterNotification, tips)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *GroupNotificationSender) GroupDismissedNotification(ctx context.Context, tips *sdkws.GroupDismissedTips) {
|
||||
|
||||
@@ -29,7 +29,6 @@ import (
|
||||
"github.com/openimsdk/tools/log"
|
||||
"github.com/openimsdk/tools/mcontext"
|
||||
"github.com/openimsdk/tools/utils/datautil"
|
||||
"github.com/openimsdk/tools/utils/stringutil"
|
||||
)
|
||||
|
||||
func (m *msgServer) SendMsg(ctx context.Context, req *pbmsg.SendMsgReq) (*pbmsg.SendMsgResp, error) {
|
||||
@@ -80,13 +79,17 @@ func (m *msgServer) sendMsgGroupChat(ctx context.Context, req *pbmsg.SendMsgReq)
|
||||
|
||||
func (m *msgServer) setConversationAtInfo(nctx context.Context, msg *sdkws.MsgData) {
|
||||
log.ZDebug(nctx, "setConversationAtInfo", "msg", msg)
|
||||
|
||||
ctx := mcontext.NewCtx("@@@" + mcontext.GetOperationID(nctx))
|
||||
|
||||
var atUserID []string
|
||||
|
||||
conversation := &pbconversation.ConversationReq{
|
||||
ConversationID: msgprocessor.GetConversationIDByMsg(msg),
|
||||
ConversationType: msg.SessionType,
|
||||
GroupID: msg.GroupID,
|
||||
}
|
||||
|
||||
tagAll := datautil.Contain(constant.AtAllString, msg.AtUserIDList...)
|
||||
if tagAll {
|
||||
memberUserIDList, err := m.GroupLocalCache.GetGroupMemberIDs(ctx, msg.GroupID)
|
||||
@@ -94,25 +97,35 @@ func (m *msgServer) setConversationAtInfo(nctx context.Context, msg *sdkws.MsgDa
|
||||
log.ZWarn(ctx, "GetGroupMemberIDs", err)
|
||||
return
|
||||
}
|
||||
atUserID = stringutil.DifferenceString([]string{constant.AtAllString}, msg.AtUserIDList)
|
||||
|
||||
memberUserIDList = datautil.DeleteElems(memberUserIDList, msg.SendID)
|
||||
|
||||
atUserID = datautil.Single([]string{constant.AtAllString}, msg.AtUserIDList)
|
||||
|
||||
if len(atUserID) == 0 { // just @everyone
|
||||
conversation.GroupAtType = &wrapperspb.Int32Value{Value: constant.AtAll}
|
||||
} else { // @Everyone and @other people
|
||||
conversation.GroupAtType = &wrapperspb.Int32Value{Value: constant.AtAllAtMe}
|
||||
|
||||
err = m.Conversation.SetConversations(ctx, atUserID, conversation)
|
||||
if err != nil {
|
||||
log.ZWarn(ctx, "SetConversations", err, "userID", atUserID, "conversation", conversation)
|
||||
}
|
||||
memberUserIDList = stringutil.DifferenceString(atUserID, memberUserIDList)
|
||||
|
||||
memberUserIDList = datautil.Single(atUserID, memberUserIDList)
|
||||
}
|
||||
|
||||
conversation.GroupAtType = &wrapperspb.Int32Value{Value: constant.AtAll}
|
||||
|
||||
err = m.Conversation.SetConversations(ctx, memberUserIDList, conversation)
|
||||
if err != nil {
|
||||
log.ZWarn(ctx, "SetConversations", err, "userID", memberUserIDList, "conversation", conversation)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
conversation.GroupAtType = &wrapperspb.Int32Value{Value: constant.AtMe}
|
||||
|
||||
err := m.Conversation.SetConversations(ctx, msg.AtUserIDList, conversation)
|
||||
if err != nil {
|
||||
log.ZWarn(ctx, "SetConversations", err, msg.AtUserIDList, conversation)
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
package third
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
|
||||
"github.com/openimsdk/protocol/third"
|
||||
"github.com/openimsdk/tools/errs"
|
||||
"github.com/openimsdk/tools/utils/datautil"
|
||||
"github.com/redis/go-redis/v9"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"time"
|
||||
)
|
||||
|
||||
func IsNotFound(err error) bool {
|
||||
switch errs.Unwrap(err) {
|
||||
case redis.Nil, mongo.ErrNoDocuments:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (t *thirdServer) db2pbApplication(val *model.Application) *third.ApplicationVersion {
|
||||
return &third.ApplicationVersion{
|
||||
Id: val.ID.Hex(),
|
||||
Platform: val.Platform,
|
||||
Version: val.Version,
|
||||
Url: val.Url,
|
||||
Text: val.Text,
|
||||
Force: val.Force,
|
||||
Latest: val.Latest,
|
||||
CreateTime: val.CreateTime.UnixMilli(),
|
||||
}
|
||||
}
|
||||
|
||||
func (t *thirdServer) LatestApplicationVersion(ctx context.Context, req *third.LatestApplicationVersionReq) (*third.LatestApplicationVersionResp, error) {
|
||||
res, err := t.applicationDatabase.LatestVersion(ctx, req.Platform)
|
||||
if err == nil {
|
||||
return &third.LatestApplicationVersionResp{Version: t.db2pbApplication(res)}, nil
|
||||
} else if IsNotFound(err) {
|
||||
return &third.LatestApplicationVersionResp{}, nil
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
func (t *thirdServer) AddApplicationVersion(ctx context.Context, req *third.AddApplicationVersionReq) (*third.AddApplicationVersionResp, error) {
|
||||
if err := authverify.CheckAdmin(ctx, t.config.Share.IMAdminUserID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
val := &model.Application{
|
||||
ID: primitive.NewObjectID(),
|
||||
Platform: req.Platform,
|
||||
Version: req.Version,
|
||||
Url: req.Url,
|
||||
Text: req.Text,
|
||||
Force: req.Force,
|
||||
Latest: req.Latest,
|
||||
CreateTime: time.Now(),
|
||||
}
|
||||
if err := t.applicationDatabase.AddVersion(ctx, val); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &third.AddApplicationVersionResp{}, nil
|
||||
}
|
||||
|
||||
func (t *thirdServer) UpdateApplicationVersion(ctx context.Context, req *third.UpdateApplicationVersionReq) (*third.UpdateApplicationVersionResp, error) {
|
||||
if err := authverify.CheckAdmin(ctx, t.config.Share.IMAdminUserID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
oid, err := primitive.ObjectIDFromHex(req.Id)
|
||||
if err != nil {
|
||||
return nil, errs.ErrArgs.WrapMsg("invalid id " + err.Error())
|
||||
}
|
||||
update := make(map[string]any)
|
||||
putUpdate(update, "platform", req.Platform)
|
||||
putUpdate(update, "version", req.Version)
|
||||
putUpdate(update, "url", req.Url)
|
||||
putUpdate(update, "text", req.Text)
|
||||
putUpdate(update, "force", req.Force)
|
||||
putUpdate(update, "latest", req.Latest)
|
||||
if err := t.applicationDatabase.UpdateVersion(ctx, oid, update); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &third.UpdateApplicationVersionResp{}, nil
|
||||
}
|
||||
|
||||
func (t *thirdServer) DeleteApplicationVersion(ctx context.Context, req *third.DeleteApplicationVersionReq) (*third.DeleteApplicationVersionResp, error) {
|
||||
if err := authverify.CheckAdmin(ctx, t.config.Share.IMAdminUserID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ids := make([]primitive.ObjectID, 0, len(req.Id))
|
||||
for _, id := range req.Id {
|
||||
oid, err := primitive.ObjectIDFromHex(id)
|
||||
if err != nil {
|
||||
return nil, errs.ErrArgs.WrapMsg("invalid id " + err.Error())
|
||||
}
|
||||
ids = append(ids, oid)
|
||||
}
|
||||
if err := t.applicationDatabase.DeleteVersion(ctx, ids); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &third.DeleteApplicationVersionResp{}, nil
|
||||
}
|
||||
|
||||
func (t *thirdServer) PageApplicationVersion(ctx context.Context, req *third.PageApplicationVersionReq) (*third.PageApplicationVersionResp, error) {
|
||||
total, res, err := t.applicationDatabase.PageVersion(ctx, req.Platform, req.Pagination)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &third.PageApplicationVersionResp{
|
||||
Total: total,
|
||||
Versions: datautil.Slice(res, t.db2pbApplication),
|
||||
}, nil
|
||||
}
|
||||
+19
-12
@@ -38,12 +38,13 @@ import (
|
||||
)
|
||||
|
||||
type thirdServer struct {
|
||||
thirdDatabase controller.ThirdDatabase
|
||||
s3dataBase controller.S3Database
|
||||
userRpcClient rpcclient.UserRpcClient
|
||||
defaultExpire time.Duration
|
||||
config *Config
|
||||
minio *minio.Minio
|
||||
thirdDatabase controller.ThirdDatabase
|
||||
s3dataBase controller.S3Database
|
||||
userRpcClient rpcclient.UserRpcClient
|
||||
defaultExpire time.Duration
|
||||
config *Config
|
||||
minio *minio.Minio
|
||||
applicationDatabase controller.ApplicationDatabase
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
@@ -74,6 +75,11 @@ func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryReg
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
applicationMgo, err := mgo.NewApplicationMgo(mgocli.GetDB())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Select the oss method according to the profile policy
|
||||
enable := config.RpcConfig.Object.Enable
|
||||
var (
|
||||
@@ -98,12 +104,13 @@ func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryReg
|
||||
}
|
||||
localcache.InitLocalCache(&config.LocalCacheConfig)
|
||||
third.RegisterThirdServer(server, &thirdServer{
|
||||
thirdDatabase: controller.NewThirdDatabase(redis.NewThirdCache(rdb), logdb),
|
||||
userRpcClient: rpcclient.NewUserRpcClient(client, config.Share.RpcRegisterName.User, config.Share.IMAdminUserID),
|
||||
s3dataBase: controller.NewS3Database(rdb, o, s3db),
|
||||
defaultExpire: time.Hour * 24 * 7,
|
||||
config: config,
|
||||
minio: minioCli,
|
||||
thirdDatabase: controller.NewThirdDatabase(redis.NewThirdCache(rdb), logdb),
|
||||
userRpcClient: rpcclient.NewUserRpcClient(client, config.Share.RpcRegisterName.User, config.Share.IMAdminUserID),
|
||||
s3dataBase: controller.NewS3Database(rdb, o, s3db),
|
||||
defaultExpire: time.Hour * 24 * 7,
|
||||
config: config,
|
||||
minio: minioCli,
|
||||
applicationDatabase: controller.NewApplicationDatabase(applicationMgo, redis.NewApplicationRedisCache(applicationMgo, rdb)),
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -82,3 +82,11 @@ func checkValidObjectName(objectName string) error {
|
||||
func (t *thirdServer) IsManagerUserID(opUserID string) bool {
|
||||
return authverify.IsManagerUserID(opUserID, t.config.Share.IMAdminUserID)
|
||||
}
|
||||
|
||||
func putUpdate[T any](update map[string]any, name string, val interface{ GetValuePtr() *T }) {
|
||||
ptrVal := val.GetValuePtr()
|
||||
if ptrVal == nil {
|
||||
return
|
||||
}
|
||||
update[name] = *ptrVal
|
||||
}
|
||||
|
||||
@@ -116,18 +116,17 @@ func Start(ctx context.Context, config *Config, client registry.SvcDiscoveryRegi
|
||||
|
||||
func (s *userServer) GetDesignateUsers(ctx context.Context, req *pbuser.GetDesignateUsersReq) (resp *pbuser.GetDesignateUsersResp, err error) {
|
||||
resp = &pbuser.GetDesignateUsersResp{}
|
||||
users, err := s.db.FindWithError(ctx, req.UserIDs)
|
||||
users, err := s.db.Find(ctx, req.UserIDs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp.UsersInfo = convert.UsersDB2Pb(users)
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// deprecated:
|
||||
|
||||
//UpdateUserInfo
|
||||
|
||||
// UpdateUserInfo
|
||||
func (s *userServer) UpdateUserInfo(ctx context.Context, req *pbuser.UpdateUserInfoReq) (resp *pbuser.UpdateUserInfoResp, err error) {
|
||||
resp = &pbuser.UpdateUserInfoResp{}
|
||||
err = authverify.CheckAccessV3(ctx, req.UserInfo.UserID, s.config.Share.IMAdminUserID)
|
||||
|
||||
Reference in New Issue
Block a user