diff --git a/internal/grpc/services/gateway/storageprovider.go b/internal/grpc/services/gateway/storageprovider.go index 73d27db39b2..61b6129d8a6 100644 --- a/internal/grpc/services/gateway/storageprovider.go +++ b/internal/grpc/services/gateway/storageprovider.go @@ -35,8 +35,6 @@ import ( "github.com/cs3org/reva/pkg/rgrpc/status" "github.com/cs3org/reva/pkg/rgrpc/todo/pool" "github.com/cs3org/reva/pkg/storage/utils/etag" - "github.com/cs3org/reva/pkg/storage/utils/templates" - "github.com/cs3org/reva/pkg/user" "github.com/cs3org/reva/pkg/utils" "github.com/dgrijalva/jwt-go" "github.com/pkg/errors" @@ -367,6 +365,7 @@ func (s *svc) InitiateFileDownload(ctx context.Context, req *provider.InitiateFi } func (s *svc) initiateFileDownload(ctx context.Context, req *provider.InitiateFileDownloadRequest) (*gateway.InitiateFileDownloadResponse, error) { + // TODO(ishank011): enable downloading references spread across storage providers, eg. /eos c, err := s.find(ctx, req.Ref) if err != nil { return &gateway.InitiateFileDownloadResponse{ @@ -858,6 +857,7 @@ func (s *svc) Delete(ctx context.Context, req *provider.DeleteRequest) (*provide } func (s *svc) delete(ctx context.Context, req *provider.DeleteRequest) (*provider.DeleteResponse, error) { + // TODO(ishank011): enable deleting references spread across storage providers, eg. /eos c, err := s.find(ctx, req.Ref) if err != nil { return &provider.DeleteResponse{ @@ -1009,6 +1009,7 @@ func (s *svc) move(ctx context.Context, req *provider.MoveRequest) (*provider.Mo } func (s *svc) SetArbitraryMetadata(ctx context.Context, req *provider.SetArbitraryMetadataRequest) (*provider.SetArbitraryMetadataResponse, error) { + // TODO(ishank011): enable for references spread across storage providers, eg. /eos c, err := s.find(ctx, req.Ref) if err != nil { return &provider.SetArbitraryMetadataResponse{ @@ -1025,6 +1026,7 @@ func (s *svc) SetArbitraryMetadata(ctx context.Context, req *provider.SetArbitra } func (s *svc) UnsetArbitraryMetadata(ctx context.Context, req *provider.UnsetArbitraryMetadataRequest) (*provider.UnsetArbitraryMetadataResponse, error) { + // TODO(ishank011): enable for references spread across storage providers, eg. /eos c, err := s.find(ctx, req.Ref) if err != nil { return &provider.UnsetArbitraryMetadataResponse{ @@ -1144,6 +1146,7 @@ func (s *svc) statSharesFolder(ctx context.Context) (*provider.StatResponse, err } func (s *svc) stat(ctx context.Context, req *provider.StatRequest) (*provider.StatResponse, error) { + // TODO(ishank011): enable for references spread across storage providers, eg. /eos c, err := s.find(ctx, req.Ref) if err != nil { return &provider.StatResponse{ @@ -1456,19 +1459,49 @@ func (s *svc) listSharesFolder(ctx context.Context) (*provider.ListContainerResp } func (s *svc) listContainer(ctx context.Context, req *provider.ListContainerRequest) (*provider.ListContainerResponse, error) { - c, err := s.find(ctx, req.Ref) + providers, err := s.findProviders(ctx, req.Ref) if err != nil { return &provider.ListContainerResponse{ - Status: status.NewStatusFromErrType(ctx, "listContainer ref="+req.Ref.String(), err), + Status: status.NewStatusFromErrType(ctx, "listContainer ref: "+req.Ref.String(), err), }, nil } - res, err := c.ListContainer(ctx, req) - if err != nil { - return nil, errors.Wrap(err, "gateway: error calling ListContainer") + var infos []*provider.ResourceInfo + + for _, p := range providers { + c, err := s.getStorageProviderClient(ctx, p) + if err != nil { + return &provider.ListContainerResponse{ + Status: status.NewInternal(ctx, err, "error connecting to storage provider="+providers[0].Address), + }, nil + } + + resPath := req.Ref.GetPath() + if resPath != "" && !strings.HasPrefix(resPath, p.ProviderPath) { + req = &provider.ListContainerRequest{ + Ref: &provider.Reference{ + Spec: &provider.Reference_Path{ + Path: p.ProviderPath, + }, + }, + } + } + res, err := c.ListContainer(ctx, req) + if err != nil { + return nil, errors.Wrap(err, "gateway: error calling ListContainer") + } + for _, inf := range res.Infos { + if parent := path.Base(inf.Path); resPath != "" && path.Clean(resPath) != parent { + continue + } + infos = append(infos, inf) + } } - return res, nil + return &provider.ListContainerResponse{ + Status: status.NewOK(ctx), + Infos: infos, + }, nil } func (s *svc) ListContainer(ctx context.Context, req *provider.ListContainerRequest) (*provider.ListContainerResponse, error) { @@ -1908,30 +1941,6 @@ func (s *svc) getStorageProviderClient(_ context.Context, p *registry.ProviderIn } func (s *svc) findProviders(ctx context.Context, ref *provider.Reference) ([]*registry.ProviderInfo, error) { - home := s.getHome(ctx) - if strings.HasPrefix(ref.GetPath(), home) && s.c.HomeMapping != "" { - if u, ok := user.ContextGetUser(ctx); ok { - layout := templates.WithUser(u, s.c.HomeMapping) - newRef := &provider.Reference{ - Spec: &provider.Reference_Path{ - Path: path.Join(layout, strings.TrimPrefix(ref.GetPath(), home)), - }, - } - res, err := s.getStorageProviders(ctx, newRef) - if err != nil { - // if we get a NotFound error, default to the original reference - if _, ok := err.(errtypes.IsNotFound); !ok { - return nil, err - } - } else { - return res, nil - } - } - } - return s.getStorageProviders(ctx, ref) -} - -func (s *svc) getStorageProviders(ctx context.Context, ref *provider.Reference) ([]*registry.ProviderInfo, error) { c, err := pool.GetStorageRegistryClient(s.c.StorageRegistryEndpoint) if err != nil { return nil, errors.Wrap(err, "gateway: error getting storage registry client") diff --git a/internal/http/services/owncloud/ocs/config/config.go b/internal/http/services/owncloud/ocs/config/config.go index 725be7eacb6..9ae7af6f02a 100644 --- a/internal/http/services/owncloud/ocs/config/config.go +++ b/internal/http/services/owncloud/ocs/config/config.go @@ -32,6 +32,7 @@ type Config struct { DefaultUploadProtocol string `mapstructure:"default_upload_protocol"` UserAgentChunkingMap map[string]string `mapstructure:"user_agent_chunking_map"` SharePrefix string `mapstructure:"share_prefix"` + HomeNamespace string `mapstructure:home_namespace` } // Init sets sane defaults @@ -48,5 +49,9 @@ func (c *Config) Init() { c.DefaultUploadProtocol = "tus" } + if c.HomeNamespace == "" { + c.HomeNamespace = "/home" + } + c.GatewaySvc = sharedconf.GetGatewaySVC(c.GatewaySvc) } diff --git a/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go b/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go index f4ddf401af5..028c3e91723 100644 --- a/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go +++ b/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go @@ -55,6 +55,7 @@ type Handler struct { gatewayAddr string publicURL string sharePrefix string + homeNamespace string userIdentifierCache *ttlcache.Cache } @@ -70,6 +71,7 @@ func (h *Handler) Init(c *config.Config) error { h.gatewayAddr = c.GatewaySvc h.publicURL = c.Config.Host h.sharePrefix = c.SharePrefix + h.homeNamespace = c.HomeNamespace h.userIdentifierCache = ttlcache.NewCache() _ = h.userIdentifierCache.SetTTL(60 * time.Second) @@ -173,16 +175,9 @@ func (h *Handler) createShare(w http.ResponseWriter, r *http.Request) { response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error getting grpc gateway client", err) return } - // prefix the path with the owners home, because ocs share requests are relative to the home dir - // TODO the path actually depends on the configured webdav_namespace - hRes, err := c.GetHome(ctx, &provider.GetHomeRequest{}) - if err != nil { - response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error sending a grpc get home request", err) - return - } - prefix := hRes.GetPath() - fn := path.Join(prefix, r.FormValue("path")) + // prefix the path with the owners home, because ocs share requests are relative to the home dir + fn := path.Join(h.homeNamespace, r.FormValue("path")) statReq := provider.StatRequest{ Ref: &provider.Reference{ @@ -591,14 +586,7 @@ func (h *Handler) listSharesWithMe(w http.ResponseWriter, r *http.Request) { // we need to lookup the resource id so we can filter the list of shares later if p != "" { // prefix the path with the owners home, because ocs share requests are relative to the home dir - // TODO the path actually depends on the configured webdav_namespace - hRes, err := gwc.GetHome(ctx, &provider.GetHomeRequest{}) - if err != nil { - response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error sending a grpc get home request", err) - return - } - - target := path.Join(hRes.Path, r.FormValue("path")) + target := path.Join(h.homeNamespace, r.FormValue("path")) statReq := &provider.StatRequest{ Ref: &provider.Reference{ @@ -728,33 +716,8 @@ func (h *Handler) listSharesWithOthers(w http.ResponseWriter, r *http.Request) { // shared with others p := r.URL.Query().Get("path") if p != "" { - c, err := pool.GetGatewayServiceClient(h.gatewayAddr) - if err != nil { - response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error getting storage grpc client", err) - return - } - // prefix the path with the owners home, because ocs share requests are relative to the home dir - // TODO the path actually depends on the configured webdav_namespace - hRes, err := c.GetHome(r.Context(), &provider.GetHomeRequest{}) - if err != nil { - response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error sending a grpc get home request", err) - return - } - - if hRes.Status.Code != rpc.Code_CODE_OK { - switch hRes.Status.Code { - case rpc.Code_CODE_NOT_FOUND: - response.WriteOCSError(w, r, response.MetaNotFound.StatusCode, "path not found", nil) - case rpc.Code_CODE_PERMISSION_DENIED: - response.WriteOCSError(w, r, response.MetaUnauthorized.StatusCode, "permission denied", nil) - default: - response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "grpc stat request failed", nil) - } - return - } - - filters, linkFilters, err = h.addFilters(w, r, hRes.GetPath()) + filters, linkFilters, err = h.addFilters(w, r, h.homeNamespace) if err != nil { // result has been written as part of addFilters return diff --git a/pkg/storage/utils/eosfs/eosfs.go b/pkg/storage/utils/eosfs/eosfs.go index 722bb9be049..c6956ea0659 100644 --- a/pkg/storage/utils/eosfs/eosfs.go +++ b/pkg/storage/utils/eosfs/eosfs.go @@ -659,7 +659,8 @@ func (fs *eosfs) listWithNominalHome(ctx context.Context, p string) (finfos []*p } } - if finfo, err := fs.convertToResourceInfo(ctx, eosFileInfo); err == nil { + // Remove the hidden folders in the topmost directory + if finfo, err := fs.convertToResourceInfo(ctx, eosFileInfo); err == nil && finfo.Path != "/" && !strings.HasPrefix(finfo.Path, "/.") { finfos = append(finfos, finfo) } } @@ -713,7 +714,7 @@ func (fs *eosfs) listHome(ctx context.Context, home string) ([]*provider.Resourc } } - if finfo, err := fs.convertToResourceInfo(ctx, eosFileInfo); err == nil { + if finfo, err := fs.convertToResourceInfo(ctx, eosFileInfo); err == nil && finfo.Path != "/" && !strings.HasPrefix(finfo.Path, "/.") { finfos = append(finfos, finfo) } }