chore: bump reva to latest edge
This commit is contained in:
@@ -4,4 +4,4 @@ TODO
|
||||
|
||||
https://github.com/owncloud/ocis/pull/10236
|
||||
https://github.com/owncloud/ocis/pull/10216
|
||||
|
||||
https://github.com/owncloud/ocis/pull/10315
|
||||
|
||||
@@ -15,7 +15,7 @@ require (
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible
|
||||
github.com/coreos/go-oidc/v3 v3.11.0
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20240724121416-062c4e3046cb
|
||||
github.com/cs3org/reva/v2 v2.25.1-0.20241004072335-2a6fdbed139d
|
||||
github.com/cs3org/reva/v2 v2.25.1-0.20241015142909-99548fe690bd
|
||||
github.com/dhowden/tag v0.0.0-20230630033851-978a0926ee25
|
||||
github.com/dutchcoders/go-clamd v0.0.0-20170520113014-b970184f4d9e
|
||||
github.com/egirna/icap-client v0.1.1
|
||||
|
||||
@@ -257,6 +257,8 @@ github.com/cs3org/go-cs3apis v0.0.0-20240724121416-062c4e3046cb h1:KmYZDReplv/yf
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20240724121416-062c4e3046cb/go.mod h1:yyP8PRo0EZou3nSH7H4qjlzQwaydPeIRNgX50npQHpE=
|
||||
github.com/cs3org/reva/v2 v2.25.1-0.20241004072335-2a6fdbed139d h1:ETrSkU/XK50QzsxCAHQrr0b7klOHb9TVmJjmOsjMhr8=
|
||||
github.com/cs3org/reva/v2 v2.25.1-0.20241004072335-2a6fdbed139d/go.mod h1:p7CHBXcg6sSqB+0JMNDfC1S7TSh9FghXkw1kTV3KcJI=
|
||||
github.com/cs3org/reva/v2 v2.25.1-0.20241015142909-99548fe690bd h1:+cV0mcJR2v4Fidrs1ckM7c0+dSINTLsmECO76AbW8No=
|
||||
github.com/cs3org/reva/v2 v2.25.1-0.20241015142909-99548fe690bd/go.mod h1:p7CHBXcg6sSqB+0JMNDfC1S7TSh9FghXkw1kTV3KcJI=
|
||||
github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4=
|
||||
github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
|
||||
github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
|
||||
|
||||
Generated
Vendored
+1
-4
@@ -75,6 +75,7 @@ func NewUnary(m map[string]interface{}) (grpc.UnaryServerInterceptor, int, error
|
||||
|
||||
executant, _ := revactx.ContextGetUser(ctx)
|
||||
|
||||
// The MoveResponse event is moved to the decomposedfs
|
||||
var ev interface{}
|
||||
switch v := res.(type) {
|
||||
case *collaboration.CreateShareResponse:
|
||||
@@ -141,10 +142,6 @@ func NewUnary(m map[string]interface{}) (grpc.UnaryServerInterceptor, int, error
|
||||
if isSuccess(v) {
|
||||
ev = ItemTrashed(v, req.(*provider.DeleteRequest), ownerID, executant)
|
||||
}
|
||||
case *provider.MoveResponse:
|
||||
if isSuccess(v) {
|
||||
ev = ItemMoved(v, req.(*provider.MoveRequest), ownerID, executant)
|
||||
}
|
||||
case *provider.PurgeRecycleResponse:
|
||||
if isSuccess(v) {
|
||||
ev = ItemPurged(v, req.(*provider.PurgeRecycleRequest), executant)
|
||||
|
||||
Generated
Vendored
+1
-1
@@ -485,7 +485,7 @@ func (s *service) GetReceivedShare(ctx context.Context, req *collaboration.GetRe
|
||||
|
||||
share, err := s.sm.GetReceivedShare(ctx, req.Ref)
|
||||
if err != nil {
|
||||
log.Err(err).Msg("error getting received share")
|
||||
log.Debug().Err(err).Msg("error getting received share")
|
||||
switch err.(type) {
|
||||
case errtypes.NotFound:
|
||||
return &collaboration.GetReceivedShareResponse{
|
||||
|
||||
Generated
Vendored
+8
-1
@@ -461,6 +461,11 @@ func (s *svc) handleOpen(openMode int) http.HandlerFunc {
|
||||
App: r.Form.Get("app_name"),
|
||||
Opaque: utils.AppendPlainToOpaque(nil, "lang", lang),
|
||||
}
|
||||
|
||||
templateID := r.Form.Get("template_id")
|
||||
if templateID != "" {
|
||||
openReq.Opaque = utils.AppendPlainToOpaque(openReq.Opaque, "template", templateID)
|
||||
}
|
||||
openRes, err := client.OpenInApp(ctx, &openReq)
|
||||
if err != nil {
|
||||
writeError(w, r, appErrorServerError,
|
||||
@@ -567,7 +572,8 @@ type MimeTypeInfo struct {
|
||||
type ProviderInfo struct {
|
||||
appregistry.ProviderInfo
|
||||
// TODO make this part of the CS3 provider info
|
||||
SecureView bool `json:"secure_view"`
|
||||
SecureView bool `json:"secure_view"`
|
||||
TargetExt string `json:"target_ext,omitempty"`
|
||||
}
|
||||
|
||||
// buildApps rewrites the mime type info to only include apps that
|
||||
@@ -598,6 +604,7 @@ func buildApps(mimeTypes []*appregistry.MimeTypeInfo, userAgent, secureViewAppAd
|
||||
}
|
||||
if len(apps) > 0 {
|
||||
mt := &MimeTypeInfo{}
|
||||
addTemplateInfo(m, apps)
|
||||
proto.Merge(&mt.MimeTypeInfo, m)
|
||||
mt.AppProviders = apps
|
||||
res = append(res, mt)
|
||||
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
package appprovider
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
appregistry "github.com/cs3org/go-cs3apis/cs3/app/registry/v1beta1"
|
||||
)
|
||||
|
||||
type TemplateList struct {
|
||||
Templates map[string][]Template `json:"templates"`
|
||||
}
|
||||
|
||||
type Template struct {
|
||||
Extension string `json:"extension"`
|
||||
MimeType string `json:"mime_type"`
|
||||
TargetExtension string `json:"target_extension"`
|
||||
}
|
||||
|
||||
var tl = TemplateList{
|
||||
Templates: map[string][]Template{
|
||||
"collabora": {
|
||||
{
|
||||
MimeType: "application/vnd.oasis.opendocument.spreadsheet-template",
|
||||
TargetExtension: "ods",
|
||||
},
|
||||
{
|
||||
MimeType: "application/vnd.oasis.opendocument.text-template",
|
||||
TargetExtension: "odt",
|
||||
},
|
||||
{
|
||||
MimeType: "application/vnd.oasis.opendocument.presentation-template",
|
||||
TargetExtension: "odp",
|
||||
},
|
||||
},
|
||||
"onlyoffice": {
|
||||
{
|
||||
MimeType: "application/vnd.ms-word.template.macroenabled.12",
|
||||
TargetExtension: "docx",
|
||||
},
|
||||
{
|
||||
MimeType: "application/vnd.oasis.opendocument.text-template",
|
||||
TargetExtension: "docx",
|
||||
},
|
||||
{
|
||||
MimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.template",
|
||||
TargetExtension: "docx",
|
||||
},
|
||||
{
|
||||
MimeType: "application/vnd.oasis.opendocument.spreadsheet-template",
|
||||
TargetExtension: "xlsx",
|
||||
},
|
||||
{
|
||||
MimeType: "application/vnd.ms-excel.template.macroenabled.12",
|
||||
TargetExtension: "xlsx",
|
||||
},
|
||||
{
|
||||
MimeType: "application/vnd.openxmlformats-officedocument.spreadsheetml.template",
|
||||
TargetExtension: "xlsx",
|
||||
},
|
||||
{
|
||||
MimeType: "application/vnd.oasis.opendocument.presentation-template",
|
||||
TargetExtension: "pptx",
|
||||
},
|
||||
{
|
||||
MimeType: "application/vnd.ms-powerpoint.template.macroenabled.12",
|
||||
TargetExtension: "pptx",
|
||||
},
|
||||
{
|
||||
MimeType: "application/vnd.openxmlformats-officedocument.presentationml.template",
|
||||
TargetExtension: "pptx",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func addTemplateInfo(mt *appregistry.MimeTypeInfo, apps []*ProviderInfo) {
|
||||
for _, app := range apps {
|
||||
if tls, ok := tl.Templates[strings.ToLower(app.Name)]; ok {
|
||||
for _, tmpl := range tls {
|
||||
if tmpl.Extension != "" && tmpl.Extension == mt.Ext {
|
||||
app.TargetExt = tmpl.TargetExtension
|
||||
continue
|
||||
}
|
||||
if tmpl.MimeType == mt.MimeType {
|
||||
app.TargetExt = tmpl.TargetExtension
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Generated
Vendored
+19
-17
@@ -29,6 +29,8 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"go.opentelemetry.io/otel/codes"
|
||||
|
||||
"github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/config"
|
||||
"github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/errors"
|
||||
"github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/net"
|
||||
@@ -36,15 +38,15 @@ import (
|
||||
"github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/propfind"
|
||||
"github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/spacelookup"
|
||||
"github.com/cs3org/reva/v2/pkg/storagespace"
|
||||
"go.opentelemetry.io/otel/codes"
|
||||
|
||||
rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
|
||||
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
||||
semconv "go.opentelemetry.io/otel/semconv/v1.20.0"
|
||||
|
||||
"github.com/cs3org/reva/v2/pkg/appctx"
|
||||
ctxpkg "github.com/cs3org/reva/v2/pkg/ctx"
|
||||
rstatus "github.com/cs3org/reva/v2/pkg/rgrpc/status"
|
||||
"github.com/cs3org/reva/v2/pkg/utils"
|
||||
semconv "go.opentelemetry.io/otel/semconv/v1.20.0"
|
||||
)
|
||||
|
||||
// TrashbinHandler handles trashbin requests
|
||||
@@ -373,8 +375,8 @@ func (h *TrashbinHandler) formatTrashPropfind(ctx context.Context, s *svc, space
|
||||
func (h *TrashbinHandler) itemToPropResponse(ctx context.Context, s *svc, spaceID, refBase string, pf *propfind.XML, item *provider.RecycleItem) (*propfind.ResponseXML, error) {
|
||||
|
||||
baseURI := ctx.Value(net.CtxKeyBaseURI).(string)
|
||||
ref := path.Join(baseURI, refBase, item.Key)
|
||||
if item.Type == provider.ResourceType_RESOURCE_TYPE_CONTAINER {
|
||||
ref := path.Join(baseURI, refBase, item.GetKey())
|
||||
if item.GetType() == provider.ResourceType_RESOURCE_TYPE_CONTAINER {
|
||||
ref += "/"
|
||||
}
|
||||
|
||||
@@ -385,9 +387,9 @@ func (h *TrashbinHandler) itemToPropResponse(ctx context.Context, s *svc, spaceI
|
||||
|
||||
// TODO(jfd): if the path we list here is taken from the ListRecycle request we rely on the gateway to prefix it with the mount point
|
||||
|
||||
t := utils.TSToTime(item.DeletionTime).UTC()
|
||||
t := utils.TSToTime(item.GetDeletionTime()).UTC()
|
||||
dTime := t.Format(time.RFC1123Z)
|
||||
size := strconv.FormatUint(item.Size, 10)
|
||||
size := strconv.FormatUint(item.GetSize(), 10)
|
||||
|
||||
// when allprops has been requested
|
||||
if pf.Allprop != nil {
|
||||
@@ -397,11 +399,11 @@ func (h *TrashbinHandler) itemToPropResponse(ctx context.Context, s *svc, spaceI
|
||||
Prop: []prop.PropertyXML{},
|
||||
}
|
||||
// yes this is redundant, can be derived from oc:trashbin-original-location which contains the full path, clients should not fetch it
|
||||
propstatOK.Prop = append(propstatOK.Prop, prop.Escaped("oc:trashbin-original-filename", path.Base(item.Ref.Path)))
|
||||
propstatOK.Prop = append(propstatOK.Prop, prop.Escaped("oc:trashbin-original-location", strings.TrimPrefix(item.Ref.Path, "/")))
|
||||
propstatOK.Prop = append(propstatOK.Prop, prop.Escaped("oc:trashbin-delete-timestamp", strconv.FormatUint(item.DeletionTime.Seconds, 10)))
|
||||
propstatOK.Prop = append(propstatOK.Prop, prop.Escaped("oc:trashbin-original-filename", path.Base(item.GetRef().GetPath())))
|
||||
propstatOK.Prop = append(propstatOK.Prop, prop.Escaped("oc:trashbin-original-location", strings.TrimPrefix(item.GetRef().GetPath(), "/")))
|
||||
propstatOK.Prop = append(propstatOK.Prop, prop.Escaped("oc:trashbin-delete-timestamp", strconv.FormatUint(item.GetDeletionTime().GetSeconds(), 10)))
|
||||
propstatOK.Prop = append(propstatOK.Prop, prop.Escaped("oc:trashbin-delete-datetime", dTime))
|
||||
if item.Type == provider.ResourceType_RESOURCE_TYPE_CONTAINER {
|
||||
if item.GetType() == provider.ResourceType_RESOURCE_TYPE_CONTAINER {
|
||||
propstatOK.Prop = append(propstatOK.Prop, prop.Raw("d:resourcetype", "<d:collection/>"))
|
||||
propstatOK.Prop = append(propstatOK.Prop, prop.Raw("oc:size", size))
|
||||
} else {
|
||||
@@ -427,21 +429,21 @@ func (h *TrashbinHandler) itemToPropResponse(ctx context.Context, s *svc, spaceI
|
||||
case net.NsOwncloud:
|
||||
switch pf.Prop[i].Local {
|
||||
case "oc:size":
|
||||
if item.Type == provider.ResourceType_RESOURCE_TYPE_CONTAINER {
|
||||
if item.GetType() == provider.ResourceType_RESOURCE_TYPE_CONTAINER {
|
||||
propstatOK.Prop = append(propstatOK.Prop, prop.Escaped("oc:size", size))
|
||||
} else {
|
||||
propstatNotFound.Prop = append(propstatNotFound.Prop, prop.NotFound("oc:size"))
|
||||
}
|
||||
case "trashbin-original-filename":
|
||||
// yes this is redundant, can be derived from oc:trashbin-original-location which contains the full path, clients should not fetch it
|
||||
propstatOK.Prop = append(propstatOK.Prop, prop.Escaped("oc:trashbin-original-filename", path.Base(item.Ref.Path)))
|
||||
propstatOK.Prop = append(propstatOK.Prop, prop.Escaped("oc:trashbin-original-filename", path.Base(item.GetRef().GetPath())))
|
||||
case "trashbin-original-location":
|
||||
// TODO (jfd) double check and clarify the cs3 spec what the Key is about and if Path is only the folder that contains the file or if it includes the filename
|
||||
propstatOK.Prop = append(propstatOK.Prop, prop.Escaped("oc:trashbin-original-location", strings.TrimPrefix(item.Ref.Path, "/")))
|
||||
propstatOK.Prop = append(propstatOK.Prop, prop.Escaped("oc:trashbin-original-location", strings.TrimPrefix(item.GetRef().GetPath(), "/")))
|
||||
case "trashbin-delete-datetime":
|
||||
propstatOK.Prop = append(propstatOK.Prop, prop.Escaped("oc:trashbin-delete-datetime", dTime))
|
||||
case "trashbin-delete-timestamp":
|
||||
propstatOK.Prop = append(propstatOK.Prop, prop.Escaped("oc:trashbin-delete-timestamp", strconv.FormatUint(item.DeletionTime.Seconds, 10)))
|
||||
propstatOK.Prop = append(propstatOK.Prop, prop.Escaped("oc:trashbin-delete-timestamp", strconv.FormatUint(item.GetDeletionTime().GetSeconds(), 10)))
|
||||
case "spaceid":
|
||||
propstatOK.Prop = append(propstatOK.Prop, prop.Escaped("oc:spaceid", spaceID))
|
||||
default:
|
||||
@@ -450,20 +452,20 @@ func (h *TrashbinHandler) itemToPropResponse(ctx context.Context, s *svc, spaceI
|
||||
case net.NsDav:
|
||||
switch pf.Prop[i].Local {
|
||||
case "getcontentlength":
|
||||
if item.Type == provider.ResourceType_RESOURCE_TYPE_CONTAINER {
|
||||
if item.GetType() == provider.ResourceType_RESOURCE_TYPE_CONTAINER {
|
||||
propstatNotFound.Prop = append(propstatNotFound.Prop, prop.NotFound("d:getcontentlength"))
|
||||
} else {
|
||||
propstatOK.Prop = append(propstatOK.Prop, prop.Escaped("d:getcontentlength", size))
|
||||
}
|
||||
case "resourcetype":
|
||||
if item.Type == provider.ResourceType_RESOURCE_TYPE_CONTAINER {
|
||||
if item.GetType() == provider.ResourceType_RESOURCE_TYPE_CONTAINER {
|
||||
propstatOK.Prop = append(propstatOK.Prop, prop.Raw("d:resourcetype", "<d:collection/>"))
|
||||
} else {
|
||||
propstatOK.Prop = append(propstatOK.Prop, prop.Raw("d:resourcetype", ""))
|
||||
// redirectref is another option
|
||||
}
|
||||
case "getcontenttype":
|
||||
if item.Type == provider.ResourceType_RESOURCE_TYPE_CONTAINER {
|
||||
if item.GetType() == provider.ResourceType_RESOURCE_TYPE_CONTAINER {
|
||||
propstatOK.Prop = append(propstatOK.Prop, prop.Raw("d:getcontenttype", "httpd/unix-directory"))
|
||||
} else {
|
||||
propstatNotFound.Prop = append(propstatNotFound.Prop, prop.NotFound("d:getcontenttype"))
|
||||
|
||||
+1
@@ -322,6 +322,7 @@ var mimeTypes = map[string]string{
|
||||
"geojson": "application/geo+json",
|
||||
"gex": "application/vnd.geometry-explorer",
|
||||
"ggb": "application/vnd.geogebra.file",
|
||||
"ggp": "application/vnd.geogebra.pinboard",
|
||||
"ggs": "application/vnd.geogebra.slides",
|
||||
"ggt": "application/vnd.geogebra.tool",
|
||||
"ghf": "application/vnd.groove-help",
|
||||
|
||||
+12
-8
@@ -88,6 +88,8 @@ func (d *driver) Upload(ctx context.Context, req storage.UploadRequest, _ storag
|
||||
return &provider.ResourceInfo{}, err
|
||||
}
|
||||
|
||||
defer cleanup(&upload{Info: info})
|
||||
|
||||
client, _, rel, err := d.webdavClient(ctx, nil, &provider.Reference{
|
||||
Path: filepath.Join(info.MetaData["dir"], info.MetaData["filename"]),
|
||||
})
|
||||
@@ -297,6 +299,7 @@ func (u *upload) FinishUpload(ctx context.Context) error {
|
||||
}
|
||||
}
|
||||
|
||||
defer cleanup(u)
|
||||
// compare if they match the sent checksum
|
||||
// TODO the tus checksum extension would do this on every chunk, but I currently don't see an easy way to pass in the requested checksum. for now we do it in FinishUpload which is also called for chunked uploads
|
||||
if u.Info.MetaData["checksum"] != "" {
|
||||
@@ -316,7 +319,6 @@ func (u *upload) FinishUpload(ctx context.Context) error {
|
||||
err = errtypes.BadRequest("unsupported checksum algorithm: " + parts[0])
|
||||
}
|
||||
if err != nil {
|
||||
u.cleanup()
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -336,7 +338,6 @@ func (u *upload) FinishUpload(ctx context.Context) error {
|
||||
Path: filepath.Join(u.Info.MetaData["dir"], u.Info.MetaData["filename"]),
|
||||
})
|
||||
if err != nil {
|
||||
u.cleanup()
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -358,13 +359,8 @@ func (u *upload) FinishUpload(ctx context.Context) error {
|
||||
return client.WriteStream(rel, f, 0)
|
||||
}
|
||||
|
||||
func (u *upload) cleanup() {
|
||||
_ = os.Remove(u.BinPath())
|
||||
_ = os.Remove(u.InfoPath())
|
||||
}
|
||||
|
||||
func (u *upload) Terminate(ctx context.Context) error {
|
||||
u.cleanup()
|
||||
cleanup(u)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -403,3 +399,11 @@ func (u *upload) checkHash(expected string, h hash.Hash) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func cleanup(u *upload) {
|
||||
if u == nil {
|
||||
return
|
||||
}
|
||||
_ = os.Remove(u.BinPath())
|
||||
_ = os.Remove(u.InfoPath())
|
||||
}
|
||||
|
||||
+4
@@ -136,6 +136,10 @@ func (m *manager) Handler(fs storage.FS) (http.Handler, error) {
|
||||
if err != nil {
|
||||
appctx.GetLogger(context.Background()).Error().Err(err).Str("session", ev.Upload.ID).Msg("failed to list upload session")
|
||||
} else {
|
||||
if len(ups) < 1 {
|
||||
appctx.GetLogger(context.Background()).Error().Str("session", ev.Upload.ID).Msg("upload session not found")
|
||||
continue
|
||||
}
|
||||
up := ups[0]
|
||||
executant := up.Executant()
|
||||
ref := up.Reference()
|
||||
|
||||
+44
-9
@@ -836,13 +836,13 @@ func (fs *Decomposedfs) Move(ctx context.Context, oldRef, newRef *provider.Refer
|
||||
return
|
||||
}
|
||||
|
||||
rp, err := fs.p.AssemblePermissions(ctx, oldNode)
|
||||
orp, err := fs.p.AssemblePermissions(ctx, oldNode)
|
||||
switch {
|
||||
case err != nil:
|
||||
return err
|
||||
case !rp.Move:
|
||||
case !orp.Move:
|
||||
f, _ := storagespace.FormatReference(oldRef)
|
||||
if rp.Stat {
|
||||
if orp.Stat {
|
||||
return errtypes.PermissionDenied(f)
|
||||
}
|
||||
return errtypes.NotFound(f)
|
||||
@@ -856,19 +856,19 @@ func (fs *Decomposedfs) Move(ctx context.Context, oldRef, newRef *provider.Refer
|
||||
return
|
||||
}
|
||||
|
||||
rp, err = fs.p.AssemblePermissions(ctx, newNode)
|
||||
nrp, err := fs.p.AssemblePermissions(ctx, newNode)
|
||||
switch {
|
||||
case err != nil:
|
||||
return err
|
||||
case oldNode.IsDir(ctx) && !rp.CreateContainer:
|
||||
case oldNode.IsDir(ctx) && !nrp.CreateContainer:
|
||||
f, _ := storagespace.FormatReference(newRef)
|
||||
if rp.Stat {
|
||||
if nrp.Stat {
|
||||
return errtypes.PermissionDenied(f)
|
||||
}
|
||||
return errtypes.NotFound(f)
|
||||
case !oldNode.IsDir(ctx) && !rp.InitiateFileUpload:
|
||||
case !oldNode.IsDir(ctx) && !nrp.InitiateFileUpload:
|
||||
f, _ := storagespace.FormatReference(newRef)
|
||||
if rp.Stat {
|
||||
if nrp.Stat {
|
||||
return errtypes.PermissionDenied(f)
|
||||
}
|
||||
return errtypes.NotFound(f)
|
||||
@@ -882,7 +882,13 @@ func (fs *Decomposedfs) Move(ctx context.Context, oldRef, newRef *provider.Refer
|
||||
return err
|
||||
}
|
||||
|
||||
return fs.tp.Move(ctx, oldNode, newNode)
|
||||
if err := fs.tp.Move(ctx, oldNode, newNode); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fs.publishEvent(ctx, fs.moveEvent(ctx, oldRef, newRef, oldNode, newNode, orp, nrp))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetMD returns the metadata for the specified resource
|
||||
@@ -1241,3 +1247,32 @@ func (fs *Decomposedfs) PurgeRecycleItem(ctx context.Context, ref *provider.Refe
|
||||
func (fs *Decomposedfs) EmptyRecycle(ctx context.Context, ref *provider.Reference) error {
|
||||
return fs.trashbin.EmptyRecycle(ctx, ref)
|
||||
}
|
||||
|
||||
func (fs *Decomposedfs) getNodePath(ctx context.Context, n *node.Node, perms *provider.ResourcePermissions) (string, error) {
|
||||
hp := func(n *node.Node) bool {
|
||||
return perms.GetGetPath()
|
||||
}
|
||||
return fs.lu.Path(ctx, n, hp)
|
||||
}
|
||||
|
||||
func (fs *Decomposedfs) refFromNode(ctx context.Context, n *node.Node, storageId string, perms *provider.ResourcePermissions) (*provider.Reference, error) {
|
||||
var err error
|
||||
if perms == nil {
|
||||
perms, err = fs.p.AssemblePermissions(ctx, n)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
path, err := fs.getNodePath(ctx, n, perms)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &provider.Reference{
|
||||
ResourceId: &provider.ResourceId{
|
||||
StorageId: storageId,
|
||||
OpaqueId: n.SpaceID,
|
||||
SpaceId: n.SpaceID,
|
||||
},
|
||||
Path: path,
|
||||
}, nil
|
||||
}
|
||||
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
// Copyright 2018-2021 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 decomposedfs
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
|
||||
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
||||
"github.com/cs3org/reva/v2/pkg/appctx"
|
||||
revactx "github.com/cs3org/reva/v2/pkg/ctx"
|
||||
"github.com/cs3org/reva/v2/pkg/events"
|
||||
"github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/node"
|
||||
"github.com/cs3org/reva/v2/pkg/utils"
|
||||
)
|
||||
|
||||
func (fs *Decomposedfs) publishEvent(ctx context.Context, evf func() (any, error)) {
|
||||
log := appctx.GetLogger(ctx)
|
||||
if fs.stream == nil {
|
||||
log.Error().Msg("Failed to publish event, stream is undefined")
|
||||
return
|
||||
}
|
||||
ev, err := evf()
|
||||
if err != nil || ev == nil {
|
||||
log.Error().Err(err).Msg("Failed to crete the event")
|
||||
return
|
||||
}
|
||||
if err := events.Publish(ctx, fs.stream, ev); err != nil {
|
||||
log.Error().Err(err).Msg("Failed to publish event")
|
||||
}
|
||||
}
|
||||
|
||||
func (fs *Decomposedfs) moveEvent(ctx context.Context, oldRef, newRef *provider.Reference, oldNode, newNode *node.Node, orp, nrp *provider.ResourcePermissions) func() (any, error) {
|
||||
return func() (any, error) {
|
||||
executant, _ := revactx.ContextGetUser(ctx)
|
||||
ev := events.ItemMoved{
|
||||
SpaceOwner: newNode.Owner(),
|
||||
Executant: executant.GetId(),
|
||||
Ref: newRef,
|
||||
OldReference: oldRef,
|
||||
Timestamp: utils.TSNow(),
|
||||
ImpersonatingUser: extractImpersonator(executant),
|
||||
}
|
||||
log := appctx.GetLogger(ctx)
|
||||
if nref, err := fs.refFromNode(ctx, newNode, newRef.GetResourceId().GetStorageId(), nrp); err == nil {
|
||||
ev.Ref = nref
|
||||
} else {
|
||||
log.Error().Err(err).Msg("Failed to get destination reference")
|
||||
}
|
||||
|
||||
if oref, err := fs.refFromNode(ctx, oldNode, oldRef.GetResourceId().GetStorageId(), orp); err == nil {
|
||||
ev.OldReference = oref
|
||||
} else {
|
||||
log.Error().Err(err).Msg("Failed to get source reference")
|
||||
}
|
||||
|
||||
return ev, nil
|
||||
}
|
||||
}
|
||||
|
||||
func extractImpersonator(u *user.User) *user.User {
|
||||
var impersonator user.User
|
||||
if err := utils.ReadJSONFromOpaque(u.Opaque, "impersonating-user", &impersonator); err != nil {
|
||||
return nil
|
||||
}
|
||||
return &impersonator
|
||||
}
|
||||
Vendored
+1
-1
@@ -367,7 +367,7 @@ github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1
|
||||
github.com/cs3org/go-cs3apis/cs3/storage/registry/v1beta1
|
||||
github.com/cs3org/go-cs3apis/cs3/tx/v1beta1
|
||||
github.com/cs3org/go-cs3apis/cs3/types/v1beta1
|
||||
# github.com/cs3org/reva/v2 v2.25.1-0.20241004072335-2a6fdbed139d
|
||||
# github.com/cs3org/reva/v2 v2.25.1-0.20241015142909-99548fe690bd
|
||||
## explicit; go 1.21
|
||||
github.com/cs3org/reva/v2/cmd/revad/internal/grace
|
||||
github.com/cs3org/reva/v2/cmd/revad/runtime
|
||||
|
||||
Reference in New Issue
Block a user