feat(fm): source-identity preconditions on move/copy/rename (#3565)
Move/copy/rename resolve sources by path; a delayed retried request can act on a different file that reused the path. The services now accept an optional expected-source hashid (expect_id / expect_ids, positional, empty entry skips) which is compared against the resolved file's database ID before mutation — mismatch fails with fs.ErrModified (409). The web app sends the selected files' IDs on every rename and move/copy. WebDAV and API callers omitting the field are unaffected.pull/3582/head
parent
5811af4503
commit
6928fd571a
@ -0,0 +1,28 @@
|
||||
package dbfs
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestSourceIDMismatch(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
// No expectations -> never mismatches.
|
||||
require.False(t, sourceIDMismatch(ctx, 0, 42))
|
||||
require.False(t, sourceIDMismatch(ctx, 5, 42))
|
||||
|
||||
ctx = WithExpectedSourceIDs(ctx, []int{11, 0, 33})
|
||||
|
||||
// Matching positions pass.
|
||||
require.False(t, sourceIDMismatch(ctx, 0, 11))
|
||||
// Zero entries disable the check for that position.
|
||||
require.False(t, sourceIDMismatch(ctx, 1, 999))
|
||||
// Positions beyond the expectation list pass.
|
||||
require.False(t, sourceIDMismatch(ctx, 3, 999))
|
||||
// Mismatches are caught per position.
|
||||
require.True(t, sourceIDMismatch(ctx, 0, 12))
|
||||
require.True(t, sourceIDMismatch(ctx, 2, 34))
|
||||
}
|
||||
Loading…
Reference in new issue