diff --git a/go.mod b/go.mod
index e6332a70..03d53763 100644
--- a/go.mod
+++ b/go.mod
@@ -56,7 +56,7 @@ require (
github.com/shirou/gopsutil/v3 v3.22.12
github.com/spf13/afero v1.9.3
github.com/spf13/cobra v1.6.1
- github.com/spf13/viper v1.14.0
+ github.com/spf13/viper v1.15.0
github.com/stretchr/testify v1.8.1
github.com/studio-b12/gowebdav v0.0.0-20221109171924-60ec5ad56012
github.com/subosito/gotenv v1.4.2
@@ -73,12 +73,12 @@ require (
golang.org/x/sys v0.4.0
golang.org/x/term v0.4.0
golang.org/x/time v0.3.0
- google.golang.org/api v0.107.0
+ google.golang.org/api v0.108.0
gopkg.in/natefinch/lumberjack.v2 v2.0.0
)
require (
- cloud.google.com/go v0.108.0 // indirect
+ cloud.google.com/go v0.109.0 // indirect
cloud.google.com/go/compute v1.15.1 // indirect
cloud.google.com/go/compute/metadata v0.2.3 // indirect
cloud.google.com/go/iam v0.10.0 // indirect
@@ -138,7 +138,6 @@ require (
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/oklog/run v1.1.0 // indirect
- github.com/pelletier/go-toml v1.9.5 // indirect
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b // indirect
@@ -158,11 +157,10 @@ require (
golang.org/x/tools v0.5.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/appengine v1.6.7 // indirect
- google.golang.org/genproto v0.0.0-20230113154510-dbe35b8444a5 // indirect
+ google.golang.org/genproto v0.0.0-20230117162540-28d6b9783ac4 // indirect
google.golang.org/grpc v1.52.0 // indirect
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
- gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
diff --git a/go.sum b/go.sum
index 0ba27bd5..f62c65d6 100644
--- a/go.sum
+++ b/go.sum
@@ -37,8 +37,8 @@ cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34h
cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA=
cloud.google.com/go v0.105.0/go.mod h1:PrLgOJNe5nfE9UMxKxgXj4mD3voiP+YQ6gdt6KMFOKM=
cloud.google.com/go v0.107.0/go.mod h1:wpc2eNrD7hXUTy8EKS10jkxpZBjASrORK7goS+3YX2I=
-cloud.google.com/go v0.108.0 h1:xntQwnfn8oHGX0crLVinvHM+AhXvi3QHQIEcX/2hiWk=
-cloud.google.com/go v0.108.0/go.mod h1:lNUfQqusBJp0bgAg6qrHgYFYbTB+dOiob1itwnlD33Q=
+cloud.google.com/go v0.109.0 h1:38CZoKGlCnPZjGdyj0ZfpoGae0/wgNfy5F0byyxg0Gk=
+cloud.google.com/go v0.109.0/go.mod h1:2sYycXt75t/CSB5R9M2wPU1tJmire7AQZTPtITcGBVE=
cloud.google.com/go/accessapproval v1.4.0/go.mod h1:zybIuC3KpDOvotz59lFe5qxRZx6C75OtwbisN56xYB4=
cloud.google.com/go/accessapproval v1.5.0/go.mod h1:HFy3tuiGvMdcd/u+Cu5b9NkO1pEICJ46IR82PoUdplw=
cloud.google.com/go/accesscontextmanager v1.3.0/go.mod h1:TgCBehyr5gNMz7ZaH9xubp+CE8dkrszb4oK9CWyvD4o=
@@ -1663,8 +1663,6 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9
github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
-github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
-github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU=
github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek=
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
@@ -1856,8 +1854,8 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
-github.com/spf13/viper v1.14.0 h1:Rg7d3Lo706X9tHsJMUjdiwMpHB7W8WnSVOssIY+JElU=
-github.com/spf13/viper v1.14.0/go.mod h1:WT//axPky3FdvXHzGw33dNdXXXfFQqmEalje+egj8As=
+github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU=
+github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA=
github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8=
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
@@ -2577,8 +2575,8 @@ google.golang.org/api v0.99.0/go.mod h1:1YOf74vkVndF7pG6hIHuINsM7eWwpVTAfNMNiL91
google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70=
google.golang.org/api v0.102.0/go.mod h1:3VFl6/fzoA+qNuS1N1/VfXY4LjoXN/wzeIp7TweWwGo=
google.golang.org/api v0.103.0/go.mod h1:hGtW6nK1AC+d9si/UBhw8Xli+QMOf6xyNAyJw4qU9w0=
-google.golang.org/api v0.107.0 h1:I2SlFjD8ZWabaIFOfeEDg3pf0BHJDh6iYQ1ic3Yu/UU=
-google.golang.org/api v0.107.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY=
+google.golang.org/api v0.108.0 h1:WVBc/faN0DkKtR43Q/7+tPny9ZoLZdIiAyG5Q9vFClg=
+google.golang.org/api v0.108.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@@ -2712,8 +2710,8 @@ google.golang.org/genproto v0.0.0-20221109142239-94d6d90a7d66/go.mod h1:rZS5c/ZV
google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg=
google.golang.org/genproto v0.0.0-20221201164419-0e50fba7f41c/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg=
google.golang.org/genproto v0.0.0-20221201204527-e3fa12d562f3/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg=
-google.golang.org/genproto v0.0.0-20230113154510-dbe35b8444a5 h1:wJT65XLOzhpSPCdAmmKfz94SlmnQzDzjm3Cj9k3fsXY=
-google.golang.org/genproto v0.0.0-20230113154510-dbe35b8444a5/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=
+google.golang.org/genproto v0.0.0-20230117162540-28d6b9783ac4 h1:yF0uHwqqYt2tIL2F4hxRWA1ZFX43SEunWAK8MnQiclk=
+google.golang.org/genproto v0.0.0-20230117162540-28d6b9783ac4/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=
google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
diff --git a/internal/common/common.go b/internal/common/common.go
index 0714baa5..df51a6b1 100644
--- a/internal/common/common.go
+++ b/internal/common/common.go
@@ -949,7 +949,7 @@ func (conns *ActiveConnections) Remove(connectionID string) {
return
}
- logger.Warn(logSender, "", "connection id %q to remove not found!", connectionID)
+ logger.Debug(logSender, "", "connection id %q to remove not found!", connectionID)
}
// Close closes an active connection.
diff --git a/internal/common/eventmanager.go b/internal/common/eventmanager.go
index 634f747c..1e103c84 100644
--- a/internal/common/eventmanager.go
+++ b/internal/common/eventmanager.go
@@ -197,6 +197,9 @@ func (r *eventRulesContainer) addUpdateRuleInternal(rule dataprovider.EventRule)
}
return
}
+ if rule.Status != 1 {
+ return
+ }
switch rule.Trigger {
case dataprovider.EventTriggerFsEvent:
r.FsEvents = append(r.FsEvents, rule)
diff --git a/internal/common/eventmanager_test.go b/internal/common/eventmanager_test.go
index a35ca01a..aa3522fd 100644
--- a/internal/common/eventmanager_test.go
+++ b/internal/common/eventmanager_test.go
@@ -320,6 +320,7 @@ func TestEventManager(t *testing.T) {
assert.NoError(t, err)
rule := &dataprovider.EventRule{
Name: "rule",
+ Status: 1,
Trigger: dataprovider.EventTriggerFsEvent,
Conditions: dataprovider.EventConditions{
FsEvents: []string{operationUpload},
@@ -595,6 +596,7 @@ func TestEventManagerErrors(t *testing.T) {
// rule with invalid trigger
eventManager.addUpdateRuleInternal(dataprovider.EventRule{
Name: "test rule",
+ Status: 1,
Trigger: -1,
})
@@ -606,6 +608,7 @@ func TestEventManagerErrors(t *testing.T) {
// rule with invalid cronspec
eventManager.addUpdateRuleInternal(dataprovider.EventRule{
Name: "test rule",
+ Status: 1,
Trigger: dataprovider.EventTriggerSchedule,
Conditions: dataprovider.EventConditions{
Schedules: []dataprovider.Schedule{
@@ -1602,6 +1605,7 @@ func TestScheduledActions(t *testing.T) {
assert.NoError(t, err)
rule := &dataprovider.EventRule{
Name: "rule",
+ Status: 1,
Trigger: dataprovider.EventTriggerSchedule,
Conditions: dataprovider.EventConditions{
Schedules: []dataprovider.Schedule{
diff --git a/internal/common/protocol_test.go b/internal/common/protocol_test.go
index bd405b8c..5a99b2a6 100644
--- a/internal/common/protocol_test.go
+++ b/internal/common/protocol_test.go
@@ -22,6 +22,7 @@ import (
"errors"
"fmt"
"io"
+ "io/fs"
"math"
"net"
"net/http"
@@ -3461,6 +3462,7 @@ func TestEventRule(t *testing.T) {
r1 := dataprovider.EventRule{
Name: "test rule1",
+ Status: 1,
Trigger: dataprovider.EventTriggerFsEvent,
Conditions: dataprovider.EventConditions{
FsEvents: []string{"upload"},
@@ -3514,6 +3516,7 @@ func TestEventRule(t *testing.T) {
r2 := dataprovider.EventRule{
Name: "test rule2",
+ Status: 1,
Trigger: dataprovider.EventTriggerFsEvent,
Conditions: dataprovider.EventConditions{
FsEvents: []string{"download"},
@@ -3548,6 +3551,7 @@ func TestEventRule(t *testing.T) {
r3 := dataprovider.EventRule{
Name: "test rule3",
+ Status: 1,
Trigger: dataprovider.EventTriggerProviderEvent,
Conditions: dataprovider.EventConditions{
ProviderEvents: []string{"delete"},
@@ -3810,6 +3814,7 @@ func TestEventRuleProviderEvents(t *testing.T) {
r := dataprovider.EventRule{
Name: "rule",
+ Status: 1,
Trigger: dataprovider.EventTriggerProviderEvent,
Conditions: dataprovider.EventConditions{
ProviderEvents: []string{"update"},
@@ -3991,6 +3996,7 @@ func TestEventRuleFsActions(t *testing.T) {
r1 := dataprovider.EventRule{
Name: "r1",
+ Status: 1,
Trigger: dataprovider.EventTriggerProviderEvent,
Conditions: dataprovider.EventConditions{
ProviderEvents: []string{"add"},
@@ -4006,6 +4012,7 @@ func TestEventRuleFsActions(t *testing.T) {
}
r2 := dataprovider.EventRule{
Name: "r2",
+ Status: 1,
Trigger: dataprovider.EventTriggerFsEvent,
Conditions: dataprovider.EventConditions{
FsEvents: []string{"upload"},
@@ -4030,6 +4037,7 @@ func TestEventRuleFsActions(t *testing.T) {
}
r3 := dataprovider.EventRule{
Name: "r3",
+ Status: 1,
Trigger: dataprovider.EventTriggerFsEvent,
Conditions: dataprovider.EventConditions{
FsEvents: []string{"mkdir"},
@@ -4051,6 +4059,7 @@ func TestEventRuleFsActions(t *testing.T) {
}
r4 := dataprovider.EventRule{
Name: "r4",
+ Status: 1,
Trigger: dataprovider.EventTriggerFsEvent,
Conditions: dataprovider.EventConditions{
FsEvents: []string{"rmdir"},
@@ -4066,6 +4075,7 @@ func TestEventRuleFsActions(t *testing.T) {
}
r5 := dataprovider.EventRule{
Name: "r5",
+ Status: 1,
Trigger: dataprovider.EventTriggerProviderEvent,
Conditions: dataprovider.EventConditions{
ProviderEvents: []string{"add"},
@@ -4216,6 +4226,7 @@ func TestEventRulePreDelete(t *testing.T) {
assert.NoError(t, err, string(resp))
r1 := dataprovider.EventRule{
Name: "rule1",
+ Status: 1,
Trigger: dataprovider.EventTriggerFsEvent,
Conditions: dataprovider.EventConditions{
FsEvents: []string{"pre-delete"},
@@ -4347,6 +4358,7 @@ func TestEventRulePreDownloadUpload(t *testing.T) {
assert.NoError(t, err, string(resp))
r1 := dataprovider.EventRule{
Name: "rule1",
+ Status: 1,
Trigger: dataprovider.EventTriggerFsEvent,
Conditions: dataprovider.EventConditions{
FsEvents: []string{"pre-download", "pre-upload"},
@@ -4386,7 +4398,20 @@ func TestEventRulePreDownloadUpload(t *testing.T) {
assert.Equal(t, int(100), n)
err = f.Close()
assert.NoError(t, err)
+ // disable the rule
+ rule1.Status = 0
+ _, _, err = httpdtest.UpdateEventRule(rule1, http.StatusOK)
+ assert.NoError(t, err)
+ err = client.RemoveDirectory(testDir)
+ assert.NoError(t, err)
+ err = client.Remove(testFileName)
+ assert.NoError(t, err)
+ err = writeSFTPFile(testFileName, 100, client)
+ assert.NoError(t, err)
+ _, err = client.Stat(testDir)
+ assert.ErrorIs(t, err, fs.ErrNotExist)
// now update the rule so that it will always fail
+ rule1.Status = 1
rule1.Actions = []dataprovider.EventAction{
{
BaseEventAction: dataprovider.BaseEventAction{
@@ -4441,6 +4466,7 @@ func TestFsActionCopy(t *testing.T) {
r1 := dataprovider.EventRule{
Name: "rule1",
+ Status: 1,
Trigger: dataprovider.EventTriggerFsEvent,
Conditions: dataprovider.EventConditions{
FsEvents: []string{"upload"},
@@ -4520,6 +4546,7 @@ func TestEventFsActionsGroupFilters(t *testing.T) {
r1 := dataprovider.EventRule{
Name: "rule1",
+ Status: 1,
Trigger: dataprovider.EventTriggerFsEvent,
Conditions: dataprovider.EventConditions{
FsEvents: []string{"upload"},
@@ -4657,6 +4684,7 @@ func TestBackupAsAttachment(t *testing.T) {
r1 := dataprovider.EventRule{
Name: "test rule certificate",
+ Status: 1,
Trigger: dataprovider.EventTriggerCertificate,
Actions: []dataprovider.EventAction{
{
@@ -4738,6 +4766,7 @@ func TestEventActionHTTPMultipart(t *testing.T) {
assert.NoError(t, err, string(resp))
r1 := dataprovider.EventRule{
Name: "test http multipart",
+ Status: 1,
Trigger: dataprovider.EventTriggerFsEvent,
Conditions: dataprovider.EventConditions{
FsEvents: []string{"upload"},
@@ -4813,6 +4842,7 @@ func TestEventActionCompress(t *testing.T) {
assert.NoError(t, err)
r1 := dataprovider.EventRule{
Name: "test compress",
+ Status: 1,
Trigger: dataprovider.EventTriggerFsEvent,
Conditions: dataprovider.EventConditions{
FsEvents: []string{"upload"},
@@ -4981,6 +5011,7 @@ func TestEventActionCompressQuotaErrors(t *testing.T) {
assert.NoError(t, err)
r1 := dataprovider.EventRule{
Name: "test compress",
+ Status: 1,
Trigger: dataprovider.EventTriggerFsEvent,
Conditions: dataprovider.EventConditions{
FsEvents: []string{"rename"},
@@ -5126,6 +5157,7 @@ func TestEventActionCompressQuotaFolder(t *testing.T) {
assert.NoError(t, err)
r1 := dataprovider.EventRule{
Name: "test compress",
+ Status: 1,
Trigger: dataprovider.EventTriggerFsEvent,
Conditions: dataprovider.EventConditions{
FsEvents: []string{"upload"},
@@ -5246,6 +5278,7 @@ func TestEventActionCompressErrors(t *testing.T) {
assert.NoError(t, err)
r1 := dataprovider.EventRule{
Name: "test compress",
+ Status: 1,
Trigger: dataprovider.EventTriggerFsEvent,
Conditions: dataprovider.EventConditions{
FsEvents: []string{"upload"},
@@ -5383,6 +5416,7 @@ func TestEventActionEmailAttachments(t *testing.T) {
assert.NoError(t, err)
r1 := dataprovider.EventRule{
Name: "test email with attachment",
+ Status: 1,
Trigger: dataprovider.EventTriggerFsEvent,
Conditions: dataprovider.EventConditions{
FsEvents: []string{"upload"},
@@ -5536,6 +5570,7 @@ func TestEventActionsRetentionReports(t *testing.T) {
assert.NoError(t, err)
r1 := dataprovider.EventRule{
Name: "test rule1",
+ Status: 1,
Trigger: dataprovider.EventTriggerFsEvent,
Conditions: dataprovider.EventConditions{
FsEvents: []string{"upload"},
@@ -5729,6 +5764,7 @@ func TestEventRuleFirstUploadDownloadActions(t *testing.T) {
assert.NoError(t, err)
r1 := dataprovider.EventRule{
Name: "test first upload rule",
+ Status: 1,
Trigger: dataprovider.EventTriggerFsEvent,
Conditions: dataprovider.EventConditions{
FsEvents: []string{"first-upload"},
@@ -5746,6 +5782,7 @@ func TestEventRuleFirstUploadDownloadActions(t *testing.T) {
assert.NoError(t, err)
r2 := dataprovider.EventRule{
Name: "test first download rule",
+ Status: 1,
Trigger: dataprovider.EventTriggerFsEvent,
Conditions: dataprovider.EventConditions{
FsEvents: []string{"first-download"},
@@ -5859,6 +5896,7 @@ func TestEventRuleRenameEvent(t *testing.T) {
assert.NoError(t, err)
r1 := dataprovider.EventRule{
Name: "test rename rule",
+ Status: 1,
Trigger: dataprovider.EventTriggerFsEvent,
Conditions: dataprovider.EventConditions{
FsEvents: []string{"rename"},
@@ -5948,6 +5986,7 @@ func TestEventRuleCertificate(t *testing.T) {
r1 := dataprovider.EventRule{
Name: "test rule certificate",
+ Status: 1,
Trigger: dataprovider.EventTriggerCertificate,
Actions: []dataprovider.EventAction{
{
@@ -5962,6 +6001,7 @@ func TestEventRuleCertificate(t *testing.T) {
assert.NoError(t, err)
r2 := dataprovider.EventRule{
Name: "test rule 2",
+ Status: 1,
Trigger: dataprovider.EventTriggerCertificate,
Actions: []dataprovider.EventAction{
{
@@ -6082,6 +6122,7 @@ func TestEventRuleIPBlocked(t *testing.T) {
r1 := dataprovider.EventRule{
Name: "test rule ip blocked",
+ Status: 1,
Trigger: dataprovider.EventTriggerIPBlocked,
Actions: []dataprovider.EventAction{
{
@@ -6096,6 +6137,7 @@ func TestEventRuleIPBlocked(t *testing.T) {
assert.NoError(t, err)
r2 := dataprovider.EventRule{
Name: "test rule 2",
+ Status: 1,
Trigger: dataprovider.EventTriggerIPBlocked,
Actions: []dataprovider.EventAction{
{
@@ -6214,6 +6256,7 @@ func TestEventRulePasswordExpiration(t *testing.T) {
r1 := dataprovider.EventRule{
Name: "rule1",
+ Status: 1,
Trigger: dataprovider.EventTriggerFsEvent,
Conditions: dataprovider.EventConditions{
FsEvents: []string{"mkdir"},
@@ -7017,6 +7060,7 @@ func TestSFTPLoopError(t *testing.T) {
assert.NoError(t, err)
r1 := dataprovider.EventRule{
Name: "rule1",
+ Status: 1,
Trigger: dataprovider.EventTriggerProviderEvent,
Conditions: dataprovider.EventConditions{
ProviderEvents: []string{"update"},
diff --git a/internal/dataprovider/bolt.go b/internal/dataprovider/bolt.go
index 41706ab1..5fc72e41 100644
--- a/internal/dataprovider/bolt.go
+++ b/internal/dataprovider/bolt.go
@@ -35,7 +35,7 @@ import (
)
const (
- boltDatabaseVersion = 25
+ boltDatabaseVersion = 26
)
var (
@@ -2833,10 +2833,41 @@ func (p *BoltProvider) migrateDatabase() error {
providerLog(logger.LevelError, "%v", err)
logger.ErrorToConsole("%v", err)
return err
- case version == 23, version == 24:
- logger.InfoToConsole(fmt.Sprintf("updating database schema version: %d -> 25", version))
- providerLog(logger.LevelInfo, "updating database schema version: %d -> 25", version)
- return updateBoltDatabaseVersion(p.dbHandle, 25)
+ case version == 23, version == 24, version == 25:
+ logger.InfoToConsole("updating database schema version: %d -> 26", version)
+ providerLog(logger.LevelInfo, "updating database schema version: %d -> 26", version)
+ err := p.dbHandle.Update(func(tx *bolt.Tx) error {
+ rules, err := p.dumpEventRules()
+ if err != nil {
+ return err
+ }
+ bucket, err := p.getRulesBucket(tx)
+ if err != nil {
+ return err
+ }
+ for _, rule := range rules {
+ rule := rule // pin
+ if rule.Status == 1 {
+ continue
+ }
+ logger.InfoToConsole("setting status to active for rule %q", rule.Name)
+ providerLog(logger.LevelInfo, "setting status to 1 for rule %q", rule.Name)
+ rule.Status = 1
+ rule.UpdatedAt = util.GetTimeAsMsSinceEpoch(time.Now())
+ buf, err := json.Marshal(rule)
+ if err != nil {
+ return err
+ }
+ if err := bucket.Put([]byte(rule.Name), buf); err != nil {
+ return err
+ }
+ }
+ return nil
+ })
+ if err != nil {
+ return err
+ }
+ return updateBoltDatabaseVersion(p.dbHandle, 26)
default:
if version > boltDatabaseVersion {
providerLog(logger.LevelError, "database schema version %d is newer than the supported one: %d", version,
@@ -2858,7 +2889,7 @@ func (p *BoltProvider) revertDatabase(targetVersion int) error {
return errors.New("current version match target version, nothing to do")
}
switch dbVersion.Version {
- case 24, 25:
+ case 24, 25, 26:
logger.InfoToConsole("downgrading database schema version: %d -> 23", dbVersion.Version)
providerLog(logger.LevelInfo, "downgrading database schema version: %d -> 23", dbVersion.Version)
err := p.dbHandle.Update(func(tx *bolt.Tx) error {
diff --git a/internal/dataprovider/dataprovider.go b/internal/dataprovider/dataprovider.go
index 91de4453..fb1539f0 100644
--- a/internal/dataprovider/dataprovider.go
+++ b/internal/dataprovider/dataprovider.go
@@ -87,7 +87,7 @@ const (
CockroachDataProviderName = "cockroachdb"
// DumpVersion defines the version for the dump.
// For restore/load we support the current version and the previous one
- DumpVersion = 14
+ DumpVersion = 15
argonPwdPrefix = "$argon2id$"
bcryptPwdPrefix = "$2a$"
diff --git a/internal/dataprovider/eventrule.go b/internal/dataprovider/eventrule.go
index 8680a782..118eae6e 100644
--- a/internal/dataprovider/eventrule.go
+++ b/internal/dataprovider/eventrule.go
@@ -1313,6 +1313,8 @@ type EventRule struct {
ID int64 `json:"id"`
// Rule name
Name string `json:"name"`
+ // 1 enabled, 0 disabled
+ Status int `json:"status"`
// optional description
Description string `json:"description,omitempty"`
// Creation time as unix timestamp in milliseconds
@@ -1338,6 +1340,7 @@ func (r *EventRule) getACopy() EventRule {
return EventRule{
ID: r.ID,
Name: r.Name,
+ Status: r.Status,
Description: r.Description,
CreatedAt: r.CreatedAt,
UpdatedAt: r.UpdatedAt,
@@ -1371,10 +1374,17 @@ func (r *EventRule) GetActionsAsString() string {
return strings.Join(actions, ",")
}
+func (r *EventRule) isStatusValid() bool {
+ return r.Status >= 0 && r.Status <= 1
+}
+
func (r *EventRule) validate() error {
if r.Name == "" {
return util.NewValidationError("name is mandatory")
}
+ if !r.isStatusValid() {
+ return util.NewValidationError(fmt.Sprintf("invalid event rule status: %d", r.Status))
+ }
if !isEventTriggerValid(r.Trigger) {
return util.NewValidationError(fmt.Sprintf("invalid event rule trigger: %d", r.Trigger))
}
diff --git a/internal/dataprovider/memory.go b/internal/dataprovider/memory.go
index b8a265fb..f3ade7da 100644
--- a/internal/dataprovider/memory.go
+++ b/internal/dataprovider/memory.go
@@ -2825,6 +2825,9 @@ func (p *MemoryProvider) restoreEventRules(dump BackupData) error {
for _, rule := range dump.EventRules {
r, err := p.eventRuleExists(rule.Name)
rule := rule // pin
+ if dump.Version < 15 {
+ rule.Status = 1
+ }
if err == nil {
rule.ID = r.ID
err = UpdateEventRule(&rule, ActionExecutorSystem, "", "")
diff --git a/internal/dataprovider/mysql.go b/internal/dataprovider/mysql.go
index 79d1a855..dbca8dd0 100644
--- a/internal/dataprovider/mysql.go
+++ b/internal/dataprovider/mysql.go
@@ -186,6 +186,9 @@ const (
mysqlV25SQL = "ALTER TABLE `{{users}}` ADD COLUMN `last_password_change` bigint DEFAULT 0 NOT NULL; " +
"ALTER TABLE `{{users}}` ALTER COLUMN `last_password_change` DROP DEFAULT; "
mysqlV25DownSQL = "ALTER TABLE `{{users}}` DROP COLUMN `last_password_change`; "
+ mysqlV26SQL = "ALTER TABLE `{{events_rules}}` ADD COLUMN `status` integer DEFAULT 1 NOT NULL; " +
+ "ALTER TABLE `{{events_rules}}` ALTER COLUMN `status` DROP DEFAULT; "
+ mysqlV26DownSQL = "ALTER TABLE `{{events_rules}}` DROP COLUMN `status`; "
)
// MySQLProvider defines the auth provider for MySQL/MariaDB database
@@ -744,6 +747,8 @@ func (p *MySQLProvider) migrateDatabase() error { //nolint:dupl
return updateMySQLDatabaseFromV23(p.dbHandle)
case version == 24:
return updateMySQLDatabaseFromV24(p.dbHandle)
+ case version == 25:
+ return updateMySQLDatabaseFromV25(p.dbHandle)
default:
if version > sqlDatabaseVersion {
providerLog(logger.LevelError, "database schema version %d is newer than the supported one: %d", version,
@@ -770,6 +775,8 @@ func (p *MySQLProvider) revertDatabase(targetVersion int) error {
return downgradeMySQLDatabaseFromV24(p.dbHandle)
case 25:
return downgradeMySQLDatabaseFromV25(p.dbHandle)
+ case 26:
+ return downgradeMySQLDatabaseFromV26(p.dbHandle)
default:
return fmt.Errorf("database schema version not handled: %d", dbVersion.Version)
}
@@ -788,7 +795,14 @@ func updateMySQLDatabaseFromV23(dbHandle *sql.DB) error {
}
func updateMySQLDatabaseFromV24(dbHandle *sql.DB) error {
- return updateMySQLDatabaseFrom24To25(dbHandle)
+ if err := updateMySQLDatabaseFrom24To25(dbHandle); err != nil {
+ return err
+ }
+ return updateMySQLDatabaseFromV25(dbHandle)
+}
+
+func updateMySQLDatabaseFromV25(dbHandle *sql.DB) error {
+ return updateMySQLDatabaseFrom25To26(dbHandle)
}
func downgradeMySQLDatabaseFromV24(dbHandle *sql.DB) error {
@@ -802,6 +816,13 @@ func downgradeMySQLDatabaseFromV25(dbHandle *sql.DB) error {
return downgradeMySQLDatabaseFromV24(dbHandle)
}
+func downgradeMySQLDatabaseFromV26(dbHandle *sql.DB) error {
+ if err := downgradeMySQLDatabaseFrom26To25(dbHandle); err != nil {
+ return err
+ }
+ return downgradeMySQLDatabaseFromV25(dbHandle)
+}
+
func updateMySQLDatabaseFrom23To24(dbHandle *sql.DB) error {
logger.InfoToConsole("updating database schema version: 23 -> 24")
providerLog(logger.LevelInfo, "updating database schema version: 23 -> 24")
@@ -819,6 +840,13 @@ func updateMySQLDatabaseFrom24To25(dbHandle *sql.DB) error {
return sqlCommonExecSQLAndUpdateDBVersion(dbHandle, strings.Split(sql, ";"), 25, true)
}
+func updateMySQLDatabaseFrom25To26(dbHandle *sql.DB) error {
+ logger.InfoToConsole("updating database schema version: 25 -> 26")
+ providerLog(logger.LevelInfo, "updating database schema version: 25 -> 26")
+ sql := strings.ReplaceAll(mysqlV26SQL, "{{events_rules}}", sqlTableEventsRules)
+ return sqlCommonExecSQLAndUpdateDBVersion(dbHandle, strings.Split(sql, ";"), 26, true)
+}
+
func downgradeMySQLDatabaseFrom24To23(dbHandle *sql.DB) error {
logger.InfoToConsole("downgrading database schema version: 24 -> 23")
providerLog(logger.LevelInfo, "downgrading database schema version: 24 -> 23")
@@ -835,3 +863,10 @@ func downgradeMySQLDatabaseFrom25To24(dbHandle *sql.DB) error {
sql := strings.ReplaceAll(mysqlV25DownSQL, "{{users}}", sqlTableUsers)
return sqlCommonExecSQLAndUpdateDBVersion(dbHandle, strings.Split(sql, ";"), 24, false)
}
+
+func downgradeMySQLDatabaseFrom26To25(dbHandle *sql.DB) error {
+ logger.InfoToConsole("downgrading database schema version: 26 -> 25")
+ providerLog(logger.LevelInfo, "downgrading database schema version: 26 -> 25")
+ sql := strings.ReplaceAll(mysqlV26DownSQL, "{{events_rules}}", sqlTableEventsRules)
+ return sqlCommonExecSQLAndUpdateDBVersion(dbHandle, strings.Split(sql, ";"), 25, false)
+}
diff --git a/internal/dataprovider/pgsql.go b/internal/dataprovider/pgsql.go
index ead72708..0f9bb387 100644
--- a/internal/dataprovider/pgsql.go
+++ b/internal/dataprovider/pgsql.go
@@ -198,6 +198,10 @@ DROP TABLE "{{roles}}" CASCADE;
ALTER TABLE "{{users}}" ALTER COLUMN "last_password_change" DROP DEFAULT;
`
pgsqlV25DownSQL = `ALTER TABLE "{{users}}" DROP COLUMN "last_password_change" CASCADE;`
+ pgsqlV26SQL = `ALTER TABLE "{{events_rules}}" ADD COLUMN "status" integer DEFAULT 1 NOT NULL;
+ALTER TABLE "{{events_rules}}" ALTER COLUMN "status" DROP DEFAULT;
+`
+ pgsqlV26DownSQL = `ALTER TABLE "{{events_rules}}" DROP COLUMN "status" CASCADE;`
)
// PGSQLProvider defines the auth provider for PostgreSQL database
@@ -715,6 +719,8 @@ func (p *PGSQLProvider) migrateDatabase() error { //nolint:dupl
return updatePgSQLDatabaseFromV23(p.dbHandle)
case version == 24:
return updatePgSQLDatabaseFromV24(p.dbHandle)
+ case version == 25:
+ return updatePgSQLDatabaseFromV25(p.dbHandle)
default:
if version > sqlDatabaseVersion {
providerLog(logger.LevelError, "database schema version %d is newer than the supported one: %d", version,
@@ -741,6 +747,8 @@ func (p *PGSQLProvider) revertDatabase(targetVersion int) error {
return downgradePgSQLDatabaseFromV24(p.dbHandle)
case 25:
return downgradePgSQLDatabaseFromV25(p.dbHandle)
+ case 26:
+ return downgradePgSQLDatabaseFromV26(p.dbHandle)
default:
return fmt.Errorf("database schema version not handled: %d", dbVersion.Version)
}
@@ -759,7 +767,14 @@ func updatePgSQLDatabaseFromV23(dbHandle *sql.DB) error {
}
func updatePgSQLDatabaseFromV24(dbHandle *sql.DB) error {
- return updatePgSQLDatabaseFrom24To25(dbHandle)
+ if err := updatePgSQLDatabaseFrom24To25(dbHandle); err != nil {
+ return err
+ }
+ return updatePgSQLDatabaseFromV25(dbHandle)
+}
+
+func updatePgSQLDatabaseFromV25(dbHandle *sql.DB) error {
+ return updatePgSQLDatabaseFrom25To26(dbHandle)
}
func downgradePgSQLDatabaseFromV24(dbHandle *sql.DB) error {
@@ -773,6 +788,13 @@ func downgradePgSQLDatabaseFromV25(dbHandle *sql.DB) error {
return downgradePgSQLDatabaseFromV24(dbHandle)
}
+func downgradePgSQLDatabaseFromV26(dbHandle *sql.DB) error {
+ if err := downgradePgSQLDatabaseFrom26To25(dbHandle); err != nil {
+ return err
+ }
+ return downgradePgSQLDatabaseFromV25(dbHandle)
+}
+
func updatePgSQLDatabaseFrom23To24(dbHandle *sql.DB) error {
logger.InfoToConsole("updating database schema version: 23 -> 24")
providerLog(logger.LevelInfo, "updating database schema version: 23 -> 24")
@@ -794,6 +816,17 @@ func updatePgSQLDatabaseFrom24To25(dbHandle *sql.DB) error {
return sqlCommonExecSQLAndUpdateDBVersion(dbHandle, []string{sql}, 25, true)
}
+func updatePgSQLDatabaseFrom25To26(dbHandle *sql.DB) error {
+ logger.InfoToConsole("updating database schema version: 25 -> 26")
+ providerLog(logger.LevelInfo, "updating database schema version: 25 -> 26")
+ sql := pgsqlV26SQL
+ if config.Driver == CockroachDataProviderName {
+ sql = strings.ReplaceAll(sql, `ALTER TABLE "{{events_rules}}" ALTER COLUMN "status" DROP DEFAULT;`, "")
+ }
+ sql = strings.ReplaceAll(sql, "{{events_rules}}", sqlTableEventsRules)
+ return sqlCommonExecSQLAndUpdateDBVersion(dbHandle, []string{sql}, 26, true)
+}
+
func downgradePgSQLDatabaseFrom24To23(dbHandle *sql.DB) error {
logger.InfoToConsole("downgrading database schema version: 24 -> 23")
providerLog(logger.LevelInfo, "downgrading database schema version: 24 -> 23")
@@ -810,3 +843,10 @@ func downgradePgSQLDatabaseFrom25To24(dbHandle *sql.DB) error {
sql := strings.ReplaceAll(pgsqlV25DownSQL, "{{users}}", sqlTableUsers)
return sqlCommonExecSQLAndUpdateDBVersion(dbHandle, []string{sql}, 24, false)
}
+
+func downgradePgSQLDatabaseFrom26To25(dbHandle *sql.DB) error {
+ logger.InfoToConsole("downgrading database schema version: 26 -> 25")
+ providerLog(logger.LevelInfo, "downgrading database schema version: 26 -> 25")
+ sql := strings.ReplaceAll(pgsqlV26DownSQL, "{{events_rules}}", sqlTableEventsRules)
+ return sqlCommonExecSQLAndUpdateDBVersion(dbHandle, []string{sql}, 25, false)
+}
diff --git a/internal/dataprovider/sqlcommon.go b/internal/dataprovider/sqlcommon.go
index d999534f..4fd9ea39 100644
--- a/internal/dataprovider/sqlcommon.go
+++ b/internal/dataprovider/sqlcommon.go
@@ -34,7 +34,7 @@ import (
)
const (
- sqlDatabaseVersion = 25
+ sqlDatabaseVersion = 26
defaultSQLQueryTimeout = 10 * time.Second
longSQLQueryTimeout = 60 * time.Second
)
@@ -1853,7 +1853,7 @@ func getEventRuleFromDbRow(row sqlScanner) (EventRule, error) {
var conditions []byte
err := row.Scan(&rule.ID, &rule.Name, &description, &rule.CreatedAt, &rule.UpdatedAt, &rule.Trigger,
- &conditions, &rule.DeletedAt)
+ &conditions, &rule.DeletedAt, &rule.Status)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return rule, util.NewRecordNotFoundError(err.Error())
@@ -3353,7 +3353,7 @@ func sqlCommonAddEventRule(rule *EventRule, dbHandle *sql.DB) error {
}
q := getAddEventRuleQuery()
_, err := tx.ExecContext(ctx, q, rule.Name, rule.Description, util.GetTimeAsMsSinceEpoch(time.Now()),
- util.GetTimeAsMsSinceEpoch(time.Now()), rule.Trigger, string(conditions))
+ util.GetTimeAsMsSinceEpoch(time.Now()), rule.Trigger, string(conditions), rule.Status)
if err != nil {
return err
}
@@ -3375,7 +3375,7 @@ func sqlCommonUpdateEventRule(rule *EventRule, dbHandle *sql.DB) error {
return sqlCommonExecuteTx(ctx, dbHandle, func(tx *sql.Tx) error {
q := getUpdateEventRuleQuery()
_, err := tx.ExecContext(ctx, q, rule.Description, util.GetTimeAsMsSinceEpoch(time.Now()),
- rule.Trigger, string(conditions), rule.Name)
+ rule.Trigger, string(conditions), rule.Status, rule.Name)
if err != nil {
return err
}
diff --git a/internal/dataprovider/sqlite.go b/internal/dataprovider/sqlite.go
index 296f08e3..bee4df3e 100644
--- a/internal/dataprovider/sqlite.go
+++ b/internal/dataprovider/sqlite.go
@@ -177,6 +177,8 @@ DROP TABLE "{{roles}}";
`
sqliteV25SQL = `ALTER TABLE "{{users}}" ADD COLUMN "last_password_change" bigint DEFAULT 0 NOT NULL;`
sqliteV25DownSQL = `ALTER TABLE "{{users}}" DROP COLUMN "last_password_change";`
+ sqliteV26SQL = `ALTER TABLE "{{events_rules}}" ADD COLUMN "status" integer DEFAULT 1 NOT NULL;`
+ sqliteV26DownSQL = `ALTER TABLE "{{events_rules}}" DROP COLUMN "status";`
)
// SQLiteProvider defines the auth provider for SQLite database
@@ -673,6 +675,8 @@ func (p *SQLiteProvider) migrateDatabase() error { //nolint:dupl
return updateSQLiteDatabaseFromV23(p.dbHandle)
case version == 24:
return updateSQLiteDatabaseFromV24(p.dbHandle)
+ case version == 25:
+ return updateSQLiteDatabaseFromV25(p.dbHandle)
default:
if version > sqlDatabaseVersion {
providerLog(logger.LevelError, "database schema version %d is newer than the supported one: %d", version,
@@ -699,6 +703,8 @@ func (p *SQLiteProvider) revertDatabase(targetVersion int) error {
return downgradeSQLiteDatabaseFromV24(p.dbHandle)
case 25:
return downgradeSQLiteDatabaseFromV25(p.dbHandle)
+ case 26:
+ return downgradeSQLiteDatabaseFromV26(p.dbHandle)
default:
return fmt.Errorf("database schema version not handled: %d", dbVersion.Version)
}
@@ -717,7 +723,14 @@ func updateSQLiteDatabaseFromV23(dbHandle *sql.DB) error {
}
func updateSQLiteDatabaseFromV24(dbHandle *sql.DB) error {
- return updateSQLiteDatabaseFrom24To25(dbHandle)
+ if err := updateSQLiteDatabaseFrom24To25(dbHandle); err != nil {
+ return err
+ }
+ return updateSQLiteDatabaseFromV25(dbHandle)
+}
+
+func updateSQLiteDatabaseFromV25(dbHandle *sql.DB) error {
+ return updateSQLiteDatabaseFrom25To26(dbHandle)
}
func downgradeSQLiteDatabaseFromV24(dbHandle *sql.DB) error {
@@ -731,6 +744,13 @@ func downgradeSQLiteDatabaseFromV25(dbHandle *sql.DB) error {
return downgradeSQLiteDatabaseFromV24(dbHandle)
}
+func downgradeSQLiteDatabaseFromV26(dbHandle *sql.DB) error {
+ if err := downgradeSQLiteDatabaseFrom26To25(dbHandle); err != nil {
+ return err
+ }
+ return downgradeSQLiteDatabaseFromV25(dbHandle)
+}
+
func updateSQLiteDatabaseFrom23To24(dbHandle *sql.DB) error {
logger.InfoToConsole("updating database schema version: 23 -> 24")
providerLog(logger.LevelInfo, "updating database schema version: 23 -> 24")
@@ -748,6 +768,13 @@ func updateSQLiteDatabaseFrom24To25(dbHandle *sql.DB) error {
return sqlCommonExecSQLAndUpdateDBVersion(dbHandle, []string{sql}, 25, true)
}
+func updateSQLiteDatabaseFrom25To26(dbHandle *sql.DB) error {
+ logger.InfoToConsole("updating database schema version: 25 -> 26")
+ providerLog(logger.LevelInfo, "updating database schema version: 25 -> 26")
+ sql := strings.ReplaceAll(sqliteV26SQL, "{{events_rules}}", sqlTableEventsRules)
+ return sqlCommonExecSQLAndUpdateDBVersion(dbHandle, []string{sql}, 26, true)
+}
+
func downgradeSQLiteDatabaseFrom24To23(dbHandle *sql.DB) error {
logger.InfoToConsole("downgrading database schema version: 24 -> 23")
providerLog(logger.LevelInfo, "downgrading database schema version: 24 -> 23")
@@ -765,6 +792,13 @@ func downgradeSQLiteDatabaseFrom25To24(dbHandle *sql.DB) error {
return sqlCommonExecSQLAndUpdateDBVersion(dbHandle, []string{sql}, 24, false)
}
+func downgradeSQLiteDatabaseFrom26To25(dbHandle *sql.DB) error {
+ logger.InfoToConsole("downgrading database schema version: 26 -> 25")
+ providerLog(logger.LevelInfo, "downgrading database schema version: 26 -> 25")
+ sql := strings.ReplaceAll(sqliteV26DownSQL, "{{events_rules}}", sqlTableEventsRules)
+ return sqlCommonExecSQLAndUpdateDBVersion(dbHandle, []string{sql}, 25, false)
+}
+
/*func setPragmaFK(dbHandle *sql.DB, value string) error {
ctx, cancel := context.WithTimeout(context.Background(), longSQLQueryTimeout)
defer cancel()
diff --git a/internal/dataprovider/sqlqueries.go b/internal/dataprovider/sqlqueries.go
index 07191294..747f9dc0 100644
--- a/internal/dataprovider/sqlqueries.go
+++ b/internal/dataprovider/sqlqueries.go
@@ -61,10 +61,10 @@ func getSQLQuotedName(name string) string {
func getSelectEventRuleFields() string {
if config.Driver == MySQLDataProviderName {
- return "id,name,description,created_at,updated_at,`trigger`,conditions,deleted_at"
+ return "id,name,description,created_at,updated_at,`trigger`,conditions,deleted_at,status"
}
- return `id,name,description,created_at,updated_at,"trigger",conditions,deleted_at`
+ return `id,name,description,created_at,updated_at,"trigger",conditions,deleted_at,status`
}
func getCoalesceDefaultForRole(role string) string {
@@ -973,16 +973,16 @@ func getEventRulesByNameQuery() string {
}
func getAddEventRuleQuery() string {
- return fmt.Sprintf(`INSERT INTO %s (name,description,created_at,updated_at,%s,conditions,deleted_at)
- VALUES (%s,%s,%s,%s,%s,%s,0)`,
+ return fmt.Sprintf(`INSERT INTO %s (name,description,created_at,updated_at,%s,conditions,deleted_at,status)
+ VALUES (%s,%s,%s,%s,%s,%s,0,%s)`,
sqlTableEventsRules, getSQLQuotedName("trigger"), sqlPlaceholders[0], sqlPlaceholders[1], sqlPlaceholders[2],
- sqlPlaceholders[3], sqlPlaceholders[4], sqlPlaceholders[5])
+ sqlPlaceholders[3], sqlPlaceholders[4], sqlPlaceholders[5], sqlPlaceholders[6])
}
func getUpdateEventRuleQuery() string {
- return fmt.Sprintf(`UPDATE %s SET description=%s,updated_at=%s,%s=%s,conditions=%s WHERE name = %s`,
+ return fmt.Sprintf(`UPDATE %s SET description=%s,updated_at=%s,%s=%s,conditions=%s,status=%s WHERE name = %s`,
sqlTableEventsRules, sqlPlaceholders[0], sqlPlaceholders[1], getSQLQuotedName("trigger"), sqlPlaceholders[2],
- sqlPlaceholders[3], sqlPlaceholders[4])
+ sqlPlaceholders[3], sqlPlaceholders[4], sqlPlaceholders[5])
}
func getDeleteEventRuleQuery(softDelete bool) string {
diff --git a/internal/httpd/api_maintenance.go b/internal/httpd/api_maintenance.go
index 69ff902a..04cb844c 100644
--- a/internal/httpd/api_maintenance.go
+++ b/internal/httpd/api_maintenance.go
@@ -212,7 +212,7 @@ func restoreBackup(content []byte, inputFile string, scanQuota, mode int, execut
return err
}
- if err = RestoreEventRules(dump.EventRules, inputFile, mode, executor, ipAddress, role); err != nil {
+ if err = RestoreEventRules(dump.EventRules, inputFile, mode, executor, ipAddress, role, dump.Version); err != nil {
return err
}
@@ -331,9 +331,14 @@ func RestoreEventActions(actions []dataprovider.BaseEventAction, inputFile strin
}
// RestoreEventRules restores the specified event rules
-func RestoreEventRules(rules []dataprovider.EventRule, inputFile string, mode int, executor, ipAddress, role string) error {
+func RestoreEventRules(rules []dataprovider.EventRule, inputFile string, mode int, executor, ipAddress,
+ role string, dumpVersion int,
+) error {
for _, rule := range rules {
rule := rule // pin
+ if dumpVersion < 15 {
+ rule.Status = 1
+ }
r, err := dataprovider.EventRuleExists(rule.Name)
if err == nil {
if mode == 1 {
diff --git a/internal/httpd/httpd_test.go b/internal/httpd/httpd_test.go
index 07312351..64ec9dc7 100644
--- a/internal/httpd/httpd_test.go
+++ b/internal/httpd/httpd_test.go
@@ -1408,6 +1408,7 @@ func TestBasicActionRulesHandling(t *testing.T) {
r := dataprovider.EventRule{
Name: "test rule name",
+ Status: 1,
Description: "",
Trigger: dataprovider.EventTriggerFsEvent,
Conditions: dataprovider.EventConditions{
@@ -1629,6 +1630,7 @@ func TestActionRuleRelations(t *testing.T) {
Order: 10,
},
}
+ rule2.Status = 1
rule2, _, err = httpdtest.UpdateEventRule(r2, http.StatusOK)
assert.NoError(t, err)
if assert.Len(t, rule2.Actions, 1) {
@@ -1936,6 +1938,11 @@ func TestEventRuleValidation(t *testing.T) {
assert.NoError(t, err)
assert.Contains(t, string(resp), "name is mandatory")
rule.Name = "r"
+ rule.Status = 100
+ _, resp, err = httpdtest.AddEventRule(rule, http.StatusBadRequest)
+ assert.NoError(t, err)
+ assert.Contains(t, string(resp), "invalid event rule status")
+ rule.Status = 1
rule.Trigger = 1000
_, resp, err = httpdtest.AddEventRule(rule, http.StatusBadRequest)
assert.NoError(t, err)
@@ -6522,7 +6529,9 @@ func TestProviderErrors(t *testing.T) {
assert.NoError(t, err)
user = getTestUser()
user.ID = 1
- backupData := dataprovider.BackupData{}
+ backupData := dataprovider.BackupData{
+ Version: dataprovider.DumpVersion,
+ }
backupData.Users = append(backupData.Users, user)
backupContent, err := json.Marshal(backupData)
assert.NoError(t, err)
@@ -6591,6 +6600,7 @@ func TestProviderErrors(t *testing.T) {
Type: dataprovider.ActionTypeFolderQuotaReset,
},
},
+ Version: dataprovider.DumpVersion,
}
backupContent, err = json.Marshal(backupData)
assert.NoError(t, err)
@@ -6623,6 +6633,7 @@ func TestProviderErrors(t *testing.T) {
},
},
},
+ Version: dataprovider.DumpVersion,
}
backupContent, err = json.Marshal(backupData)
assert.NoError(t, err)
@@ -6636,6 +6647,7 @@ func TestProviderErrors(t *testing.T) {
Name: "role1",
},
},
+ Version: dataprovider.DumpVersion,
}
backupContent, err = json.Marshal(backupData)
assert.NoError(t, err)
@@ -7036,7 +7048,9 @@ func TestRestoreShares(t *testing.T) {
UsedTokens: 8,
AllowFrom: []string{"127.0.0.0/8"},
}
- backupData := dataprovider.BackupData{}
+ backupData := dataprovider.BackupData{
+ Version: dataprovider.DumpVersion,
+ }
backupData.Shares = append(backupData.Shares, share)
backupContent, err := json.Marshal(backupData)
assert.NoError(t, err)
@@ -7088,7 +7102,9 @@ func TestLoaddataFromPostBody(t *testing.T) {
admin.Permissions = []string{dataprovider.PermAdminAddUsers, dataprovider.PermAdminChangeUsers,
dataprovider.PermAdminDeleteUsers, dataprovider.PermAdminViewUsers}
admin.Role = role.Name
- backupData := dataprovider.BackupData{}
+ backupData := dataprovider.BackupData{
+ Version: dataprovider.DumpVersion,
+ }
backupData.Users = append(backupData.Users, user)
backupData.Groups = append(backupData.Groups, group)
backupData.Admins = append(backupData.Admins, admin)
@@ -7273,7 +7289,9 @@ func TestLoaddata(t *testing.T) {
},
},
}
- backupData := dataprovider.BackupData{}
+ backupData := dataprovider.BackupData{
+ Version: 14,
+ }
backupData.Users = append(backupData.Users, user)
backupData.Roles = append(backupData.Roles, role)
backupData.Groups = append(backupData.Groups, group)
@@ -7350,6 +7368,7 @@ func TestLoaddata(t *testing.T) {
rule, _, err = httpdtest.GetEventRuleByName(rule.Name, http.StatusOK)
assert.NoError(t, err)
+ assert.Equal(t, 1, rule.Status)
if assert.Len(t, rule.Actions, 1) {
if assert.NotNil(t, rule.Actions[0].BaseEventAction.Options.HTTPConfig.Password) {
assert.Equal(t, sdkkms.SecretStatusSecretBox, rule.Actions[0].BaseEventAction.Options.HTTPConfig.Password.GetStatus())
@@ -7516,7 +7535,9 @@ func TestLoaddataMode(t *testing.T) {
},
},
}
- backupData := dataprovider.BackupData{}
+ backupData := dataprovider.BackupData{
+ Version: dataprovider.DumpVersion,
+ }
backupData.Users = append(backupData.Users, user)
backupData.Groups = append(backupData.Groups, group)
backupData.Admins = append(backupData.Admins, admin)
@@ -7603,6 +7624,7 @@ func TestLoaddataMode(t *testing.T) {
rule, _, err = httpdtest.GetEventRuleByName(rule.Name, http.StatusOK)
assert.NoError(t, err)
+ assert.Equal(t, 0, rule.Status)
oldRuleDesc := rule.Description
rule.Description = "new rule description"
rule, _, err = httpdtest.UpdateEventRule(rule, http.StatusOK)
@@ -17653,7 +17675,9 @@ func TestWebMaintenanceMock(t *testing.T) {
Key: fmt.Sprintf("%v.%v", util.GenerateUniqueID(), util.GenerateUniqueID()),
Scope: dataprovider.APIKeyScopeAdmin,
}
- backupData := dataprovider.BackupData{}
+ backupData := dataprovider.BackupData{
+ Version: dataprovider.DumpVersion,
+ }
backupData.Users = append(backupData.Users, user)
backupData.Admins = append(backupData.Admins, admin)
backupData.APIKeys = append(backupData.APIKeys, apiKey)
@@ -19027,7 +19051,9 @@ func TestFolderTemplateMock(t *testing.T) {
rr = executeRequest(req)
checkResponseCode(t, http.StatusOK, rr)
- dump = dataprovider.BackupData{}
+ dump = dataprovider.BackupData{
+ Version: dataprovider.DumpVersion,
+ }
err = json.Unmarshal(rr.Body.Bytes(), &dump)
require.NoError(t, err)
require.Len(t, dump.Users, 0)
@@ -20530,6 +20556,7 @@ func TestWebEventRule(t *testing.T) {
assert.NoError(t, err)
rule := dataprovider.EventRule{
Name: "test_web_rule",
+ Status: 1,
Description: "rule added using web API",
Trigger: dataprovider.EventTriggerSchedule,
Conditions: dataprovider.EventConditions{
@@ -20574,13 +20601,22 @@ func TestWebEventRule(t *testing.T) {
form := make(url.Values)
form.Set("name", rule.Name)
form.Set("description", rule.Description)
- form.Set("trigger", "a")
+ form.Set("status", "a")
req, err := http.NewRequest(http.MethodPost, webAdminEventRulePath, bytes.NewBuffer([]byte(form.Encode())))
assert.NoError(t, err)
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
setJWTCookieForReq(req, webToken)
rr := executeRequest(req)
checkResponseCode(t, http.StatusOK, rr)
+ assert.Contains(t, rr.Body.String(), "invalid status")
+ form.Set("status", fmt.Sprintf("%d", rule.Status))
+ form.Set("trigger", "a")
+ req, err = http.NewRequest(http.MethodPost, webAdminEventRulePath, bytes.NewBuffer([]byte(form.Encode())))
+ assert.NoError(t, err)
+ req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
+ setJWTCookieForReq(req, webToken)
+ rr = executeRequest(req)
+ checkResponseCode(t, http.StatusOK, rr)
assert.Contains(t, rr.Body.String(), "invalid trigger")
form.Set("trigger", fmt.Sprintf("%d", rule.Trigger))
form.Set("schedule_hour0", rule.Conditions.Schedules[0].Hours)
@@ -20668,13 +20704,15 @@ func TestWebEventRule(t *testing.T) {
ruleGet, _, err := httpdtest.GetEventRuleByName(rule.Name, http.StatusOK)
assert.NoError(t, err)
assert.Equal(t, rule.Trigger, ruleGet.Trigger)
+ assert.Equal(t, rule.Status, ruleGet.Status)
assert.Equal(t, rule.Description, ruleGet.Description)
assert.Equal(t, rule.Conditions, ruleGet.Conditions)
if assert.Len(t, ruleGet.Actions, 1) {
assert.Equal(t, rule.Actions[0].Name, ruleGet.Actions[0].Name)
assert.Equal(t, rule.Actions[0].Order, ruleGet.Actions[0].Order)
}
- // change rule trigger
+ // change rule trigger and status
+ rule.Status = 0
rule.Trigger = dataprovider.EventTriggerFsEvent
rule.Conditions = dataprovider.EventConditions{
FsEvents: []string{"upload", "download"},
@@ -20707,6 +20745,7 @@ func TestWebEventRule(t *testing.T) {
MaxFileSize: 5 * 1024 * 1024,
},
}
+ form.Set("status", fmt.Sprintf("%d", rule.Status))
form.Set("trigger", fmt.Sprintf("%d", rule.Trigger))
for _, event := range rule.Conditions.FsEvents {
form.Add("fs_events", event)
@@ -20727,6 +20766,7 @@ func TestWebEventRule(t *testing.T) {
// check the rule
ruleGet, _, err = httpdtest.GetEventRuleByName(rule.Name, http.StatusOK)
assert.NoError(t, err)
+ assert.Equal(t, rule.Status, ruleGet.Status)
assert.Equal(t, rule.Trigger, ruleGet.Trigger)
assert.Equal(t, rule.Description, ruleGet.Description)
assert.Equal(t, rule.Conditions, ruleGet.Conditions)
diff --git a/internal/httpd/webadmin.go b/internal/httpd/webadmin.go
index 02df9bd7..3d6eb00a 100644
--- a/internal/httpd/webadmin.go
+++ b/internal/httpd/webadmin.go
@@ -2339,6 +2339,10 @@ func getEventRuleFromPostFields(r *http.Request) (dataprovider.EventRule, error)
if err != nil {
return dataprovider.EventRule{}, err
}
+ status, err := strconv.Atoi(r.Form.Get("status"))
+ if err != nil {
+ return dataprovider.EventRule{}, fmt.Errorf("invalid status: %w", err)
+ }
trigger, err := strconv.Atoi(r.Form.Get("trigger"))
if err != nil {
return dataprovider.EventRule{}, fmt.Errorf("invalid trigger: %w", err)
@@ -2353,6 +2357,7 @@ func getEventRuleFromPostFields(r *http.Request) (dataprovider.EventRule, error)
}
rule := dataprovider.EventRule{
Name: r.Form.Get("name"),
+ Status: status,
Description: r.Form.Get("description"),
Trigger: trigger,
Conditions: conditions,
@@ -3499,6 +3504,7 @@ func (s *httpdServer) handleWebGetEventRules(w http.ResponseWriter, r *http.Requ
func (s *httpdServer) handleWebAddEventRuleGet(w http.ResponseWriter, r *http.Request) {
r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
rule := dataprovider.EventRule{
+ Status: 1,
Trigger: dataprovider.EventTriggerFsEvent,
}
s.renderEventRulePage(w, r, rule, genericPageModeAdd, "")
diff --git a/internal/httpdtest/httpdtest.go b/internal/httpdtest/httpdtest.go
index f1805d3e..03cc1695 100644
--- a/internal/httpdtest/httpdtest.go
+++ b/internal/httpdtest/httpdtest.go
@@ -1601,6 +1601,9 @@ func checkEventRule(expected, actual dataprovider.EventRule) error {
if dataprovider.ConvertName(expected.Name) != actual.Name {
return errors.New("name mismatch")
}
+ if expected.Status != actual.Status {
+ return errors.New("status mismatch")
+ }
if expected.Description != actual.Description {
return errors.New("description mismatch")
}
diff --git a/internal/service/service.go b/internal/service/service.go
index cb1707a4..b1786853 100644
--- a/internal/service/service.go
+++ b/internal/service/service.go
@@ -382,7 +382,8 @@ func (s *Service) restoreDump(dump *dataprovider.BackupData) error {
if err != nil {
return fmt.Errorf("unable to restore event actions from file %#v: %v", s.LoadDataFrom, err)
}
- err = httpd.RestoreEventRules(dump.EventRules, s.LoadDataFrom, s.LoadDataMode, dataprovider.ActionExecutorSystem, "", "")
+ err = httpd.RestoreEventRules(dump.EventRules, s.LoadDataFrom, s.LoadDataMode, dataprovider.ActionExecutorSystem,
+ "", "", dump.Version)
if err != nil {
return fmt.Errorf("unable to restore event rules from file %#v: %v", s.LoadDataFrom, err)
}
diff --git a/openapi/openapi.yaml b/openapi/openapi.yaml
index 2dcb55ec..ccf7468d 100644
--- a/openapi/openapi.yaml
+++ b/openapi/openapi.yaml
@@ -6748,6 +6748,15 @@ components:
name:
type: string
description: unique name
+ status:
+ type: integer
+ enum:
+ - 0
+ - 1
+ description: |
+ status:
+ * `0` disabled
+ * `1` enabled
description:
type: string
description: optional description
diff --git a/templates/webadmin/admin.html b/templates/webadmin/admin.html
index 126fdff1..cff24d1d 100644
--- a/templates/webadmin/admin.html
+++ b/templates/webadmin/admin.html
@@ -41,6 +41,16 @@ along with this program. If not, see