Skip to content

Commit

Permalink
add restore
Browse files Browse the repository at this point in the history
  • Loading branch information
gmgigi96 committed Feb 13, 2024
1 parent 5839f5d commit 1786a6b
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 43 deletions.
23 changes: 23 additions & 0 deletions internal/grpc/services/storageprovider/storageprovider.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ type config struct {
AvailableXS map[string]uint32 `docs:"nil;List of available checksums." mapstructure:"available_checksums"`
CustomMimeTypesJSON string `docs:"nil;An optional mapping file with the list of supported custom file extensions and corresponding mime types." mapstructure:"custom_mime_types_json"`
MinimunAllowedPathLevelForShare int `mapstructure:"minimum_allowed_path_level_for_share"`
SpaceLevel int `mapstructure:"space_level"`
}

func (c *config) ApplyDefaults() {
Expand All @@ -91,6 +92,10 @@ func (c *config) ApplyDefaults() {
}
}

if c.SpaceLevel == 0 {
c.SpaceLevel = 4
}

// set sane defaults
if len(c.AvailableXS) == 0 {
c.AvailableXS = map[string]uint32{"md5": 100, "unset": 1000}
Expand Down Expand Up @@ -758,6 +763,22 @@ func (s *service) Move(ctx context.Context, req *provider.MoveRequest) (*provide
return res, nil
}

func spaceFromPath(path string, lvl int) string {
path = strings.TrimPrefix(path, "/")
s := strings.SplitN(path, "/", lvl+1)
if len(s) < lvl {
// TODO: outside space. what to do??
panic("not yet implemented")
}

return "/" + strings.Join(s[:lvl], "/")
}

func (s *service) addSpaceInfo(ri *provider.ResourceInfo) {
space := spaceFromPath(ri.Path, s.conf.SpaceLevel)
ri.Id.SpaceId = space
}

func (s *service) Stat(ctx context.Context, req *provider.StatRequest) (*provider.StatResponse, error) {
newRef, err := s.unwrap(ctx, req.Ref)
if err != nil {
Expand Down Expand Up @@ -789,6 +810,7 @@ func (s *service) Stat(ctx context.Context, req *provider.StatRequest) (*provide
}, nil
}
s.fixPermissions(md)
s.addSpaceInfo(md)
res := &provider.StatResponse{
Status: status.NewOK(ctx),
Info: md,
Expand Down Expand Up @@ -949,6 +971,7 @@ func (s *service) ListContainer(ctx context.Context, req *provider.ListContainer
}, nil
}
s.fixPermissions(md)
s.addSpaceInfo(md)
infos = append(infos, md)
}
res := &provider.ListContainerResponse{
Expand Down
44 changes: 26 additions & 18 deletions internal/http/services/owncloud/ocdav/dav.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,26 +178,34 @@ func (h *DavHandler) Handler(s *svc) http.Handler {
base := path.Join(ctx.Value(ctxKeyBaseURI).(string), "spaces")
ctx := context.WithValue(ctx, ctxKeyBaseURI, base)

// path is of type: space_id/relative/path/from/space
// the space_id is the base64 encode of the path where
// the space is located
spaceID, relativeSpacePath := router.ShiftPath(r.URL.Path)

_, base, ok := spaces.DecodeSpaceID(spaceID)
if !ok {
// TODO: bad request
panic("not yet implemented")
}
var head string
head, r.URL.Path = router.ShiftPath(r.URL.Path)

fullPath := filepath.Join(base, relativeSpacePath)
r.URL.Path = fullPath
switch head {
case "trash-bin":
r = r.WithContext(ctx)
h.TrashbinHandler.Handler(s).ServeHTTP(w, r)
default:
// path is of type: space_id/relative/path/from/space
// the space_id is the base64 encode of the path where
// the space is located

_, base, ok := spaces.DecodeSpaceID(head)
if !ok {
// TODO: bad request
panic("not yet implemented")
}

ctx = context.WithValue(ctx, ctxSpaceID, spaceID)
ctx = context.WithValue(ctx, ctxSpaceFullPath, fullPath)
ctx = context.WithValue(ctx, ctxSpacePath, base)
ctx = context.WithValue(ctx, ctxSpaceRelativePath, relativeSpacePath)
r = r.WithContext(ctx)
h.SpacesHandler.Handler(s).ServeHTTP(w, r)
fullPath := filepath.Join(base, r.URL.Path)
r.URL.Path = fullPath

ctx = context.WithValue(ctx, ctxSpaceID, head)
ctx = context.WithValue(ctx, ctxSpaceFullPath, fullPath)
ctx = context.WithValue(ctx, ctxSpacePath, base)
ctx = context.WithValue(ctx, ctxSpaceRelativePath, r.URL.Path)
r = r.WithContext(ctx)
h.SpacesHandler.Handler(s).ServeHTTP(w, r)
}
case "ocm":
base := path.Join(ctx.Value(ctxKeyBaseURI).(string), "ocm")
ctx := context.WithValue(ctx, ctxKeyBaseURI, base)
Expand Down
7 changes: 1 addition & 6 deletions internal/http/services/owncloud/ocdav/ocdav.go
Original file line number Diff line number Diff line change
Expand Up @@ -343,12 +343,7 @@ func extractDestination(r *http.Request) (string, error) {
baseURI := r.Context().Value(ctxKeyBaseURI).(string)
// TODO check if path is on same storage, return 502 on problems, see https://tools.ietf.org/html/rfc4918#section-9.9.4
// Strip the base URI from the destination. The destination might contain redirection prefixes which need to be handled
urlSplit := strings.Split(dstURL.Path, baseURI)
if len(urlSplit) != 2 {
return "", errors.Wrap(errInvalidValue, "destination path does not contain base URI")
}

return urlSplit[1], nil
return strings.TrimPrefix(dstURL.Path, baseURI), nil
}

// replaceAllStringSubmatchFunc is taken from 'Go: Replace String with Regular Expression Callback'
Expand Down
7 changes: 4 additions & 3 deletions internal/http/services/owncloud/ocdav/propfind.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import (
"github.com/cs3org/reva/internal/grpc/services/storageprovider"
"github.com/cs3org/reva/internal/http/services/owncloud/ocs/conversions"
"github.com/cs3org/reva/pkg/appctx"
"github.com/cs3org/reva/pkg/spaces"

"github.com/cs3org/reva/pkg/publicshare"
"github.com/cs3org/reva/pkg/rhttp/router"
Expand Down Expand Up @@ -626,7 +627,7 @@ func (s *svc) mdToPropResponse(ctx context.Context, pf *propfindXML, md *provide
// return all known properties

if md.Id != nil {
id := resourceid.OwnCloudResourceIDWrap(md.Id)
id := spaces.EncodeResourceID(md.Id)
propstatOK.Prop = append(propstatOK.Prop,
s.newProp("oc:id", id),
s.newProp("oc:fileid", id),
Expand Down Expand Up @@ -725,13 +726,13 @@ func (s *svc) mdToPropResponse(ctx context.Context, pf *propfindXML, md *provide
// I tested the desktop client and phoenix to annotate which properties are requestted, see below cases
case "fileid": // phoenix only
if md.Id != nil {
propstatOK.Prop = append(propstatOK.Prop, s.newProp("oc:fileid", resourceid.OwnCloudResourceIDWrap(md.Id)))
propstatOK.Prop = append(propstatOK.Prop, s.newProp("oc:fileid", spaces.EncodeResourceID(md.Id)))
} else {
propstatNotFound.Prop = append(propstatNotFound.Prop, s.newProp("oc:fileid", ""))
}
case "id": // desktop client only
if md.Id != nil {
propstatOK.Prop = append(propstatOK.Prop, s.newProp("oc:id", resourceid.OwnCloudResourceIDWrap(md.Id)))
propstatOK.Prop = append(propstatOK.Prop, s.newProp("oc:id", spaces.EncodeResourceID(md.Id)))
} else {
propstatNotFound.Prop = append(propstatNotFound.Prop, s.newProp("oc:id", ""))
}
Expand Down
52 changes: 40 additions & 12 deletions internal/http/services/owncloud/ocdav/trashbin.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ package ocdav

import (
"context"
"encoding/base32"
"encoding/xml"
"fmt"
"net/http"
Expand All @@ -34,6 +33,7 @@ import (
rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
"github.com/cs3org/reva/pkg/appctx"
"github.com/cs3org/reva/pkg/spaces"

"github.com/cs3org/reva/pkg/rgrpc/todo/pool"
"github.com/cs3org/reva/pkg/rhttp/router"
Expand All @@ -44,7 +44,6 @@ import (
// TrashbinHandler handles trashbin requests.
type TrashbinHandler struct {
gatewaySvc string
spaces bool
}

func (h *TrashbinHandler) init(c *Config) error {
Expand All @@ -56,24 +55,53 @@ func (h *TrashbinHandler) handleTrashbinSpaces(s *svc, w http.ResponseWriter, r
ctx := r.Context()
log := appctx.GetLogger(ctx)

space, _ := router.ShiftPath(r.URL.Path)
var spaceId string
spaceId, r.URL.Path = router.ShiftPath(r.URL.Path)

spaceId, err := base32.StdEncoding.DecodeString(space)
if err != nil {
log.Error().Err(err).Msgf("error decoding space id: %s", space)
w.WriteHeader(http.StatusBadRequest)
return
_, base, ok := spaces.DecodeSpaceID(spaceId)
if !ok {
// TODO: bad request
panic("not yet implemented: bad request")
}

path := string(spaceId)
log.Debug().Str("path", path).Msg("decoded space base path")
log.Debug().Str("path", base).Msg("decoded space base path")

u := appctx.ContextMustGetUser(ctx)

if r.Method == MethodPropfind {
h.listTrashbin(w, r, s, u, path, "", "")
h.listTrashbin(w, r, s, u, base, "", "")
return
}

var key string
key, r.URL.Path = router.ShiftPath(r.URL.Path)
if key != "" && r.Method == MethodMove {
// find path in url relative to trash base
// trashBase := ctx.Value(ctxKeyBaseURI).(string)
// baseURI := path.Join(path.Dir(trashBase), "files", username)
// ctx = context.WithValue(ctx, ctxKeyBaseURI, baseURI)
// r = r.WithContext(ctx)

// TODO make request.php optional in destination header
dst, err := extractDestination(r)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
dst = path.Clean(dst)
_, dst = router.ShiftPath(dst)

log.Debug().Str("key", key).Str("dst", dst).Msg("restore")

h.restore(w, r, s, u, base, dst, key, "")
return
}

if r.Method == http.MethodDelete {
h.delete(w, r, s, u, base, key, "")
return
}

http.Error(w, "501 Not implemented", http.StatusNotImplemented)
}

// Handler handles requests.
Expand Down
9 changes: 5 additions & 4 deletions pkg/spaces/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,14 @@ func EncodeResourceID(r *provider.ResourceId) string {
if r.OpaqueId == "" {
panic("opaque id cannot be empty")
}
// if r.SpaceId == "" {
// panic("space id cannot be empty")
// }
if r.SpaceId == "" {
panic("space id cannot be empty")
}
if r.StorageId == "" {
panic("storage id cannot be empty")
}
return fmt.Sprintf("%s$%s!%s", r.StorageId, r.SpaceId, r.OpaqueId)
spaceID := EncodeSpaceID(r.StorageId, r.SpaceId)
return fmt.Sprintf("%s!%s", spaceID, r.OpaqueId)
}

// EncodeSpaceID encodes storage ID and path to create a space ID,
Expand Down

0 comments on commit 1786a6b

Please sign in to comment.