From e48b76821f666498329e88443d342f1d511ceca6 Mon Sep 17 00:00:00 2001 From: Nicola Murino Date: Fri, 15 Nov 2024 13:53:38 +0100 Subject: [PATCH] provider rule events: allows you to filter by user groups Signed-off-by: Nicola Murino --- internal/common/eventmanager.go | 4 + internal/common/protocol_test.go | 132 +++++++++++++++++++++++++++++ internal/dataprovider/eventrule.go | 1 - templates/webadmin/eventrule.html | 2 +- 4 files changed, 137 insertions(+), 2 deletions(-) diff --git a/internal/common/eventmanager.go b/internal/common/eventmanager.go index 240f1c26..93a62bf1 100644 --- a/internal/common/eventmanager.go +++ b/internal/common/eventmanager.go @@ -95,6 +95,7 @@ func init() { } if u, ok := object.(*dataprovider.User); ok { p.Email = u.Email + p.Groups = u.Groups } else if a, ok := object.(*dataprovider.Admin); ok { p.Email = a.Email } @@ -315,6 +316,9 @@ func (*eventRulesContainer) checkProviderEventMatch(conditions *dataprovider.Eve if !checkEventConditionPatterns(params.Name, conditions.Options.Names) { return false } + if !checkEventGroupConditionPatterns(params.Groups, conditions.Options.GroupNames) { + return false + } if !checkEventConditionPatterns(params.Role, conditions.Options.RoleNames) { return false } diff --git a/internal/common/protocol_test.go b/internal/common/protocol_test.go index 20bb59fc..7d9f13ff 100644 --- a/internal/common/protocol_test.go +++ b/internal/common/protocol_test.go @@ -5502,6 +5502,138 @@ func TestEventFsActionsGroupFilters(t *testing.T) { require.NoError(t, err) } +func TestEventProviderActionGroupFilters(t *testing.T) { + smtpCfg := smtp.Config{ + Host: "127.0.0.1", + Port: 2525, + From: "notification@example.com", + TemplatesPath: "templates", + } + err := smtpCfg.Initialize(configDir, true) + require.NoError(t, err) + + a1 := dataprovider.BaseEventAction{ + Name: "a1", + Type: dataprovider.ActionTypeEmail, + Options: dataprovider.BaseEventActionOptions{ + EmailConfig: dataprovider.EventActionEmailConfig{ + Recipients: []string{"example@example.net"}, + Subject: `New "{{Event}}" from "{{Name}}"`, + Body: "IP: {{IP}}", + }, + }, + } + action1, _, err := httpdtest.AddEventAction(a1, http.StatusCreated) + assert.NoError(t, err) + + r1 := dataprovider.EventRule{ + Name: "rule1", + Status: 1, + Trigger: dataprovider.EventTriggerProviderEvent, + Conditions: dataprovider.EventConditions{ + ProviderEvents: []string{"add", "update"}, + Options: dataprovider.ConditionOptions{ + GroupNames: []dataprovider.ConditionPattern{ + { + Pattern: "group_*", + }, + }, + ProviderObjects: []string{"user"}, + }, + }, + Actions: []dataprovider.EventAction{ + { + BaseEventAction: dataprovider.BaseEventAction{ + Name: action1.Name, + }, + Order: 1, + }, + }, + } + rule1, _, err := httpdtest.AddEventRule(r1, http.StatusCreated) + assert.NoError(t, err) + + g1 := dataprovider.Group{ + BaseGroup: sdk.BaseGroup{ + Name: "agroup_1", + }, + } + group1, _, err := httpdtest.AddGroup(g1, http.StatusCreated) + assert.NoError(t, err) + + g2 := dataprovider.Group{ + BaseGroup: sdk.BaseGroup{ + Name: "group_2", + }, + } + group2, _, err := httpdtest.AddGroup(g2, http.StatusCreated) + assert.NoError(t, err) + + u := getTestUser() + u.Groups = []sdk.GroupMapping{ + { + Name: group2.Name, + Type: sdk.GroupTypePrimary, + }, + } + + lastReceivedEmail.reset() + user, _, err := httpdtest.AddUser(u, http.StatusCreated) + assert.NoError(t, err) + assert.Eventually(t, func() bool { + return lastReceivedEmail.get().From != "" + }, 1500*time.Millisecond, 100*time.Millisecond) + email := lastReceivedEmail.get() + assert.Len(t, email.To, 1) + + user.Groups = []sdk.GroupMapping{ + { + Name: group1.Name, + Type: sdk.GroupTypePrimary, + }, + } + + lastReceivedEmail.reset() + user, _, err = httpdtest.UpdateUser(user, http.StatusOK, "") + assert.NoError(t, err) + time.Sleep(300 * time.Millisecond) + email = lastReceivedEmail.get() + assert.Len(t, email.To, 0) + + user.Groups = []sdk.GroupMapping{ + { + Name: group2.Name, + Type: sdk.GroupTypePrimary, + }, + } + + lastReceivedEmail.reset() + user, _, err = httpdtest.UpdateUser(user, http.StatusOK, "") + assert.NoError(t, err) + assert.Eventually(t, func() bool { + return lastReceivedEmail.get().From != "" + }, 1500*time.Millisecond, 100*time.Millisecond) + email = lastReceivedEmail.get() + assert.Len(t, email.To, 1) + + _, err = httpdtest.RemoveEventRule(rule1, http.StatusOK) + assert.NoError(t, err) + _, err = httpdtest.RemoveEventAction(action1, http.StatusOK) + assert.NoError(t, err) + _, err = httpdtest.RemoveUser(user, http.StatusOK) + assert.NoError(t, err) + err = os.RemoveAll(user.GetHomeDir()) + assert.NoError(t, err) + _, err = httpdtest.RemoveGroup(group1, http.StatusOK) + assert.NoError(t, err) + _, err = httpdtest.RemoveGroup(group2, http.StatusOK) + assert.NoError(t, err) + + smtpCfg = smtp.Config{} + err = smtpCfg.Initialize(configDir, true) + require.NoError(t, err) +} + func TestBackupAsAttachment(t *testing.T) { smtpCfg := smtp.Config{ Host: "127.0.0.1", diff --git a/internal/dataprovider/eventrule.go b/internal/dataprovider/eventrule.go index 7fab5801..0c7d0e35 100644 --- a/internal/dataprovider/eventrule.go +++ b/internal/dataprovider/eventrule.go @@ -1503,7 +1503,6 @@ func (c *EventConditions) validate(trigger int) error { case EventTriggerProviderEvent: c.FsEvents = nil c.Schedules = nil - c.Options.GroupNames = nil c.Options.FsPaths = nil c.Options.Protocols = nil c.Options.EventStatuses = nil diff --git a/templates/webadmin/eventrule.html b/templates/webadmin/eventrule.html index 76c52eab..b1b39183 100644 --- a/templates/webadmin/eventrule.html +++ b/templates/webadmin/eventrule.html @@ -302,7 +302,7 @@ explicit grant from the SFTPGo Team (support@sftpgo.com). -
+

Group name filters