1# --
2# Copyright (C) 2001-2020 OTRS AG, https://otrs.com/
3# --
4# This software comes with ABSOLUTELY NO WARRANTY. For details, see
5# the enclosed file COPYING for license information (GPL). If you
6# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
7# --
8
9package Kernel::System::PostMaster::Filter::Match;
10
11use strict;
12use warnings;
13
14use Kernel::System::VariableCheck qw(:all);
15
16our @ObjectDependencies = (
17    'Kernel::System::Log',
18);
19
20sub new {
21    my ( $Type, %Param ) = @_;
22
23    # allocate new hash for object
24    my $Self = {};
25    bless( $Self, $Type );
26
27    # get parser object
28    $Self->{ParserObject} = $Param{ParserObject} || die "Got no ParserObject!";
29
30    # Get communication log object.
31    $Self->{CommunicationLogObject} = $Param{CommunicationLogObject} || die "Got no CommunicationLogObject!";
32
33    return $Self;
34}
35
36sub Run {
37    my ( $Self, %Param ) = @_;
38
39    # check needed stuff
40    for (qw(JobConfig GetParam)) {
41        if ( !$Param{$_} ) {
42            $Self->{CommunicationLogObject}->ObjectLog(
43                ObjectLogType => 'Message',
44                Priority      => 'Error',
45                Key           => 'Kernel::System::PostMaster::Filter::Match',
46                Value         => "Need $_!",
47            );
48            return;
49        }
50    }
51
52    # get config options
53    my %Config;
54    my @Match;
55    my @Set;
56    my $StopAfterMatch;
57    if ( $Param{JobConfig} && ref $Param{JobConfig} eq 'HASH' ) {
58        %Config = %{ $Param{JobConfig} };
59
60        if ( IsArrayRefWithData( $Config{Match} ) ) {
61            @Match = @{ $Config{Match} };
62        }
63        elsif ( IsHashRefWithData( $Config{Match} ) ) {
64            for my $Key ( sort keys %{ $Config{Match} } ) {
65                push @Match, {
66                    Key   => $Key,
67                    Value => $Config{Match}->{$Key},
68                };
69            }
70        }
71
72        if ( IsArrayRefWithData( $Config{Set} ) ) {
73            @Set = @{ $Config{Set} };
74        }
75        elsif ( IsHashRefWithData( $Config{Set} ) ) {
76
77            for my $Key ( sort keys %{ $Config{Set} } ) {
78                push @Set, {
79                    Key   => $Key,
80                    Value => $Config{Set}->{$Key},
81                };
82            }
83        }
84        $StopAfterMatch = $Config{StopAfterMatch} || 0;
85    }
86
87    my $Prefix = '';
88    if ( $Config{Name} ) {
89        $Prefix = "Filter: '$Config{Name}' ";
90    }
91
92    # match 'Match => ???' stuff
93    my $Matched       = '';
94    my $MatchedNot    = 0;
95    my $MatchedResult = '';
96    for my $Index ( 0 .. ( scalar @Match ) - 1 ) {
97        my $Key   = $Match[$Index]->{Key};
98        my $Value = $Match[$Index]->{Value};
99
100        # match only email addresses
101        if ( $Param{GetParam}->{$Key} && $Value =~ /^EMAILADDRESS:(.*)$/ ) {
102            my $SearchEmail    = $1;
103            my @EmailAddresses = $Self->{ParserObject}->SplitAddressLine(
104                Line => $Param{GetParam}->{$Key},
105            );
106            my $LocalMatched;
107            RECIPIENTS:
108            for my $Recipients (@EmailAddresses) {
109
110                my $Email = $Self->{ParserObject}->GetEmailAddress( Email => $Recipients );
111
112                if ( $Email =~ /^$SearchEmail$/i ) {
113
114                    $LocalMatched = 1;
115
116                    if ($SearchEmail) {
117                        $MatchedResult = $SearchEmail;
118                    }
119                    $Self->{CommunicationLogObject}->ObjectLog(
120                        ObjectLogType => 'Message',
121                        Priority      => 'Debug',
122                        Key           => 'Kernel::System::PostMaster::Filter::Match',
123                        Value         => "$Prefix'$Param{GetParam}->{$Key}' =~ /$Value/i matched!",
124                    );
125
126                    last RECIPIENTS;
127                }
128            }
129            if ( !$LocalMatched ) {
130                $MatchedNot = 1;
131            }
132            else {
133                $Matched = 1;
134            }
135        }
136
137        # match string
138        elsif ( $Param{GetParam}->{$Key} && $Param{GetParam}->{$Key} =~ /$Value/i ) {
139
140            # don't lose older match values if more than one header is
141            # used for matching.
142            $Matched = 1;
143
144            if ($1) {
145                $MatchedResult = $1;
146            }
147
148            $Self->{CommunicationLogObject}->ObjectLog(
149                ObjectLogType => 'Message',
150                Priority      => 'Debug',
151                Key           => 'Kernel::System::PostMaster::Filter::Match',
152                Value         => "$Prefix'$Param{GetParam}->{$Key}' =~ /$Value/i matched!",
153            );
154        }
155        else {
156
157            $MatchedNot = 1;
158
159            $Self->{CommunicationLogObject}->ObjectLog(
160                ObjectLogType => 'Message',
161                Priority      => 'Debug',
162                Key           => 'Kernel::System::PostMaster::Filter::Match',
163                Value         => "$Prefix'$Param{GetParam}->{$Key}' =~ /$Value/i matched NOT!",
164            );
165        }
166    }
167
168    # should I ignore the incoming mail?
169    if ( $Matched && !$MatchedNot ) {
170
171        for my $SetItem (@Set) {
172            my $Key   = $SetItem->{Key};
173            my $Value = $SetItem->{Value};
174            $Value =~ s/\[\*\*\*\]/$MatchedResult/;
175            $Param{GetParam}->{$Key} = $Value;
176
177            $Self->{CommunicationLogObject}->ObjectLog(
178                ObjectLogType => 'Message',
179                Priority      => 'Notice',
180                Key           => 'Kernel::System::PostMaster::Filter::Match',
181                Value => $Prefix . "Set param '$Key' to '$Value' (Message-ID: $Param{GetParam}->{'Message-ID'})",
182            );
183        }
184
185        # stop after match
186        if ($StopAfterMatch) {
187            $Self->{CommunicationLogObject}->ObjectLog(
188                ObjectLogType => 'Message',
189                Priority      => 'Notice',
190                Key           => 'Kernel::System::PostMaster::Filter::Match',
191                Value         => $Prefix
192                    . "Stopped filter processing because of used 'StopAfterMatch' (Message-ID: $Param{GetParam}->{'Message-ID'})",
193            );
194            return 1;
195        }
196    }
197    return 1;
198}
199
2001;
201