github.com/cs3org/reva/v2@v2.27.7/internal/grpc/interceptors/readonly/readonly.go (about) 1 // Copyright 2018-2021 CERN 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 // In applying this license, CERN does not waive the privileges and immunities 16 // granted to it by virtue of its status as an Intergovernmental Organization 17 // or submit itself to any jurisdiction. 18 19 package readonly 20 21 import ( 22 "context" 23 24 provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" 25 registry "github.com/cs3org/go-cs3apis/cs3/storage/registry/v1beta1" 26 "github.com/cs3org/reva/v2/pkg/appctx" 27 "github.com/cs3org/reva/v2/pkg/rgrpc" 28 rstatus "github.com/cs3org/reva/v2/pkg/rgrpc/status" 29 "google.golang.org/grpc" 30 "google.golang.org/grpc/codes" 31 "google.golang.org/grpc/status" 32 ) 33 34 const ( 35 defaultPriority = 200 36 ) 37 38 func init() { 39 rgrpc.RegisterUnaryInterceptor("readonly", NewUnary) 40 } 41 42 // NewUnary returns a new unary interceptor 43 // that checks grpc calls and blocks write requests. 44 func NewUnary(map[string]interface{}) (grpc.UnaryServerInterceptor, int, error) { 45 return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { 46 log := appctx.GetLogger(ctx) 47 48 switch req.(type) { 49 // handle known non-write request types 50 case *provider.GetHomeRequest, 51 *provider.GetPathRequest, 52 *provider.GetQuotaRequest, 53 *registry.GetStorageProvidersRequest, 54 *provider.InitiateFileDownloadRequest, 55 *provider.ListFileVersionsRequest, 56 *provider.ListGrantsRequest, 57 *provider.ListRecycleRequest: 58 return handler(ctx, req) 59 case *provider.ListContainerRequest: 60 resp, err := handler(ctx, req) 61 if listResp, ok := resp.(*provider.ListContainerResponse); ok && listResp.Infos != nil { 62 for _, info := range listResp.Infos { 63 // use the existing PermissionsSet and change the writes to false 64 if info.PermissionSet != nil { 65 info.PermissionSet.AddGrant = false 66 info.PermissionSet.CreateContainer = false 67 info.PermissionSet.Delete = false 68 info.PermissionSet.InitiateFileUpload = false 69 info.PermissionSet.Move = false 70 info.PermissionSet.RemoveGrant = false 71 info.PermissionSet.PurgeRecycle = false 72 info.PermissionSet.RestoreFileVersion = false 73 info.PermissionSet.RestoreRecycleItem = false 74 info.PermissionSet.UpdateGrant = false 75 } 76 } 77 } 78 return resp, err 79 case *provider.StatRequest: 80 resp, err := handler(ctx, req) 81 if statResp, ok := resp.(*provider.StatResponse); ok && statResp.Info != nil && statResp.Info.PermissionSet != nil { 82 // use the existing PermissionsSet and change the writes to false 83 statResp.Info.PermissionSet.AddGrant = false 84 statResp.Info.PermissionSet.CreateContainer = false 85 statResp.Info.PermissionSet.Delete = false 86 statResp.Info.PermissionSet.InitiateFileUpload = false 87 statResp.Info.PermissionSet.Move = false 88 statResp.Info.PermissionSet.RemoveGrant = false 89 statResp.Info.PermissionSet.PurgeRecycle = false 90 statResp.Info.PermissionSet.RestoreFileVersion = false 91 statResp.Info.PermissionSet.RestoreRecycleItem = false 92 statResp.Info.PermissionSet.UpdateGrant = false 93 } 94 return resp, err 95 // Don't allow the following requests types 96 case *provider.AddGrantRequest: 97 return &provider.AddGrantResponse{ 98 Status: rstatus.NewPermissionDenied(ctx, nil, "permission denied: tried to add grant on readonly storage"), 99 }, nil 100 case *provider.CreateContainerRequest: 101 return &provider.CreateContainerResponse{ 102 Status: rstatus.NewPermissionDenied(ctx, nil, "permission denied: tried to create resource on read-only storage"), 103 }, nil 104 case *provider.TouchFileRequest: 105 return &provider.TouchFileResponse{ 106 Status: rstatus.NewPermissionDenied(ctx, nil, "permission denied: tried to create resource on read-only storage"), 107 }, nil 108 case *provider.CreateHomeRequest: 109 return &provider.CreateHomeResponse{ 110 Status: rstatus.NewPermissionDenied(ctx, nil, "permission denied: tried to create home on readonly storage"), 111 }, nil 112 case *provider.DeleteRequest: 113 return &provider.DeleteResponse{ 114 Status: rstatus.NewPermissionDenied(ctx, nil, "permission denied: tried to delete resource on readonly storage"), 115 }, nil 116 case *provider.InitiateFileUploadRequest: 117 return &provider.InitiateFileUploadResponse{ 118 Status: rstatus.NewPermissionDenied(ctx, nil, "permission denied: tried to upload resource on readonly storage"), 119 }, nil 120 case *provider.MoveRequest: 121 return &provider.MoveResponse{ 122 Status: rstatus.NewPermissionDenied(ctx, nil, "permission denied: tried to move resource on readonly storage"), 123 }, nil 124 case *provider.PurgeRecycleRequest: 125 return &provider.PurgeRecycleResponse{ 126 Status: rstatus.NewPermissionDenied(ctx, nil, "permission denied: tried to purge recycle on readonly storage"), 127 }, nil 128 case *provider.RemoveGrantRequest: 129 return &provider.RemoveGrantResponse{ 130 Status: rstatus.NewPermissionDenied(ctx, nil, "permission denied: tried to remove grant on readonly storage"), 131 }, nil 132 case *provider.RestoreRecycleItemRequest: 133 return &provider.RestoreRecycleItemResponse{ 134 Status: rstatus.NewPermissionDenied(ctx, nil, "permission denied: tried to restore recycle item on readonly storage"), 135 }, nil 136 case *provider.SetArbitraryMetadataRequest: 137 return &provider.SetArbitraryMetadataResponse{ 138 Status: rstatus.NewPermissionDenied(ctx, nil, "permission denied: tried to set arbitrary metadata on readonly storage"), 139 }, nil 140 case *provider.UnsetArbitraryMetadataRequest: 141 return &provider.UnsetArbitraryMetadataResponse{ 142 Status: rstatus.NewPermissionDenied(ctx, nil, "permission denied: tried to unset arbitrary metadata on readonly storage"), 143 }, nil 144 // block unknown request types and return error 145 default: 146 log.Debug().Msg("storage is readonly") 147 return nil, status.Errorf(codes.PermissionDenied, "permission denied: tried to execute an unknown operation: %T!", req) 148 } 149 }, defaultPriority, nil 150 }