github.com/cs3org/reva/v2@v2.27.7/internal/grpc/services/gateway/gateway.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 gateway 20 21 import ( 22 "fmt" 23 "net/url" 24 "strings" 25 26 gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1" 27 "github.com/cs3org/reva/v2/pkg/errtypes" 28 "github.com/cs3org/reva/v2/pkg/rgrpc" 29 "github.com/cs3org/reva/v2/pkg/sharedconf" 30 "github.com/cs3org/reva/v2/pkg/storage/cache" 31 "github.com/cs3org/reva/v2/pkg/token" 32 "github.com/cs3org/reva/v2/pkg/token/manager/registry" 33 "github.com/mitchellh/mapstructure" 34 "github.com/pkg/errors" 35 "github.com/rs/zerolog" 36 "google.golang.org/grpc" 37 ) 38 39 const ( 40 _spaceTypePersonal = "personal" 41 _spaceTypeProject = "project" 42 _spaceTypeVirtual = "virtual" 43 ) 44 45 func init() { 46 rgrpc.Register("gateway", New) 47 } 48 49 type config struct { 50 AuthRegistryEndpoint string `mapstructure:"authregistrysvc"` 51 ApplicationAuthEndpoint string `mapstructure:"applicationauthsvc"` 52 StorageRegistryEndpoint string `mapstructure:"storageregistrysvc"` 53 AppRegistryEndpoint string `mapstructure:"appregistrysvc"` 54 PreferencesEndpoint string `mapstructure:"preferencessvc"` 55 UserShareProviderEndpoint string `mapstructure:"usershareprovidersvc"` 56 PublicShareProviderEndpoint string `mapstructure:"publicshareprovidersvc"` 57 OCMShareProviderEndpoint string `mapstructure:"ocmshareprovidersvc"` 58 OCMInviteManagerEndpoint string `mapstructure:"ocminvitemanagersvc"` 59 OCMProviderAuthorizerEndpoint string `mapstructure:"ocmproviderauthorizersvc"` 60 OCMCoreEndpoint string `mapstructure:"ocmcoresvc"` 61 UserProviderEndpoint string `mapstructure:"userprovidersvc"` 62 GroupProviderEndpoint string `mapstructure:"groupprovidersvc"` 63 DataTxEndpoint string `mapstructure:"datatx"` 64 DataGatewayEndpoint string `mapstructure:"datagateway"` 65 PermissionsEndpoint string `mapstructure:"permissionssvc"` 66 CommitShareToStorageGrant bool `mapstructure:"commit_share_to_storage_grant"` 67 DisableHomeCreationOnLogin bool `mapstructure:"disable_home_creation_on_login"` 68 TransferSharedSecret string `mapstructure:"transfer_shared_secret"` 69 TransferExpires int64 `mapstructure:"transfer_expires"` 70 TokenManager string `mapstructure:"token_manager"` 71 // ShareFolder is the location where to create shares in the recipient's storage provider. 72 // FIXME get rid of ShareFolder, there are findByPath calls in the ocmshareporvider.go and usershareprovider.go 73 ShareFolder string `mapstructure:"share_folder"` 74 DataTransfersFolder string `mapstructure:"data_transfers_folder"` 75 TokenManagers map[string]map[string]interface{} `mapstructure:"token_managers"` 76 AllowedUserAgents map[string][]string `mapstructure:"allowed_user_agents"` // map[path][]user-agent 77 CreatePersonalSpaceCacheConfig cache.Config `mapstructure:"create_personal_space_cache_config"` 78 ProviderCacheConfig cache.Config `mapstructure:"provider_cache_config"` 79 UseCommonSpaceRootShareLogic bool `mapstructure:"use_common_space_root_share_logic"` 80 } 81 82 // sets defaults 83 func (c *config) init() { 84 if c.ShareFolder == "" { 85 c.ShareFolder = "MyShares" 86 } 87 88 c.ShareFolder = strings.Trim(c.ShareFolder, "/") 89 90 if c.DataTransfersFolder == "" { 91 c.DataTransfersFolder = "DataTransfers" 92 } 93 94 if c.TokenManager == "" { 95 c.TokenManager = "jwt" 96 } 97 98 // if services address are not specified we used the shared conf 99 // for the gatewaysvc to have dev setups very quickly. 100 c.AuthRegistryEndpoint = sharedconf.GetGatewaySVC(c.AuthRegistryEndpoint) 101 c.ApplicationAuthEndpoint = sharedconf.GetGatewaySVC(c.ApplicationAuthEndpoint) 102 c.StorageRegistryEndpoint = sharedconf.GetGatewaySVC(c.StorageRegistryEndpoint) 103 c.AppRegistryEndpoint = sharedconf.GetGatewaySVC(c.AppRegistryEndpoint) 104 c.PreferencesEndpoint = sharedconf.GetGatewaySVC(c.PreferencesEndpoint) 105 c.UserShareProviderEndpoint = sharedconf.GetGatewaySVC(c.UserShareProviderEndpoint) 106 c.PublicShareProviderEndpoint = sharedconf.GetGatewaySVC(c.PublicShareProviderEndpoint) 107 c.OCMShareProviderEndpoint = sharedconf.GetGatewaySVC(c.OCMShareProviderEndpoint) 108 c.OCMInviteManagerEndpoint = sharedconf.GetGatewaySVC(c.OCMInviteManagerEndpoint) 109 c.OCMProviderAuthorizerEndpoint = sharedconf.GetGatewaySVC(c.OCMProviderAuthorizerEndpoint) 110 c.OCMCoreEndpoint = sharedconf.GetGatewaySVC(c.OCMCoreEndpoint) 111 c.UserProviderEndpoint = sharedconf.GetGatewaySVC(c.UserProviderEndpoint) 112 c.GroupProviderEndpoint = sharedconf.GetGatewaySVC(c.GroupProviderEndpoint) 113 c.DataTxEndpoint = sharedconf.GetGatewaySVC(c.DataTxEndpoint) 114 115 c.DataGatewayEndpoint = sharedconf.GetDataGateway(c.DataGatewayEndpoint) 116 117 // use shared secret if not set 118 c.TransferSharedSecret = sharedconf.GetJWTSecret(c.TransferSharedSecret) 119 120 // lifetime for the transfer token (TUS upload) 121 if c.TransferExpires == 0 { 122 c.TransferExpires = 100 * 60 // seconds 123 } 124 125 // caching needs to be explicitly enabled 126 if c.ProviderCacheConfig.Store == "" { 127 c.ProviderCacheConfig.Store = "noop" 128 } 129 130 if c.ProviderCacheConfig.Database == "" { 131 c.ProviderCacheConfig.Database = "reva" 132 } 133 134 if c.CreatePersonalSpaceCacheConfig.Store == "" { 135 c.CreatePersonalSpaceCacheConfig.Store = "memory" 136 } 137 138 if c.CreatePersonalSpaceCacheConfig.Database == "" { 139 c.CreatePersonalSpaceCacheConfig.Database = "reva" 140 } 141 } 142 143 type svc struct { 144 c *config 145 dataGatewayURL url.URL 146 tokenmgr token.Manager 147 providerCache cache.ProviderCache 148 createPersonalSpaceCache cache.CreatePersonalSpaceCache 149 } 150 151 // New creates a new gateway svc that acts as a proxy for any grpc operation. 152 // The gateway is responsible for high-level controls: rate-limiting, coordination between svcs 153 // like sharing and storage acls, asynchronous transactions, ... 154 func New(m map[string]interface{}, _ *grpc.Server, _ *zerolog.Logger) (rgrpc.Service, error) { 155 c, err := parseConfig(m) 156 if err != nil { 157 return nil, err 158 } 159 160 c.init() 161 162 // ensure DataGatewayEndpoint is a valid URI 163 u, err := url.Parse(c.DataGatewayEndpoint) 164 if err != nil { 165 return nil, err 166 } 167 168 tokenManager, err := getTokenManager(c.TokenManager, c.TokenManagers) 169 if err != nil { 170 return nil, err 171 } 172 173 s := &svc{ 174 c: c, 175 dataGatewayURL: *u, 176 tokenmgr: tokenManager, 177 providerCache: cache.GetProviderCache(c.ProviderCacheConfig), 178 createPersonalSpaceCache: cache.GetCreatePersonalSpaceCache(c.CreatePersonalSpaceCacheConfig), 179 } 180 181 return s, nil 182 } 183 184 func (s *svc) Register(ss *grpc.Server) { 185 gateway.RegisterGatewayAPIServer(ss, s) 186 } 187 188 func (s *svc) Close() error { 189 s.providerCache.Close() 190 s.createPersonalSpaceCache.Close() 191 return nil 192 } 193 194 func (s *svc) UnprotectedEndpoints() []string { 195 return []string{"/cs3.gateway.v1beta1.GatewayAPI"} 196 } 197 198 func parseConfig(m map[string]interface{}) (*config, error) { 199 c := &config{} 200 if err := mapstructure.Decode(m, c); err != nil { 201 err = errors.Wrap(err, "gateway: error decoding conf") 202 return nil, err 203 } 204 return c, nil 205 } 206 207 func getTokenManager(manager string, m map[string]map[string]interface{}) (token.Manager, error) { 208 if f, ok := registry.NewFuncs[manager]; ok { 209 return f(m[manager]) 210 } 211 212 return nil, errtypes.NotFound(fmt.Sprintf("driver %s not found for token manager", manager)) 213 }