mirror of
https://github.com/openimsdk/open-im-server.git
synced 2026-06-28 21:58:17 +08:00
用户设置
This commit is contained in:
parent
33e2a71362
commit
42064d31a7
@ -159,6 +159,11 @@ func newGinRouter(ctx context.Context, client discovery.SvcDiscoveryRegistry, co
|
||||
userRouterGroup.POST("/update_notification_account", u.UpdateNotificationAccountInfo)
|
||||
userRouterGroup.POST("/search_notification_account", u.SearchNotificationAccount)
|
||||
|
||||
// 手机号可见性设置(所有人/仅好友/隐藏)
|
||||
userRouterGroup.POST("/set_phone_visibility", u.SetPhoneVisibility)
|
||||
userRouterGroup.POST("/set_call_accept_setting", u.SetCallAcceptSetting)
|
||||
userRouterGroup.POST("/set_msg_receive_setting", u.SetMsgReceiveSetting)
|
||||
|
||||
// 全局黑名单管理(仅管理员)
|
||||
userRouterGroup.POST("/add_global_blacklist", bl.AddGlobalBlacklist)
|
||||
userRouterGroup.POST("/remove_global_blacklist", bl.RemoveGlobalBlacklist)
|
||||
|
||||
@ -305,3 +305,15 @@ func (u *UserApi) UpdateNotificationAccountInfo(c *gin.Context) {
|
||||
func (u *UserApi) SearchNotificationAccount(c *gin.Context) {
|
||||
a2r.Call(c, user.UserClient.SearchNotificationAccount, u.Client)
|
||||
}
|
||||
|
||||
func (u *UserApi) SetPhoneVisibility(c *gin.Context) {
|
||||
a2r.Call(c, user.UserClient.SetPhoneVisibility, u.Client)
|
||||
}
|
||||
|
||||
func (u *UserApi) SetCallAcceptSetting(c *gin.Context) {
|
||||
a2r.Call(c, user.UserClient.SetCallAcceptSetting, u.Client)
|
||||
}
|
||||
|
||||
func (u *UserApi) SetMsgReceiveSetting(c *gin.Context) {
|
||||
a2r.Call(c, user.UserClient.SetMsgReceiveSetting, u.Client)
|
||||
}
|
||||
|
||||
@ -38,6 +38,10 @@ func (s *groupServer) groupDB2PB(group *model.Group, ownerUserID string, memberC
|
||||
ApplyMemberFriend: group.ApplyMemberFriend,
|
||||
NotificationUpdateTime: group.NotificationUpdateTime.UnixMilli(),
|
||||
NotificationUserID: group.NotificationUserID,
|
||||
AllowSendMsg: group.AllowSendMsg,
|
||||
AllowPinMsg: group.AllowPinMsg,
|
||||
AllowAddMember: group.AllowAddMember,
|
||||
AllowEditGroupInfo: group.AllowEditGroupInfo,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -53,6 +53,18 @@ func UpdateGroupInfoMap(ctx context.Context, group *sdkws.GroupInfoForSet) map[s
|
||||
if group.Ex != nil {
|
||||
m["ex"] = group.Ex.Value
|
||||
}
|
||||
if group.AllowSendMsg != nil {
|
||||
m["allow_send_msg"] = group.AllowSendMsg.Value
|
||||
}
|
||||
if group.AllowPinMsg != nil {
|
||||
m["allow_pin_msg"] = group.AllowPinMsg.Value
|
||||
}
|
||||
if group.AllowAddMember != nil {
|
||||
m["allow_add_member"] = group.AllowAddMember.Value
|
||||
}
|
||||
if group.AllowEditGroupInfo != nil {
|
||||
m["allow_edit_group_info"] = group.AllowEditGroupInfo.Value
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
@ -100,6 +112,22 @@ func UpdateGroupInfoExMap(ctx context.Context, group *pbgroup.SetGroupInfoExReq)
|
||||
m["ex"] = group.Ex.Value
|
||||
normalFlag = true
|
||||
}
|
||||
if group.AllowSendMsg != nil {
|
||||
m["allow_send_msg"] = group.AllowSendMsg.Value
|
||||
normalFlag = true
|
||||
}
|
||||
if group.AllowPinMsg != nil {
|
||||
m["allow_pin_msg"] = group.AllowPinMsg.Value
|
||||
normalFlag = true
|
||||
}
|
||||
if group.AllowAddMember != nil {
|
||||
m["allow_add_member"] = group.AllowAddMember.Value
|
||||
normalFlag = true
|
||||
}
|
||||
if group.AllowEditGroupInfo != nil {
|
||||
m["allow_edit_group_info"] = group.AllowEditGroupInfo.Value
|
||||
normalFlag = true
|
||||
}
|
||||
|
||||
return m, normalFlag, groupNameFlag, notificationFlag, nil
|
||||
}
|
||||
|
||||
@ -458,6 +458,11 @@ func (s *groupServer) InviteUserToGroup(ctx context.Context, req *pbgroup.Invite
|
||||
if err := s.PopulateGroupMember(ctx, groupMember); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// AllowAddMember == 1 时仅群主/管理员可拉人
|
||||
isOwnerOrAdmin := groupMember.RoleLevel == constant.GroupOwner || groupMember.RoleLevel == constant.GroupAdmin
|
||||
if group.AllowAddMember == model.GroupPermAdminOnly && !isOwnerOrAdmin {
|
||||
return nil, errs.ErrNoPermission.WrapMsg("only owner or admin can add members to this group")
|
||||
}
|
||||
} else {
|
||||
opUserID = mcontext.GetOpUserID(ctx)
|
||||
}
|
||||
@ -1098,8 +1103,22 @@ func (s *groupServer) SetGroupInfo(ctx context.Context, req *pbgroup.SetGroupInf
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !(opMember.RoleLevel == constant.GroupOwner || opMember.RoleLevel == constant.GroupAdmin) {
|
||||
return nil, errs.ErrNoPermission.WrapMsg("no group owner or admin")
|
||||
isOwnerOrAdmin := opMember.RoleLevel == constant.GroupOwner || opMember.RoleLevel == constant.GroupAdmin
|
||||
requestsPermField := req.GroupInfoForSet.AllowSendMsg != nil ||
|
||||
req.GroupInfoForSet.AllowPinMsg != nil ||
|
||||
req.GroupInfoForSet.AllowAddMember != nil ||
|
||||
req.GroupInfoForSet.AllowEditGroupInfo != nil
|
||||
if requestsPermField && !isOwnerOrAdmin {
|
||||
return nil, errs.ErrNoPermission.WrapMsg("only owner or admin can change group permission settings")
|
||||
}
|
||||
if !isOwnerOrAdmin {
|
||||
grp, err := s.db.TakeGroup(ctx, req.GroupInfoForSet.GroupID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if grp.AllowEditGroupInfo == model.GroupPermAdminOnly {
|
||||
return nil, errs.ErrNoPermission.WrapMsg("only owner or admin can edit group info")
|
||||
}
|
||||
}
|
||||
if err := s.PopulateGroupMember(ctx, opMember); err != nil {
|
||||
return nil, err
|
||||
@ -1193,9 +1212,24 @@ func (s *groupServer) SetGroupInfoEx(ctx context.Context, req *pbgroup.SetGroupI
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !(opMember.RoleLevel == constant.GroupOwner || opMember.RoleLevel == constant.GroupAdmin) {
|
||||
return nil, errs.ErrNoPermission.WrapMsg("no group owner or admin")
|
||||
isOwnerOrAdmin := opMember.RoleLevel == constant.GroupOwner || opMember.RoleLevel == constant.GroupAdmin
|
||||
// 4个群权限字段始终只有群主/管理员可修改
|
||||
requestsPermField := req.AllowSendMsg != nil ||
|
||||
req.AllowPinMsg != nil ||
|
||||
req.AllowAddMember != nil ||
|
||||
req.AllowEditGroupInfo != nil
|
||||
if requestsPermField && !isOwnerOrAdmin {
|
||||
return nil, errs.ErrNoPermission.WrapMsg("only owner or admin can change group permission settings")
|
||||
}
|
||||
// 其他字段:按 AllowEditGroupInfo 决定是否允许普通成员操作
|
||||
if !isOwnerOrAdmin {
|
||||
grp, err := s.db.TakeGroup(ctx, req.GroupID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if grp.AllowEditGroupInfo == model.GroupPermAdminOnly {
|
||||
return nil, errs.ErrNoPermission.WrapMsg("only owner or admin can edit group info")
|
||||
}
|
||||
}
|
||||
|
||||
if err := s.PopulateGroupMember(ctx, opMember); err != nil {
|
||||
|
||||
@ -59,9 +59,7 @@ func (m *msgServer) messageVerification(ctx context.Context, data *msg.SendMsgRe
|
||||
data.MsgData.ContentType >= constant.NotificationBegin {
|
||||
return nil
|
||||
}
|
||||
if err := m.webhookBeforeSendSingleMsg(ctx, &m.config.WebhooksConfig.BeforeSendSingleMsg, data); err != nil {
|
||||
return err
|
||||
}
|
||||
// 先做本地轻量级拦截(黑名单 + 消息接收权限),避免不必要的 webhook 触发
|
||||
black, err := m.FriendLocalCache.IsBlack(ctx, data.MsgData.SendID, data.MsgData.RecvID)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -69,6 +67,33 @@ func (m *msgServer) messageVerification(ctx context.Context, data *msg.SendMsgRe
|
||||
if black {
|
||||
return servererrs.ErrBlockedByPeer.Wrap()
|
||||
}
|
||||
// 校验接收方消息接收权限(MsgReceiveSetting)
|
||||
// 0=所有人可发送,1=仅好友可发送,2=所有人不可发送
|
||||
recvUserInfo, err := m.UserLocalCache.GetUserInfo(ctx, data.MsgData.RecvID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch recvUserInfo.MsgReceiveSetting {
|
||||
case 2: // MsgReceiveSettingNobody
|
||||
return servererrs.ErrMsgReceiveNotAllowed.Wrap()
|
||||
case 1: // MsgReceiveSettingFriends
|
||||
isFriend, err := m.FriendLocalCache.IsFriend(ctx, data.MsgData.RecvID, data.MsgData.SendID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !isFriend {
|
||||
return servererrs.ErrMsgReceiveNotAllowed.Wrap()
|
||||
}
|
||||
// 已确认是好友,触发 webhook 后放行,不做 FriendVerify 冗余查询
|
||||
if err := m.webhookBeforeSendSingleMsg(ctx, &m.config.WebhooksConfig.BeforeSendSingleMsg, data); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
// MsgReceiveSetting==0(所有人可发),触发 webhook,再按全局 FriendVerify 兜底
|
||||
if err := m.webhookBeforeSendSingleMsg(ctx, &m.config.WebhooksConfig.BeforeSendSingleMsg, data); err != nil {
|
||||
return err
|
||||
}
|
||||
if m.config.RpcConfig.FriendVerify {
|
||||
friend, err := m.FriendLocalCache.IsFriend(ctx, data.MsgData.SendID, data.MsgData.RecvID)
|
||||
if err != nil {
|
||||
@ -77,7 +102,6 @@ func (m *msgServer) messageVerification(ctx context.Context, data *msg.SendMsgRe
|
||||
if !friend {
|
||||
return servererrs.ErrNotPeersFriend.Wrap()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
case constant.ReadGroupChatType:
|
||||
@ -124,6 +148,10 @@ func (m *msgServer) messageVerification(ctx context.Context, data *msg.SendMsgRe
|
||||
if groupInfo.Status == constant.GroupStatusMuted && groupMemberInfo.RoleLevel != constant.GroupAdmin {
|
||||
return servererrs.ErrMutedGroup.Wrap()
|
||||
}
|
||||
// AllowSendMsg == 1 时仅群主/管理员可发消息
|
||||
if groupInfo.AllowSendMsg == 1 && groupMemberInfo.RoleLevel != constant.GroupAdmin {
|
||||
return servererrs.ErrNoPermission.WrapMsg("only owner or admin can send messages in this group")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
default:
|
||||
|
||||
@ -39,12 +39,13 @@ type Config struct {
|
||||
|
||||
type rtcServer struct {
|
||||
rtc.UnimplementedRtcServiceServer
|
||||
config *Config
|
||||
db controller.RtcDatabase
|
||||
roomClient *lksdk.RoomServiceClient
|
||||
msgClient *rpcli.MsgClient
|
||||
userClient *rpcli.UserClient
|
||||
tokenExpiry time.Duration
|
||||
config *Config
|
||||
db controller.RtcDatabase
|
||||
roomClient *lksdk.RoomServiceClient
|
||||
msgClient *rpcli.MsgClient
|
||||
userClient *rpcli.UserClient
|
||||
relationClient *rpcli.RelationClient
|
||||
tokenExpiry time.Duration
|
||||
}
|
||||
|
||||
// Start initialises the RTC gRPC service and registers it with the gRPC server.
|
||||
@ -69,6 +70,11 @@ func Start(ctx context.Context, cfg *Config, client discovery.SvcDiscoveryRegist
|
||||
return err
|
||||
}
|
||||
|
||||
friendConn, err := client.GetConn(ctx, cfg.Share.RpcRegisterName.Friend)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
lk := cfg.RpcConfig.LiveKit
|
||||
roomClient := lksdk.NewRoomServiceClient(lk.InternalAddress, lk.APIKey, lk.APISecret)
|
||||
|
||||
@ -78,12 +84,13 @@ func Start(ctx context.Context, cfg *Config, client discovery.SvcDiscoveryRegist
|
||||
}
|
||||
|
||||
s := &rtcServer{
|
||||
config: cfg,
|
||||
db: controller.NewRtcDatabase(signalDB),
|
||||
roomClient: roomClient,
|
||||
msgClient: rpcli.NewMsgClient(msgConn),
|
||||
userClient: rpcli.NewUserClient(userConn),
|
||||
tokenExpiry: tokenExpiry,
|
||||
config: cfg,
|
||||
db: controller.NewRtcDatabase(signalDB),
|
||||
roomClient: roomClient,
|
||||
msgClient: rpcli.NewMsgClient(msgConn),
|
||||
userClient: rpcli.NewUserClient(userConn),
|
||||
relationClient: rpcli.NewRelationClient(friendConn),
|
||||
tokenExpiry: tokenExpiry,
|
||||
}
|
||||
|
||||
rtc.RegisterRtcServiceServer(server, s)
|
||||
|
||||
@ -99,6 +99,18 @@ func (s *rtcServer) handleInvite(ctx context.Context, req *rtc.SignalInviteReq,
|
||||
inv.InviterUserID = req.UserID
|
||||
inv.InitiateTime = time.Now().UnixMilli()
|
||||
|
||||
// 校验每位被邀请者的通话接受权限,1-to-1 场景:有任一被邀请者拒绝则直接返错
|
||||
for _, inviteeID := range inv.InviteeUserIDList {
|
||||
allowed, err := s.isCallAllowed(ctx, req.UserID, inviteeID)
|
||||
if err != nil {
|
||||
log.ZError(ctx, "handleInvite: isCallAllowed failed", err, "inviteeID", inviteeID)
|
||||
return nil, err
|
||||
}
|
||||
if !allowed {
|
||||
return nil, errs.ErrNoPermission.WrapMsg("the invitee does not accept calls from you", "inviteeID", inviteeID)
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := s.roomClient.CreateRoom(ctx, &livekit.CreateRoomRequest{Name: inv.RoomID}); err != nil {
|
||||
log.ZError(ctx, "handleInvite", err, "r", err.Error())
|
||||
return nil, errs.WrapMsg(err, "LiveKit CreateRoom failed", "roomID", inv.RoomID)
|
||||
@ -157,6 +169,15 @@ func (s *rtcServer) handleInviteInGroup(ctx context.Context, req *rtc.SignalInvi
|
||||
|
||||
content := marshalSignalReq(signalReq)
|
||||
for _, inviteeID := range inv.InviteeUserIDList {
|
||||
allowed, err := s.isCallAllowed(ctx, req.UserID, inviteeID)
|
||||
if err != nil {
|
||||
log.ZWarn(ctx, "handleInviteInGroup: isCallAllowed failed, skipping invitee", err, "inviteeID", inviteeID)
|
||||
continue
|
||||
}
|
||||
if !allowed {
|
||||
log.ZInfo(ctx, "handleInviteInGroup: skipping invitee (call setting blocked)", "inviteeID", inviteeID)
|
||||
continue
|
||||
}
|
||||
if err := s.sendSignalingNotification(ctx, req.UserID, inviteeID, int32(constant.ReadGroupChatType), req.OfflinePushInfo, content); err != nil {
|
||||
log.ZWarn(ctx, "sendSignalingNotification to group invitee failed", err, "inviteeID", inviteeID)
|
||||
}
|
||||
@ -169,6 +190,30 @@ func (s *rtcServer) handleInviteInGroup(ctx context.Context, req *rtc.SignalInvi
|
||||
}, nil
|
||||
}
|
||||
|
||||
// isCallAllowed 判断 inviterID 是否被允许向 inviteeID 发起音视频通话。
|
||||
// 规则:
|
||||
// - CallAcceptSettingPublic(0) → 所有人均可
|
||||
// - CallAcceptSettingFriends(1) → 仅当 inviterID 在 inviteeID 好友列表中
|
||||
// - CallAcceptSettingNobody(2) → 任何人均不可
|
||||
func (s *rtcServer) isCallAllowed(ctx context.Context, inviterID, inviteeID string) (bool, error) {
|
||||
userInfo, err := s.userClient.GetUserInfo(ctx, inviteeID)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
switch userInfo.CallAcceptSetting {
|
||||
case model.CallAcceptSettingNobody:
|
||||
return false, nil
|
||||
case model.CallAcceptSettingFriends:
|
||||
isFriend, err := s.relationClient.IsFriend(ctx, inviteeID, inviterID)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return isFriend, nil
|
||||
default: // CallAcceptSettingPublic
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
// handleAccept processes a call acceptance.
|
||||
func (s *rtcServer) handleAccept(ctx context.Context, req *rtc.SignalAcceptReq, signalReq *rtc.SignalReq) (*rtc.SignalAcceptResp, error) {
|
||||
inv := req.Invitation
|
||||
|
||||
@ -35,6 +35,7 @@ import (
|
||||
"github.com/openimsdk/protocol/group"
|
||||
friendpb "github.com/openimsdk/protocol/relation"
|
||||
"github.com/openimsdk/tools/db/redisutil"
|
||||
"github.com/openimsdk/tools/mcontext"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/convert"
|
||||
@ -149,10 +150,50 @@ func (s *userServer) GetDesignateUsers(ctx context.Context, req *pbuser.GetDesig
|
||||
return nil, servererrs.ErrUserBlocked.WrapMsg("user is banned", "userIDs", bannedIDs)
|
||||
}
|
||||
|
||||
resp.UsersInfo = convert.UsersDB2Pb(users)
|
||||
pbUsers := convert.UsersDB2Pb(users)
|
||||
viewerID := mcontext.GetOpUserID(ctx)
|
||||
if err := s.applyPhoneVisibility(ctx, viewerID, pbUsers, users); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp.UsersInfo = pbUsers
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// applyPhoneVisibility 根据 phone_visibility 和好友关系决定是否下发明文手机号。
|
||||
// pbUsers 与 dbUsers 下标一一对应。
|
||||
func (s *userServer) applyPhoneVisibility(ctx context.Context, viewerID string, pbUsers []*sdkws.UserInfo, dbUsers []*tablerelation.User) error {
|
||||
for i, db := range dbUsers {
|
||||
pb := pbUsers[i]
|
||||
if db.Phone == "" {
|
||||
// 未设置手机号,直接跳过
|
||||
continue
|
||||
}
|
||||
switch db.PhoneVisibility {
|
||||
case tablerelation.PhoneVisibilityPublic:
|
||||
// 所有人可见,保留 phone 字段(已由 UserDB2Pb 填充)
|
||||
case tablerelation.PhoneVisibilityHidden:
|
||||
// 完全隐藏:即使本人也不通过此接口暴露,客户端自行从个人设置接口获取
|
||||
pb.Phone = ""
|
||||
case tablerelation.PhoneVisibilityFriends:
|
||||
// 仅好友可见
|
||||
if viewerID == db.UserID {
|
||||
// 本人始终可见
|
||||
break
|
||||
}
|
||||
isFriend, err := s.relationClient.IsFriend(ctx, viewerID, db.UserID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !isFriend {
|
||||
pb.Phone = ""
|
||||
}
|
||||
default:
|
||||
pb.Phone = ""
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// deprecated:
|
||||
// UpdateUserInfo
|
||||
func (s *userServer) UpdateUserInfo(ctx context.Context, req *pbuser.UpdateUserInfoReq) (resp *pbuser.UpdateUserInfoResp, err error) {
|
||||
@ -237,6 +278,82 @@ func (s *userServer) SetGlobalRecvMessageOpt(ctx context.Context, req *pbuser.Se
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// SetPhoneVisibility 设置手机号及其可见性(0=所有人,1=仅好友,2=隐藏)。
|
||||
// 只允许本人或管理员操作。
|
||||
func (s *userServer) SetPhoneVisibility(ctx context.Context, req *pbuser.SetPhoneVisibilityReq) (*pbuser.SetPhoneVisibilityResp, error) {
|
||||
if req.UserID == "" {
|
||||
return nil, errs.ErrArgs.WrapMsg("userID is required")
|
||||
}
|
||||
if req.PhoneVisibility < 0 || req.PhoneVisibility > 2 {
|
||||
return nil, errs.ErrArgs.WrapMsg("phoneVisibility must be 0, 1 or 2")
|
||||
}
|
||||
if err := authverify.CheckAccessV3(ctx, req.UserID, s.config.Share.IMAdminUserID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, err := s.db.FindWithError(ctx, []string{req.UserID}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m := map[string]any{
|
||||
"phone_visibility": req.PhoneVisibility,
|
||||
}
|
||||
if req.Phone != "" {
|
||||
m["phone"] = req.Phone
|
||||
}
|
||||
if err := s.db.UpdateByMap(ctx, req.UserID, m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.friendNotificationSender.UserInfoUpdatedNotification(ctx, req.UserID)
|
||||
return &pbuser.SetPhoneVisibilityResp{}, nil
|
||||
}
|
||||
|
||||
// SetCallAcceptSetting 设置音视频通话接受权限(0=所有人,1=仅好友,2=不接受任何通话)。
|
||||
// 只允许本人或管理员操作。
|
||||
func (s *userServer) SetCallAcceptSetting(ctx context.Context, req *pbuser.SetCallAcceptSettingReq) (*pbuser.SetCallAcceptSettingResp, error) {
|
||||
if req.UserID == "" {
|
||||
return nil, errs.ErrArgs.WrapMsg("userID is required")
|
||||
}
|
||||
if req.CallAcceptSetting < 0 || req.CallAcceptSetting > 2 {
|
||||
return nil, errs.ErrArgs.WrapMsg("callAcceptSetting must be 0, 1 or 2")
|
||||
}
|
||||
if err := authverify.CheckAccessV3(ctx, req.UserID, s.config.Share.IMAdminUserID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, err := s.db.FindWithError(ctx, []string{req.UserID}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := s.db.UpdateByMap(ctx, req.UserID, map[string]any{
|
||||
"call_accept_setting": req.CallAcceptSetting,
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.friendNotificationSender.UserInfoUpdatedNotification(ctx, req.UserID)
|
||||
return &pbuser.SetCallAcceptSettingResp{}, nil
|
||||
}
|
||||
|
||||
// SetMsgReceiveSetting 设置会话消息接收权限(0=所有人,1=仅好友,2=所有人不可发送)。
|
||||
// 只允许本人或管理员操作。
|
||||
func (s *userServer) SetMsgReceiveSetting(ctx context.Context, req *pbuser.SetMsgReceiveSettingReq) (*pbuser.SetMsgReceiveSettingResp, error) {
|
||||
if req.UserID == "" {
|
||||
return nil, errs.ErrArgs.WrapMsg("userID is required")
|
||||
}
|
||||
if req.MsgReceiveSetting < 0 || req.MsgReceiveSetting > 2 {
|
||||
return nil, errs.ErrArgs.WrapMsg("msgReceiveSetting must be 0, 1 or 2")
|
||||
}
|
||||
if err := authverify.CheckAccessV3(ctx, req.UserID, s.config.Share.IMAdminUserID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, err := s.db.FindWithError(ctx, []string{req.UserID}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := s.db.UpdateByMap(ctx, req.UserID, map[string]any{
|
||||
"msg_receive_setting": req.MsgReceiveSetting,
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.friendNotificationSender.UserInfoUpdatedNotification(ctx, req.UserID)
|
||||
return &pbuser.SetMsgReceiveSettingResp{}, nil
|
||||
}
|
||||
|
||||
func (s *userServer) AccountCheck(ctx context.Context, req *pbuser.AccountCheckReq) (resp *pbuser.AccountCheckResp, err error) {
|
||||
resp = &pbuser.AccountCheckResp{}
|
||||
if datautil.Duplicate(req.CheckUserIDs) {
|
||||
|
||||
@ -31,6 +31,10 @@ func UserDB2Pb(user *relationtb.User) *sdkws.UserInfo {
|
||||
CreateTime: user.CreateTime.UnixMilli(),
|
||||
AppMangerLevel: user.AppMangerLevel,
|
||||
GlobalRecvMsgOpt: user.GlobalRecvMsgOpt,
|
||||
Phone: user.Phone,
|
||||
PhoneVisibility: user.PhoneVisibility,
|
||||
CallAcceptSetting: user.CallAcceptSetting,
|
||||
MsgReceiveSetting: user.MsgReceiveSetting,
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,6 +94,18 @@ func UserPb2DBMapEx(user *sdkws.UserInfoWithEx) map[string]any {
|
||||
if user.GlobalRecvMsgOpt != nil {
|
||||
val["global_recv_msg_opt"] = user.GlobalRecvMsgOpt.Value
|
||||
}
|
||||
if user.Phone != nil {
|
||||
val["phone"] = user.Phone.Value
|
||||
}
|
||||
if user.PhoneVisibility != nil {
|
||||
val["phone_visibility"] = user.PhoneVisibility.Value
|
||||
}
|
||||
if user.CallAcceptSetting != nil {
|
||||
val["call_accept_setting"] = user.CallAcceptSetting.Value
|
||||
}
|
||||
if user.MsgReceiveSetting != nil {
|
||||
val["msg_receive_setting"] = user.MsgReceiveSetting.Value
|
||||
}
|
||||
|
||||
return val
|
||||
}
|
||||
|
||||
@ -76,6 +76,7 @@ const (
|
||||
MutedInGroup = 1402 // Member muted in the group
|
||||
MutedGroup = 1403 // Group is muted
|
||||
MsgAlreadyRevoke = 1404 // Message already revoked
|
||||
MsgReceiveNotAllowed = 1405 // Recipient does not allow receiving messages from this sender
|
||||
|
||||
// Token error codes.
|
||||
TokenExpiredError = 1501
|
||||
|
||||
@ -59,6 +59,7 @@ var (
|
||||
ErrMutedInGroup = errs.NewCodeError(MutedInGroup, "MutedInGroup")
|
||||
ErrMutedGroup = errs.NewCodeError(MutedGroup, "MutedGroup")
|
||||
ErrMsgAlreadyRevoke = errs.NewCodeError(MsgAlreadyRevoke, "MsgAlreadyRevoke")
|
||||
ErrMsgReceiveNotAllowed = errs.NewCodeError(MsgReceiveNotAllowed, "MsgReceiveNotAllowed")
|
||||
|
||||
ErrConnOverMaxNumLimit = errs.NewCodeError(ConnOverMaxNumLimit, "ConnOverMaxNumLimit")
|
||||
|
||||
|
||||
@ -18,6 +18,13 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// GroupPermission 群组操作权限枚举。
|
||||
// 0=全员可操作(默认),1=仅群主/管理员可操作
|
||||
const (
|
||||
GroupPermAllMember = int32(0) // 全员均可
|
||||
GroupPermAdminOnly = int32(1) // 仅群主/管理员
|
||||
)
|
||||
|
||||
type Group struct {
|
||||
GroupID string `bson:"group_id"`
|
||||
GroupName string `bson:"group_name"`
|
||||
@ -34,4 +41,12 @@ type Group struct {
|
||||
ApplyMemberFriend int32 `bson:"apply_member_friend"`
|
||||
NotificationUpdateTime time.Time `bson:"notification_update_time"`
|
||||
NotificationUserID string `bson:"notification_user_id"`
|
||||
// AllowSendMsg 0=全员可发消息 1=仅群主/管理员可发消息
|
||||
AllowSendMsg int32 `bson:"allow_send_msg"`
|
||||
// AllowPinMsg 0=全员可置顶消息 1=仅群主/管理员可置顶消息
|
||||
AllowPinMsg int32 `bson:"allow_pin_msg"`
|
||||
// AllowAddMember 0=全员可拉人入群 1=仅群主/管理员可拉人入群
|
||||
AllowAddMember int32 `bson:"allow_add_member"`
|
||||
// AllowEditGroupInfo 0=全员可编辑群资料 1=仅群主/管理员可编辑群资料
|
||||
AllowEditGroupInfo int32 `bson:"allow_edit_group_info"`
|
||||
}
|
||||
|
||||
@ -18,6 +18,30 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// PhoneVisibility 手机号可见性枚举。
|
||||
// 0=所有人可见, 1=仅好友可见, 2=完全隐藏
|
||||
const (
|
||||
PhoneVisibilityPublic int32 = 0
|
||||
PhoneVisibilityFriends int32 = 1
|
||||
PhoneVisibilityHidden int32 = 2
|
||||
)
|
||||
|
||||
// CallAcceptSetting 音视频通话接受权限枚举。
|
||||
// 0=所有人可发起, 1=仅好友可发起, 2=不接受任何通话
|
||||
const (
|
||||
CallAcceptSettingPublic int32 = 0
|
||||
CallAcceptSettingFriends int32 = 1
|
||||
CallAcceptSettingNobody int32 = 2
|
||||
)
|
||||
|
||||
// MsgReceiveSetting 会话消息接收权限枚举。
|
||||
// 0=所有人可发送, 1=仅好友可发送, 2=所有人不可发送
|
||||
const (
|
||||
MsgReceiveSettingPublic int32 = 0
|
||||
MsgReceiveSettingFriends int32 = 1
|
||||
MsgReceiveSettingNobody int32 = 2
|
||||
)
|
||||
|
||||
type User struct {
|
||||
UserID string `bson:"user_id"`
|
||||
Nickname string `bson:"nickname"`
|
||||
@ -26,6 +50,14 @@ type User struct {
|
||||
AppMangerLevel int32 `bson:"app_manger_level"`
|
||||
GlobalRecvMsgOpt int32 `bson:"global_recv_msg_opt"`
|
||||
CreateTime time.Time `bson:"create_time"`
|
||||
// Phone 用户手机号(明文,仅服务端留存,下发时按 PhoneVisibility 过滤)
|
||||
Phone string `bson:"phone"`
|
||||
// PhoneVisibility 0=所有人可见 1=仅好友可见 2=隐藏
|
||||
PhoneVisibility int32 `bson:"phone_visibility"`
|
||||
// CallAcceptSetting 0=所有人可发起 1=仅好友可发起 2=不接受任何通话
|
||||
CallAcceptSetting int32 `bson:"call_accept_setting"`
|
||||
// MsgReceiveSetting 0=所有人可发送 1=仅好友可发送 2=所有人不可发送
|
||||
MsgReceiveSetting int32 `bson:"msg_receive_setting"`
|
||||
}
|
||||
|
||||
func (u *User) GetNickname() string {
|
||||
|
||||
@ -21,3 +21,15 @@ func (x *RelationClient) GetFriendsInfo(ctx context.Context, ownerUserID string,
|
||||
req := &relation.GetFriendInfoReq{OwnerUserID: ownerUserID, FriendUserIDs: friendUserIDs}
|
||||
return extractField(ctx, x.FriendClient.GetFriendInfo, req, (*relation.GetFriendInfoResp).GetFriendInfos)
|
||||
}
|
||||
|
||||
// IsFriend checks whether userID2 is in userID1's friend list.
|
||||
func (x *RelationClient) IsFriend(ctx context.Context, ownerUserID, friendUserID string) (bool, error) {
|
||||
resp, err := x.FriendClient.IsFriend(ctx, &relation.IsFriendReq{
|
||||
UserID1: ownerUserID,
|
||||
UserID2: friendUserID,
|
||||
})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return resp.InUser1Friends, nil
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user