web/editor/editor.go
Rama master · réplica de lectura del repositorio original.
// Package editor is about the routes used to open files with editors.
package editor
import (
"net/http"
"os"
"strconv"
"github.com/cozy/cozy-stack/model/permission"
"github.com/cozy/cozy-stack/model/sharing"
"github.com/cozy/cozy-stack/model/vfs"
"github.com/cozy/cozy-stack/pkg/consts"
"github.com/cozy/cozy-stack/pkg/jsonapi"
"github.com/cozy/cozy-stack/web/middlewares"
"github.com/labstack/echo/v4"
)
// OpenURL is the API handler for GET /editor/:file-id/open. It returns the
// parameters to build the URL where the file can be opened by an editor.
func OpenURL(c echo.Context) error {
return OpenURLWithReadOnly(c, c.QueryParam("ReadOnly") == "true")
}
// OpenURLWithReadOnly is like OpenURL, with the read-only flag given
// explicitly instead of read from the query.
func OpenURLWithReadOnly(c echo.Context, readOnly bool) error {
inst := middlewares.GetInstance(c)
fileID := c.Param("file-id")
open, err := sharing.OpenEditor(inst, fileID)
if err != nil {
return wrapError(err)
}
pdoc, err := middlewares.GetPermission(c)
if err != nil {
return err
}
memberIndex, _ := strconv.Atoi(c.QueryParam("MemberIndex"))
// If a directory is shared by link and contains the file, it can be opened
// with the same sharecode as the directory. The sharecode is also used to
// identify the member that previews a sharing.
if pdoc.Type == permission.TypeShareByLink ||
pdoc.Type == permission.TypeSharePreview ||
pdoc.Type == permission.TypeShareInteract {
code := middlewares.GetRequestToken(c)
open.AddShareByLinkCode(code)
readOnly = readOnlyForSharedOpen(pdoc, readOnly)
}
sharingID := c.QueryParam("SharingID") // Cozy to Cozy sharing
if err := open.CheckPermission(pdoc, sharingID); err != nil {
return middlewares.ErrForbidden
}
doc, err := open.GetResult(memberIndex, readOnly)
if err != nil {
return wrapError(err)
}
return jsonapi.Data(c, http.StatusOK, doc, nil)
}
// Routes sets the routing for opening files with editors.
func Routes(router *echo.Group) {
router.GET("/:file-id/open", OpenURL)
}
func readOnlyForSharedOpen(pdoc *permission.Permission, readOnly bool) bool {
if readOnly {
return true
}
for _, perm := range pdoc.Permissions {
if perm.Type == consts.Files && !perm.Verbs.ReadOnly() {
return false
}
}
return true
}
func wrapError(err error) *jsonapi.Error {
switch err {
case sharing.ErrCannotOpenFile, sharing.ErrMemberNotFound:
return jsonapi.NotFound(err)
case os.ErrNotExist, vfs.ErrParentDoesNotExist, vfs.ErrParentInTrash:
return jsonapi.NotFound(err)
}
return jsonapi.InternalServerError(err)
}