allow to disable event rules

Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
This commit is contained in:
Nicola Murino 2023-01-19 18:33:04 +01:00
parent 496c8bc785
commit 53f17b5715
No known key found for this signature in database
GPG key ID: 935D2952DEC4EECF
24 changed files with 342 additions and 62 deletions

10
go.mod
View file

@ -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
)

18
go.sum
View file

@ -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=

View file

@ -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.

View file

@ -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)

View file

@ -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{

View file

@ -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"},

View file

@ -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 {

View file

@ -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$"

View file

@ -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))
}

View file

@ -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, "", "")

View file

@ -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)
}

View file

@ -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)
}

View file

@ -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
}

View file

@ -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()

View file

@ -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 {

View file

@ -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 {

View file

@ -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)

View file

@ -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, "")

View file

@ -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")
}

View file

@ -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)
}

View file

@ -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

View file

@ -41,6 +41,16 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
</div>
</div>
<div class="form-group row">
<label for="idStatus" class="col-sm-2 col-form-label">Status</label>
<div class="col-sm-10">
<select class="form-control selectpicker" id="idStatus" name="status">
<option value="1" {{if eq .Admin.Status 1 }}selected{{end}}>Active</option>
<option value="0" {{if eq .Admin.Status 0 }}selected{{end}}>Inactive</option>
</select>
</div>
</div>
<div class="form-group row">
<label for="idEmail" class="col-sm-2 col-form-label">Email</label>
<div class="col-sm-10">
@ -60,16 +70,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
</div>
</div>
<div class="form-group row">
<label for="idStatus" class="col-sm-2 col-form-label">Status</label>
<div class="col-sm-10">
<select class="form-control selectpicker" id="idStatus" name="status">
<option value="1" {{if eq .Admin.Status 1 }}selected{{end}}>Active</option>
<option value="0" {{if eq .Admin.Status 0 }}selected{{end}}>Inactive</option>
</select>
</div>
</div>
<div class="form-group row">
<label for="idPassword" class="col-sm-2 col-form-label">Password</label>
<div class="col-sm-10">

View file

@ -41,6 +41,16 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
</div>
</div>
<div class="form-group row">
<label for="idStatus" class="col-sm-2 col-form-label">Status</label>
<div class="col-sm-10">
<select class="form-control selectpicker" id="idStatus" name="status">
<option value="1" {{if eq .Rule.Status 1 }}selected{{end}}>Active</option>
<option value="0" {{if eq .Rule.Status 0 }}selected{{end}}>Inactive</option>
</select>
</div>
</div>
<div class="form-group row">
<label for="idDescription" class="col-sm-2 col-form-label">Description</label>
<div class="col-sm-10">

View file

@ -39,6 +39,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
<thead>
<tr>
<th>Name</th>
<th>Status</th>
<th>Description</th>
<th>Trigger</th>
<th>Actions</th>
@ -48,6 +49,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
{{range .Rules}}
<tr>
<td>{{.Name}}</td>
<td>{{if eq .Status 1 }}Active{{else}}Inactive{{end}}</td>
<td>{{.Description}}</td>
<td>{{.GetTriggerAsString}}</td>
<td>{{.GetActionsAsString}}</td>
@ -184,11 +186,15 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
],
"columnDefs": [
{
"targets": [0],
"targets": [0,1],
"className": "noVis"
},
{
"targets": [3],
"targets": [2],
"visible": false
},
{
"targets": [4],
"render": $.fn.dataTable.render.ellipsis(100, true)
},
],