Skip to content

Commit

Permalink
Allow full paths (cs3org#1739)
Browse files Browse the repository at this point in the history
  • Loading branch information
butonic authored and glpatcern committed Sep 23, 2021
1 parent c9a95b1 commit c55e637
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 4 deletions.
6 changes: 6 additions & 0 deletions changelog/unreleased/fix-sharing-paths.md
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,27 @@ 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 := client.ListContainer(ctx, &provider.ListContainerRequest{
Ref: &provider.Reference{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, len(lrsRes.GetShares()))

// TODO(refs) filter out "invalid" shares
Expand Down Expand Up @@ -600,16 +621,60 @@ func (h *Handler) listSharesWithMe(w http.ResponseWriter, r *http.Request) {
h.mapUserIds(r.Context(), client, data)

if 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/<space id> 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
data.Path = path.Join(h.sharePrefix, path.Base(info.Path))

if h.sharePrefix != "/" {
// 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 = path.Join(h.sharePrefix, path.Base(info.Path))
data.Path = path.Join(h.sharePrefix, path.Base(info.Path))
}
} else {
data.FileTarget = info.Path
data.Path = info.Path
}
}

shares = append(shares, data)
log.Debug().Msgf("share: %+v", *data)
}

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)

Expand Down Expand Up @@ -731,12 +796,17 @@ func (h *Handler) addFileInfo(ctx context.Context, s *conversions.ShareData, inf
// TODO Storage: int
s.ItemSource = wrapResourceID(info.Id)
s.FileSource = s.ItemSource
if s.ShareType == conversions.ShareTypePublicLink {
switch {
case s.ShareType == conversions.ShareTypePublicLink:
s.FileTarget = path.Join("/", path.Base(info.Path))
} else {
s.Path = path.Join("/", path.Base(info.Path))
case h.sharePrefix == "/":
s.FileTarget = path.Join("/", path.Base(info.Path))
s.Path = path.Join("/", path.Base(info.Path))
default:
s.FileTarget = path.Join(h.sharePrefix, path.Base(info.Path))
s.Path = path.Join("/", path.Base(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.StorageID = storageIDPrefix + s.FileTarget
// TODO FileParent:
// item type
Expand Down

0 comments on commit c55e637

Please sign in to comment.