feat: 接入消息加密与实名认证能力
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
@@ -127,11 +128,23 @@ func serveInternalAdminResourceList(wrt http.ResponseWriter, req *http.Request,
|
||||
writeIMError(wrt, req, http.StatusBadRequest, 30000, imReasonMalformedRequest, "malformed request", nil)
|
||||
return
|
||||
}
|
||||
result, err := store.InternalAdminQueries.Query(tenantID, query, countQuery, args, page, perPage)
|
||||
var result *types.InternalAdminQueryResult
|
||||
keyword := strings.TrimSpace(req.URL.Query().Get("keyword"))
|
||||
if (resource == "private-messages" || resource == "group-messages") && keyword != "" {
|
||||
result, err = queryEncryptedAdminMessages(req, tenantID, spec, scope, keyword, page, perPage)
|
||||
} else {
|
||||
result, err = store.InternalAdminQueries.Query(tenantID, query, countQuery, args, page, perPage)
|
||||
}
|
||||
if err != nil {
|
||||
writeInternalQueryError(wrt, req, err)
|
||||
return
|
||||
}
|
||||
if resource == "private-messages" || resource == "group-messages" {
|
||||
if err = decryptInternalAdminMessageRows(tenantID, result.Items); err != nil {
|
||||
writeInternalQueryError(wrt, req, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
writeIMSuccess(wrt, req, map[string]any{
|
||||
"items": normalizeInternalAdminRowsForAPI(result.Items),
|
||||
"total": result.Total,
|
||||
@@ -140,6 +153,81 @@ func serveInternalAdminResourceList(wrt http.ResponseWriter, req *http.Request,
|
||||
})
|
||||
}
|
||||
|
||||
func queryEncryptedAdminMessages(req *http.Request, tenantID types.TenantID, spec *internalQuerySpec, scope, keyword string, page, perPage int) (*types.InternalAdminQueryResult, error) {
|
||||
requestCopy := req.Clone(req.Context())
|
||||
urlCopy := *req.URL
|
||||
queryValues := req.URL.Query()
|
||||
queryValues.Del("keyword")
|
||||
urlCopy.RawQuery = queryValues.Encode()
|
||||
requestCopy.URL = &urlCopy
|
||||
query, countQuery, args, _, _, err := buildInternalAdminListQuery(requestCopy, spec, scope)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
const batchSize = 200
|
||||
start := (page - 1) * perPage
|
||||
end := start + perPage
|
||||
items := make([]map[string]any, 0, perPage)
|
||||
matched := 0
|
||||
for batchPage := 1; ; batchPage++ {
|
||||
batch, queryErr := store.InternalAdminQueries.Query(tenantID, query, countQuery, args, batchPage, batchSize)
|
||||
if queryErr != nil {
|
||||
return nil, queryErr
|
||||
}
|
||||
if err = decryptInternalAdminMessageRows(tenantID, batch.Items); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, row := range batch.Items {
|
||||
if !strings.Contains(strings.ToLower(fmt.Sprint(row["content_excerpt"])), strings.ToLower(keyword)) {
|
||||
continue
|
||||
}
|
||||
if matched >= start && matched < end {
|
||||
items = append(items, row)
|
||||
}
|
||||
matched++
|
||||
}
|
||||
if len(batch.Items) < batchSize || int64(batchPage*batchSize) >= batch.Total {
|
||||
break
|
||||
}
|
||||
}
|
||||
return &types.InternalAdminQueryResult{Items: items, Total: int64(matched), Page: page, PerPage: perPage}, nil
|
||||
}
|
||||
|
||||
func decryptInternalAdminMessageRows(tenantID types.TenantID, rows []map[string]any) error {
|
||||
for _, row := range rows {
|
||||
seq, ok := numericID(row["seq_id"])
|
||||
if !ok || seq <= 0 {
|
||||
continue
|
||||
}
|
||||
msg, err := store.Messages.GetOne(tenantID, fmt.Sprint(row["topic"]), seq)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
row["content_excerpt"] = internalMessageExcerpt(msg.Content)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func internalMessageExcerpt(content any) string {
|
||||
if value, ok := content.(map[string]any); ok {
|
||||
for _, key := range []string{"txt", "text", "content", "title"} {
|
||||
if text := strings.TrimSpace(fmt.Sprint(value[key])); text != "" && text != "<nil>" {
|
||||
if len([]rune(text)) > 500 {
|
||||
return string([]rune(text)[:500])
|
||||
}
|
||||
return text
|
||||
}
|
||||
}
|
||||
}
|
||||
raw, _ := json.Marshal(content)
|
||||
text := string(raw)
|
||||
if len([]rune(text)) > 500 {
|
||||
text = string([]rune(text)[:500])
|
||||
}
|
||||
return text
|
||||
}
|
||||
|
||||
func serveInternalAdminResourceDetail(wrt http.ResponseWriter, req *http.Request, tenantID types.TenantID, resource, id string) {
|
||||
spec, ok := internalAdminQuerySpec(resource)
|
||||
if !ok || spec.DetailKey == "" {
|
||||
|
||||
Reference in New Issue
Block a user