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
WHERE (fu.id=? OR fu.location=? OR fu.location LIKE ?) AND fu.status=? AND (
fu.userid=?
OR EXISTS (
SELECT 1 FROM im_filemsglinks AS fml
WHERE fml.fileid=fu.id AND fml.topic LIKE 'cvp%'
)
OR EXISTS (
SELECT 1 FROM im_filemsglinks AS fml
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
WHERE fu.tenant_id=? AND (fu.id=? OR fu.location=? OR fu.location LIKE ?) AND fu.status=? AND (
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 (
SELECT 1 FROM im_filemsglinks AS fml
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 {
UserID int64 `json:"user_id"`
FileIDs []string `json:"file_ids"`
UserID int64 `json:"user_id"`
ReferenceID int64 `json:"reference_id"`
FileIDs []string `json:"file_ids"`
}
type cultivateReviewRequest struct {
@@ -162,6 +163,7 @@ func serveCultivateFiles(w http.ResponseWriter, r *http.Request, tenantID types.
}
uid := store.EncodeUid(body.UserID)
items := make([]map[string]any, 0, len(body.FileIDs))
fileIDs := make([]string, 0, len(body.FileIDs))
for _, supplied := range body.FileIDs {
fileID := normalizeIMUploadedFileID(supplied)
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})
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)})
}
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})
}
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 {
if file == nil {
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())
}
}
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)
}
}