diff --git a/pkg/storage/fs/ocis/ocis.go b/pkg/storage/fs/ocis/ocis.go index fd68e4484f5..a01ad08c9ea 100644 --- a/pkg/storage/fs/ocis/ocis.go +++ b/pkg/storage/fs/ocis/ocis.go @@ -398,8 +398,8 @@ func (fs *ocisfs) ListFolder(ctx context.Context, ref *provider.Reference, mdKey for i := range children { np := rp + // add this childs permissions addPermissions(np, node.PermissionSet(ctx)) - // TODO only add this childs permissions if ri, err := children[i].AsResourceInfo(ctx, np, mdKeys); err == nil { finfos = append(finfos, ri) } diff --git a/pkg/storage/fs/owncloud/owncloud.go b/pkg/storage/fs/owncloud/owncloud.go index 22fb636eb5f..1a08f1b3e0e 100644 --- a/pkg/storage/fs/owncloud/owncloud.go +++ b/pkg/storage/fs/owncloud/owncloud.go @@ -523,6 +523,53 @@ func (fs *ocfs) getUser(ctx context.Context, usernameOrID string) (id *userpb.Us return res.User, nil } +// permissionSet returns the permission set for the current user +func (fs *ocfs) permissionSet(ctx context.Context, owner *userpb.UserId) *provider.ResourcePermissions { + if owner == nil { + return &provider.ResourcePermissions{ + Stat: true, + } + } + u, ok := user.ContextGetUser(ctx) + if !ok { + return &provider.ResourcePermissions{ + // no permissions + } + } + if u.Id == nil { + return &provider.ResourcePermissions{ + // no permissions + } + } + if u.Id.OpaqueId == owner.OpaqueId && u.Id.Idp == owner.Idp { + return &provider.ResourcePermissions{ + // owner has all permissions + AddGrant: true, + CreateContainer: true, + Delete: true, + GetPath: true, + GetQuota: true, + InitiateFileDownload: true, + InitiateFileUpload: true, + ListContainer: true, + ListFileVersions: true, + ListGrants: true, + ListRecycle: true, + Move: true, + PurgeRecycle: true, + RemoveGrant: true, + RestoreFileVersion: true, + RestoreRecycleItem: true, + Stat: true, + UpdateGrant: true, + } + } + // TODO fix permissions for share recipients by traversing reading acls up to the root? cache acls for the parent node and reuse it + return &provider.ResourcePermissions{ + ListContainer: true, + CreateContainer: true, + } +} func (fs *ocfs) convertToResourceInfo(ctx context.Context, fi os.FileInfo, ip string, sp string, c redis.Conn, mdKeys []string) *provider.ResourceInfo { id := readOrCreateID(ctx, ip, c) @@ -596,13 +643,12 @@ func (fs *ocfs) convertToResourceInfo(ctx context.Context, fi os.FileInfo, ip st } ri := &provider.ResourceInfo{ - Id: &provider.ResourceId{OpaqueId: id}, - Path: sp, - Type: getResourceType(fi.IsDir()), - Etag: etag, - MimeType: mime.Detect(fi.IsDir(), ip), - Size: uint64(fi.Size()), - PermissionSet: &provider.ResourcePermissions{ListContainer: true, CreateContainer: true}, + Id: &provider.ResourceId{OpaqueId: id}, + Path: sp, + Type: getResourceType(fi.IsDir()), + Etag: etag, + MimeType: mime.Detect(fi.IsDir(), ip), + Size: uint64(fi.Size()), Mtime: &types.Timestamp{ Seconds: uint64(fi.ModTime().Unix()), // TODO read nanos from where? Nanos: fi.MTimeNanos, @@ -618,6 +664,8 @@ func (fs *ocfs) convertToResourceInfo(ctx context.Context, fi os.FileInfo, ip st appctx.GetLogger(ctx).Error().Err(err).Msg("error getting owner") } + ri.PermissionSet = fs.permissionSet(ctx, ri.Owner) + return ri } func getResourceType(isDir bool) provider.ResourceType { diff --git a/pkg/storage/fs/s3/s3.go b/pkg/storage/fs/s3/s3.go index a943fdb948d..078a9efea28 100644 --- a/pkg/storage/fs/s3/s3.go +++ b/pkg/storage/fs/s3/s3.go @@ -142,6 +142,32 @@ type s3FS struct { config *config } +// permissionSet returns the permission set for the current user +func (fs *s3FS) permissionSet(ctx context.Context) *provider.ResourcePermissions { + // TODO fix permissions for share recipients by traversing reading acls up to the root? cache acls for the parent node and reuse it + return &provider.ResourcePermissions{ + // owner has all permissions + AddGrant: true, + CreateContainer: true, + Delete: true, + GetPath: true, + GetQuota: true, + InitiateFileDownload: true, + InitiateFileUpload: true, + ListContainer: true, + ListFileVersions: true, + ListGrants: true, + ListRecycle: true, + Move: true, + PurgeRecycle: true, + RemoveGrant: true, + RestoreFileVersion: true, + RestoreRecycleItem: true, + Stat: true, + UpdateGrant: true, + } +} + func (fs *s3FS) normalizeObject(ctx context.Context, o *s3.Object, fn string) *provider.ResourceInfo { fn = fs.removeRoot(path.Join("/", fn)) isDir := strings.HasSuffix(*o.Key, "/") @@ -151,7 +177,7 @@ func (fs *s3FS) normalizeObject(ctx context.Context, o *s3.Object, fn string) *p Type: getResourceType(isDir), Etag: *o.ETag, MimeType: mime.Detect(isDir, fn), - PermissionSet: &provider.ResourcePermissions{ListContainer: true, CreateContainer: true}, + PermissionSet: fs.permissionSet(ctx), Size: uint64(*o.Size), Mtime: &types.Timestamp{ Seconds: uint64(o.LastModified.Unix()), @@ -180,7 +206,7 @@ func (fs *s3FS) normalizeHead(ctx context.Context, o *s3.HeadObjectOutput, fn st Type: getResourceType(isDir), Etag: *o.ETag, MimeType: mime.Detect(isDir, fn), - PermissionSet: &provider.ResourcePermissions{ListContainer: true, CreateContainer: true}, + PermissionSet: fs.permissionSet(ctx), Size: uint64(*o.ContentLength), Mtime: &types.Timestamp{ Seconds: uint64(o.LastModified.Unix()), @@ -200,7 +226,7 @@ func (fs *s3FS) normalizeCommonPrefix(ctx context.Context, p *s3.CommonPrefix) * Type: getResourceType(true), Etag: "TODO(labkode)", MimeType: mime.Detect(true, fn), - PermissionSet: &provider.ResourcePermissions{ListContainer: true, CreateContainer: true}, + PermissionSet: fs.permissionSet(ctx), Size: 0, Mtime: &types.Timestamp{ Seconds: 0, @@ -492,13 +518,13 @@ func (fs *s3FS) GetMD(ctx context.Context, ref *provider.Reference, mdKeys []str return nil, errors.Wrap(err, "s3FS: error listing "+fn) } - for _, o := range output.CommonPrefixes { + for i := range output.CommonPrefixes { log.Debug(). - Interface("object", *o). + Interface("object", output.CommonPrefixes[i]). Str("fn", fn). Msg("found CommonPrefix") - if *o.Prefix == fn+"/" { - return fs.normalizeCommonPrefix(ctx, o), nil + if *output.CommonPrefixes[i].Prefix == fn+"/" { + return fs.normalizeCommonPrefix(ctx, output.CommonPrefixes[i]), nil } } @@ -532,12 +558,12 @@ func (fs *s3FS) ListFolder(ctx context.Context, ref *provider.Reference, mdKeys return nil, errors.Wrap(err, "s3FS: error listing "+fn) } - for _, p := range output.CommonPrefixes { - finfos = append(finfos, fs.normalizeCommonPrefix(ctx, p)) + for i := range output.CommonPrefixes { + finfos = append(finfos, fs.normalizeCommonPrefix(ctx, output.CommonPrefixes[i])) } - for _, o := range output.Contents { - finfos = append(finfos, fs.normalizeObject(ctx, o, *o.Key)) + for i := range output.Contents { + finfos = append(finfos, fs.normalizeObject(ctx, output.Contents[i], *output.Contents[i].Key)) } input.ContinuationToken = output.NextContinuationToken diff --git a/pkg/storage/utils/eosfs/eosfs.go b/pkg/storage/utils/eosfs/eosfs.go index 8952f684899..87f53a3022e 100644 --- a/pkg/storage/utils/eosfs/eosfs.go +++ b/pkg/storage/utils/eosfs/eosfs.go @@ -1310,24 +1310,22 @@ func (fs *eosfs) convertToFileReference(ctx context.Context, eosFileInfo *eoscli return info, nil } -// permissionSet returns the permission set for the curren user +// permissionSet returns the permission set for the current user func (fs *eosfs) permissionSet(ctx context.Context, owner *userpb.UserId) *provider.ResourcePermissions { u, ok := user.ContextGetUser(ctx) if !ok { - appctx.GetLogger(ctx).Debug().Msg("no user in context, returning default permissions (none)") return &provider.ResourcePermissions{ // no permissions } } if u.Id == nil { - appctx.GetLogger(ctx).Error().Msg("user has no id, returning default permissions (none)") return &provider.ResourcePermissions{ // no permissions } } if u.Id.OpaqueId == owner.OpaqueId && u.Id.Idp == owner.Idp { return &provider.ResourcePermissions{ - // owner has all all permissions + // owner has all permissions AddGrant: true, CreateContainer: true, Delete: true, diff --git a/pkg/storage/utils/localfs/localfs.go b/pkg/storage/utils/localfs/localfs.go index 909b1acd9d3..f49016e71f7 100644 --- a/pkg/storage/utils/localfs/localfs.go +++ b/pkg/storage/utils/localfs/localfs.go @@ -252,6 +252,49 @@ func (fs *localfs) isShareFolderChild(ctx context.Context, p string) bool { return len(vals) > 1 && vals[1] != "" } +// permissionSet returns the permission set for the current user +func (fs *localfs) permissionSet(ctx context.Context, owner *userpb.UserId) *provider.ResourcePermissions { + u, ok := user.ContextGetUser(ctx) + if !ok { + return &provider.ResourcePermissions{ + // no permissions + } + } + if u.Id == nil { + return &provider.ResourcePermissions{ + // no permissions + } + } + if u.Id.OpaqueId == owner.OpaqueId && u.Id.Idp == owner.Idp { + return &provider.ResourcePermissions{ + // owner has all permissions + AddGrant: true, + CreateContainer: true, + Delete: true, + GetPath: true, + GetQuota: true, + InitiateFileDownload: true, + InitiateFileUpload: true, + ListContainer: true, + ListFileVersions: true, + ListGrants: true, + ListRecycle: true, + Move: true, + PurgeRecycle: true, + RemoveGrant: true, + RestoreFileVersion: true, + RestoreRecycleItem: true, + Stat: true, + UpdateGrant: true, + } + } + // TODO fix permissions for share recipients by traversing reading acls up to the root? cache acls for the parent node and reuse it + return &provider.ResourcePermissions{ + ListContainer: true, + CreateContainer: true, + } +} + func (fs *localfs) normalize(ctx context.Context, fi os.FileInfo, fn string, mdKeys []string) (*provider.ResourceInfo, error) { fp := fs.unwrap(ctx, path.Join("/", fn)) owner, err := getUser(ctx) @@ -279,7 +322,7 @@ func (fs *localfs) normalize(ctx context.Context, fi os.FileInfo, fn string, mdK Etag: calcEtag(ctx, fi), MimeType: mime.Detect(fi.IsDir(), fp), Size: uint64(fi.Size()), - PermissionSet: &provider.ResourcePermissions{ListContainer: true, CreateContainer: true}, + PermissionSet: fs.permissionSet(ctx, owner.Id), Mtime: &types.Timestamp{ Seconds: uint64(fi.ModTime().Unix()), },