mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-06-22 14:59:12 -04:00
Merge branch 'origin/stable-7.2' into 'next-release/stable-7.2'
This commit is contained in:
2
go.mod
2
go.mod
@@ -64,7 +64,7 @@ require (
|
||||
github.com/open-policy-agent/opa v1.15.2
|
||||
github.com/opencloud-eu/icap-client v0.0.0-20250930132611-28a2afe62d89
|
||||
github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20260310090739-853d972b282d
|
||||
github.com/opencloud-eu/reva/v2 v2.46.3-0.20260610093751-a33d8108dd91
|
||||
github.com/opencloud-eu/reva/v2 v2.46.5
|
||||
github.com/opensearch-project/opensearch-go/v4 v4.6.0
|
||||
github.com/orcaman/concurrent-map v1.0.0
|
||||
github.com/pkg/errors v0.9.1
|
||||
|
||||
4
go.sum
4
go.sum
@@ -948,8 +948,8 @@ github.com/opencloud-eu/icap-client v0.0.0-20250930132611-28a2afe62d89 h1:W1ms+l
|
||||
github.com/opencloud-eu/icap-client v0.0.0-20250930132611-28a2afe62d89/go.mod h1:vigJkNss1N2QEceCuNw/ullDehncuJNFB6mEnzfq9UI=
|
||||
github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20260310090739-853d972b282d h1:JcqGDiyrcaQwVyV861TUyQgO7uEmsjkhfm7aQd84dOw=
|
||||
github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20260310090739-853d972b282d/go.mod h1:pzatilMEHZFT3qV7C/X3MqOa3NlRQuYhlRhZTL+hN6Q=
|
||||
github.com/opencloud-eu/reva/v2 v2.46.3-0.20260610093751-a33d8108dd91 h1:A/a0d9UNclpNBWGp2NUDWF+qO+U/u38EBH4CIk2dqIE=
|
||||
github.com/opencloud-eu/reva/v2 v2.46.3-0.20260610093751-a33d8108dd91/go.mod h1:RoFQt+u7edxwzHr1IZ2Y6VaDinMiRPQupAvMBy3WVmE=
|
||||
github.com/opencloud-eu/reva/v2 v2.46.5 h1:Zv3CUj//N8qalWEklQ5zJEPyPJvqDnT0gcqF47bUEso=
|
||||
github.com/opencloud-eu/reva/v2 v2.46.5/go.mod h1:RoFQt+u7edxwzHr1IZ2Y6VaDinMiRPQupAvMBy3WVmE=
|
||||
github.com/opencloud-eu/secure v0.0.0-20260312082735-b6f5cb2244e4 h1:l2oB/RctH+t8r7QBj5p8thfEHCM/jF35aAY3WQ3hADI=
|
||||
github.com/opencloud-eu/secure v0.0.0-20260312082735-b6f5cb2244e4/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
|
||||
@@ -1119,7 +1119,7 @@ func (g Graph) DeleteDrive(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
case cs3rpc.Code_CODE_PERMISSION_DENIED:
|
||||
logger.Debug().Interface("id", rid).Msg("could not delete drive: permission denied")
|
||||
errorcode.ItemNotFound.Render(w, r, http.StatusNotFound, "drive not found")
|
||||
errorcode.AccessDenied.Render(w, r, http.StatusForbidden, "permission denied")
|
||||
return
|
||||
case cs3rpc.Code_CODE_NOT_FOUND:
|
||||
logger.Debug().Interface("id", rid).Msg("could not delete drive: drive not found")
|
||||
|
||||
@@ -63,28 +63,28 @@ Feature: Disabling and deleting space
|
||||
Scenario Outline: user cannot delete their own space without first disabling it
|
||||
Given the administrator has assigned the role "<user-role>" to user "Alice" using the Graph API
|
||||
When user "Alice" deletes a space "Project Moon"
|
||||
Then the HTTP status code should be "400"
|
||||
Then the HTTP status code should be "<code>"
|
||||
And the user "Alice" should have a space called "Project Moon"
|
||||
Examples:
|
||||
| user-role |
|
||||
| Admin |
|
||||
| Space Admin |
|
||||
| User |
|
||||
| User Light |
|
||||
| user-role | code |
|
||||
| Admin | 400 |
|
||||
| Space Admin | 400 |
|
||||
| User | 403 |
|
||||
| User Light | 403 |
|
||||
|
||||
|
||||
Scenario Outline: user can delete their own disabled space via the Graph API
|
||||
Scenario Outline: user cannot delete their own disabled space via the Graph API
|
||||
Given the administrator has assigned the role "<user-role>" to user "Alice" using the Graph API
|
||||
And user "Alice" has disabled a space "Project Moon"
|
||||
When user "Alice" deletes a space "Project Moon"
|
||||
Then the HTTP status code should be "204"
|
||||
And the user "Alice" should not have a space called "Project Moon"
|
||||
Then the HTTP status code should be "<code>"
|
||||
And the user "Alice" <shouldOrNot> have a space called "Project Moon"
|
||||
Examples:
|
||||
| user-role |
|
||||
| Admin |
|
||||
| Space Admin |
|
||||
| User |
|
||||
| User Light |
|
||||
| user-role | code | shouldOrNot |
|
||||
| Admin | 204 | should not |
|
||||
| Space Admin | 204 | should not |
|
||||
| User | 403 | should |
|
||||
| User Light | 403 | should |
|
||||
|
||||
|
||||
Scenario Outline: an admin and space manager can disable other space via the Graph API
|
||||
@@ -134,7 +134,7 @@ Feature: Disabling and deleting space
|
||||
|
||||
Scenario Outline: viewer and space editor cannot disable space
|
||||
When user "<user>" tries to disable a space "Project Moon" owned by user "Alice"
|
||||
Then the HTTP status code should be "404"
|
||||
Then the HTTP status code should be "403"
|
||||
And the user "<user>" should have a space called "Project Moon"
|
||||
Examples:
|
||||
| user |
|
||||
|
||||
@@ -152,11 +152,14 @@ Feature: Space management
|
||||
|
||||
Scenario Outline: space admin user tries to disable the personal space
|
||||
When user "<user>" disables a space "Alice Hansen" owned by user "Alice"
|
||||
Then the HTTP status code should be "404"
|
||||
Then the HTTP status code should be "<code>"
|
||||
Examples:
|
||||
| user |
|
||||
| Brian |
|
||||
| Carol |
|
||||
| user | code |
|
||||
# Brian is Space Admin and can currently list all Personal Spaces, so he
|
||||
# gets a 403 instead of a 404 here. This might change in the future see:
|
||||
# https://github.com/opencloud-eu/opencloud/issues/2979
|
||||
| Brian | 403 |
|
||||
| Carol | 404 |
|
||||
|
||||
|
||||
Scenario: space admin user deletes the project space
|
||||
|
||||
@@ -631,7 +631,10 @@ func (s *Service) DeleteStorageSpace(ctx context.Context, req *provider.DeleteSt
|
||||
case errtypes.IsNotFound:
|
||||
st = status.NewNotFound(ctx, "space not found")
|
||||
case errtypes.PermissionDenied:
|
||||
st = status.NewPermissionDenied(ctx, err, "permission denied")
|
||||
// The requesting user, while being a member of the space, is currently
|
||||
// not allowed to list that space. E.g. because it is disabled. Return
|
||||
// a "NotFound" status here.
|
||||
st = status.NewNotFound(ctx, "space not found")
|
||||
case errtypes.BadRequest:
|
||||
st = status.NewInvalid(ctx, err.Error())
|
||||
default:
|
||||
|
||||
23
vendor/github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocdav/tus.go
generated
vendored
23
vendor/github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocdav/tus.go
generated
vendored
@@ -119,11 +119,18 @@ func (s *svc) handleTusPost(ctx context.Context, w http.ResponseWriter, r *http.
|
||||
isSecretFileDrop = true
|
||||
}
|
||||
|
||||
// r.Header.Get(net.HeaderOCChecksum)
|
||||
// TODO must be SHA1, ADLER32 or MD5 ... in capital letters????
|
||||
// curl -X PUT https://demo.example.org/remote.php/webdav/testcs.bin -u demo:demo -d '123' -v -H 'OC-Checksum: SHA1:40bd001563085fc35165329ea1ff5c5ecbdbbeef'
|
||||
|
||||
// TODO check Expect: 100-continue
|
||||
checksum := ""
|
||||
if cs, ok := meta["checksum"]; ok {
|
||||
cparts := strings.SplitN(cs, " ", 2)
|
||||
if len(cparts) != 2 {
|
||||
log.Debug().Str("upload-checksum", cs).Msg("invalid Upload-Checksum format, expected '[algorithm] [checksum]'")
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
} else {
|
||||
// we do not check the algorithm here, because it might depend on the storage
|
||||
checksum = strings.ToLower(cparts[0]) + " " + cparts[1]
|
||||
}
|
||||
}
|
||||
|
||||
client, err := s.gatewaySelector.Next()
|
||||
if err != nil {
|
||||
@@ -216,6 +223,12 @@ func (s *svc) handleTusPost(ctx context.Context, w http.ResponseWriter, r *http.
|
||||
},
|
||||
}
|
||||
|
||||
if checksum != "" {
|
||||
opaqueMap[net.HeaderUploadChecksum] = &typespb.OpaqueEntry{
|
||||
Decoder: "plain",
|
||||
Value: []byte(checksum),
|
||||
}
|
||||
}
|
||||
mtime := meta["mtime"]
|
||||
if mtime != "" {
|
||||
opaqueMap[net.HeaderOCMtime] = &typespb.OpaqueEntry{
|
||||
|
||||
92
vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/ignore/ignore.go
generated
vendored
92
vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/ignore/ignore.go
generated
vendored
@@ -7,10 +7,21 @@ import (
|
||||
"github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/blobstore"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/lookup"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/options"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/tree/propagator"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/storage/utils/templates"
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
const (
|
||||
// The needles include the separator at the beginning to avoid matching internal dir names in substrings
|
||||
// The end segment boundary is checked in isInternalDir
|
||||
trashNeedle = needle(string(filepath.Separator) + lookup.TrashDir)
|
||||
metadataNeedle = needle(string(filepath.Separator) + lookup.MetadataDir)
|
||||
tmpNeedle = needle(string(filepath.Separator) + blobstore.TMPDir)
|
||||
)
|
||||
|
||||
type needle string
|
||||
|
||||
// Ignorer handles checking if paths should be ignored in posix operations
|
||||
type Ignorer struct {
|
||||
options *options.Options
|
||||
@@ -31,39 +42,29 @@ func NewIgnorer(options *options.Options, log *zerolog.Logger) *Ignorer {
|
||||
|
||||
// IsIgnored checking if paths should be ignored in posix operations
|
||||
func (i *Ignorer) IsIgnored(path string) bool {
|
||||
return IsLockFile(path) || IsTrash(path) || i.IsUpload(path) || i.IsInternal(path) || i.IsRootPath(path) || i.IsSpaceRoot(path)
|
||||
return i.IsChanges(path) ||
|
||||
i.IsIndex(path) ||
|
||||
IsLockFile(path) ||
|
||||
i.IsTrash(path) ||
|
||||
i.IsMetadata(path) ||
|
||||
i.IsTemporary(path) ||
|
||||
i.IsUpload(path) ||
|
||||
i.IsRootPath(path) ||
|
||||
i.IsSpaceRoot(path)
|
||||
}
|
||||
|
||||
func (i *Ignorer) IsChanges(path string) bool {
|
||||
return strings.HasPrefix(path, filepath.Join(i.options.Root, propagator.ChangesDir))
|
||||
}
|
||||
|
||||
func (i *Ignorer) IsIndex(path string) bool {
|
||||
return strings.HasPrefix(path, filepath.Join(i.options.Root, lookup.IndexesDir))
|
||||
}
|
||||
|
||||
func (i *Ignorer) IsUpload(path string) bool {
|
||||
return strings.HasPrefix(path, i.options.UploadDirectory)
|
||||
}
|
||||
|
||||
func (i *Ignorer) IsIndex(path string) bool {
|
||||
return strings.HasPrefix(path, filepath.Join(i.options.Root, "indexes"))
|
||||
}
|
||||
|
||||
func (i *Ignorer) IsChanges(path string) bool {
|
||||
return strings.HasPrefix(path, filepath.Join(i.options.Root, "changes"))
|
||||
}
|
||||
|
||||
func (i *Ignorer) IsTemporary(path string) bool {
|
||||
if filepath.IsAbs(path) {
|
||||
tmpDirPattern := filepath.Join(i.options.Root, "*", "*", blobstore.TMPDir)
|
||||
isTempDir, err := filepath.Match(tmpDirPattern, path)
|
||||
if err != nil {
|
||||
i.log.Error().Err(err).Str("pattern", tmpDirPattern).Str("path", path).Msg("error matching temporary path")
|
||||
return false
|
||||
}
|
||||
isTempParentDir, err := filepath.Match(tmpDirPattern, filepath.Dir(path))
|
||||
if err != nil {
|
||||
i.log.Error().Err(err).Str("pattern", tmpDirPattern).Str("path", filepath.Dir(path)).Msg("error matching temporary path")
|
||||
return false
|
||||
}
|
||||
return isTempDir || isTempParentDir
|
||||
}
|
||||
return path == blobstore.TMPDir || filepath.Dir(path) == blobstore.TMPDir
|
||||
}
|
||||
|
||||
func (i *Ignorer) IsRootPath(path string) bool {
|
||||
return path == i.options.Root ||
|
||||
path == i.personalSpacesRoot ||
|
||||
@@ -75,14 +76,39 @@ func (i *Ignorer) IsSpaceRoot(path string) bool {
|
||||
return parent == i.personalSpacesRoot || parent == i.projectSpacesRoot
|
||||
}
|
||||
|
||||
func (i *Ignorer) IsInternal(path string) bool {
|
||||
return i.IsIndex(path) || strings.Contains(path, lookup.MetadataDir) || i.IsTemporary(path) || i.IsChanges(path)
|
||||
}
|
||||
|
||||
func IsLockFile(path string) bool {
|
||||
return strings.HasSuffix(path, ".flock") || strings.HasSuffix(path, ".mlock")
|
||||
}
|
||||
|
||||
func IsTrash(path string) bool {
|
||||
return strings.HasSuffix(path, ".trashinfo") || strings.HasSuffix(path, ".trashitem") || strings.Contains(path, ".Trash")
|
||||
func (i *Ignorer) IsMetadata(path string) bool {
|
||||
return i.isInternalDir(path, metadataNeedle)
|
||||
}
|
||||
|
||||
func (i *Ignorer) IsTemporary(path string) bool {
|
||||
return i.isInternalDir(path, tmpNeedle)
|
||||
}
|
||||
|
||||
func (i *Ignorer) IsTrash(path string) bool {
|
||||
return i.isInternalDir(path, trashNeedle)
|
||||
}
|
||||
|
||||
// isInternalDir checks if the path contains the match dir and that the match lives
|
||||
// in the space root, e.g. "/storage/users/user1/.metadata/file" -> match is ".metadata",
|
||||
// parent dir is "/storage/users/user1" which is a space root, so this would return true
|
||||
func (i *Ignorer) isInternalDir(path string, match needle) bool {
|
||||
idx := strings.Index(path, string(match))
|
||||
if idx <= 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
// must end at a segment boundary (end of path or separator)
|
||||
if length := idx + len(match); length != len(path) && path[length] != filepath.Separator {
|
||||
return false
|
||||
}
|
||||
|
||||
// get the path of the parent dir, e.g. "/a/match" -> index of "match" is 3
|
||||
// so parentPath is path[:2] -> "/a"
|
||||
parentPath := path[:idx-1]
|
||||
|
||||
return len(parentPath) > 0 && i.IsSpaceRoot(parentPath)
|
||||
}
|
||||
|
||||
7
vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/lookup/lookup.go
generated
vendored
7
vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/lookup/lookup.go
generated
vendored
@@ -34,6 +34,7 @@ import (
|
||||
"github.com/opencloud-eu/reva/v2/pkg/errtypes"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/idcache"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/options"
|
||||
dfslookup "github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/lookup"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/metadata"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/metadata/prefixes"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/node"
|
||||
@@ -48,7 +49,11 @@ import (
|
||||
|
||||
var tracer trace.Tracer
|
||||
|
||||
const MetadataDir = ".oc-nodes"
|
||||
const (
|
||||
IndexesDir = dfslookup.IndexesDir
|
||||
MetadataDir = ".oc-nodes"
|
||||
TrashDir = ".Trash"
|
||||
)
|
||||
|
||||
var _spaceTypePersonal = "personal"
|
||||
var _spaceTypeProject = "project"
|
||||
|
||||
12
vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/trashbin/trashbin.go
generated
vendored
12
vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/trashbin/trashbin.go
generated
vendored
@@ -145,7 +145,7 @@ func (tb *Trashbin) Setup(fs storage.FS) error {
|
||||
}
|
||||
|
||||
func trashRootForNode(n *node.Node) string {
|
||||
return filepath.Join(n.SpaceRoot.InternalPath(), ".Trash")
|
||||
return filepath.Join(n.SpaceRoot.InternalPath(), lookup.TrashDir)
|
||||
}
|
||||
|
||||
func (tb *Trashbin) MoveToTrash(ctx context.Context, n *node.Node, path string) error {
|
||||
@@ -192,7 +192,7 @@ func (tb *Trashbin) ListRecycle(ctx context.Context, spaceID string, key, relati
|
||||
_, span := tracer.Start(ctx, "ListRecycle")
|
||||
defer span.End()
|
||||
|
||||
trashRoot := filepath.Join(tb.lu.InternalPath(spaceID, spaceID), ".Trash")
|
||||
trashRoot := filepath.Join(tb.lu.InternalPath(spaceID, spaceID), lookup.TrashDir)
|
||||
base := filepath.Join(trashRoot, "files")
|
||||
|
||||
var originalPath string
|
||||
@@ -304,7 +304,7 @@ func (tb *Trashbin) RestoreRecycleItem(ctx context.Context, spaceID string, key,
|
||||
_, span := tracer.Start(ctx, "RestoreRecycleItem")
|
||||
defer span.End()
|
||||
|
||||
trashRoot := filepath.Join(tb.lu.InternalPath(spaceID, spaceID), ".Trash")
|
||||
trashRoot := filepath.Join(tb.lu.InternalPath(spaceID, spaceID), lookup.TrashDir)
|
||||
trashPath := filepath.Clean(filepath.Join(trashRoot, "files", key+".trashitem", relativePath))
|
||||
|
||||
restorePath := ""
|
||||
@@ -377,7 +377,7 @@ func (tb *Trashbin) PurgeRecycleItem(ctx context.Context, spaceID, key, relative
|
||||
_, span := tracer.Start(ctx, "PurgeRecycleItem")
|
||||
defer span.End()
|
||||
|
||||
trashRoot := filepath.Join(tb.lu.InternalPath(spaceID, spaceID), ".Trash")
|
||||
trashRoot := filepath.Join(tb.lu.InternalPath(spaceID, spaceID), lookup.TrashDir)
|
||||
trashPath := filepath.Clean(filepath.Join(trashRoot, "files", key+".trashitem", relativePath))
|
||||
|
||||
type item struct {
|
||||
@@ -522,7 +522,7 @@ func (tb *Trashbin) EmptyRecycle(ctx context.Context, spaceID string) error {
|
||||
_, span := tracer.Start(ctx, "EmptyRecycle")
|
||||
defer span.End()
|
||||
|
||||
trashRoot := filepath.Join(tb.lu.InternalPath(spaceID, spaceID), ".Trash")
|
||||
trashRoot := filepath.Join(tb.lu.InternalPath(spaceID, spaceID), lookup.TrashDir)
|
||||
filesRoot := filepath.Join(trashRoot, "files")
|
||||
|
||||
entries, err := os.ReadDir(filesRoot)
|
||||
@@ -582,7 +582,7 @@ func (tb *Trashbin) EmptyRecycle(ctx context.Context, spaceID string) error {
|
||||
func (tb *Trashbin) IsEmpty(ctx context.Context, spaceID string) bool {
|
||||
_, span := tracer.Start(ctx, "HasTrashedItems")
|
||||
defer span.End()
|
||||
trashRoot := filepath.Join(tb.lu.InternalPath(spaceID, spaceID), ".Trash", "info")
|
||||
trashRoot := filepath.Join(tb.lu.InternalPath(spaceID, spaceID), lookup.TrashDir, "info")
|
||||
trash, err := os.Open(filepath.Clean(trashRoot))
|
||||
if err != nil {
|
||||
// there is no trash for this space, so no trashed items
|
||||
|
||||
6
vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/tree/assimilation.go
generated
vendored
6
vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/tree/assimilation.go
generated
vendored
@@ -41,7 +41,6 @@ import (
|
||||
|
||||
"github.com/opencloud-eu/reva/v2/pkg/errtypes"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/events"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/ignore"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/watcher"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/metadata"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/metadata/prefixes"
|
||||
@@ -898,10 +897,7 @@ func (t *Tree) WarmupIDCache(root string, assimilate, onlyDirty bool) error {
|
||||
}
|
||||
|
||||
// skip irrelevant files
|
||||
if t.Ignorer.IsInternal(path) ||
|
||||
ignore.IsLockFile(path) ||
|
||||
ignore.IsTrash(path) ||
|
||||
t.Ignorer.IsUpload(path) {
|
||||
if !t.Ignorer.IsSpaceRoot(path) && t.Ignorer.IsIgnored(path) {
|
||||
if info.IsDir() {
|
||||
return filepath.SkipDir
|
||||
}
|
||||
|
||||
15
vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/tree/tree.go
generated
vendored
15
vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/tree/tree.go
generated
vendored
@@ -326,6 +326,10 @@ func (t *Tree) GetMD(_ context.Context, n *node.Node) (os.FileInfo, error) {
|
||||
|
||||
// TouchFile creates a new empty file
|
||||
func (t *Tree) TouchFile(ctx context.Context, n *node.Node, markprocessing bool, mtime string) error {
|
||||
if t.Ignorer.IsIgnored(filepath.Join(n.ParentPath(), n.Name)) {
|
||||
return errtypes.PermissionDenied(n.ID)
|
||||
}
|
||||
|
||||
if n.Exists {
|
||||
if markprocessing {
|
||||
return n.SetXattr(ctx, prefixes.StatusPrefix, []byte(node.ProcessingStatus))
|
||||
@@ -566,7 +570,7 @@ func (t *Tree) ListFolder(ctx context.Context, n *node.Node) ([]*node.Node, erro
|
||||
g.Go(func() error {
|
||||
defer close(work)
|
||||
for _, name := range names {
|
||||
if t.Ignorer.IsInternal(name) || ignore.IsLockFile(name) || ignore.IsTrash(name) {
|
||||
if t.Ignorer.IsIgnored(filepath.Join(dir, name)) {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -758,6 +762,10 @@ func (t *Tree) ResolveSpaceIDIndexEntry(spaceID string) (string, error) {
|
||||
|
||||
// InitNewNode initializes a new node
|
||||
func (t *Tree) InitNewNode(ctx context.Context, n *node.Node, fsize uint64) (metadata.UnlockFunc, error) {
|
||||
if t.Ignorer.IsIgnored(filepath.Join(n.ParentPath(), n.Name)) {
|
||||
return nil, errtypes.PermissionDenied(n.ID)
|
||||
}
|
||||
|
||||
_, span := tracer.Start(ctx, "InitNewNode")
|
||||
defer span.End()
|
||||
// create folder structure (if needed)
|
||||
@@ -804,6 +812,10 @@ func (t *Tree) InitNewNode(ctx context.Context, n *node.Node, fsize uint64) (met
|
||||
|
||||
// TODO check if node exists?
|
||||
func (t *Tree) createDirNode(ctx context.Context, n *node.Node) (err error) {
|
||||
if t.Ignorer.IsIgnored(filepath.Join(n.ParentPath(), n.Name)) {
|
||||
return errtypes.PermissionDenied(n.ID)
|
||||
}
|
||||
|
||||
ctx, span := tracer.Start(ctx, "createDirNode")
|
||||
defer span.End()
|
||||
|
||||
@@ -850,6 +862,7 @@ func (t *Tree) createDirNode(ctx context.Context, n *node.Node) (err error) {
|
||||
attributes := n.NodeMetadata(ctx)
|
||||
attributes[prefixes.MTimeAttr] = []byte(mtime.UTC().Format(time.RFC3339Nano))
|
||||
attributes[prefixes.IDAttr] = []byte(n.ID)
|
||||
attributes[prefixes.SpaceIDAttr] = []byte(n.SpaceID)
|
||||
attributes[prefixes.TreesizeAttr] = []byte("0") // initialize as empty, TODO why bother? if it is not set we could treat it as 0?
|
||||
|
||||
if t.options.TreeTimeAccounting || t.options.TreeSizeAccounting {
|
||||
|
||||
23
vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/tree/watcher_darwin.go
generated
vendored
23
vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/tree/watcher_darwin.go
generated
vendored
@@ -12,7 +12,6 @@ import (
|
||||
"github.com/fsnotify/fsnotify"
|
||||
"github.com/rs/zerolog"
|
||||
|
||||
"github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/ignore"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/options"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/watcher"
|
||||
)
|
||||
@@ -43,7 +42,7 @@ func NewWatcher(tree *Tree, o *options.Options, log *zerolog.Logger) (*FSnotifyW
|
||||
// add takes care of adding watches for root and its subpaths.
|
||||
func (w *FSnotifyWatcher) add(fsWatcher *fsnotify.Watcher, root string) error {
|
||||
// Check if the root is ignored before walking the tree
|
||||
if isPathIgnored(w.tree, root) {
|
||||
if w.tree.Ignorer.IsIgnored(root) {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -53,7 +52,7 @@ func (w *FSnotifyWatcher) add(fsWatcher *fsnotify.Watcher, root string) error {
|
||||
}
|
||||
|
||||
// skip ignored paths or files
|
||||
if isPathIgnored(w.tree, p) || !d.IsDir() {
|
||||
if w.tree.Ignorer.IsIgnored(p) || !d.IsDir() {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -99,7 +98,7 @@ func (w *FSnotifyWatcher) handleEvent(fsWatcher *fsnotify.Watcher, event fsnotif
|
||||
isWrite := event.Op&fsnotify.Write != 0
|
||||
|
||||
isKnownEvent := isCreate || isRemove || isRename || isWrite
|
||||
isIgnored := isPathIgnored(w.tree, event.Name)
|
||||
isIgnored := w.tree.Ignorer.IsIgnored(event.Name)
|
||||
|
||||
// filter out unwanted events
|
||||
if isIgnored || !isKnownEvent {
|
||||
@@ -209,19 +208,3 @@ func isSubpath(root, p string) bool {
|
||||
|
||||
return rel != "." && !strings.HasPrefix(rel, "..")
|
||||
}
|
||||
|
||||
// isIgnored checks if the path is ignored by its tree.
|
||||
func isPathIgnored(tree *Tree, path string) bool {
|
||||
|
||||
isLockFile := ignore.IsLockFile(path)
|
||||
isTrash := ignore.IsTrash(path)
|
||||
isUpload := tree.isUpload(path)
|
||||
isInternal := tree.isInternal(path)
|
||||
|
||||
// ask the tree if the path is internal or ignored
|
||||
return path == "" ||
|
||||
isLockFile ||
|
||||
isTrash ||
|
||||
isUpload ||
|
||||
isInternal
|
||||
}
|
||||
|
||||
6
vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/decomposedfs.go
generated
vendored
6
vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/decomposedfs.go
generated
vendored
@@ -206,17 +206,17 @@ func New(o *options.Options, aspects aspects.Aspects, log *zerolog.Logger) (stor
|
||||
if o.LockCycleDurationFactor != 0 {
|
||||
filelocks.SetLockCycleDurationFactor(o.LockCycleDurationFactor)
|
||||
}
|
||||
userSpaceIndex := spaceidindex.New(filepath.Join(o.Root, "indexes"), "by-user-id")
|
||||
userSpaceIndex := spaceidindex.New(filepath.Join(o.Root, lookup.IndexesDir), "by-user-id")
|
||||
err = userSpaceIndex.Init()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
groupSpaceIndex := spaceidindex.New(filepath.Join(o.Root, "indexes"), "by-group-id")
|
||||
groupSpaceIndex := spaceidindex.New(filepath.Join(o.Root, lookup.IndexesDir), "by-group-id")
|
||||
err = groupSpaceIndex.Init()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
spaceTypeIndex := spaceidindex.New(filepath.Join(o.Root, "indexes"), "by-type")
|
||||
spaceTypeIndex := spaceidindex.New(filepath.Join(o.Root, lookup.IndexesDir), "by-type")
|
||||
err = spaceTypeIndex.Init()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
2
vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/lookup/lookup.go
generated
vendored
2
vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/lookup/lookup.go
generated
vendored
@@ -45,6 +45,8 @@ var tracer trace.Tracer
|
||||
|
||||
const (
|
||||
_spaceTypePersonal = "personal"
|
||||
|
||||
IndexesDir = "indexes"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
||||
4
vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/spaces.go
generated
vendored
4
vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/spaces.go
generated
vendored
@@ -1147,8 +1147,8 @@ func canDeleteSpace(ctx context.Context, spaceID string, typ string, purge bool,
|
||||
return errtypes.PermissionDenied("user is not allowed to delete a personal space")
|
||||
}
|
||||
|
||||
// space managers are allowed to disable and delete their project spaces
|
||||
if rp, err := p.AssemblePermissions(ctx, n); err == nil && permissions.IsManager(rp) {
|
||||
// space managers are allowed to disable their project spaces
|
||||
if rp, err := p.AssemblePermissions(ctx, n); err == nil && !purge && permissions.IsManager(rp) {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,10 @@ import (
|
||||
"github.com/vmihailenco/msgpack/v5"
|
||||
)
|
||||
|
||||
const (
|
||||
ChangesDir = "changes"
|
||||
)
|
||||
|
||||
var _propagationGracePeriod = 3 * time.Minute
|
||||
|
||||
type PropagationNode interface {
|
||||
@@ -80,7 +84,7 @@ func NewAsyncPropagator(treeSizeAccounting, treeTimeAccounting bool, o options.A
|
||||
return
|
||||
}
|
||||
|
||||
changesDirPath := filepath.Join(p.lookup.InternalRoot(), "changes")
|
||||
changesDirPath := filepath.Join(p.lookup.InternalRoot(), ChangesDir)
|
||||
doSleep := false // switch to not sleep on the first iteration
|
||||
for {
|
||||
if doSleep {
|
||||
@@ -426,5 +430,5 @@ func (p AsyncPropagator) propagate(ctx context.Context, pn PropagationNode, reca
|
||||
}
|
||||
|
||||
func (p AsyncPropagator) changesPath(spaceID, nodeID, filename string) string {
|
||||
return filepath.Join(p.lookup.InternalRoot(), "changes", spaceID[0:2], spaceID+":"+nodeID, filename)
|
||||
return filepath.Join(p.lookup.InternalRoot(), ChangesDir, spaceID[0:2], spaceID+":"+nodeID, filename)
|
||||
}
|
||||
|
||||
1
vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/tree/tree.go
generated
vendored
1
vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/tree/tree.go
generated
vendored
@@ -845,6 +845,7 @@ func (t *Tree) createDirNode(ctx context.Context, n *node.Node) (err error) {
|
||||
}
|
||||
|
||||
attributes := n.NodeMetadata(ctx)
|
||||
attributes[prefixes.SpaceIDAttr] = []byte(n.SpaceID)
|
||||
attributes[prefixes.TreesizeAttr] = []byte("0") // initialize as empty, TODO why bother? if it is not set we could treat it as 0?
|
||||
if t.options.TreeTimeAccounting || t.options.TreeSizeAccounting {
|
||||
attributes[prefixes.PropagationAttr] = []byte("1") // mark the node for propagation
|
||||
|
||||
1
vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/upload/upload.go
generated
vendored
1
vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/upload/upload.go
generated
vendored
@@ -135,6 +135,7 @@ func (session *DecomposedFsSession) FinishUploadDecomposed(ctx context.Context)
|
||||
|
||||
ctx = ctxpkg.ContextSetInitiator(ctx, session.InitiatorID())
|
||||
|
||||
ctx = context.WithoutCancel(ctx) // Do not cancel the finish process, we unconditionally want to complete the upload.
|
||||
sha1h, md5h, adler32h, err := node.CalculateChecksums(ctx, session.binPath())
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
1
vendor/github.com/opencloud-eu/reva/v2/pkg/storage/utils/decomposedfs/tree/tree.go
generated
vendored
1
vendor/github.com/opencloud-eu/reva/v2/pkg/storage/utils/decomposedfs/tree/tree.go
generated
vendored
@@ -867,6 +867,7 @@ func (t *Tree) createDirNode(ctx context.Context, n *node.Node) (err error) {
|
||||
}
|
||||
|
||||
attributes := n.NodeMetadata(ctx)
|
||||
attributes[prefixes.SpaceIDAttr] = []byte(n.SpaceID)
|
||||
attributes[prefixes.TreesizeAttr] = []byte("0") // initialize as empty, TODO why bother? if it is not set we could treat it as 0?
|
||||
if t.options.TreeTimeAccounting || t.options.TreeSizeAccounting {
|
||||
attributes[prefixes.PropagationAttr] = []byte("1") // mark the node for propagation
|
||||
|
||||
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
@@ -1360,7 +1360,7 @@ github.com/opencloud-eu/icap-client
|
||||
# github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20260310090739-853d972b282d
|
||||
## explicit; go 1.18
|
||||
github.com/opencloud-eu/libre-graph-api-go
|
||||
# github.com/opencloud-eu/reva/v2 v2.46.3-0.20260610093751-a33d8108dd91
|
||||
# github.com/opencloud-eu/reva/v2 v2.46.5
|
||||
## explicit; go 1.25.0
|
||||
github.com/opencloud-eu/reva/v2/cmd/revad/internal/grace
|
||||
github.com/opencloud-eu/reva/v2/cmd/revad/runtime
|
||||
|
||||
Reference in New Issue
Block a user