diff --git a/filemanager.go b/filemanager.go index 72fb6b59..e38e9d71 100644 --- a/filemanager.go +++ b/filemanager.go @@ -3,6 +3,7 @@ package filemanager import ( "crypto/rand" "errors" + "fmt" "log" "net/http" "os" @@ -133,6 +134,14 @@ func (m *FileManager) Setup() error { "after_save": {}, "before_publish": {}, "after_publish": {}, + "before_copy": {}, + "after_copy": {}, + "before_rename": {}, + "after_rename": {}, + "before_upload": {}, + "after_upload": {}, + "before_delete": {}, + "after_delete": {}, } err = m.Store.Config.Save("commands", m.Commands) } @@ -248,7 +257,7 @@ func (m FileManager) ShareCleaner() { } // Runner runs the commands for a certain event type. -func (m FileManager) Runner(event string, path string) error { +func (m FileManager) Runner(event string, path string, destination string, user *User) error { commands := []string{} // Get the commands from the File Manager instance itself. @@ -273,7 +282,15 @@ func (m FileManager) Runner(event string, path string) error { } cmd := exec.Command(command, args...) - cmd.Env = append(os.Environ(), "file="+path) + cmd.Env = append(os.Environ(), fmt.Sprintf("FILE=%s", path)) + cmd.Env = append(cmd.Env, fmt.Sprintf("ROOT=%s", string(user.Scope))) + cmd.Env = append(cmd.Env, fmt.Sprintf("TRIGGER=%s", event)) + cmd.Env = append(cmd.Env, fmt.Sprintf("USERNAME=%s", user.Username)) + + if destination != "" { + cmd.Env = append(cmd.Env, fmt.Sprintf("DESTINATION=%s", destination)) + } + cmd.Stdin = os.Stdin cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr diff --git a/http/resource.go b/http/resource.go index 5a49dae6..a312de90 100644 --- a/http/resource.go +++ b/http/resource.go @@ -38,7 +38,7 @@ func resourceHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int case http.MethodPut: // Before save command handler. path := filepath.Join(c.User.Scope, r.URL.Path) - if err := c.Runner("before_save", path); err != nil { + if err := c.Runner("before_save", path, "", c.User); err != nil { return http.StatusInternalServerError, err } @@ -48,7 +48,7 @@ func resourceHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) (int } // After save command handler. - if err := c.Runner("after_save", path); err != nil { + if err := c.Runner("after_save", path, "", c.User); err != nil { return http.StatusInternalServerError, err } @@ -139,12 +139,22 @@ func resourceDeleteHandler(c *fm.Context, w http.ResponseWriter, r *http.Request return http.StatusForbidden, nil } + // Fire the before trigger. + if err := c.Runner("before_delete", r.URL.Path, "", c.User); err != nil { + return http.StatusInternalServerError, err + } + // Remove the file or folder. err := c.User.FileSystem.RemoveAll(r.URL.Path) if err != nil { return ErrorToHTTP(err, true), err } + // Fire the after trigger. + if err := c.Runner("after_delete", r.URL.Path, "", c.User); err != nil { + return http.StatusInternalServerError, err + } + return http.StatusOK, nil } @@ -185,6 +195,11 @@ func resourcePostPutHandler(c *fm.Context, w http.ResponseWriter, r *http.Reques } } + // Fire the before trigger. + if err := c.Runner("before_upload", r.URL.Path, "", c.User); err != nil { + return http.StatusInternalServerError, err + } + // Create/Open the file. f, err := c.User.FileSystem.OpenFile(r.URL.Path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0776) if err != nil { @@ -216,6 +231,12 @@ func resourcePostPutHandler(c *fm.Context, w http.ResponseWriter, r *http.Reques // Writes the ETag Header. etag := fmt.Sprintf(`"%x%x"`, fi.ModTime().UnixNano(), fi.Size()) w.Header().Set("ETag", etag) + + // Fire the after trigger. + if err := c.Runner("after_upload", r.URL.Path, "", c.User); err != nil { + return http.StatusInternalServerError, err + } + return http.StatusOK, nil } @@ -254,7 +275,7 @@ func resourcePublish(c *fm.Context, w http.ResponseWriter, r *http.Request) (int path := filepath.Join(c.User.Scope, r.URL.Path) // Before save command handler. - if err := c.Runner("before_publish", path); err != nil { + if err := c.Runner("before_publish", path, "", c.User); err != nil { return http.StatusInternalServerError, err } @@ -264,7 +285,7 @@ func resourcePublish(c *fm.Context, w http.ResponseWriter, r *http.Request) (int } // Executed the before publish command. - if err := c.Runner("before_publish", path); err != nil { + if err := c.Runner("before_publish", path, "", c.User); err != nil { return http.StatusInternalServerError, err } @@ -291,9 +312,31 @@ func resourcePatchHandler(c *fm.Context, w http.ResponseWriter, r *http.Request) } if action == "copy" { + // Fire the after trigger. + if err := c.Runner("before_copy", src, dst, c.User); err != nil { + return http.StatusInternalServerError, err + } + + // Copy the file. err = c.User.FileSystem.Copy(src, dst) + + // Fire the after trigger. + if err := c.Runner("after_copy", src, dst, c.User); err != nil { + return http.StatusInternalServerError, err + } } else { + // Fire the after trigger. + if err := c.Runner("before_rename", src, dst, c.User); err != nil { + return http.StatusInternalServerError, err + } + + // Rename the file. err = c.User.FileSystem.Rename(src, dst) + + // Fire the after trigger. + if err := c.Runner("after_rename", src, dst, c.User); err != nil { + return http.StatusInternalServerError, err + } } return ErrorToHTTP(err, true), err