у записи появился владелец: чужую больше не отдают

- колонка `owner` связью с `users` в обеих коллекциях новым шагом схемы
  `202608140001`; чтение задачи сужено владельцем, и чужая, ничья и
  несуществующая дают один ответ; правило просмотра файлов сужено им же
- приём по HTTP берёт владельца из сессии, а предъявителя без учётной записи
  пользователя отвергает до чтения тела: позже пришлось бы убирать уложенный
  файл, а уборки файлов сервис не умеет. Выборка воркера владельцем не сужается
- удаление учётной записи с записями отвергается стражем, и вешает его сама
  сборка хранилища: сборка, забывшая его позвать, теряла защиту молча
This commit is contained in:
av
2026-08-14 12:18:11 +03:00
parent b7d4660aef
commit 8af8ec2e54
46 changed files with 2520 additions and 101 deletions
@@ -116,7 +116,7 @@ func (repo *FileRepository) Localize(fileID string) (contract.WorkFile, error) {
// библиотеки строит его из имени, данного отправителем, а имя отправителя в
// хранилище не попадает — путь к файлу читается в журнале, и инвариант
// приватности этого не допускает. Свой суффикс хранилище допишет само.
func (repo *FileRepository) CreateLocal(name string, work contract.WorkFile) (*entity.File, error) {
func (repo *FileRepository) CreateLocal(name string, work contract.WorkFile, ownerID string) (*entity.File, error) {
collection, err := findCollection(repo.app, migrations.FilesCollection)
if err != nil {
return nil, err
@@ -132,6 +132,11 @@ func (repo *FileRepository) CreateLocal(name string, work contract.WorkFile) (*e
record.Set("file", stored)
record.Set("location", entity.LocationLocal)
record.Set("size", stored.Size)
// Владелец файла — владелец записи, которой файл принадлежит. Пустой значит
// «файл без владельца»: таков всякий файл записи, принятой ботом. Правило
// просмотра коллекции сужено этой колонкой, и без неё чужое аудио осталось
// бы доступным всякому вошедшему.
record.Set("owner", ownerID)
if err := repo.app.Save(record); err != nil {
// Отказ укладки называет имя файла — то самое, из которого строится
@@ -143,7 +148,7 @@ func (repo *FileRepository) CreateLocal(name string, work contract.WorkFile) (*e
return recordToFile(record), nil
}
func (repo *FileRepository) CreateRemote(objectKey string, size int64) (*entity.File, error) {
func (repo *FileRepository) CreateRemote(objectKey string, size int64, ownerID string) (*entity.File, error) {
collection, err := findCollection(repo.app, migrations.FilesCollection)
if err != nil {
return nil, err
@@ -153,6 +158,7 @@ func (repo *FileRepository) CreateRemote(objectKey string, size int64) (*entity.
record.Set("location", entity.LocationS3)
record.Set("object_key", objectKey)
record.Set("size", size)
record.Set("owner", ownerID)
if err := repo.app.Save(record); err != nil {
return nil, fmt.Errorf("failed to store remote file record: %w", err)