Ctrl K
ComunidadGuías…

web/editor/editor.go

Rama master · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
// 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)
}