1
0
mirror of https://github.com/cs3org/reva.git synced 2025-04-18 13:44:12 +03:00

Fix for broken ListRevision in EOS Projects (#5064)

* Fix for broken ListRevision in EOS Projects: we impersonate the owner for ListRevisions

* Update CI

---------

Co-authored-by: Jesse Geens <jgeens@cern.ch>
This commit is contained in:
Jesse Geens 2025-02-04 15:12:10 +01:00 committed by GitHub
parent 9f14cb9025
commit 19a7a864d4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 21 additions and 84 deletions

View File

@ -50,7 +50,7 @@ jobs:
push: ${{ inputs.push }}
platforms: ${{ inputs.platforms }}
- name: Upload ${{ steps.build.outputs.imageid }} Docker image to artifacts
uses: ishworkh/docker-image-artifact-upload@v1
uses: ishworkh/container-image-artifact-upload@v2.0.0
if: inputs.load
with:
image: ${{ steps.build.outputs.imageid }}

View File

@ -0,0 +1,5 @@
Bugfix: impersonate owner on ListRevisions
ListRevisions is currently broken for projects, because this happens on behalf of the user, instead of the owner of the file. This behaviour is changed to do the call on behalf of the owner (if we are in a non-home space).
https://github.com/cs3org/reva/pull/5064

View File

@ -1229,13 +1229,17 @@ func (c *Client) List(ctx context.Context, auth eosclient.Authorization, dpath s
fdrq.Role = new(erpc.RoleId)
uid, gid, err := utils.ExtractUidGid(auth)
if err != nil {
return nil, errors.Wrap(err, "Failed to extract uid/gid from auth")
}
fdrq.Role.Uid = uid
fdrq.Role.Gid = gid
if err == nil {
fdrq.Role.Uid = uid
fdrq.Role.Gid = gid
fdrq.Authkey = c.opt.Authkey
fdrq.Authkey = c.opt.Authkey
} else {
if auth.Token == "" {
return nil, errors.Wrap(err, "Failed to extract uid/gid from auth")
}
fdrq.Authkey = auth.Token
}
// Now send the req and see what happens
resp, err := c.cl.Find(appctx.ContextGetClean(ctx), fdrq)
@ -1580,8 +1584,7 @@ func (c *Client) ListVersions(ctx context.Context, auth eosclient.Authorization,
versionFolder := getVersionFolder(p)
finfos, err := c.List(ctx, auth, versionFolder)
if err != nil {
// we send back an empty list
return []*eosclient.FileInfo{}, nil
return []*eosclient.FileInfo{}, err
}
return finfos, nil
}

View File

@ -1285,66 +1285,6 @@ func (fs *eosfs) CreateHome(ctx context.Context) error {
return nil
}
func (fs *eosfs) createUserDir(ctx context.Context, u *userpb.User, path string, recursiveAttr bool) error {
rootAuth, err := fs.getRootAuth(ctx)
if err != nil {
return nil
}
chownAuth, err := fs.getUserAuth(ctx, u, "")
if err != nil {
return err
}
err = fs.c.CreateDir(ctx, rootAuth, path)
if err != nil {
// EOS will return success on mkdir over an existing directory.
return errors.Wrap(err, "eosfs: error creating dir")
}
err = fs.c.Chown(ctx, rootAuth, chownAuth, path)
if err != nil {
return errors.Wrap(err, "eosfs: error chowning directory")
}
err = fs.c.Chmod(ctx, rootAuth, "2700", path)
if err != nil {
return errors.Wrap(err, "eosfs: error chmoding directory")
}
attrs := []*eosclient.Attribute{
{
Type: SystemAttr,
Key: "mask",
Val: "700",
},
{
Type: SystemAttr,
Key: "allow.oc.sync",
Val: "1",
},
{
Type: SystemAttr,
Key: "mtime.propagation",
Val: "1",
},
{
Type: SystemAttr,
Key: "forced.atomic",
Val: "1",
},
}
for _, attr := range attrs {
err = fs.c.SetAttr(ctx, rootAuth, attr, false, recursiveAttr, path, "")
if err != nil {
return errors.Wrap(err, "eosfs: error setting attribute")
}
}
return nil
}
func (fs *eosfs) CreateDir(ctx context.Context, ref *provider.Reference) error {
log := appctx.GetLogger(ctx)
@ -1478,8 +1418,7 @@ func (fs *eosfs) ListRevisions(ctx context.Context, ref *provider.Reference) ([]
var auth eosclient.Authorization
var fn string
var err error
if !fs.conf.EnableHome && fs.conf.ImpersonateOwnerforRevisions {
if !fs.conf.EnableHome {
// We need to access the revisions for a non-home reference.
// We'll get the owner of the particular resource and impersonate them
// if we have access to it.
@ -1490,7 +1429,8 @@ func (fs *eosfs) ListRevisions(ctx context.Context, ref *provider.Reference) ([]
fn = fs.wrap(ctx, md.Path)
if md.PermissionSet.ListFileVersions {
auth, err = fs.getUIDGateway(ctx, md.Owner)
user := appctx.ContextMustGetUser(ctx)
auth, err = fs.getEOSToken(ctx, user, fn)
if err != nil {
return nil, err
}
@ -2084,6 +2024,7 @@ func (fs *eosfs) getUserAuth(ctx context.Context, u *userpb.User, fn string) (eo
return fs.extractUIDAndGID(u)
}
// Generate an EOS token that acts on behalf of the owner of the file `fn`
func (fs *eosfs) getEOSToken(ctx context.Context, u *userpb.User, fn string) (eosclient.Authorization, error) {
if fn == "" {
return eosclient.Authorization{}, errtypes.BadRequest("eosfs: path cannot be empty")
@ -2133,18 +2074,6 @@ func (fs *eosfs) getEOSToken(ctx context.Context, u *userpb.User, fn string) (eo
return eosclient.Authorization{Token: tkn}, nil
}
func (fs *eosfs) getRootAuth(ctx context.Context) (eosclient.Authorization, error) {
if fs.conf.ForceSingleUserMode {
if fs.singleUserAuth.Role.UID != "" && fs.singleUserAuth.Role.GID != "" {
return fs.singleUserAuth, nil
}
var err error
fs.singleUserAuth, err = fs.getUIDGateway(ctx, &userpb.UserId{OpaqueId: fs.conf.SingleUsername})
return fs.singleUserAuth, err
}
return eosclient.Authorization{Role: eosclient.Role{UID: "0", GID: "0"}}, nil
}
// Returns an eosclient.Authorization object with the uid/gid of the daemon user
// This is a system user with read-only access to files.
// We use it e.g. when retrieving metadata from a file when accessing through a guest account,