filebrowser/http/share.go
Henrique Dias 4b602be5e3 updates
Former-commit-id: 54b88552d11f2151a165dba9debb4657dfa56cf8 [formerly 0ce53651a8e9660f9d5f977295f553b5b1d1e93a] [formerly 7ebca3a8896222091c95af86a9cf1d12550b8b76 [formerly 174330929a]]
Former-commit-id: 993d0cdb239f9969587d13a11ee8469fa8b91287 [formerly c22c911f944dd8d6597ab95589842d3c68d34869]
Former-commit-id: 44ed259fe50a085e8bcace3f1f14caafec97ce66
2017-08-18 09:00:32 +01:00

139 lines
2.9 KiB
Go

package http
import (
"encoding/hex"
"net/http"
"path/filepath"
"strconv"
"strings"
"time"
"github.com/asdine/storm"
"github.com/asdine/storm/q"
fm "github.com/hacdias/filemanager"
)
type shareLink struct {
Hash string `json:"hash" storm:"id,index"`
Path string `json:"path" storm:"index"`
Expires bool `json:"expires"`
ExpireDate time.Time `json:"expireDate"`
}
func shareHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
r.URL.Path = sanitizeURL(r.URL.Path)
switch r.Method {
case http.MethodGet:
return shareGetHandler(c, w, r)
case http.MethodDelete:
return shareDeleteHandler(c, w, r)
case http.MethodPost:
return sharePostHandler(c, w, r)
}
return http.StatusNotImplemented, nil
}
func shareGetHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
var (
s []*shareLink
path = filepath.Join(string(c.User.FileSystem), r.URL.Path)
)
err := c.db.Find("Path", path, &s)
if err == storm.ErrNotFound {
return http.StatusNotFound, nil
}
if err != nil {
return http.StatusInternalServerError, err
}
for i, link := range s {
if link.Expires && link.ExpireDate.Before(time.Now()) {
c.db.DeleteStruct(&shareLink{Hash: link.Hash})
s = append(s[:i], s[i+1:]...)
}
}
return renderJSON(w, s)
}
func sharePostHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
path := filepath.Join(string(c.User.FileSystem), r.URL.Path)
var s shareLink
expire := r.URL.Query().Get("expires")
unit := r.URL.Query().Get("unit")
if expire == "" {
err := c.db.Select(q.Eq("Path", path), q.Eq("Expires", false)).First(&s)
if err == nil {
w.Write([]byte(c.RootURL() + "/share/" + s.Hash))
return 0, nil
}
}
bytes, err := generateRandomBytes(32)
if err != nil {
return http.StatusInternalServerError, err
}
str := hex.EncodeToString(bytes)
s = shareLink{
Path: path,
Hash: str,
Expires: expire != "",
}
if expire != "" {
num, err := strconv.Atoi(expire)
if err != nil {
return http.StatusInternalServerError, err
}
var add time.Duration
switch unit {
case "seconds":
add = time.Second * time.Duration(num)
case "minutes":
add = time.Minute * time.Duration(num)
case "days":
add = time.Hour * 24 * time.Duration(num)
default:
add = time.Hour * time.Duration(num)
}
s.ExpireDate = time.Now().Add(add)
}
err = c.db.Save(&s)
if err != nil {
return http.StatusInternalServerError, err
}
return renderJSON(w, s)
}
func shareDeleteHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int, error) {
var s shareLink
err := c.db.One("Hash", strings.TrimPrefix(r.URL.Path, "/"), &s)
if err == storm.ErrNotFound {
return http.StatusNotFound, nil
}
if err != nil {
return http.StatusInternalServerError, err
}
err = c.db.DeleteStruct(&s)
if err != nil {
return http.StatusInternalServerError, err
}
return http.StatusOK, nil
}