mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-01-07 12:50:21 -06:00
fix: code adjustments based on the wopi validator
This commit is contained in:
@@ -49,6 +49,10 @@ type PutRelativeResponse struct {
|
||||
HostEdit string
|
||||
}
|
||||
|
||||
type RenameResponse struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
// FileConnectorService is the interface to implement the "Files"
|
||||
// endpoint. Basically lock operations on the file plus the CheckFileInfo.
|
||||
// All operations need a context containing a WOPI context and, optionally,
|
||||
@@ -99,8 +103,8 @@ type FileConnectorService interface {
|
||||
// RenameFile will rename the provided file in the context to the requested
|
||||
// filename. The filename must be UTF8-encoded.
|
||||
// In case of conflict, this method will return the actual lockId in
|
||||
// the file.
|
||||
RenameFile(ctx context.Context, lockID, target string) (string, error)
|
||||
// the file as second return value.
|
||||
RenameFile(ctx context.Context, lockID, target string) (*RenameResponse, string, error)
|
||||
}
|
||||
|
||||
// FileConnector implements the "File" endpoint.
|
||||
@@ -626,6 +630,11 @@ func (f *FileConnector) PutRelativeFileSuggested(ctx context.Context, ccs Conten
|
||||
}
|
||||
}
|
||||
|
||||
// adjust the wopi file reference to use only the resource id without path
|
||||
if err := f.adjustWopiReference(ctx, &wopiContext, newLogger); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
wopiSrcURL, err := f.generateWOPISrc(ctx, wopiContext, newLogger)
|
||||
if err != nil {
|
||||
logger.Error().Err(err).Msg("PutRelativeFileSuggested: error generating the WOPISrc parameter")
|
||||
@@ -638,7 +647,9 @@ func (f *FileConnector) PutRelativeFileSuggested(ctx context.Context, ccs Conten
|
||||
Url: wopiSrcURL.String(),
|
||||
}
|
||||
|
||||
logger.Debug().Msg("PutRelativeFileSuggested: success")
|
||||
logger.Debug().
|
||||
Str("FinalReference", wopiContext.FileReference.String()).
|
||||
Msg("PutRelativeFileSuggested: success")
|
||||
return result, nil
|
||||
}
|
||||
|
||||
@@ -716,6 +727,9 @@ func (f *FileConnector) PutRelativeFileRelative(ctx context.Context, ccs Content
|
||||
}
|
||||
|
||||
if conError.HttpCodeOut == 409 {
|
||||
if err := f.adjustWopiReference(ctx, &wopiContext, newLogger); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
// if conflict generate a different name and retry.
|
||||
// this should happen only once
|
||||
wopiSrcURL, err2 := f.generateWOPISrc(ctx, wopiContext, newLogger)
|
||||
@@ -753,6 +767,10 @@ func (f *FileConnector) PutRelativeFileRelative(ctx context.Context, ccs Content
|
||||
}
|
||||
}
|
||||
|
||||
if err := f.adjustWopiReference(ctx, &wopiContext, newLogger); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
wopiSrcURL, err := f.generateWOPISrc(ctx, wopiContext, newLogger)
|
||||
if err != nil {
|
||||
newLogger.Error().Err(err).Msg("PutRelativeFileRelative: error generating the WOPISrc parameter")
|
||||
@@ -856,12 +874,14 @@ func (f *FileConnector) DeleteFile(ctx context.Context, lockID string) (string,
|
||||
// You can pass a pre-configured zerologger instance through the context that
|
||||
// will be used to log messages.
|
||||
//
|
||||
// The method will return the actual lockId in case of conflict, otherwise
|
||||
// the returned lockId will be empty.
|
||||
func (f *FileConnector) RenameFile(ctx context.Context, lockID, target string) (string, error) {
|
||||
// The method will return the final target name as first return value (target
|
||||
// is just a suggestion, so it could have changed) and the actual lockId in
|
||||
// case of conflict as second return value, otherwise the returned lockId will
|
||||
// be empty.
|
||||
func (f *FileConnector) RenameFile(ctx context.Context, lockID, target string) (*RenameResponse, string, error) {
|
||||
wopiContext, err := middleware.WopiContextFromCtx(ctx)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
logger := zerolog.Ctx(ctx).With().
|
||||
@@ -875,15 +895,20 @@ func (f *FileConnector) RenameFile(ctx context.Context, lockID, target string) (
|
||||
})
|
||||
if err != nil {
|
||||
logger.Error().Err(err).Msg("RenameFile: stat failed")
|
||||
return "", err
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
if oldStatRes.GetStatus().GetCode() != rpcv1beta1.Code_CODE_OK {
|
||||
logger.Error().
|
||||
Str("StatusCode", oldStatRes.GetStatus().GetCode().String()).
|
||||
Str("StatusMsg", oldStatRes.GetStatus().GetMessage()).
|
||||
Msg("RenameFile: stat failed with unexpected status")
|
||||
return "", NewConnectorError(500, oldStatRes.GetStatus().GetCode().String()+" "+oldStatRes.GetStatus().GetMessage())
|
||||
if oldStatRes.GetStatus().GetCode() == rpcv1beta1.Code_CODE_NOT_FOUND {
|
||||
logger.Error().Msg("RenameFile: file not found")
|
||||
return nil, "", NewConnectorError(404, oldStatRes.GetStatus().GetCode().String()+" "+oldStatRes.GetStatus().GetMessage())
|
||||
} else {
|
||||
logger.Error().
|
||||
Str("StatusCode", oldStatRes.GetStatus().GetCode().String()).
|
||||
Str("StatusMsg", oldStatRes.GetStatus().GetMessage()).
|
||||
Msg("RenameFile: stat failed with unexpected status")
|
||||
return nil, "", NewConnectorError(500, oldStatRes.GetStatus().GetCode().String()+" "+oldStatRes.GetStatus().GetMessage())
|
||||
}
|
||||
}
|
||||
|
||||
// the target doesn't include the extension
|
||||
@@ -908,10 +933,10 @@ func (f *FileConnector) RenameFile(ctx context.Context, lockID, target string) (
|
||||
})
|
||||
if err != nil {
|
||||
newLogger.Error().Err(err).Msg("RenameFile: move failed")
|
||||
return "", err
|
||||
return nil, "", err
|
||||
}
|
||||
if moveRes.GetStatus().GetCode() != rpcv1beta1.Code_CODE_OK {
|
||||
if moveRes.GetStatus().GetCode() == rpcv1beta1.Code_CODE_LOCKED {
|
||||
if moveRes.GetStatus().GetCode() == rpcv1beta1.Code_CODE_LOCKED || moveRes.GetStatus().GetCode() == rpcv1beta1.Code_CODE_ABORTED {
|
||||
currentLockID := ""
|
||||
if oldStatRes.GetInfo().GetLock() != nil {
|
||||
currentLockID = oldStatRes.GetInfo().GetLock().GetLockId()
|
||||
@@ -921,7 +946,7 @@ func (f *FileConnector) RenameFile(ctx context.Context, lockID, target string) (
|
||||
Str("StatusCode", moveRes.GetStatus().GetCode().String()).
|
||||
Str("StatusMsg", moveRes.GetStatus().GetMessage()).
|
||||
Msg("RenameFile: conflict")
|
||||
return currentLockID, NewConnectorError(409, "file is locked")
|
||||
return nil, currentLockID, NewConnectorError(409, "file is locked")
|
||||
}
|
||||
|
||||
if moveRes.GetStatus().GetCode() == rpcv1beta1.Code_CODE_ALREADY_EXISTS {
|
||||
@@ -936,7 +961,7 @@ func (f *FileConnector) RenameFile(ctx context.Context, lockID, target string) (
|
||||
Str("StatusMsg", moveRes.GetStatus().GetMessage()).
|
||||
Msg("RenameFile: move failed with unexpected status")
|
||||
|
||||
return "", NewConnectorError(500, moveRes.GetStatus().GetCode().String()+" "+moveRes.GetStatus().GetMessage())
|
||||
return nil, "", NewConnectorError(500, moveRes.GetStatus().GetCode().String()+" "+moveRes.GetStatus().GetMessage())
|
||||
}
|
||||
} else {
|
||||
// if the put is successful, exit the loop and move on
|
||||
@@ -944,8 +969,11 @@ func (f *FileConnector) RenameFile(ctx context.Context, lockID, target string) (
|
||||
logger = newLogger
|
||||
}
|
||||
}
|
||||
|
||||
logger.Debug().Msg("RenameFile: success")
|
||||
return "", nil
|
||||
return &RenameResponse{
|
||||
Name: strings.TrimSuffix(path.Base(finalTarget), path.Ext(finalTarget)), // return the final filename without extension
|
||||
}, "", nil
|
||||
|
||||
}
|
||||
|
||||
@@ -1178,3 +1206,29 @@ func (f *FileConnector) generateWOPISrc(ctx context.Context, wopiContext middlew
|
||||
|
||||
return wopiSrcURL, nil
|
||||
}
|
||||
|
||||
func (f *FileConnector) adjustWopiReference(ctx context.Context, wopiContext *middleware.WopiContext, logger zerolog.Logger) error {
|
||||
// using resourceid + path won't do for WOPI, we need just the resource if of the new file
|
||||
// the wopicontext has resourceid + path, which is good enough for the stat request
|
||||
newStatRes, err := f.gwc.Stat(ctx, &providerv1beta1.StatRequest{
|
||||
Ref: &wopiContext.FileReference,
|
||||
})
|
||||
if err != nil {
|
||||
logger.Error().Err(err).Msg("stat failed")
|
||||
return err
|
||||
}
|
||||
|
||||
if newStatRes.GetStatus().GetCode() != rpcv1beta1.Code_CODE_OK {
|
||||
logger.Error().
|
||||
Str("StatusCode", newStatRes.GetStatus().GetCode().String()).
|
||||
Str("StatusMsg", newStatRes.GetStatus().GetMessage()).
|
||||
Msg("stat failed with unexpected status")
|
||||
return NewConnectorError(500, newStatRes.GetStatus().GetCode().String()+" "+newStatRes.GetStatus().GetMessage())
|
||||
}
|
||||
// adjust the reference in the wopi context to use only the resourceid without the path
|
||||
wopiContext.FileReference = providerv1beta1.Reference{
|
||||
ResourceId: newStatRes.GetInfo().GetId(),
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -364,7 +364,7 @@ func (h *HttpAdapter) RenameFile(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
fileCon := h.con.GetFileConnector()
|
||||
newLockID, err := fileCon.RenameFile(r.Context(), lockID, utf8Target)
|
||||
response, newLockID, err := fileCon.RenameFile(r.Context(), lockID, utf8Target)
|
||||
if err != nil {
|
||||
var conError *ConnectorError
|
||||
if errors.As(err, &conError) {
|
||||
@@ -377,6 +377,25 @@ func (h *HttpAdapter) RenameFile(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
return
|
||||
}
|
||||
// If no error, a HTTP 200 should be sent automatically.
|
||||
// X-WOPI-Lock header isn't needed on HTTP 200
|
||||
|
||||
// need to return a JSON response with the name if this is successful
|
||||
logger := zerolog.Ctx(r.Context())
|
||||
|
||||
jsonFileInfo, err := json.Marshal(response)
|
||||
if err != nil {
|
||||
logger.Error().Err(err).Msg("RenameFile: failed to marshal response")
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Length", strconv.Itoa(len(jsonFileInfo)))
|
||||
w.WriteHeader(http.StatusOK)
|
||||
bytes, err := w.Write(jsonFileInfo)
|
||||
|
||||
if err != nil {
|
||||
logger.Error().
|
||||
Err(err).
|
||||
Int("TotalBytes", len(jsonFileInfo)).
|
||||
Int("WrittenBytes", bytes).
|
||||
Msg("RenameFile: failed to write contents in the HTTP response")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user