fix: retain cultivate feed media references

This commit is contained in:
richjohnrambo
2026-09-24 14:27:17 +08:00
parent 5cea4d1e2e
commit 0881256103
4 changed files with 39 additions and 2 deletions
+4
View File
@@ -4615,6 +4615,10 @@ func (a *adapter) FileUserHasAccess(fid string, uid t.Uid) (bool, error) {
SELECT COUNT(*) FROM im_fileuploads AS fu SELECT COUNT(*) FROM im_fileuploads AS fu
WHERE (fu.id=? OR fu.location=? OR fu.location LIKE ?) AND fu.status=? AND ( WHERE (fu.id=? OR fu.location=? OR fu.location LIKE ?) AND fu.status=? AND (
fu.userid=? fu.userid=?
OR EXISTS (
SELECT 1 FROM im_filemsglinks AS fml
WHERE fml.fileid=fu.id AND fml.topic LIKE 'cvp%'
)
OR EXISTS ( OR EXISTS (
SELECT 1 FROM im_filemsglinks AS fml SELECT 1 FROM im_filemsglinks AS fml
WHERE fml.fileid=fu.id AND fml.userid=? WHERE fml.fileid=fu.id AND fml.userid=?
+4
View File
@@ -5303,6 +5303,10 @@ func (a *adapter) TenantFileUserHasAccess(id t.TenantID, fid string, uid t.Uid)
SELECT COUNT(*) FROM im_fileuploads AS fu SELECT COUNT(*) FROM im_fileuploads AS fu
WHERE fu.tenant_id=? AND (fu.id=? OR fu.location=? OR fu.location LIKE ?) AND fu.status=? AND ( WHERE fu.tenant_id=? AND (fu.id=? OR fu.location=? OR fu.location LIKE ?) AND fu.status=? AND (
fu.userid=? fu.userid=?
OR EXISTS (
SELECT 1 FROM im_filemsglinks AS fml
WHERE fml.tenant_id=fu.tenant_id AND fml.fileid=fu.id AND fml.topic LIKE 'cvp%%'
)
OR EXISTS ( OR EXISTS (
SELECT 1 FROM im_filemsglinks AS fml SELECT 1 FROM im_filemsglinks AS fml
WHERE fml.tenant_id=fu.tenant_id AND fml.fileid=fu.id AND fml.userid=? WHERE fml.tenant_id=fu.tenant_id AND fml.fileid=fu.id AND fml.userid=?
+17 -2
View File
@@ -23,8 +23,9 @@ type cultivateRelationsRequest struct {
} }
type cultivateFilesRequest struct { type cultivateFilesRequest struct {
UserID int64 `json:"user_id"` UserID int64 `json:"user_id"`
FileIDs []string `json:"file_ids"` ReferenceID int64 `json:"reference_id"`
FileIDs []string `json:"file_ids"`
} }
type cultivateReviewRequest struct { type cultivateReviewRequest struct {
@@ -162,6 +163,7 @@ func serveCultivateFiles(w http.ResponseWriter, r *http.Request, tenantID types.
} }
uid := store.EncodeUid(body.UserID) uid := store.EncodeUid(body.UserID)
items := make([]map[string]any, 0, len(body.FileIDs)) items := make([]map[string]any, 0, len(body.FileIDs))
fileIDs := make([]string, 0, len(body.FileIDs))
for _, supplied := range body.FileIDs { for _, supplied := range body.FileIDs {
fileID := normalizeIMUploadedFileID(supplied) fileID := normalizeIMUploadedFileID(supplied)
file, err := store.Files.Get(tenantID, fileID) file, err := store.Files.Get(tenantID, fileID)
@@ -173,11 +175,24 @@ func serveCultivateFiles(w http.ResponseWriter, r *http.Request, tenantID types.
writeIMError(w, r, http.StatusUnprocessableEntity, 30000, imReasonMalformedRequest, "invalid file", map[string]any{"file_id": supplied}) writeIMError(w, r, http.StatusUnprocessableEntity, 30000, imReasonMalformedRequest, "invalid file", map[string]any{"file_id": supplied})
return return
} }
fileIDs = append(fileIDs, fileID)
items = append(items, map[string]any{"file_id": fileID, "mime_type": file.MimeType, "size": file.Size, "review_status": cultivateFileReviewStatus(tenantID, fileID)}) items = append(items, map[string]any{"file_id": fileID, "mime_type": file.MimeType, "size": file.Size, "review_status": cultivateFileReviewStatus(tenantID, fileID)})
} }
if body.ReferenceID > 0 {
for index, fileID := range fileIDs {
if err := store.Files.LinkAttachments(tenantID, cultivateFileReferenceTopic(body.ReferenceID, index), types.ZeroUid, []string{fileID}); err != nil {
writeIMError(w, r, http.StatusInternalServerError, 90000, imReasonInternal, "failed to retain file", nil)
return
}
}
}
writeIMSuccess(w, r, map[string]any{"items": items}) writeIMSuccess(w, r, map[string]any{"items": items})
} }
func cultivateFileReferenceTopic(referenceID int64, index int) string {
return "cvp" + strconv.FormatInt(referenceID, 36) + "x" + strconv.FormatInt(int64(index), 36)
}
func fileOwner(file *types.FileDef) string { func fileOwner(file *types.FileDef) string {
if file == nil { if file == nil {
return "" return ""
+14
View File
@@ -46,3 +46,17 @@ func TestInternalCultivateUsesSharedInternalCredential(t *testing.T) {
t.Fatalf("shared internal credential was rejected: status=%d body=%s", rec.Code, rec.Body.String()) t.Fatalf("shared internal credential was rejected: status=%d body=%s", rec.Code, rec.Body.String())
} }
} }
func TestCultivateFileReferenceTopic(t *testing.T) {
first := cultivateFileReferenceTopic(1577072518975639552, 0)
second := cultivateFileReferenceTopic(1577072518975639552, 1)
if first == second {
t.Fatalf("file references must be unique per media item: %q", first)
}
if len(first) > 25 || len(second) > 25 {
t.Fatalf("file reference exceeds im_filemsglinks.topic capacity: %q %q", first, second)
}
if first != cultivateFileReferenceTopic(1577072518975639552, 0) {
t.Fatalf("file reference is not deterministic: %q", first)
}
}