From 105b22e4fdc95c0008fb8e8e16a2f23298357f38 Mon Sep 17 00:00:00 2001 From: Hugo Gonzalez Labrador Date: Wed, 31 Mar 2021 16:35:43 +0200 Subject: [PATCH 1/6] allow full paths targets --- .../owncloud/ocs/handlers/apps/sharing/shares/shares.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go b/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go index 8cc1dd79fe..9fbfe77457 100644 --- a/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go +++ b/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go @@ -737,11 +737,12 @@ func (h *Handler) listSharesWithMe(w http.ResponseWriter, r *http.Request) { if data.State == ocsStateAccepted { // Needed because received shares can be jailed in a folder in the users home - data.FileTarget = path.Join(h.sharePrefix, path.Base(info.Path)) - data.Path = path.Join(h.sharePrefix, path.Base(info.Path)) + data.FileTarget = path.Join(h.sharePrefix, info.Path) + data.Path = path.Join(h.sharePrefix, info.Path) } shares = append(shares, data) + log.Info().Msgf("listSharesWithMe: %+v", *data) } response.WriteOCSSuccess(w, r, shares) @@ -897,7 +898,7 @@ func (h *Handler) addFileInfo(ctx context.Context, s *conversions.ShareData, inf // TODO Storage: int s.ItemSource = wrapResourceID(info.Id) s.FileSource = s.ItemSource - s.FileTarget = path.Join("/", path.Base(info.Path)) + s.FileTarget = path.Join("/", info.Path) s.Path = path.Join("/", path.Base(info.Path)) // TODO hm this might have to be relative to the users home ... depends on the webdav_namespace config // TODO FileParent: // item type From e17332184fb343e42548656673364422dd7895a0 Mon Sep 17 00:00:00 2001 From: Hugo Gonzalez Labrador Date: Wed, 31 Mar 2021 16:49:36 +0200 Subject: [PATCH 2/6] add changelog --- changelog/unreleased/fix-sharing-paths.md | 6 ++++++ .../owncloud/ocs/handlers/apps/sharing/shares/shares.go | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 changelog/unreleased/fix-sharing-paths.md diff --git a/changelog/unreleased/fix-sharing-paths.md b/changelog/unreleased/fix-sharing-paths.md new file mode 100644 index 0000000000..c59bc5c38a --- /dev/null +++ b/changelog/unreleased/fix-sharing-paths.md @@ -0,0 +1,6 @@ +Bugfix: Allow to expose full paths in OCS API + +Before this fix a share file_target was always harcoded to use a base path. +This fix provides the possiblity to expose full paths in the OCIS API and asymptotically in OCIS web. + +https://github.com/cs3org/reva/pull/1605 diff --git a/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go b/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go index 9fbfe77457..9ea4d5e121 100644 --- a/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go +++ b/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go @@ -742,7 +742,7 @@ func (h *Handler) listSharesWithMe(w http.ResponseWriter, r *http.Request) { } shares = append(shares, data) - log.Info().Msgf("listSharesWithMe: %+v", *data) + log.Debug().Msgf("listSharesWithMe: %+v", *data) } response.WriteOCSSuccess(w, r, shares) From 435819b128993427ba36eb11636c08c7db534db3 Mon Sep 17 00:00:00 2001 From: Hugo Gonzalez Labrador Date: Thu, 1 Apr 2021 13:36:29 +0200 Subject: [PATCH 3/6] fix logic --- .../owncloud/ocs/handlers/apps/sharing/shares/shares.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go b/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go index 9ea4d5e121..b70eb0ef38 100644 --- a/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go +++ b/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go @@ -664,17 +664,16 @@ func (h *Handler) listSharesWithMe(w http.ResponseWriter, r *http.Request) { response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "grpc ListReceivedShares request failed", err) return } - lrsRes.GetShares() shares := make([]*conversions.ShareData, 0) var info *provider.ResourceInfo // TODO(refs) filter out "invalid" shares for _, rs := range lrsRes.GetShares() { - if stateFilter != ocsStateUnknown && rs.GetState() != stateFilter { continue } + if pinfo != nil { // check if the shared resource matches the path resource if rs.Share.ResourceId.StorageId != pinfo.GetId().StorageId || @@ -898,8 +897,8 @@ func (h *Handler) addFileInfo(ctx context.Context, s *conversions.ShareData, inf // TODO Storage: int s.ItemSource = wrapResourceID(info.Id) s.FileSource = s.ItemSource - s.FileTarget = path.Join("/", info.Path) - s.Path = path.Join("/", path.Base(info.Path)) // TODO hm this might have to be relative to the users home ... depends on the webdav_namespace config + s.FileTarget = path.Join("/", path.Base(info.Path)) + s.Path = path.Join("/", info.Path) // TODO hm this might have to be relative to the users home ... depends on the webdav_namespace config // TODO FileParent: // item type s.ItemType = conversions.ResourceType(info.GetType()).String() From 69077a60d04f5898b7261ec7814a184ce6dfd66e Mon Sep 17 00:00:00 2001 From: Hugo Gonzalez Labrador Date: Thu, 1 Apr 2021 16:20:44 +0200 Subject: [PATCH 4/6] more fixes --- .../owncloud/ocs/handlers/apps/sharing/shares/shares.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go b/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go index b70eb0ef38..7989c11fbc 100644 --- a/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go +++ b/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go @@ -736,12 +736,12 @@ func (h *Handler) listSharesWithMe(w http.ResponseWriter, r *http.Request) { if data.State == ocsStateAccepted { // Needed because received shares can be jailed in a folder in the users home - data.FileTarget = path.Join(h.sharePrefix, info.Path) + data.FileTarget = path.Join(h.sharePrefix, path.Base(info.Path)) data.Path = path.Join(h.sharePrefix, info.Path) } shares = append(shares, data) - log.Debug().Msgf("listSharesWithMe: %+v", *data) + log.Debug().Msgf("share: %+v", *data) } response.WriteOCSSuccess(w, r, shares) From 3d58237dd7ec5fb2e05658e0934aded670862d98 Mon Sep 17 00:00:00 2001 From: Hugo Gonzalez Labrador Date: Tue, 6 Apr 2021 10:47:11 +0200 Subject: [PATCH 5/6] use full paths for file target --- .../owncloud/ocs/handlers/apps/sharing/shares/shares.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go b/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go index 7989c11fbc..edfefd04d4 100644 --- a/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go +++ b/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go @@ -736,7 +736,7 @@ func (h *Handler) listSharesWithMe(w http.ResponseWriter, r *http.Request) { if data.State == ocsStateAccepted { // Needed because received shares can be jailed in a folder in the users home - data.FileTarget = path.Join(h.sharePrefix, path.Base(info.Path)) + data.FileTarget = path.Join(h.sharePrefix, info.Path) data.Path = path.Join(h.sharePrefix, info.Path) } @@ -897,8 +897,8 @@ func (h *Handler) addFileInfo(ctx context.Context, s *conversions.ShareData, inf // TODO Storage: int s.ItemSource = wrapResourceID(info.Id) s.FileSource = s.ItemSource - s.FileTarget = path.Join("/", path.Base(info.Path)) - s.Path = path.Join("/", info.Path) // TODO hm this might have to be relative to the users home ... depends on the webdav_namespace config + s.FileTarget = path.Join("/", info.Path) + s.Path = path.Join("/", info.Path) // TODO FileParent: // item type s.ItemType = conversions.ResourceType(info.GetType()).String() From a2a32228195f6a5a52744d5c679289b4bbfd5793 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Thu, 6 May 2021 12:50:16 +0000 Subject: [PATCH 6/6] use path and name from shares jail if it is configured MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jörn Friedrich Dreyer --- .../handlers/apps/sharing/shares/shares.go | 81 ++++++++++++++++--- 1 file changed, 69 insertions(+), 12 deletions(-) diff --git a/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go b/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go index edfefd04d4..14c9570eaa 100644 --- a/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go +++ b/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go @@ -665,6 +665,29 @@ func (h *Handler) listSharesWithMe(w http.ResponseWriter, r *http.Request) { return } + // in a jailed namespace we have to point to the mount point in the users /Shares jail + // to do that we have to list the /Shares jail and use those paths instead of stating the shared resources + // The stat results would start with a path outside the jail and thus be inaccessible + + var shareJailInfos []*provider.ResourceInfo + + if h.sharePrefix != "/" { + // we only need the path from the share jail for accepted shares + if stateFilter == collaboration.ShareState_SHARE_STATE_ACCEPTED || stateFilter == ocsStateUnknown { + // only log errors. They may happen but we can continue trying to at least list the shares + lcRes, err := gwc.ListContainer(ctx, &provider.ListContainerRequest{ + Ref: &provider.Reference{ + Spec: &provider.Reference_Path{Path: path.Join(h.homeNamespace, h.sharePrefix)}, + }, + }) + if err != nil || lcRes.Status.Code != rpc.Code_CODE_OK { + h.logProblems(lcRes.GetStatus(), err, "could not list container, continuing without share jail path info") + } else { + shareJailInfos = lcRes.Infos + } + } + } + shares := make([]*conversions.ShareData, 0) var info *provider.ResourceInfo @@ -717,29 +740,54 @@ func (h *Handler) listSharesWithMe(w http.ResponseWriter, r *http.Request) { continue } + if err := h.addFileInfo(ctx, data, info); err != nil { + log.Debug().Interface("received_share", rs).Interface("info", info).Interface("shareData", data).Err(err).Msg("could not add file info, skipping") + continue + } + h.mapUserIds(r.Context(), gwc, data) + switch rs.GetState() { case collaboration.ShareState_SHARE_STATE_PENDING: data.State = ocsStatePending case collaboration.ShareState_SHARE_STATE_ACCEPTED: data.State = ocsStateAccepted + // only accepted shares can be accessed when jailing users into their home. + // in this case we cannot stat shared resources that are outside the users home (/home), + // the path (/users/u-u-i-d/foo) will not be accessible + + // in a global namespace we can access the share using the full path + // in a jailed namespace we have to point to the mount point in the users /Shares jail + // - needed for oc10 hot migration + // or use the /dav/spaces/ endpoint? + + // list /Shares and match fileids with list of received shares + // - only works for a /Shares folder jail + // - does not work for freely mountable shares as in oc10 because we would need to iterate over the whole tree, there is no listing of mountpoints, yet + + // can we return the mountpoint when the gateway resolves the listing of shares? + // - no, the gateway only sees the same list any has the same options as the ocs service + // - we would need to have a list of mountpoints for the shares -> owncloudstorageprovider for hot migration migration + + // best we can do for now is stat the /Shares jail if it is set and return those paths + + // if we are in a jail and the current share has been accepted use the stat from the share jail + // Needed because received shares can be jailed in a folder in the users home + + // if we have share jail infos use them to build the path + if sji := findMatch(shareJailInfos, rs.Share.ResourceId); sji != nil { + // override path with info from share jail + data.FileTarget = path.Join(h.sharePrefix, path.Base(sji.Path)) + data.Path = path.Join(h.sharePrefix, path.Base(sji.Path)) + } else { + data.FileTarget = info.Path + data.Path = info.Path + } case collaboration.ShareState_SHARE_STATE_REJECTED: data.State = ocsStateRejected default: data.State = ocsStateUnknown } - if err := h.addFileInfo(ctx, data, info); err != nil { - log.Debug().Interface("received_share", rs).Interface("info", info).Interface("shareData", data).Err(err).Msg("could not add file info, skipping") - continue - } - h.mapUserIds(r.Context(), gwc, data) - - if data.State == ocsStateAccepted { - // Needed because received shares can be jailed in a folder in the users home - data.FileTarget = path.Join(h.sharePrefix, info.Path) - data.Path = path.Join(h.sharePrefix, info.Path) - } - shares = append(shares, data) log.Debug().Msgf("share: %+v", *data) } @@ -747,6 +795,15 @@ func (h *Handler) listSharesWithMe(w http.ResponseWriter, r *http.Request) { response.WriteOCSSuccess(w, r, shares) } +func findMatch(shareJailInfos []*provider.ResourceInfo, id *provider.ResourceId) *provider.ResourceInfo { + for i := range shareJailInfos { + if shareJailInfos[i].Id != nil && shareJailInfos[i].Id.StorageId == id.StorageId && shareJailInfos[i].Id.OpaqueId == id.OpaqueId { + return shareJailInfos[i] + } + } + return nil +} + func (h *Handler) listSharesWithOthers(w http.ResponseWriter, r *http.Request) { shares := make([]*conversions.ShareData, 0)