diff --git a/changelog/unreleased/noshare.md b/changelog/unreleased/noshare.md new file mode 100644 index 0000000000..95151bd7ab --- /dev/null +++ b/changelog/unreleased/noshare.md @@ -0,0 +1,6 @@ +Enhancement: Disable sharing on a storage provider + +Added a GRPC interceptor that disable sharing permissions +on a storage provider. + +https://github.com/cs3org/reva/pull/4162 diff --git a/internal/grpc/interceptors/loader/loader.go b/internal/grpc/interceptors/loader/loader.go index 9a3ef052d7..82e684dfe6 100644 --- a/internal/grpc/interceptors/loader/loader.go +++ b/internal/grpc/interceptors/loader/loader.go @@ -21,6 +21,7 @@ package loader import ( // Load core GRPC services. _ "github.com/cs3org/reva/internal/grpc/interceptors/eventsmiddleware" + _ "github.com/cs3org/reva/internal/grpc/interceptors/noshare" _ "github.com/cs3org/reva/internal/grpc/interceptors/notrashbin" _ "github.com/cs3org/reva/internal/grpc/interceptors/noversions" _ "github.com/cs3org/reva/internal/grpc/interceptors/readonly" diff --git a/internal/grpc/interceptors/noshare/noshare.go b/internal/grpc/interceptors/noshare/noshare.go new file mode 100644 index 0000000000..28fd74620b --- /dev/null +++ b/internal/grpc/interceptors/noshare/noshare.go @@ -0,0 +1,85 @@ +// Copyright 2018-2023 CERN +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// In applying this license, CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +package noshare + +import ( + "context" + + provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" + "github.com/cs3org/reva/pkg/rgrpc" + rstatus "github.com/cs3org/reva/pkg/rgrpc/status" + "google.golang.org/grpc" +) + +const ( + defaultPriority = 200 +) + +func init() { + rgrpc.RegisterUnaryInterceptor("noshare", NewUnary) +} + +// NewUnary returns a new unary interceptor +// that checks grpc calls and blocks write requests. +func NewUnary(_ map[string]interface{}) (grpc.UnaryServerInterceptor, int, error) { + return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { + switch req.(type) { + case *provider.ListContainerRequest: + resp, err := handler(ctx, req) + if listResp, ok := resp.(*provider.ListContainerResponse); ok && listResp.Infos != nil { + for _, info := range listResp.Infos { + if info.PermissionSet != nil { + info.PermissionSet.AddGrant = false + info.PermissionSet.RemoveGrant = false + info.PermissionSet.UpdateGrant = false + info.PermissionSet.DenyGrant = false + } + } + } + return resp, err + case *provider.StatRequest: + resp, err := handler(ctx, req) + if statResp, ok := resp.(*provider.StatResponse); ok && statResp.Info != nil && statResp.Info.PermissionSet != nil { + statResp.Info.PermissionSet.AddGrant = false + statResp.Info.PermissionSet.RemoveGrant = false + statResp.Info.PermissionSet.UpdateGrant = false + statResp.Info.PermissionSet.DenyGrant = false + } + return resp, err + case *provider.AddGrantRequest: + return &provider.AddGrantResponse{ + Status: rstatus.NewPermissionDenied(ctx, nil, "permission denied: tried to add grant on a noshare storage"), + }, nil + case *provider.DenyGrantRequest: + return &provider.DenyGrantResponse{ + Status: rstatus.NewPermissionDenied(ctx, nil, "permission denied: tried to deny grant on a noshare storage"), + }, nil + case *provider.RemoveGrantRequest: + return &provider.RemoveGrantResponse{ + Status: rstatus.NewPermissionDenied(ctx, nil, "permission denied: tried to remove grant on a noshare storage"), + }, nil + case *provider.UpdateGrantRequest: + return &provider.UpdateGrantResponse{ + Status: rstatus.NewPermissionDenied(ctx, nil, "permission denied: tried to update grant on a noshare storage"), + }, nil + default: + return handler(ctx, req) + } + }, defaultPriority, nil +}