Skip to content

Commit

Permalink
allow full paths targets
Browse files Browse the repository at this point in the history
add changelog

fix logic

more fixes

use full paths for file target

use path and name from shares jail if it is configured

Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>

adjust tests, lots of them

Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>

make share_prefix determine paths

Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>

revert test exceptions

Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>

drop unrelated changes after rebase

Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>

fix rebase

Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>

fix tests

Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>
  • Loading branch information
labkode authored and butonic committed Aug 10, 2021
1 parent b317948 commit 0efb2c8
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 5 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
2 changes: 1 addition & 1 deletion internal/http/services/owncloud/ocs/conversions/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ type ShareData struct {
FileSource string `json:"file_source" xml:"file_source"`
// The unique node id of the parent node of the item being shared.
FileParent string `json:"file_parent" xml:"file_parent"`
// The basename of the shared file.
// The mount path of the shared file.
FileTarget string `json:"file_target" xml:"file_target"`
// The uid of the share recipient. This is either
// - a GID (group id) if it is being shared with a group or
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,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 @@ -648,8 +669,42 @@ 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)
Expand All @@ -658,6 +713,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)

Expand Down Expand Up @@ -790,12 +854,22 @@ 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 {
s.Path = path.Join("/", info.Path)
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("/", info.Path)
s.Path = path.Join("/", info.Path)
default:
s.FileTarget = path.Join(h.sharePrefix, path.Base(info.Path))
s.Path = path.Join("/", path.Base(info.Path))
// FIXME make tests path with:
// s.Path = path.Join("/", info.Path)
// the sharing tests expect the paths to bo relative to the owners home path,
// but ocis returns a global path, which starts with /users/<username> (or /home or whatever ... at least something global)
}
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
s.ItemType = conversions.ResourceType(info.GetType()).String()
Expand Down

0 comments on commit 0efb2c8

Please sign in to comment.