mirror of
https://github.com/mickael-kerjean/filestash.git
synced 2026-10-19 16:14:39 +00:00
chore (refactoring): migrate journal to pkg/journal
This commit is contained in:
@@ -16,8 +16,10 @@ import (
|
||||
. "github.com/mickael-kerjean/filestash/server/pkg/env"
|
||||
. "github.com/mickael-kerjean/filestash/server/pkg/kernel"
|
||||
. "github.com/mickael-kerjean/filestash/server/pkg/mime"
|
||||
. "github.com/mickael-kerjean/filestash/server/pkg/permissions"
|
||||
. "github.com/mickael-kerjean/filestash/server/pkg/utils"
|
||||
|
||||
"github.com/mickael-kerjean/filestash/server/pkg/permissions"
|
||||
"github.com/mickael-kerjean/filestash/server/pkg/journal"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -54,7 +56,7 @@ func FileCat(ctx *App, res http.ResponseWriter, req *http.Request) {
|
||||
MaxAge: -1,
|
||||
Path: "/",
|
||||
})
|
||||
if CanRead(ctx) == false {
|
||||
if permissions.CanRead(ctx) == false {
|
||||
Log.Debug("cat::permission 'permission denied'")
|
||||
SendErrorResult(res, ErrPermissionDenied)
|
||||
return
|
||||
@@ -308,4 +310,5 @@ func FileCat(ctx *App, res http.ResponseWriter, req *http.Request) {
|
||||
io.CopyBuffer(res, file, *buf)
|
||||
}
|
||||
file.Close()
|
||||
journal.Send(ctx, req, "cat", path)
|
||||
}
|
||||
|
||||
@@ -12,8 +12,10 @@ import (
|
||||
|
||||
. "github.com/mickael-kerjean/filestash/server/pkg/core"
|
||||
. "github.com/mickael-kerjean/filestash/server/pkg/kernel"
|
||||
. "github.com/mickael-kerjean/filestash/server/pkg/permissions"
|
||||
. "github.com/mickael-kerjean/filestash/server/pkg/utils"
|
||||
|
||||
"github.com/mickael-kerjean/filestash/server/pkg/journal"
|
||||
"github.com/mickael-kerjean/filestash/server/pkg/permissions"
|
||||
)
|
||||
|
||||
type FileInfo struct {
|
||||
@@ -26,8 +28,8 @@ type FileInfo struct {
|
||||
}
|
||||
|
||||
func FileLs(ctx *App, res http.ResponseWriter, req *http.Request) {
|
||||
if CanRead(ctx) == false {
|
||||
if CanUpload(ctx) == false {
|
||||
if permissions.CanRead(ctx) == false {
|
||||
if permissions.CanUpload(ctx) == false {
|
||||
Log.Debug("ls::permission 'permission denied'")
|
||||
SendErrorResult(res, ErrPermissionDenied)
|
||||
return
|
||||
@@ -73,7 +75,7 @@ func FileLs(ctx *App, res http.ResponseWriter, req *http.Request) {
|
||||
}
|
||||
ctx.Context = context.WithValue(ctx.Context, "AUDIT", nil)
|
||||
}
|
||||
if CanEdit(ctx) == false {
|
||||
if permissions.CanEdit(ctx) == false {
|
||||
perms.CanCreateFile = NewBool(false)
|
||||
perms.CanCreateDirectory = NewBool(false)
|
||||
perms.CanRename = NewBool(false)
|
||||
@@ -81,14 +83,14 @@ func FileLs(ctx *App, res http.ResponseWriter, req *http.Request) {
|
||||
perms.CanDelete = NewBool(false)
|
||||
perms.CanUpload = NewBool(false)
|
||||
}
|
||||
if CanUpload(ctx) == false {
|
||||
if permissions.CanUpload(ctx) == false {
|
||||
perms.CanCreateDirectory = NewBool(false)
|
||||
perms.CanRename = NewBool(false)
|
||||
perms.CanMove = NewBool(false)
|
||||
perms.CanDelete = NewBool(false)
|
||||
perms.CanUpload = NewBool(false)
|
||||
}
|
||||
if CanShare(ctx) == false {
|
||||
if permissions.CanShare(ctx) == false {
|
||||
perms.CanShare = NewBool(false)
|
||||
}
|
||||
|
||||
@@ -135,7 +137,8 @@ func FileLs(ctx *App, res http.ResponseWriter, req *http.Request) {
|
||||
res.Header().Set("Etag", etagValue)
|
||||
if etagValue != "" && req.Header.Get("If-None-Match") == etagValue {
|
||||
res.WriteHeader(http.StatusNotModified)
|
||||
return
|
||||
} else {
|
||||
SendSuccessResultsWithMetadata(res, files, perms)
|
||||
}
|
||||
SendSuccessResultsWithMetadata(res, files, perms)
|
||||
journal.Send(ctx, req, "ls", path)
|
||||
}
|
||||
|
||||
@@ -6,11 +6,13 @@ import (
|
||||
. "github.com/mickael-kerjean/filestash/server/pkg/core"
|
||||
. "github.com/mickael-kerjean/filestash/server/pkg/kernel"
|
||||
. "github.com/mickael-kerjean/filestash/server/pkg/utils"
|
||||
. "github.com/mickael-kerjean/filestash/server/pkg/permissions"
|
||||
|
||||
"github.com/mickael-kerjean/filestash/server/pkg/permissions"
|
||||
"github.com/mickael-kerjean/filestash/server/pkg/journal"
|
||||
)
|
||||
|
||||
func FileMkdir(ctx *App, res http.ResponseWriter, req *http.Request) {
|
||||
if CanUpload(ctx) == false {
|
||||
if permissions.CanUpload(ctx) == false {
|
||||
Log.Debug("mkdir::permission 'permission denied'")
|
||||
SendErrorResult(res, NewError("Permission denied", 403))
|
||||
return
|
||||
@@ -38,5 +40,5 @@ func FileMkdir(ctx *App, res http.ResponseWriter, req *http.Request) {
|
||||
return
|
||||
}
|
||||
SendSuccessResult(res, nil)
|
||||
EventWatch(ctx, req, "mkdir", path)
|
||||
journal.Send(ctx, req, "mkdir", path)
|
||||
}
|
||||
|
||||
@@ -6,11 +6,13 @@ import (
|
||||
. "github.com/mickael-kerjean/filestash/server/pkg/core"
|
||||
. "github.com/mickael-kerjean/filestash/server/pkg/kernel"
|
||||
. "github.com/mickael-kerjean/filestash/server/pkg/utils"
|
||||
. "github.com/mickael-kerjean/filestash/server/pkg/permissions"
|
||||
|
||||
"github.com/mickael-kerjean/filestash/server/pkg/permissions"
|
||||
"github.com/mickael-kerjean/filestash/server/pkg/journal"
|
||||
)
|
||||
|
||||
func FileMv(ctx *App, res http.ResponseWriter, req *http.Request) {
|
||||
if CanEdit(ctx) == false {
|
||||
if permissions.CanEdit(ctx) == false {
|
||||
Log.Debug("mv::permission 'permission denied'")
|
||||
SendErrorResult(res, NewError("Permission denied", 403))
|
||||
return
|
||||
@@ -49,5 +51,5 @@ func FileMv(ctx *App, res http.ResponseWriter, req *http.Request) {
|
||||
return
|
||||
}
|
||||
SendSuccessResult(res, nil)
|
||||
EventWatch(ctx, req, "mv", from, to)
|
||||
journal.Send(ctx, req, "mv", from, to)
|
||||
}
|
||||
|
||||
@@ -6,11 +6,13 @@ import (
|
||||
. "github.com/mickael-kerjean/filestash/server/pkg/core"
|
||||
. "github.com/mickael-kerjean/filestash/server/pkg/kernel"
|
||||
. "github.com/mickael-kerjean/filestash/server/pkg/utils"
|
||||
. "github.com/mickael-kerjean/filestash/server/pkg/permissions"
|
||||
|
||||
"github.com/mickael-kerjean/filestash/server/pkg/permissions"
|
||||
"github.com/mickael-kerjean/filestash/server/pkg/journal"
|
||||
)
|
||||
|
||||
func FileRm(ctx *App, res http.ResponseWriter, req *http.Request) {
|
||||
if CanEdit(ctx) == false {
|
||||
if permissions.CanEdit(ctx) == false {
|
||||
Log.Debug("rm::permission 'permission denied'")
|
||||
SendErrorResult(res, NewError("Permission denied", 403))
|
||||
return
|
||||
@@ -38,5 +40,5 @@ func FileRm(ctx *App, res http.ResponseWriter, req *http.Request) {
|
||||
return
|
||||
}
|
||||
SendSuccessResult(res, nil)
|
||||
EventWatch(ctx, req, "rm", path)
|
||||
journal.Send(ctx, req, "rm", path)
|
||||
}
|
||||
|
||||
@@ -17,8 +17,10 @@ import (
|
||||
|
||||
. "github.com/mickael-kerjean/filestash/server/pkg/core"
|
||||
. "github.com/mickael-kerjean/filestash/server/pkg/kernel"
|
||||
. "github.com/mickael-kerjean/filestash/server/pkg/permissions"
|
||||
. "github.com/mickael-kerjean/filestash/server/pkg/utils"
|
||||
|
||||
"github.com/mickael-kerjean/filestash/server/pkg/permissions"
|
||||
"github.com/mickael-kerjean/filestash/server/pkg/journal"
|
||||
)
|
||||
|
||||
func FileSave(ctx *App, res http.ResponseWriter, req *http.Request) {
|
||||
@@ -39,8 +41,8 @@ func FileSave(ctx *App, res http.ResponseWriter, req *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if CanEdit(ctx) == false {
|
||||
if CanUpload(ctx) == false {
|
||||
if permissions.CanEdit(ctx) == false {
|
||||
if permissions.CanUpload(ctx) == false {
|
||||
Log.Debug("files::save action=permission_upload err=permission_denied")
|
||||
SendErrorResult(res, ErrPermissionDenied)
|
||||
return
|
||||
@@ -88,7 +90,7 @@ func FileSave(ctx *App, res http.ResponseWriter, req *http.Request) {
|
||||
SendErrorResult(res, ErrNotImplemented)
|
||||
return
|
||||
}
|
||||
EventWatch(ctx, req, "save", path)
|
||||
journal.Send(ctx, req, "save", path)
|
||||
}
|
||||
|
||||
func handlerClassic(ctx *App, res http.ResponseWriter, req *http.Request, path string, h http.Header) {
|
||||
|
||||
@@ -6,11 +6,13 @@ import (
|
||||
. "github.com/mickael-kerjean/filestash/server/pkg/core"
|
||||
. "github.com/mickael-kerjean/filestash/server/pkg/kernel"
|
||||
. "github.com/mickael-kerjean/filestash/server/pkg/utils"
|
||||
. "github.com/mickael-kerjean/filestash/server/pkg/permissions"
|
||||
|
||||
"github.com/mickael-kerjean/filestash/server/pkg/permissions"
|
||||
"github.com/mickael-kerjean/filestash/server/pkg/journal"
|
||||
)
|
||||
|
||||
func FileTouch(ctx *App, res http.ResponseWriter, req *http.Request) {
|
||||
if CanUpload(ctx) == false {
|
||||
if permissions.CanUpload(ctx) == false {
|
||||
Log.Debug("touch::permission 'permission denied'")
|
||||
SendErrorResult(res, NewError("Permission denied", 403))
|
||||
return
|
||||
@@ -38,5 +40,5 @@ func FileTouch(ctx *App, res http.ResponseWriter, req *http.Request) {
|
||||
return
|
||||
}
|
||||
SendSuccessResult(res, nil)
|
||||
EventWatch(ctx, req, "touch", path)
|
||||
journal.Send(ctx, req, "touch", path)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package journal
|
||||
|
||||
import (
|
||||
"time"
|
||||
"strings"
|
||||
"net/http"
|
||||
|
||||
. "github.com/mickael-kerjean/filestash/server/pkg/core"
|
||||
. "github.com/mickael-kerjean/filestash/server/pkg/utils"
|
||||
)
|
||||
|
||||
func Send(ctx *App, req *http.Request, op string, path string, target ...string) {
|
||||
t := time.Now()
|
||||
go func() {
|
||||
cVal := fileop{
|
||||
Kind: "fs",
|
||||
Operation: op,
|
||||
Path: path,
|
||||
Target: strings.Join(target, ","),
|
||||
Time: t.UTC(),
|
||||
StorageID: GenerateID(ctx.Session),
|
||||
UserAgent: req.Header.Get("User-Agent"),
|
||||
}
|
||||
gate.L.Lock()
|
||||
journal.Value = cVal
|
||||
journal = journal.Next()
|
||||
gate.Broadcast()
|
||||
gate.L.Unlock()
|
||||
}()
|
||||
}
|
||||
@@ -1,12 +1,10 @@
|
||||
package files
|
||||
package journal
|
||||
|
||||
import (
|
||||
"container/ring"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
. "github.com/mickael-kerjean/filestash/server/pkg/core"
|
||||
@@ -14,30 +12,7 @@ import (
|
||||
. "github.com/mickael-kerjean/filestash/server/pkg/utils"
|
||||
)
|
||||
|
||||
var (
|
||||
journal = ring.New(5000)
|
||||
gate = sync.NewCond(&sync.Mutex{})
|
||||
)
|
||||
|
||||
func init() {
|
||||
t := time.Now().UTC()
|
||||
for i := 0; i < journal.Len(); i++ {
|
||||
journal.Value = mutation{Time: t}
|
||||
journal = journal.Next()
|
||||
}
|
||||
}
|
||||
|
||||
type mutation struct {
|
||||
Operation string `json:"operation"`
|
||||
Path string `json:"path"`
|
||||
Target string `json:"target,omitempty"`
|
||||
Echo bool `json:"echo"`
|
||||
StorageID string `json:"-"`
|
||||
Time time.Time `json:"-"`
|
||||
UserAgent string `json:"-"`
|
||||
}
|
||||
|
||||
func FileWatch(ctx *App, res http.ResponseWriter, req *http.Request) {
|
||||
func Handler(ctx *App, res http.ResponseWriter, req *http.Request) {
|
||||
flusher, ok := res.(http.Flusher)
|
||||
if !ok {
|
||||
SendErrorResult(res, NewError("streaming not supported", 500))
|
||||
@@ -66,9 +41,9 @@ func FileWatch(ctx *App, res http.ResponseWriter, req *http.Request) {
|
||||
} else if firstRun == false {
|
||||
gate.Wait()
|
||||
}
|
||||
changes := make([]mutation, 0, 10)
|
||||
changes := make([]fileop, 0, 10)
|
||||
for i, len, curr := 0, journal.Len(), journal.Prev(); i < len; i, curr = i+1, curr.Prev() {
|
||||
el := curr.Value.(mutation)
|
||||
el := curr.Value.(fileop)
|
||||
if el.Time.Before(checkpoint) || el.Time.Equal(checkpoint) {
|
||||
break
|
||||
}
|
||||
@@ -84,28 +59,9 @@ func FileWatch(ctx *App, res http.ResponseWriter, req *http.Request) {
|
||||
for i := len(changes); i > 0; i-- {
|
||||
el := changes[i-1]
|
||||
data, _ := json.Marshal(el)
|
||||
fmt.Fprintf(res, "id: %s\nevent: mutation\ndata: %s\n\n", el.Time.Format(time.RFC3339Nano), data)
|
||||
fmt.Fprintf(res, "id: %s\nevent: %s\ndata: %s\n\n", el.Time.Format(time.RFC3339Nano), el.Kind, data)
|
||||
checkpoint = changes[0].Time
|
||||
}
|
||||
flusher.Flush()
|
||||
}
|
||||
}
|
||||
|
||||
func EventWatch(ctx *App, req *http.Request, op string, path string, target ...string) {
|
||||
t := time.Now()
|
||||
go func() {
|
||||
cVal := mutation{
|
||||
Operation: op,
|
||||
Path: path,
|
||||
Target: strings.Join(target, ","),
|
||||
Time: t.UTC(),
|
||||
StorageID: GenerateID(ctx.Session),
|
||||
UserAgent: req.Header.Get("User-Agent"),
|
||||
}
|
||||
gate.L.Lock()
|
||||
journal.Value = cVal
|
||||
journal = journal.Next()
|
||||
gate.Broadcast()
|
||||
gate.L.Unlock()
|
||||
}()
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package journal
|
||||
|
||||
import (
|
||||
"container/ring"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
journal = ring.New(5000)
|
||||
gate = sync.NewCond(&sync.Mutex{})
|
||||
)
|
||||
|
||||
func init() {
|
||||
t := time.Now().UTC()
|
||||
for i := 0; i < journal.Len(); i++ {
|
||||
journal.Value = fileop{Time: t}
|
||||
journal = journal.Next()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package journal
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type fileop struct {
|
||||
Kind string `json:"-"`
|
||||
Operation string `json:"operation"`
|
||||
Path string `json:"path"`
|
||||
Target string `json:"target,omitempty"`
|
||||
Echo bool `json:"echo"`
|
||||
StorageID string `json:"-"`
|
||||
Time time.Time `json:"-"`
|
||||
UserAgent string `json:"-"`
|
||||
}
|
||||
+3
-1
@@ -14,6 +14,7 @@ import (
|
||||
|
||||
"github.com/mickael-kerjean/filestash/server/pkg/admin"
|
||||
"github.com/mickael-kerjean/filestash/server/pkg/files"
|
||||
"github.com/mickael-kerjean/filestash/server/pkg/journal"
|
||||
"github.com/mickael-kerjean/filestash/server/pkg/frontend"
|
||||
"github.com/mickael-kerjean/filestash/server/pkg/session"
|
||||
"github.com/mickael-kerjean/filestash/server/pkg/share"
|
||||
@@ -71,7 +72,6 @@ func Build(r *mux.Router) {
|
||||
router.HandleFunc("/rm", NewMiddlewareChain(files.FileRm, middlewares)).Methods("POST")
|
||||
router.HandleFunc("/mkdir", NewMiddlewareChain(files.FileMkdir, middlewares)).Methods("POST")
|
||||
router.HandleFunc("/touch", NewMiddlewareChain(files.FileTouch, middlewares)).Methods("POST")
|
||||
router.HandleFunc("/watch", NewMiddlewareChain(files.FileWatch, middlewares)).Methods("GET")
|
||||
middlewares = []Middleware{ApiHeaders, SecureHeaders, SecureOrigin, SessionStart, LoggedInOnly, PluginInjector}
|
||||
router.HandleFunc("/search", NewMiddlewareChain(files.FileSearch, middlewares)).Methods("GET")
|
||||
|
||||
@@ -114,6 +114,8 @@ func Build(r *mux.Router) {
|
||||
r.HandleFunc(WithBase("/favicon.ico"), NewMiddlewareChain(frontend.ServeFavicon, middlewares)).Methods("GET")
|
||||
|
||||
// Other endpoints
|
||||
middlewares = []Middleware{ApiHeaders, SecureHeaders, SessionStart, LoggedInOnly}
|
||||
r.HandleFunc(WithBase("/api/watch"), NewMiddlewareChain(journal.Handler, middlewares)).Methods("GET")
|
||||
middlewares = []Middleware{ApiHeaders, PluginInjector, PublicCORS}
|
||||
r.HandleFunc(WithBase("/report"), NewMiddlewareChain(frontend.ReportHandler, middlewares)).Methods("POST", "OPTIONS")
|
||||
middlewares = []Middleware{IndexHeaders, SecureHeaders, PluginInjector}
|
||||
|
||||
Reference in New Issue
Block a user