mirror of
https://github.com/drakkan/sftpgo.git
synced 2024-11-22 07:30:25 +00:00
eventmanager: add placeholder to get the parent directory
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
This commit is contained in:
parent
80244bd83b
commit
bf45d04600
4 changed files with 107 additions and 2 deletions
|
@ -28,10 +28,13 @@ The following placeholders are supported:
|
||||||
- `{{StatusString}}`. Status as string. Possible values "OK", "KO".
|
- `{{StatusString}}`. Status as string. Possible values "OK", "KO".
|
||||||
- `{{ErrorString}}`. Error details. Replaced with an empty string if no errors occur.
|
- `{{ErrorString}}`. Error details. Replaced with an empty string if no errors occur.
|
||||||
- `{{VirtualPath}}`. Path seen by SFTPGo users, for example `/adir/afile.txt`.
|
- `{{VirtualPath}}`. Path seen by SFTPGo users, for example `/adir/afile.txt`.
|
||||||
|
- `{{VirtualDirPath}}`. Parent directory for VirtualPath, for example if VirtualPath is "/adir/afile.txt", VirtualDirPath is "/adir".
|
||||||
- `{{FsPath}}`. Full filesystem path, for example `/user/homedir/adir/afile.txt` or `C:/data/user/homedir/adir/afile.txt` on Windows.
|
- `{{FsPath}}`. Full filesystem path, for example `/user/homedir/adir/afile.txt` or `C:/data/user/homedir/adir/afile.txt` on Windows.
|
||||||
- `{{ObjectName}}`. File/directory name, for example `afile.txt` or provider object name.
|
- `{{ObjectName}}`. File/directory name, for example `afile.txt` or provider object name.
|
||||||
- `{{ObjectType}}`. Object type for provider events: `user`, `group`, `admin`, etc.
|
- `{{ObjectType}}`. Object type for provider events: `user`, `group`, `admin`, etc.
|
||||||
- `{{VirtualTargetPath}}`. Virtual target path for renames.
|
- `{{VirtualTargetPath}}`. Virtual target path for renames.
|
||||||
|
- `{{VirtualTargetDirPath}}`. Parent directory for VirtualTargetPath.
|
||||||
|
- `{{TargetName}}`. Target object name for renames.
|
||||||
- `{{FsTargetPath}}`. Full filesystem target path for renames.
|
- `{{FsTargetPath}}`. Full filesystem target path for renames.
|
||||||
- `{{FileSize}}`. File size.
|
- `{{FileSize}}`. File size.
|
||||||
- `{{Protocol}}`. Used protocol, for example `SFTP`, `FTP`.
|
- `{{Protocol}}`. Used protocol, for example `SFTP`, `FTP`.
|
||||||
|
|
|
@ -483,7 +483,13 @@ func (p *EventParams) setBackupParams(backupPath string) {
|
||||||
}
|
}
|
||||||
p.sender = dataprovider.ActionExecutorSystem
|
p.sender = dataprovider.ActionExecutorSystem
|
||||||
p.FsPath = backupPath
|
p.FsPath = backupPath
|
||||||
p.VirtualPath = filepath.Base(backupPath)
|
p.ObjectName = filepath.Base(backupPath)
|
||||||
|
p.VirtualPath = "/" + p.ObjectName
|
||||||
|
p.Timestamp = time.Now().UnixNano()
|
||||||
|
info, err := os.Stat(backupPath)
|
||||||
|
if err == nil {
|
||||||
|
p.FileSize = info.Size()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *EventParams) getStatusString() string {
|
func (p *EventParams) getStatusString() string {
|
||||||
|
@ -607,6 +613,13 @@ func (p *EventParams) getStringReplacements(addObjectData bool) []string {
|
||||||
"{{Timestamp}}", fmt.Sprintf("%d", p.Timestamp),
|
"{{Timestamp}}", fmt.Sprintf("%d", p.Timestamp),
|
||||||
"{{StatusString}}", p.getStatusString(),
|
"{{StatusString}}", p.getStatusString(),
|
||||||
}
|
}
|
||||||
|
if p.VirtualPath != "" {
|
||||||
|
replacements = append(replacements, "{{VirtualDirPath}}", path.Dir(p.VirtualPath))
|
||||||
|
}
|
||||||
|
if p.VirtualTargetPath != "" {
|
||||||
|
replacements = append(replacements, "{{VirtualTargetDirPath}}", path.Dir(p.VirtualTargetPath))
|
||||||
|
replacements = append(replacements, "{{TargetName}}", path.Base(p.VirtualTargetPath))
|
||||||
|
}
|
||||||
if len(p.errors) > 0 {
|
if len(p.errors) > 0 {
|
||||||
replacements = append(replacements, "{{ErrorString}}", strings.Join(p.errors, ", "))
|
replacements = append(replacements, "{{ErrorString}}", strings.Join(p.errors, ", "))
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -3868,7 +3868,7 @@ func TestEventRuleFsActions(t *testing.T) {
|
||||||
Type: dataprovider.FilesystemActionRename,
|
Type: dataprovider.FilesystemActionRename,
|
||||||
Renames: []dataprovider.KeyValue{
|
Renames: []dataprovider.KeyValue{
|
||||||
{
|
{
|
||||||
Key: "/{{VirtualPath}}",
|
Key: "/{{VirtualDirPath}}/{{ObjectName}}",
|
||||||
Value: "/{{ObjectName}}_renamed",
|
Value: "/{{ObjectName}}_renamed",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -5294,6 +5294,86 @@ func TestEventRuleFirstUploadDownloadActions(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestEventRuleRenameEvent(t *testing.T) {
|
||||||
|
smtpCfg := smtp.Config{
|
||||||
|
Host: "127.0.0.1",
|
||||||
|
Port: 2525,
|
||||||
|
From: "notify@example.com",
|
||||||
|
TemplatesPath: "templates",
|
||||||
|
}
|
||||||
|
err := smtpCfg.Initialize(configDir)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
a1 := dataprovider.BaseEventAction{
|
||||||
|
Name: "action1",
|
||||||
|
Type: dataprovider.ActionTypeEmail,
|
||||||
|
Options: dataprovider.BaseEventActionOptions{
|
||||||
|
EmailConfig: dataprovider.EventActionEmailConfig{
|
||||||
|
Recipients: []string{"test@example.com"},
|
||||||
|
Subject: `"{{Event}}" from "{{Name}}"`,
|
||||||
|
Body: `Fs path {{FsPath}}, Target path "{{VirtualTargetDirPath}}/{{TargetName}}", size: {{FileSize}}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
action1, _, err := httpdtest.AddEventAction(a1, http.StatusCreated)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
r1 := dataprovider.EventRule{
|
||||||
|
Name: "test rename rule",
|
||||||
|
Trigger: dataprovider.EventTriggerFsEvent,
|
||||||
|
Conditions: dataprovider.EventConditions{
|
||||||
|
FsEvents: []string{"rename"},
|
||||||
|
},
|
||||||
|
Actions: []dataprovider.EventAction{
|
||||||
|
{
|
||||||
|
BaseEventAction: dataprovider.BaseEventAction{
|
||||||
|
Name: action1.Name,
|
||||||
|
},
|
||||||
|
Order: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
rule1, _, err := httpdtest.AddEventRule(r1, http.StatusCreated)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
user, _, err := httpdtest.AddUser(getTestUser(), http.StatusCreated)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
conn, client, err := getSftpClient(user)
|
||||||
|
if assert.NoError(t, err) {
|
||||||
|
defer conn.Close()
|
||||||
|
defer client.Close()
|
||||||
|
|
||||||
|
testFileSize := int64(32768)
|
||||||
|
lastReceivedEmail.reset()
|
||||||
|
err = writeSFTPFileNoCheck(testFileName, testFileSize, client)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
err = client.Mkdir("subdir")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
err = client.Rename(testFileName, path.Join("/subdir", testFileName))
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Eventually(t, func() bool {
|
||||||
|
return lastReceivedEmail.get().From != ""
|
||||||
|
}, 1500*time.Millisecond, 100*time.Millisecond)
|
||||||
|
email := lastReceivedEmail.get()
|
||||||
|
assert.Len(t, email.To, 1)
|
||||||
|
assert.True(t, util.Contains(email.To, "test@example.com"))
|
||||||
|
assert.Contains(t, email.Data, fmt.Sprintf(`Subject: "rename" from "%s"`, user.Username))
|
||||||
|
assert.Contains(t, email.Data, fmt.Sprintf("Target path %q", path.Join("/subdir", testFileName)))
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = httpdtest.RemoveEventRule(rule1, http.StatusOK)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
_, err = httpdtest.RemoveEventAction(action1, http.StatusOK)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
_, err = httpdtest.RemoveUser(user, http.StatusOK)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
err = os.RemoveAll(user.GetHomeDir())
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
smtpCfg = smtp.Config{}
|
||||||
|
err = smtpCfg.Initialize(configDir)
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
func TestEventRuleCertificate(t *testing.T) {
|
func TestEventRuleCertificate(t *testing.T) {
|
||||||
smtpCfg := smtp.Config{
|
smtpCfg := smtp.Config{
|
||||||
Host: "127.0.0.1",
|
Host: "127.0.0.1",
|
||||||
|
|
|
@ -669,6 +669,9 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
<p>
|
<p>
|
||||||
<span class="shortcut"><b>{{`{{VirtualPath}}`}}</b></span> => Path seen by SFTPGo users, for example "/adir/afile.txt".
|
<span class="shortcut"><b>{{`{{VirtualPath}}`}}</b></span> => Path seen by SFTPGo users, for example "/adir/afile.txt".
|
||||||
</p>
|
</p>
|
||||||
|
<p>
|
||||||
|
<span class="shortcut"><b>{{`{{VirtualDirPath}}`}}</b></span> => Parent directory for VirtualPath, for example if VirtualPath is "/adir/afile.txt", VirtualDirPath is "/adir".
|
||||||
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<span class="shortcut"><b>{{`{{FsPath}}`}}</b></span> => Full filesystem path, for example "/user/homedir/adir/afile.txt" or "C:/data/user/homedir/adir/afile.txt" on Windows.
|
<span class="shortcut"><b>{{`{{FsPath}}`}}</b></span> => Full filesystem path, for example "/user/homedir/adir/afile.txt" or "C:/data/user/homedir/adir/afile.txt" on Windows.
|
||||||
</p>
|
</p>
|
||||||
|
@ -681,6 +684,12 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
<p>
|
<p>
|
||||||
<span class="shortcut"><b>{{`{{VirtualTargetPath}}`}}</b></span> => Virtual target path for renames.
|
<span class="shortcut"><b>{{`{{VirtualTargetPath}}`}}</b></span> => Virtual target path for renames.
|
||||||
</p>
|
</p>
|
||||||
|
<p>
|
||||||
|
<span class="shortcut"><b>{{`{{VirtualTargetDirPath}}`}}</b></span> => Parent directory for VirtualTargetPath.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<span class="shortcut"><b>{{`{{TargetName}}`}}</b></span> => Target object name for renames.
|
||||||
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<span class="shortcut"><b>{{`{{FsTargetPath}}`}}</b></span> => Full filesystem target path for renames.
|
<span class="shortcut"><b>{{`{{FsTargetPath}}`}}</b></span> => Full filesystem target path for renames.
|
||||||
</p>
|
</p>
|
||||||
|
|
Loading…
Reference in a new issue