From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 4DC9D9241A for ; Thu, 1 Feb 2024 16:37:02 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id B555812D49 for ; Thu, 1 Feb 2024 16:37:01 +0100 (CET) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [94.136.29.106]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS for ; Thu, 1 Feb 2024 16:36:59 +0100 (CET) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id 3FE1341F64 for ; Thu, 1 Feb 2024 16:36:59 +0100 (CET) From: Dominik Csapak To: pmg-devel@lists.proxmox.com Date: Thu, 1 Feb 2024 16:36:51 +0100 Message-Id: <20240201153657.1067215-6-d.csapak@proxmox.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20240201153657.1067215-1-d.csapak@proxmox.com> References: <20240201153657.1067215-1-d.csapak@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.020 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record T_SCC_BODY_TEXT_LINE -0.01 - Subject: [pmg-devel] [RFC PATCH pmg-api 05/11] add objectgroup attributes and/invert X-BeenThere: pmg-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox Mail Gateway development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 01 Feb 2024 15:37:02 -0000 add a new table Objectgroup_Attributes where we can save additional attributes for objectgroups (like the Attribut tables for objects). Adds two new attributes for the groups: * and * invert These will modify the match behaviour for object groups Signed-off-by: Dominik Csapak --- src/PMG/API2/ObjectGroupHelpers.pm | 36 ++++++++++++++- src/PMG/DBTools.pm | 15 ++++++ src/PMG/RuleDB.pm | 74 ++++++++++++++++++++++++------ 3 files changed, 110 insertions(+), 15 deletions(-) diff --git a/src/PMG/API2/ObjectGroupHelpers.pm b/src/PMG/API2/ObjectGroupHelpers.pm index 48078fb..40ade5d 100644 --- a/src/PMG/API2/ObjectGroupHelpers.pm +++ b/src/PMG/API2/ObjectGroupHelpers.pm @@ -53,6 +53,21 @@ sub format_object_group { return $res; } +my $group_attributes = { + and => { + description => "If set to 1, objects in this group are 'and' combined.", + type => 'boolean', + default => 0, + optional => 1, + }, + invert => { + description => "If set to 1, the resulting match is inverted.", + type => 'boolean', + default => 0, + optional => 1, + }, +}; + sub register_group_list_api { my ($apiclass, $oclass) = @_; @@ -86,6 +101,11 @@ sub register_group_list_api { return format_object_group($ogroups); }}); + my $additional_parameters = {}; + if ($oclass =~ /^(?:what|when|from|to)$/i) { + $additional_parameters = { $group_attributes->%* }; + } + $apiclass->register_method({ name => "create_${oclass}_group", path => $oclass, @@ -108,6 +128,7 @@ sub register_group_list_api { maxLength => 255, optional => 1, }, + $additional_parameters->%*, }, }, returns => { type => 'integer' }, @@ -119,6 +140,10 @@ sub register_group_list_api { my $og = PMG::RuleDB::Group->new( $param->{name}, $param->{info} // '', $oclass); + for my $prop (qw(and invert)) { + $og->{$prop} = $param->{$prop} if defined($param->{$prop}); + } + return $rdb->save_group($og); }}); } @@ -199,6 +224,11 @@ sub register_object_group_config_api { }}); + my $additional_parameters = {}; + if ($oclass =~ /^(?:what|when|from|to)$/i) { + $additional_parameters = { $group_attributes->%* }; + } + $apiclass->register_method({ name => 'set_config', path => $path, @@ -226,6 +256,7 @@ sub register_object_group_config_api { maxLength => 255, optional => 1, }, + $additional_parameters->%*, }, }, returns => { type => "null" }, @@ -243,8 +274,9 @@ sub register_object_group_config_api { my $og = shift @$list || die "$oclass group '$ogroup' not found\n"; - $og->{name} = $param->{name} if defined($param->{name}); - $og->{info} = $param->{info} if defined($param->{info}); + for my $prop (qw(name info and invert)) { + $og->{$prop} = $param->{$prop} if defined($param->{$prop}); + } $rdb->save_group($og); diff --git a/src/PMG/DBTools.pm b/src/PMG/DBTools.pm index 9e133bc..0d3d9c3 100644 --- a/src/PMG/DBTools.pm +++ b/src/PMG/DBTools.pm @@ -295,6 +295,18 @@ my $userprefs_ctablecmd = <<__EOD; __EOD +my $object_group_attributes_cmd = <<__EOD; + CREATE TABLE Objectgroup_Attributes ( + Objectgroup_ID INTEGER NOT NULL, + Name VARCHAR(20) NOT NULL, + Value BYTEA NULL, + PRIMARY KEY (Objectgroup_ID, Name) + ); + + CREATE INDEX Objectgroup_Attributes_Objectgroup_ID_Index ON Objectgroup_Attributes(Objectgroup_ID); + +__EOD + sub cond_create_dbtable { my ($dbh, $name, $ctablecmd) = @_; @@ -439,6 +451,8 @@ sub create_ruledb { $userprefs_ctablecmd; $virusinfo_stat_ctablecmd; + + $object_group_attributes_cmd; EOD ); @@ -494,6 +508,7 @@ sub upgradedb { 'CStatistic', $cstatistic_ctablecmd, 'ClusterInfo', $clusterinfo_ctablecmd, 'VirusInfo', $virusinfo_stat_ctablecmd, + 'Objectgroup_Attributes', $object_group_attributes_cmd, }; foreach my $table (keys %$tables) { diff --git a/src/PMG/RuleDB.pm b/src/PMG/RuleDB.pm index a6b0b79..cc69915 100644 --- a/src/PMG/RuleDB.pm +++ b/src/PMG/RuleDB.pm @@ -160,6 +160,30 @@ sub load_groups_by_name { }; } +sub update_group_attributes { + my ($self, $og) = @_; + + my $attributes = [qw(and invert)]; + + for my $attribute ($attributes->@*) { + # only save the values if they're set to 1 + if ($og->{$attribute}) { + $self->{dbh}->do( + "INSERT INTO Objectgroup_Attributes (Objectgroup_ID, Name, Value) " . + "VALUES (?, ?, ?) ". + "ON CONFLICT (Objectgroup_ID, Name) DO UPDATE SET Value = ?", undef, + $og->{id}, $attribute, $og->{$attribute}, $og->{$attribute}, + ); + } else { + $self->{dbh}->do( + "DELETE FROM Objectgroup_Attributes " . + "WHERE Objectgroup_ID = ? AND Name = ?", undef, + $og->{id}, $attribute, + ); + } + } +} + sub save_group { my ($self, $og) = @_; @@ -171,27 +195,51 @@ sub save_group { die "undefined group attribute - class: ERROR"; if (defined($og->{id})) { + $self->{dbh}->begin_work; - $self->{dbh}->do("UPDATE Objectgroup " . - "SET Name = ?, Info = ? " . - "WHERE ID = ?", undef, - encode('UTF-8', $og->{name}), - encode('UTF-8', $og->{info}), - $og->{id}); + eval { + $self->{dbh}->do("UPDATE Objectgroup " . + "SET Name = ?, Info = ? " . + "WHERE ID = ?", undef, + encode('UTF-8', $og->{name}), + encode('UTF-8', $og->{info}), + $og->{id}); - return $og->{id}; + $self->update_group_attributes($og); + $self->{dbh}->commit; + }; + + if (my $err = $@) { + $self->{dbh}->rollback; + syslog('err', $err); + return undef; + } } else { - my $sth = $self->{dbh}->prepare( - "INSERT INTO Objectgroup (Name, Info, Class) " . - "VALUES (?, ?, ?);"); + $self->{dbh}->begin_work; + + eval { + my $sth = $self->{dbh}->prepare( + "INSERT INTO Objectgroup (Name, Info, Class) " . + "VALUES (?, ?, ?);"); + + $sth->execute(encode('UTF-8', $og->name), encode('UTF-8', $og->info), $og->class); - $sth->execute(encode('UTF-8', $og->name), encode('UTF-8', $og->info), $og->class); + $og->{id} = PMG::Utils::lastid($self->{dbh}, 'objectgroup_id_seq'); - return $og->{id} = PMG::Utils::lastid($self->{dbh}, 'objectgroup_id_seq'); + $self->update_group_attributes($og); + + $self->{dbh}->commit; + }; + + if (my $err = $@) { + $self->{dbh}->rollback; + syslog('err', $err); + return undef; + } } - return undef; + return $og->{id}; } sub delete_group { -- 2.30.2