180 lines
3.3 KiB
Go
180 lines
3.3 KiB
Go
package collabora
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"io"
|
|
"io/ioutil"
|
|
"net/http"
|
|
"os"
|
|
"regexp"
|
|
"time"
|
|
|
|
"github.com/labstack/echo/v4"
|
|
"gitnet.fr/deblan/budget/config"
|
|
"gitnet.fr/deblan/budget/database/model"
|
|
f "gitnet.fr/deblan/budget/file"
|
|
"gitnet.fr/deblan/budget/backend/view"
|
|
tpl "gitnet.fr/deblan/budget/backend/view/template/collabora"
|
|
)
|
|
|
|
func getToken() string {
|
|
now := time.Now()
|
|
dateString := fmt.Sprintf(
|
|
"%04d-%02d-%02d-%s",
|
|
now.Year(),
|
|
now.Month(), now.Day(),
|
|
config.Get().Security.Secret,
|
|
)
|
|
|
|
hash := sha256.New()
|
|
hash.Write([]byte(dateString))
|
|
hashedBytes := hash.Sum(nil)
|
|
|
|
hashedString := hex.EncodeToString(hashedBytes)
|
|
|
|
return hashedString[:32]
|
|
}
|
|
|
|
type Controller struct {
|
|
Token string
|
|
}
|
|
|
|
func New(e *echo.Echo) *Controller {
|
|
c := Controller{
|
|
Token: getToken(),
|
|
}
|
|
|
|
e.GET("/collabora/:id", c.Iframe)
|
|
e.GET("/wopi/:id", c.Info)
|
|
e.GET("/wopi/:id/contents", c.WopiContentGet)
|
|
e.POST("/wopi/:id/contents", c.WopiContentPost)
|
|
|
|
return &c
|
|
}
|
|
|
|
func (ctrl *Controller) Iframe(c echo.Context) error {
|
|
if nil == model.LoadSessionUser(c) {
|
|
return c.Redirect(302, "/login")
|
|
}
|
|
|
|
resp, err := http.Get(config.Get().Collabora.HostingDiscoveryUrl())
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
defer resp.Body.Close()
|
|
|
|
regex, _ := regexp.Compile(fmt.Sprintf(
|
|
`<action default="true" ext="%s" name="edit" urlsrc="([^"]+)"/>`,
|
|
c.Param("extension"),
|
|
))
|
|
body, _ := io.ReadAll(resp.Body)
|
|
items := regex.FindStringSubmatch(string(body))
|
|
|
|
if len(items) == 0 {
|
|
return nil
|
|
}
|
|
|
|
wopiSrc := fmt.Sprintf(
|
|
"%s%s",
|
|
config.Get().Server.BaseUrl,
|
|
"/wopi/"+c.Param("id"),
|
|
)
|
|
|
|
url := items[1] + "WOPISrc=" + wopiSrc
|
|
|
|
return view.Render(c, 200, tpl.Iframe(url, ctrl.Token))
|
|
}
|
|
|
|
func (ctrl *Controller) Info(c echo.Context) error {
|
|
if c.QueryParam("access_token") != ctrl.Token {
|
|
return c.JSON(403, nil)
|
|
}
|
|
|
|
var file string
|
|
files := []f.File{}
|
|
f.GetFiles(&files, config.Get().File.Path)
|
|
|
|
for _, f := range files {
|
|
if f.Id == c.Param("id") {
|
|
file = f.Path
|
|
}
|
|
}
|
|
|
|
if file == "" {
|
|
return c.JSON(404, "File not found")
|
|
}
|
|
|
|
fi, _ := os.Stat(file)
|
|
|
|
type res struct {
|
|
BaseFileName string
|
|
Size int64
|
|
UserId uint
|
|
UserCanWrite bool
|
|
}
|
|
|
|
return c.JSON(200, res{
|
|
BaseFileName: fi.Name(),
|
|
Size: fi.Size(),
|
|
UserId: 1, // User.ID,
|
|
UserCanWrite: true,
|
|
})
|
|
}
|
|
|
|
func (ctrl *Controller) WopiContentGet(c echo.Context) error {
|
|
if c.QueryParam("access_token") != ctrl.Token {
|
|
return c.JSON(403, nil)
|
|
}
|
|
|
|
var file string
|
|
files := []f.File{}
|
|
f.GetFiles(&files, config.Get().File.Path)
|
|
|
|
for _, f := range files {
|
|
if f.Id == c.Param("id") {
|
|
file = f.Path
|
|
}
|
|
}
|
|
|
|
if file == "" {
|
|
return c.JSON(404, "File not found")
|
|
}
|
|
|
|
content, _ := os.ReadFile(file)
|
|
|
|
return c.Blob(200, "application/vnd.oasis.opendocument.spreadsheet", content)
|
|
}
|
|
|
|
func (ctrl *Controller) WopiContentPost(c echo.Context) error {
|
|
if c.QueryParam("access_token") != ctrl.Token {
|
|
return c.JSON(403, nil)
|
|
}
|
|
|
|
var file string
|
|
files := []f.File{}
|
|
f.GetFiles(&files, config.Get().File.Path)
|
|
|
|
for _, f := range files {
|
|
if f.Id == c.Param("id") {
|
|
file = f.Path
|
|
}
|
|
}
|
|
|
|
if file == "" {
|
|
return c.JSON(404, "File not found")
|
|
}
|
|
|
|
data, _ := ioutil.ReadAll(c.Request().Body)
|
|
|
|
err := os.WriteFile(file, data, 0600)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return c.JSON(200, nil)
|
|
}
|