You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Open-IM-Server/internal/rpc/msg/report.go

144 lines
4.2 KiB

// Copyright © 2024 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 msg
import (
"context"
"crypto/rand"
"time"
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
"github.com/openimsdk/protocol/msg"
"github.com/openimsdk/tools/errs"
"github.com/openimsdk/tools/mcontext"
"github.com/openimsdk/tools/utils/datautil"
)
func genReportID() string {
const dataLen = 12
data := make([]byte, dataLen)
rand.Read(data)
chars := []byte("0123456789abcdefghijklmnopqrstuvwxyz")
for i := 0; i < len(data); i++ {
data[i] = chars[data[i]%byte(len(chars))]
}
return string(data)
}
func (m *msgServer) ReportSpam(ctx context.Context, req *msg.ReportSpamReq) (*msg.ReportSpamResp, error) {
if req.ReportedUserID == "" {
return nil, errs.ErrArgs.WrapMsg("reportedUserID is required")
}
if req.ReasonType <= 0 {
return nil, errs.ErrArgs.WrapMsg("reasonType must be positive")
}
reporterUserID := mcontext.GetOpUserID(ctx)
report := &model.SpamReport{
ReporterUserID: reporterUserID,
ReportedUserID: req.ReportedUserID,
ConversationID: req.ConversationID,
ClientMsgID: req.ClientMsgID,
Seq: req.Seq,
ReasonType: req.ReasonType,
Reason: req.Reason,
Status: model.SpamReportStatusPending,
CreateTime: time.Now(),
Ex: req.Ex,
}
// Generate a unique reportID.
for i := 0; i < 20; i++ {
id := genReportID()
existing, err := m.spamReportDB.Get(ctx, id)
if err == nil && existing != nil {
continue
}
report.ReportID = id
break
}
if report.ReportID == "" {
return nil, errs.ErrInternalServer.WrapMsg("failed to generate report ID")
}
if err := m.spamReportDB.Create(ctx, report); err != nil {
return nil, err
}
return &msg.ReportSpamResp{ReportID: report.ReportID}, nil
}
func (m *msgServer) GetSpamReports(ctx context.Context, req *msg.GetSpamReportsReq) (*msg.GetSpamReportsResp, error) {
if err := authverify.CheckAdmin(ctx, m.config.Share.IMAdminUserID); err != nil {
return nil, err
}
var start, end time.Time
if req.StartTime > 0 {
start = time.UnixMilli(req.StartTime)
}
if req.EndTime > 0 {
end = time.UnixMilli(req.EndTime)
}
total, reports, err := m.spamReportDB.Find(ctx, req.Status, req.ReportedUserID, req.ReporterUserID,
start, end, req.Pagination)
if err != nil {
return nil, err
}
pbReports := datautil.Slice(reports, func(r *model.SpamReport) *msg.SpamReportInfo {
return &msg.SpamReportInfo{
ReportID: r.ReportID,
ReporterUserID: r.ReporterUserID,
ReportedUserID: r.ReportedUserID,
ConversationID: r.ConversationID,
ClientMsgID: r.ClientMsgID,
Seq: r.Seq,
ReasonType: r.ReasonType,
Reason: r.Reason,
Status: r.Status,
CreateTime: r.CreateTime.UnixMilli(),
HandleTime: r.HandleTime.UnixMilli(),
HandlerUserID: r.HandlerUserID,
Ex: r.Ex,
}
})
return &msg.GetSpamReportsResp{
Reports: pbReports,
Total: uint32(total),
}, nil
}
func (m *msgServer) HandleSpamReport(ctx context.Context, req *msg.HandleSpamReportReq) (*msg.HandleSpamReportResp, error) {
if err := authverify.CheckAdmin(ctx, m.config.Share.IMAdminUserID); err != nil {
return nil, err
}
if req.ReportID == "" {
return nil, errs.ErrArgs.WrapMsg("reportID is required")
}
if req.Status != model.SpamReportStatusHandled && req.Status != model.SpamReportStatusIgnored {
return nil, errs.ErrArgs.WrapMsg("status must be 1 (handled) or 2 (ignored)")
}
handlerUserID := mcontext.GetOpUserID(ctx)
if err := m.spamReportDB.UpdateStatus(ctx, req.ReportID, req.Status, handlerUserID, time.Now()); err != nil {
return nil, err
}
return &msg.HandleSpamReportResp{}, nil
}