203 lines
4.1 KiB
Go
203 lines
4.1 KiB
Go
package file
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/labstack/echo/v4"
|
|
"gitnet.fr/deblan/budget/backend/controller/crud"
|
|
"gitnet.fr/deblan/budget/backend/message"
|
|
"gitnet.fr/deblan/budget/config"
|
|
"gitnet.fr/deblan/budget/database/model"
|
|
f "gitnet.fr/deblan/budget/file"
|
|
)
|
|
|
|
type Controller struct {
|
|
}
|
|
|
|
func New(e *echo.Echo) *Controller {
|
|
c := Controller{}
|
|
|
|
e.GET("/api/filemanager/files", c.List)
|
|
e.POST("/api/filemanager/file", c.CreateFile)
|
|
e.POST("/api/filemanager/directory", c.CreateDirectory)
|
|
e.GET("/api/filemanager/file/:id/:name", c.Download)
|
|
e.DELETE("/api/filemanager/file/:id", c.Delete)
|
|
|
|
return &c
|
|
}
|
|
|
|
func (ctrl *Controller) List(c echo.Context) error {
|
|
if nil == model.LoadApiUser(c) {
|
|
return c.JSON(403, crud.Error{Code: 403, Message: message.LoginRequired})
|
|
}
|
|
|
|
tree := f.GetTree("", config.Get().File.Path)
|
|
|
|
return c.JSON(200, tree)
|
|
}
|
|
|
|
func (ctrl *Controller) CreateFile(c echo.Context) error {
|
|
if nil == model.LoadApiUser(c) {
|
|
return c.JSON(403, crud.Error{Code: 403, Message: message.LoginRequired})
|
|
}
|
|
|
|
file, err := c.FormFile("file")
|
|
if err != nil {
|
|
return c.JSON(400, crud.Error{
|
|
Code: 400,
|
|
Message: err.Error(),
|
|
})
|
|
}
|
|
|
|
src, err := file.Open()
|
|
if err != nil {
|
|
return c.JSON(400, crud.Error{
|
|
Code: 400,
|
|
Message: err.Error(),
|
|
})
|
|
}
|
|
|
|
defer src.Close()
|
|
|
|
var buf bytes.Buffer
|
|
io.Copy(&buf, src)
|
|
|
|
output := searchDirectory(c.FormValue("path"), f.GetTree("", config.Get().File.Path))
|
|
|
|
if output != nil {
|
|
os.WriteFile(output.Path+"/"+file.Filename, buf.Bytes(), 0644)
|
|
return c.JSON(200, true)
|
|
}
|
|
|
|
return c.JSON(400, false)
|
|
}
|
|
|
|
func (ctrl *Controller) CreateDirectory(c echo.Context) error {
|
|
if nil == model.LoadApiUser(c) {
|
|
return c.JSON(403, crud.Error{Code: 403, Message: message.LoginRequired})
|
|
}
|
|
|
|
type body struct {
|
|
Directory string `json:"directory" validate:"required"`
|
|
Path string `json:"path" validate:"required"`
|
|
}
|
|
|
|
value := new(body)
|
|
|
|
if err := c.Bind(value); err != nil {
|
|
return c.JSON(400, crud.Error{
|
|
Code: 400,
|
|
Message: "Bad request",
|
|
})
|
|
}
|
|
|
|
fmt.Printf("%+v\n", value)
|
|
|
|
value.Directory = strings.ReplaceAll(value.Directory, "..", "")
|
|
value.Directory = strings.ReplaceAll(value.Directory, "/", "")
|
|
value.Directory = strings.ReplaceAll(value.Directory, "\\", "")
|
|
value.Directory = strings.TrimSpace(value.Directory)
|
|
|
|
fmt.Printf("%+v\n", value)
|
|
|
|
if err := c.Validate(value); err != nil {
|
|
return c.JSON(400, crud.Error{
|
|
Code: 400,
|
|
Message: err.Error(),
|
|
})
|
|
}
|
|
|
|
output := searchDirectory(value.Path, f.GetTree("", config.Get().File.Path))
|
|
|
|
if output != nil {
|
|
dir := strings.ReplaceAll(output.Path+"/"+value.Directory, "//", "/")
|
|
os.MkdirAll(dir, 0750)
|
|
return c.JSON(200, true)
|
|
}
|
|
|
|
return c.JSON(400, crud.Error{
|
|
Code: 400,
|
|
Message: "Bad request",
|
|
})
|
|
}
|
|
|
|
func (ctrl *Controller) Download(c echo.Context) error {
|
|
if nil == model.LoadUser(c) {
|
|
return c.JSON(403, crud.Error{Code: 403, Message: message.LoginRequired})
|
|
}
|
|
|
|
var file string
|
|
var contentType string
|
|
|
|
files := []f.File{}
|
|
f.GetFiles(&files, config.Get().File.Path)
|
|
|
|
for _, f := range files {
|
|
if f.Id == c.Param("id") {
|
|
file = f.Path
|
|
contentType = f.Type
|
|
}
|
|
}
|
|
|
|
if file == "" {
|
|
return c.JSON(404, message.FileNotFound)
|
|
}
|
|
|
|
content, _ := os.ReadFile(file)
|
|
|
|
return c.Blob(200, contentType, content)
|
|
}
|
|
|
|
func (ctrl *Controller) Delete(c echo.Context) error {
|
|
if nil == model.LoadApiUser(c) {
|
|
return c.JSON(403, crud.Error{Code: 403, Message: message.LoginRequired})
|
|
}
|
|
|
|
var file string
|
|
|
|
files := []f.File{}
|
|
directories := []f.Directory{}
|
|
|
|
f.GetFiles(&files, config.Get().File.Path)
|
|
f.GetDirectories(&directories, config.Get().File.Path)
|
|
|
|
for _, f := range files {
|
|
if f.Id == c.Param("id") {
|
|
file = f.Path
|
|
}
|
|
}
|
|
|
|
for _, f := range directories {
|
|
if f.Id == c.Param("id") {
|
|
file = f.Path
|
|
}
|
|
}
|
|
|
|
if file == "" {
|
|
return c.JSON(404, message.FileNotFound)
|
|
}
|
|
|
|
os.RemoveAll(file)
|
|
|
|
return c.JSON(200, nil)
|
|
}
|
|
|
|
func searchDirectory(id string, tree f.Tree) *f.Tree {
|
|
if tree.Id == id {
|
|
return &tree
|
|
}
|
|
|
|
for _, tree = range tree.Directories {
|
|
tr := searchDirectory(id, tree)
|
|
|
|
if tr != nil {
|
|
return tr
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|