From b039f7b1a503770a0192ff21d8805a4786668887 Mon Sep 17 00:00:00 2001 From: Roman Perekhod Date: Tue, 27 Aug 2024 20:52:52 +0200 Subject: [PATCH] Protect the hidden space metafiles --- changelog/unreleased/space-metafiles.md | 6 ++++ .../http/services/owncloud/ocdav/delete.go | 28 +++++++++++++++++++ internal/http/services/owncloud/ocdav/move.go | 5 ++++ 3 files changed, 39 insertions(+) create mode 100644 changelog/unreleased/space-metafiles.md diff --git a/changelog/unreleased/space-metafiles.md b/changelog/unreleased/space-metafiles.md new file mode 100644 index 00000000000..e522d41a7f1 --- /dev/null +++ b/changelog/unreleased/space-metafiles.md @@ -0,0 +1,6 @@ +Enhancement: Protect the hidden space metafiles + +Protect the hidden space metafiles .space and .space/readme.md from deleting or moving. + +https://github.com/owncloud/reva/pull/248 +https://github.com/owncloud/ocis/issues/11112 diff --git a/internal/http/services/owncloud/ocdav/delete.go b/internal/http/services/owncloud/ocdav/delete.go index b2f29294a03..2763bb6a06c 100644 --- a/internal/http/services/owncloud/ocdav/delete.go +++ b/internal/http/services/owncloud/ocdav/delete.go @@ -23,7 +23,10 @@ import ( "errors" "net/http" "path" + "slices" + "strings" + gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1" rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1" provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" "github.com/owncloud/reva/v2/internal/http/services/owncloud/ocdav/net" @@ -81,6 +84,17 @@ func (s *svc) handleDelete(ctx context.Context, w http.ResponseWriter, r *http.R return http.StatusInternalServerError, errtypes.InternalError(err.Error()) } + sRes, err := client.Stat(ctx, &provider.StatRequest{Ref: ref}) + switch { + case err != nil: + span.RecordError(err) + return http.StatusInternalServerError, err + case sRes.GetStatus().GetCode() == rpc.Code_CODE_OK: + if sRes.GetInfo().GetSpace().GetSpaceType() == "project" && isPathInList(ctx, client, ref, ".space", ".space/readme.md") { + return http.StatusMethodNotAllowed, errors.New("deleting spaces meta file is not allowed") + } + } + res, err := client.Delete(ctx, req) switch { case err != nil: @@ -147,3 +161,17 @@ func (s *svc) handleSpacesDelete(w http.ResponseWriter, r *http.Request, spaceID return s.handleDelete(ctx, w, r, &ref) } + +func isPathInList(ctx context.Context, client gateway.GatewayAPIClient, ref *provider.Reference, paths ...string) bool { + resPath := strings.TrimPrefix(ref.GetPath(), "./") + if ref.GetResourceId().GetOpaqueId() != "" && ref.Path == "." { + gpRes, err := client.GetPath(ctx, &provider.GetPathRequest{ + ResourceId: ref.GetResourceId(), + }) + if err != nil || gpRes.GetStatus().GetCode() != rpc.Code_CODE_OK { + return false + } + resPath = strings.TrimPrefix(gpRes.GetPath(), "/") + } + return slices.Contains(paths, resPath) +} diff --git a/internal/http/services/owncloud/ocdav/move.go b/internal/http/services/owncloud/ocdav/move.go index 65192cfa3a6..d43c4d840b0 100644 --- a/internal/http/services/owncloud/ocdav/move.go +++ b/internal/http/services/owncloud/ocdav/move.go @@ -224,6 +224,11 @@ func (s *svc) handleMove(ctx context.Context, w http.ResponseWriter, r *http.Req w.WriteHeader(http.StatusBadRequest) return } + if srcStatRes.GetInfo().GetSpace().GetSpaceType() == "project" && isPathInList(ctx, client, src, ".space", ".space/readme.md") { + log.Error().Msg("moving spaces meta file is not allowed") + w.WriteHeader(http.StatusMethodNotAllowed) + return + } // check dst exists dstStatReq := &provider.StatRequest{Ref: dst}