|
|
|
package fs
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
"github.com/olivere/elastic/v7"
|
|
|
|
"github.com/veypi/OneAuth/cfg"
|
|
|
|
"github.com/veypi/OneAuth/libs/webdav"
|
|
|
|
"github.com/veypi/OneAuth/models"
|
|
|
|
"github.com/veypi/OneAuth/models/index"
|
|
|
|
"github.com/veypi/utils/log"
|
|
|
|
"gorm.io/gorm"
|
|
|
|
"net/http"
|
|
|
|
"strconv"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
func updateUserSize(uid uint, delta int64) error {
|
|
|
|
if uid == 0 {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
err := cfg.DB().Model(&models.User{}).Where("ID = ?", uid).
|
|
|
|
Update("Used", gorm.Expr("Used + ?", delta)).Error
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
func removeFile(r *http.Request, prefix string, h *webdav.Handler) error {
|
|
|
|
f := &models.File{}
|
|
|
|
f.OwnerID = h.OwnerID
|
|
|
|
f.Path = prefix
|
|
|
|
res, err := index.File.Get().Id(f.ID()).Do(r.Context())
|
|
|
|
if err != nil {
|
|
|
|
if elastic.IsNotFound(err) {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
_, err = index.File.Delete().Id(f.ID()).Do(r.Context())
|
|
|
|
if err == nil {
|
|
|
|
err = json.Unmarshal(res.Source, f)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
uid, _ := strconv.Atoi(h.OwnerID)
|
|
|
|
if f.Size > 0 && uid > 0 {
|
|
|
|
err = updateUserSize(uint(uid), -int64(f.Size))
|
|
|
|
}
|
|
|
|
_ = addHistory(r, h, models.ActDelete, res.Id, f.Path)
|
|
|
|
}
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
func updateFile(ctx context.Context, fileID string, props interface{}) error {
|
|
|
|
_, err := index.File.Update().Id(fileID).Doc(props).Do(ctx)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
func getFile(ctx context.Context, path string, h *webdav.Handler) (*models.File, error) {
|
|
|
|
f := &models.File{}
|
|
|
|
f.OwnerID = h.OwnerID
|
|
|
|
f.Path = path
|
|
|
|
//body, err := cfg.ES().Update().Index(models.IndexFile).Id(f.ID()).Upsert(f).Do(ctx)
|
|
|
|
body, err := index.File.Get().Id(f.ID()).Do(ctx)
|
|
|
|
if elastic.IsNotFound(err) {
|
|
|
|
f.CreatedAt = time.Now()
|
|
|
|
_, err = index.File.Index().Id(f.ID()).BodyJson(f).Do(ctx)
|
|
|
|
return f, err
|
|
|
|
} else if err != nil {
|
|
|
|
return f, err
|
|
|
|
}
|
|
|
|
err = json.Unmarshal(body.Source, f)
|
|
|
|
return f, err
|
|
|
|
}
|
|
|
|
|
|
|
|
func addHistory(r *http.Request, h *webdav.Handler, act models.Action, fileID string, tag string) error {
|
|
|
|
his := &models.History{
|
|
|
|
Action: act,
|
|
|
|
OwnerID: h.OwnerID,
|
|
|
|
ActorID: h.ActorID,
|
|
|
|
FileID: fileID,
|
|
|
|
Tag: tag,
|
|
|
|
IP: r.RemoteAddr,
|
|
|
|
}
|
|
|
|
his.CreatedAt = time.Now()
|
|
|
|
_, err := index.History.Index().BodyJson(his).Do(r.Context())
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if act == models.ActGet && fileID != "" {
|
|
|
|
_, err = index.File.Update().Id(fileID).
|
|
|
|
Script(elastic.NewScript("ctx._source.Count ++")).Do(r.Context())
|
|
|
|
}
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
func CleanHistory(days uint) error {
|
|
|
|
res, err := index.History.DeleteByQuery().
|
|
|
|
Query(elastic.NewRangeQuery("CreatedAt").Lt(fmt.Sprintf("now-%dd/d", days))).
|
|
|
|
Do(cfg.Ctx)
|
|
|
|
if err == nil && res.Deleted > 0 {
|
|
|
|
log.Info().Msgf("clean %d records of history.", res.Deleted)
|
|
|
|
}
|
|
|
|
return err
|
|
|
|
}
|