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:
parent
9f14cb9025
commit
19a7a864d4
2
.github/workflows/docker.yml
vendored
2
.github/workflows/docker.yml
vendored
@ -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 }}
|
||||
|
5
changelog/unreleased/listrevisions-impersonate.md
Normal file
5
changelog/unreleased/listrevisions-impersonate.md
Normal 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
|
@ -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
|
||||
}
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user