From 9f03073f6f67ec692e3451cdf5afabed1efcd513 Mon Sep 17 00:00:00 2001 From: Michael Barz Date: Thu, 14 Dec 2023 15:53:52 +0100 Subject: [PATCH 1/3] feat: bump reva --- go.mod | 2 +- go.sum | 6 +- .../publicshareprovider.go | 139 ++++++++++++++++-- vendor/modules.txt | 3 +- 4 files changed, 133 insertions(+), 17 deletions(-) diff --git a/go.mod b/go.mod index 4979437bb22..38981b8c272 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/coreos/go-oidc v2.2.1+incompatible github.com/coreos/go-oidc/v3 v3.9.0 github.com/cs3org/go-cs3apis v0.0.0-20231023073225-7748710e0781 - github.com/cs3org/reva/v2 v2.17.1-0.20231214082636-a8467337208a + github.com/cs3org/reva/v2 v2.17.1-0.20231215110403-2f85376a4d3f github.com/dhowden/tag v0.0.0-20230630033851-978a0926ee25 github.com/disintegration/imaging v1.6.2 github.com/dutchcoders/go-clamd v0.0.0-20170520113014-b970184f4d9e diff --git a/go.sum b/go.sum index 1566bc39207..f769635fb97 100644 --- a/go.sum +++ b/go.sum @@ -1021,8 +1021,8 @@ github.com/crewjam/saml v0.4.14 h1:g9FBNx62osKusnFzs3QTN5L9CVA/Egfgm+stJShzw/c= github.com/crewjam/saml v0.4.14/go.mod h1:UVSZCf18jJkk6GpWNVqcyQJMD5HsRugBPf4I1nl2mME= github.com/cs3org/go-cs3apis v0.0.0-20231023073225-7748710e0781 h1:BUdwkIlf8IS2FasrrPg8gGPHQPOrQ18MS1Oew2tmGtY= github.com/cs3org/go-cs3apis v0.0.0-20231023073225-7748710e0781/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY= -github.com/cs3org/reva/v2 v2.17.1-0.20231214082636-a8467337208a h1:ri98OWOuAY5tF3jpeKSItna3O4I0SedxzVgPQJPZXoM= -github.com/cs3org/reva/v2 v2.17.1-0.20231214082636-a8467337208a/go.mod h1:oX1YtLKGr7jatGk0CpPM4GKbSEIdHhmsQuSAYElnN1U= +github.com/cs3org/reva/v2 v2.17.1-0.20231215110403-2f85376a4d3f h1:AF7fcQ7dfi3sxKLpIFJ8Y2uKJ8umB9K+nFe+3tDa4oA= +github.com/cs3org/reva/v2 v2.17.1-0.20231215110403-2f85376a4d3f/go.mod h1:oX1YtLKGr7jatGk0CpPM4GKbSEIdHhmsQuSAYElnN1U= github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -1688,6 +1688,8 @@ github.com/maxymania/go-system v0.0.0-20170110133659-647cc364bf0b h1:Q53idHrTuQD github.com/maxymania/go-system v0.0.0-20170110133659-647cc364bf0b/go.mod h1:KirJrATYGbTyUwVR26xIkaipRqRcMRXBf8N5dacvGus= github.com/mendsley/gojwk v0.0.0-20141217222730-4d5ec6e58103 h1:Z/i1e+gTZrmcGeZyWckaLfucYG6KYOXLWo4co8pZYNY= github.com/mendsley/gojwk v0.0.0-20141217222730-4d5ec6e58103/go.mod h1:o9YPB5aGP8ob35Vy6+vyq3P3bWe7NQWzf+JLiXCiMaE= +github.com/micbar/reva/v2 v2.0.0-20231214215940-ac484c63b45e h1:IsCx3d+WflZgIGFV5TPqGoMRWiygaj11QJvefcUNTUQ= +github.com/micbar/reva/v2 v2.0.0-20231214215940-ac484c63b45e/go.mod h1:oX1YtLKGr7jatGk0CpPM4GKbSEIdHhmsQuSAYElnN1U= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.40/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= diff --git a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/publicshareprovider/publicshareprovider.go b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/publicshareprovider/publicshareprovider.go index 8687a4da459..38b64f49d44 100644 --- a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/publicshareprovider/publicshareprovider.go +++ b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/publicshareprovider/publicshareprovider.go @@ -20,6 +20,7 @@ package publicshareprovider import ( "context" + "encoding/json" "fmt" "regexp" "strconv" @@ -301,7 +302,7 @@ func (s *service) CreatePublicShare(ctx context.Context, req *link.CreatePublicS // enforce password if needed setPassword := grant.GetPassword() - if !isInternalLink && enforcePassword(grant, s.conf) && len(setPassword) == 0 { + if !isInternalLink && enforcePassword(false, grant.GetPermissions().GetPermissions(), s.conf) && len(setPassword) == 0 { return &link.CreatePublicShareResponse{ Status: status.NewInvalidArg(ctx, "password protection is enforced"), }, nil @@ -316,13 +317,9 @@ func (s *service) CreatePublicShare(ctx context.Context, req *link.CreatePublicS } } - u, ok := ctxpkg.ContextGetUser(ctx) - if !ok { - log.Error().Msg(getUserCtxErrMsg) - } - + user := ctxpkg.ContextMustGetUser(ctx) res := &link.CreatePublicShareResponse{} - share, err := s.sm.CreatePublicShare(ctx, u, req.GetResourceInfo(), req.GetGrant()) + share, err := s.sm.CreatePublicShare(ctx, user, req.GetResourceInfo(), req.GetGrant()) switch { case err != nil: log.Error().Err(err).Interface("request", req).Msg("could not write public share") @@ -462,12 +459,114 @@ func (s *service) UpdatePublicShare(ctx context.Context, req *link.UpdatePublicS log := appctx.GetLogger(ctx) log.Info().Str("publicshareprovider", "update").Msg("update public share") - u, ok := ctxpkg.ContextGetUser(ctx) - if !ok { - log.Error().Msg(getUserCtxErrMsg) + gatewayClient, err := s.gatewaySelector.Next() + if err != nil { + return nil, err } - updateR, err := s.sm.UpdatePublicShare(ctx, u, req) + user := ctxpkg.ContextMustGetUser(ctx) + ps, err := s.sm.GetPublicShare(ctx, user, req.GetRef(), false) + if err != nil { + return &link.UpdatePublicShareResponse{ + Status: status.NewInternal(ctx, "error loading public share"), + }, err + } + + isInternalLink := isInternalLink(req, ps) + + // users should always be able to downgrade links to internal links + // when they are the creator of the link + // all other users should have the WritePublicLink permission + if !isInternalLink && !publicshare.IsCreatedByUser(*ps, user) { + canWriteLink, err := utils.CheckPermission(ctx, permission.WritePublicLink, gatewayClient) + if err != nil { + return &link.UpdatePublicShareResponse{ + Status: status.NewInternal(ctx, "error loading public share"), + }, err + } + if !canWriteLink { + return &link.UpdatePublicShareResponse{ + Status: status.NewPermissionDenied(ctx, nil, "no permission to update public share"), + }, nil + } + } + + sRes, err := gatewayClient.Stat(ctx, &provider.StatRequest{Ref: &provider.Reference{ResourceId: ps.ResourceId}}) + if err != nil { + log.Err(err).Interface("resource_id", ps.ResourceId).Msg("failed to stat shared resource") + return &link.UpdatePublicShareResponse{ + Status: status.NewInternal(ctx, "failed to stat shared resource"), + }, err + } + + if !publicshare.IsCreatedByUser(*ps, user) { + if !sRes.GetInfo().GetPermissionSet().UpdateGrant { + return &link.UpdatePublicShareResponse{ + Status: status.NewPermissionDenied(ctx, nil, "no permission to update public share"), + }, err + } + } + + // check if the user can change the permissions to the desired permissions + updatePermissions := req.GetUpdate().GetType() == link.UpdatePublicShareRequest_Update_TYPE_PERMISSIONS + if updatePermissions && + !conversions.SufficientCS3Permissions( + sRes.GetInfo().GetPermissionSet(), + req.GetUpdate().GetGrant().GetPermissions().GetPermissions(), + ) { + return &link.UpdatePublicShareResponse{ + Status: status.NewInvalidArg(ctx, "insufficient permissions to update that kind of share"), + }, nil + } + if updatePermissions { + beforePerm, _ := json.Marshal(sRes.GetInfo().GetPermissionSet()) + afterPerm, _ := json.Marshal(req.GetUpdate().GetGrant().GetPermissions()) + log.Info(). + Str("shares", "update"). + Msgf("updating permissions from %v to: %v", + string(beforePerm), + string(afterPerm), + ) + } + + grant := req.GetUpdate().GetGrant() + + // validate expiration date + if grant.GetExpiration() != nil { + expirationDateTime := utils.TSToTime(grant.GetExpiration()).UTC() + if expirationDateTime.Before(time.Now().UTC()) { + msg := fmt.Sprintf("expiration date is in the past: %s", expirationDateTime.Format(time.RFC3339)) + return &link.UpdatePublicShareResponse{ + Status: status.NewInvalidArg(ctx, msg), + }, nil + } + } + + // enforce password if needed + canOptOut, err := utils.CheckPermission(ctx, permission.DeleteReadOnlyPassword, gatewayClient) + if err != nil { + return &link.UpdatePublicShareResponse{ + Status: status.NewInternal(ctx, err.Error()), + }, nil + } + updatePassword := req.GetUpdate().GetType() == link.UpdatePublicShareRequest_Update_TYPE_PASSWORD + setPassword := grant.GetPassword() + if updatePassword && !isInternalLink && enforcePassword(canOptOut, ps.GetPermissions().GetPermissions(), s.conf) && len(setPassword) == 0 { + return &link.UpdatePublicShareResponse{ + Status: status.NewInvalidArg(ctx, "password protection is enforced"), + }, nil + } + + // validate password policy + if updatePassword && len(setPassword) > 0 { + if err := s.passwordValidator.Validate(setPassword); err != nil { + return &link.UpdatePublicShareResponse{ + Status: status.NewInvalidArg(ctx, err.Error()), + }, nil + } + } + + updateR, err := s.sm.UpdatePublicShare(ctx, user, req) if err != nil { return &link.UpdatePublicShareResponse{ Status: status.NewInternal(ctx, err.Error()), @@ -481,11 +580,25 @@ func (s *service) UpdatePublicShare(ctx context.Context, req *link.UpdatePublicS return res, nil } -func enforcePassword(grant *link.Grant, conf *config) bool { +func isInternalLink(req *link.UpdatePublicShareRequest, ps *link.PublicShare) bool { + switch { + case req.GetUpdate().GetType() == link.UpdatePublicShareRequest_Update_TYPE_PERMISSIONS: + return grants.PermissionsEqual(req.GetUpdate().GetGrant().GetPermissions().GetPermissions(), &provider.ResourcePermissions{}) + default: + return grants.PermissionsEqual(ps.GetPermissions().GetPermissions(), &provider.ResourcePermissions{}) + } +} + +func enforcePassword(canOptOut bool, permissions *provider.ResourcePermissions, conf *config) bool { + isReadOnly := conversions.SufficientCS3Permissions(conversions.NewViewerRole(true).CS3ResourcePermissions(), permissions) + if isReadOnly && canOptOut { + return false + } + if conf.PublicShareMustHavePassword { return true } - isReadOnly := conversions.SufficientCS3Permissions(conversions.NewViewerRole(true).CS3ResourcePermissions(), grant.GetPermissions().GetPermissions()) + return !isReadOnly && conf.WriteableShareMustHavePassword } diff --git a/vendor/modules.txt b/vendor/modules.txt index b8037d3e473..1bc0a28f92c 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -362,7 +362,7 @@ github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1 github.com/cs3org/go-cs3apis/cs3/storage/registry/v1beta1 github.com/cs3org/go-cs3apis/cs3/tx/v1beta1 github.com/cs3org/go-cs3apis/cs3/types/v1beta1 -# github.com/cs3org/reva/v2 v2.17.1-0.20231214082636-a8467337208a +# github.com/cs3org/reva/v2 v2.17.1-0.20231214082636-a8467337208a => github.com/micbar/reva/v2 v2.0.0-20231214215940-ac484c63b45e ## explicit; go 1.21 github.com/cs3org/reva/v2/cmd/revad/internal/grace github.com/cs3org/reva/v2/cmd/revad/runtime @@ -2299,3 +2299,4 @@ stash.kopano.io/kgol/oidc-go stash.kopano.io/kgol/rndm # github.com/go-micro/plugins/v4/store/nats-js-kv => github.com/kobergj/plugins/v4/store/nats-js-kv v0.0.0-20231207143248-4d424e3ae348 # github.com/studio-b12/gowebdav => github.com/aduffeck/gowebdav v0.0.0-20231123085457-ff658b6ea159 +# github.com/cs3org/reva/v2 => github.com/micbar/reva/v2 v2.0.0-20231214215940-ac484c63b45e From 0b42151c1fc599fa9f7ae7ab1fde6f42a849e076 Mon Sep 17 00:00:00 2001 From: Michael Barz Date: Fri, 15 Dec 2023 12:10:36 +0100 Subject: [PATCH 2/3] docs: add changelog --- changelog/unreleased/add-validation-update-public-share.md | 5 +++++ changelog/unreleased/bump-reva.md | 1 + 2 files changed, 6 insertions(+) create mode 100644 changelog/unreleased/add-validation-update-public-share.md diff --git a/changelog/unreleased/add-validation-update-public-share.md b/changelog/unreleased/add-validation-update-public-share.md new file mode 100644 index 00000000000..f3e661671d4 --- /dev/null +++ b/changelog/unreleased/add-validation-update-public-share.md @@ -0,0 +1,5 @@ +Enhancement: Add validation update public share + +For Sharing NG, we needed validation in the implementing reva service to keep the client implementation simple. + +https://github.com/owncloud/ocis/pull/7978 diff --git a/changelog/unreleased/bump-reva.md b/changelog/unreleased/bump-reva.md index 5e3f954f8f7..02ba9ff631d 100644 --- a/changelog/unreleased/bump-reva.md +++ b/changelog/unreleased/bump-reva.md @@ -3,3 +3,4 @@ Enhancement: Bump reva Bumps reva version https://github.com/owncloud/ocis/pull/7793 +https://github.com/owncloud/ocis/pull/7978 From e14aa633dc178785ffcbbca9c79255e2003a50d0 Mon Sep 17 00:00:00 2001 From: Michael Barz Date: Fri, 15 Dec 2023 12:22:00 +0100 Subject: [PATCH 3/3] deps: fix vendoring --- vendor/modules.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/vendor/modules.txt b/vendor/modules.txt index 1bc0a28f92c..30186125d99 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -362,7 +362,7 @@ github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1 github.com/cs3org/go-cs3apis/cs3/storage/registry/v1beta1 github.com/cs3org/go-cs3apis/cs3/tx/v1beta1 github.com/cs3org/go-cs3apis/cs3/types/v1beta1 -# github.com/cs3org/reva/v2 v2.17.1-0.20231214082636-a8467337208a => github.com/micbar/reva/v2 v2.0.0-20231214215940-ac484c63b45e +# github.com/cs3org/reva/v2 v2.17.1-0.20231215110403-2f85376a4d3f ## explicit; go 1.21 github.com/cs3org/reva/v2/cmd/revad/internal/grace github.com/cs3org/reva/v2/cmd/revad/runtime @@ -2299,4 +2299,3 @@ stash.kopano.io/kgol/oidc-go stash.kopano.io/kgol/rndm # github.com/go-micro/plugins/v4/store/nats-js-kv => github.com/kobergj/plugins/v4/store/nats-js-kv v0.0.0-20231207143248-4d424e3ae348 # github.com/studio-b12/gowebdav => github.com/aduffeck/gowebdav v0.0.0-20231123085457-ff658b6ea159 -# github.com/cs3org/reva/v2 => github.com/micbar/reva/v2 v2.0.0-20231214215940-ac484c63b45e