diff --git a/go.mod b/go.mod index 3d1fd08e0f..ac5cceb28e 100644 --- a/go.mod +++ b/go.mod @@ -68,7 +68,7 @@ require ( github.com/open-policy-agent/opa v1.21.1 github.com/opencloud-eu/icap-client v0.0.0-20250930132611-28a2afe62d89 github.com/opencloud-eu/libre-graph-api-go v1.0.9-0.20261016073229-17ed3d5dd346 - github.com/opencloud-eu/reva/v2 v2.52.2-0.20261111125001-fa3c9e289ad6 + github.com/opencloud-eu/reva/v2 v2.52.2-0.20261113073431-67131be3db65 github.com/opensearch-project/opensearch-go/v4 v4.7.3 github.com/orcaman/concurrent-map v1.0.0 github.com/pkg/errors v0.9.1 diff --git a/go.sum b/go.sum index f41d24777e..38aae85d4e 100644 --- a/go.sum +++ b/go.sum @@ -761,8 +761,8 @@ github.com/opencloud-eu/icap-client v0.0.0-20250930132611-28a2afe62d89 h1:W1ms+l github.com/opencloud-eu/icap-client v0.0.0-20250930132611-28a2afe62d89/go.mod h1:vigJkNss1N2QEceCuNw/ullDehncuJNFB6mEnzfq9UI= github.com/opencloud-eu/libre-graph-api-go v1.0.9-0.20261016073229-17ed3d5dd346 h1:3ptbiFhSK4fzY/rC3idcYUveiwepMoOov1sBpc7Rg3k= github.com/opencloud-eu/libre-graph-api-go v1.0.9-0.20261016073229-17ed3d5dd346/go.mod h1:lTM8JeGblNpoMySTW7Lui2+c5TTLI95mwxtdUIHHrhU= -github.com/opencloud-eu/reva/v2 v2.52.2-0.20261111125001-fa3c9e289ad6 h1:EvMm2GuJwm2f7C6CgIulV4ijksRhXj4bgwI5BSfHTxo= -github.com/opencloud-eu/reva/v2 v2.52.2-0.20261111125001-fa3c9e289ad6/go.mod h1:nKOQFFHQZiBFiiXBqEIc99giHQ/Pe0XYf5cztJhZDYw= +github.com/opencloud-eu/reva/v2 v2.52.2-0.20261113073431-67131be3db65 h1:u9GVH5aM8Kv8PjKsfxTND8YtRdjuGjviIcNor1L7iV4= +github.com/opencloud-eu/reva/v2 v2.52.2-0.20261113073431-67131be3db65/go.mod h1:nKOQFFHQZiBFiiXBqEIc99giHQ/Pe0XYf5cztJhZDYw= github.com/opencloud-eu/secure v0.0.0-20260312082735-b6f5cb2244e4 h1:l2oB/RctH+t8r7QBj5p8thfEHCM/jF35aAY3WQ3hADI= github.com/opencloud-eu/secure v0.0.0-20260312082735-b6f5cb2244e4/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= diff --git a/services/graph/pkg/service/v0/api_driveitem_permissions.go b/services/graph/pkg/service/v0/api_driveitem_permissions.go index 411a3aae66..79ddc7d92b 100644 --- a/services/graph/pkg/service/v0/api_driveitem_permissions.go +++ b/services/graph/pkg/service/v0/api_driveitem_permissions.go @@ -23,6 +23,7 @@ import ( "github.com/go-chi/render" libregraph "github.com/opencloud-eu/libre-graph-api-go" revactx "github.com/opencloud-eu/reva/v2/pkg/ctx" + "github.com/opencloud-eu/reva/v2/pkg/errtypes" "github.com/opencloud-eu/reva/v2/pkg/publicshare" "github.com/opencloud-eu/reva/v2/pkg/rgrpc/todo/pool" "github.com/opencloud-eu/reva/v2/pkg/share" @@ -500,7 +501,11 @@ func (s DriveItemPermissionsService) ListPermissions(ctx context.Context, itemID driveItems, err = s.listPublicShares(ctx, []*link.ListPublicSharesRequest_Filter{ publicshare.ResourceIDFilter(itemID), }, driveItems) - if err != nil { + if err != nil && strings.Contains(err.Error(), errtypes.ERR_ALREADY_EXISTS) { + s.logger.Info().Err(err).Str("storageID", itemID.GetStorageId()).Msg("listPublicShares error: " + err.Error()) + } + if err != nil && !strings.Contains(err.Error(), errtypes.ERR_ALREADY_EXISTS) { + s.logger.Error().Err(err).Str("storageID", itemID.GetStorageId()).Msg("listPublicShares failed") return collectionOfPermissions, err } } diff --git a/services/graph/pkg/service/v0/api_driveitem_permissions_test.go b/services/graph/pkg/service/v0/api_driveitem_permissions_test.go index 7b29a54239..9e7fd437c3 100644 --- a/services/graph/pkg/service/v0/api_driveitem_permissions_test.go +++ b/services/graph/pkg/service/v0/api_driveitem_permissions_test.go @@ -29,6 +29,7 @@ import ( roleconversions "github.com/opencloud-eu/reva/v2/pkg/conversions" revactx "github.com/opencloud-eu/reva/v2/pkg/ctx" + "github.com/opencloud-eu/reva/v2/pkg/errtypes" "github.com/opencloud-eu/reva/v2/pkg/rgrpc/status" "github.com/opencloud-eu/reva/v2/pkg/rgrpc/todo/pool" "github.com/opencloud-eu/reva/v2/pkg/storagespace" @@ -512,6 +513,46 @@ var _ = Describe("DriveItemPermissionsService", func() { Expect(len(permissions.LibreGraphPermissionsRolesAllowedValues)).ToNot(BeZero()) Expect(len(permissions.Value)).To(Equal(2)) }) + Context("when listing the public shares fails", func() { + BeforeEach(func() { + statResponse.Info.PermissionSet = roleconversions.NewEditorRole().CS3ResourcePermissions() + listSharesResponse.Shares = []*collaboration.Share{ + { + Id: &collaboration.ShareId{OpaqueId: "1"}, + Permissions: &collaboration.SharePermissions{ + Permissions: roleconversions.NewViewerRole().CS3ResourcePermissions(), + }, + ResourceId: itemID, + Grantee: &provider.Grantee{ + Type: provider.GranteeType_GRANTEE_TYPE_USER, + Id: &provider.Grantee_UserId{ + UserId: &userpb.UserId{ + OpaqueId: "user-id", + }, + }, + }, + }, + } + gatewayClient.On("Stat", mock.Anything, mock.Anything).Return(statResponse, nil) + gatewayClient.On("ListShares", mock.Anything, mock.Anything).Return(listSharesResponse, nil) + gatewayClient.On("GetUser", mock.Anything, mock.Anything).Return(getUserResponse, nil).Maybe() + }) + It("still returns the other permissions on an already exists error", func() { + gatewayClient.On("ListPublicShares", mock.Anything, mock.Anything).Return(&link.ListPublicSharesResponse{ + Status: status.NewInternal(ctx, errtypes.AlreadyExists("metadata space").Error()), + }, nil) + permissions, err := driveItemPermissionsService.ListPermissions(context.Background(), itemID, svc.ListPermissionsQueryOptions{}) + Expect(err).ToNot(HaveOccurred()) + Expect(len(permissions.Value)).To(Equal(1)) + }) + It("returns the error on any other error", func() { + gatewayClient.On("ListPublicShares", mock.Anything, mock.Anything).Return(&link.ListPublicSharesResponse{ + Status: status.NewInternal(ctx, "transport error"), + }, nil) + _, err := driveItemPermissionsService.ListPermissions(context.Background(), itemID, svc.ListPermissionsQueryOptions{}) + Expect(err).To(HaveOccurred()) + }) + }) It("returns role denied", func() { statResponse.Info.PermissionSet = roleconversions.NewManagerRole().CS3ResourcePermissions() statResponse.Info.Type = provider.ResourceType_RESOURCE_TYPE_CONTAINER diff --git a/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/services/publicshareprovider/publicshareprovider.go b/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/services/publicshareprovider/publicshareprovider.go index 8d8b0c6a71..88684ac3ae 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/services/publicshareprovider/publicshareprovider.go +++ b/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/services/publicshareprovider/publicshareprovider.go @@ -24,6 +24,7 @@ import ( "fmt" "regexp" "strconv" + "strings" "time" gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1" @@ -458,10 +459,10 @@ func (s *service) ListPublicShares(ctx context.Context, req *link.ListPublicShar user, _ := ctxpkg.ContextGetUser(ctx) shares, err := s.sm.ListPublicShares(ctx, user, req.Filters, req.GetSign()) - if err != nil { - log.Err(err).Msg("error listing shares") + if err != nil && !strings.Contains(err.Error(), errtypes.ERR_ALREADY_EXISTS) { + log.Err(err).Str("user", user.GetId().GetOpaqueId()).Msg("error listing shares") return &link.ListPublicSharesResponse{ - Status: status.NewInternal(ctx, "error listing public shares"), + Status: status.NewInternal(ctx, err.Error()), }, nil } diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/errtypes/errtypes.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/errtypes/errtypes.go index 5ef7e995bf..ddf8807c60 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/errtypes/errtypes.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/errtypes/errtypes.go @@ -99,7 +99,11 @@ func (e PreconditionFailed) IsPreconditionFailed() {} // AlreadyExists is the error to use when a resource something is not found. type AlreadyExists string -func (e AlreadyExists) Error() string { return "error: already exists: " + string(e) } +// ERR_ALREADY_EXISTS is the prefix of every AlreadyExists error message, for callers +// that only see the message (e.g. a status message passed through grpc). +const ERR_ALREADY_EXISTS = "error: already exists:" + +func (e AlreadyExists) Error() string { return ERR_ALREADY_EXISTS + " " + string(e) } // IsAlreadyExists implements the IsAlreadyExists interface. func (e AlreadyExists) IsAlreadyExists() {} diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/owncloud/ocs/capabilities.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/owncloud/ocs/capabilities.go index ea4b73c207..3e1e00177d 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/owncloud/ocs/capabilities.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/owncloud/ocs/capabilities.go @@ -156,12 +156,13 @@ type CapabilitiesSearchPropertyExtended struct { // Spaces lets a service configure its advertised options related to Storage Spaces. type Spaces struct { - Version string `json:"version" xml:"version" mapstructure:"version"` - Enabled bool `json:"enabled" xml:"enabled" mapstructure:"enabled"` - Projects bool `json:"projects" xml:"projects" mapstructure:"projects"` - ShareJail bool `json:"share_jail" xml:"share_jail" mapstructure:"share_jail"` - MaxQuota uint64 `json:"max_quota" xml:"max_quota" mapstructure:"max_quota"` - DefaultQuota uint64 `json:"default_quota" xml:"default_quota" mapstructure:"default_quota"` + Version string `json:"version" xml:"version" mapstructure:"version"` + Enabled bool `json:"enabled" xml:"enabled" mapstructure:"enabled"` + Projects bool `json:"projects" xml:"projects" mapstructure:"projects"` + ShareJail bool `json:"share_jail" xml:"share_jail" mapstructure:"share_jail"` + MaxQuota uint64 `json:"max_quota" xml:"max_quota" mapstructure:"max_quota"` + DefaultQuota uint64 `json:"default_quota" xml:"default_quota" mapstructure:"default_quota"` + ServerManaged bool `json:"server_managed" xml:"server_managed" mapstructure:"server_managed"` } // CapabilitiesCore holds webdav config diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/node/permissions.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/node/permissions.go index 1f4ea0da49..27f2b14128 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/node/permissions.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/node/permissions.go @@ -101,7 +101,8 @@ func ServiceAccountPermissions() *provider.ResourcePermissions { Delete: true, // for cli restore command with replace option CreateContainer: true, // for space provisioning AddGrant: true, // for initial project space member assignment - ListGrants: true, // for initial project space member assignment + UpdateGrant: true, // for automatic space membership management + ListGrants: true, // for initial project space member assignment and automatic space membership management } } diff --git a/vendor/modules.txt b/vendor/modules.txt index 23ab9422b2..edc90a3a16 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1360,7 +1360,7 @@ github.com/opencloud-eu/icap-client # github.com/opencloud-eu/libre-graph-api-go v1.0.9-0.20261016073229-17ed3d5dd346 ## explicit; go 1.23 github.com/opencloud-eu/libre-graph-api-go -# github.com/opencloud-eu/reva/v2 v2.52.2-0.20261111125001-fa3c9e289ad6 +# github.com/opencloud-eu/reva/v2 v2.52.2-0.20261113073431-67131be3db65 ## explicit; go 1.26.0 github.com/opencloud-eu/reva/v2/cmd/revad/internal/grace github.com/opencloud-eu/reva/v2/cmd/revad/runtime