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::FollowUpArticleVisibilityCheck; 10 11use strict; 12use warnings; 13 14our @ObjectDependencies = ( 15 'Kernel::System::Log', 16 'Kernel::System::CustomerUser', 17 'Kernel::System::Ticket', 18 'Kernel::System::Ticket::Article', 19); 20 21sub new { 22 my ( $Type, %Param ) = @_; 23 24 # allocate new hash for object 25 my $Self = {}; 26 bless( $Self, $Type ); 27 28 # get parser object 29 $Self->{ParserObject} = $Param{ParserObject} || die "Got no ParserObject!"; 30 31 # Get communication log object. 32 $Self->{CommunicationLogObject} = $Param{CommunicationLogObject} || die "Got no CommunicationLogObject!"; 33 34 return $Self; 35} 36 37sub Run { 38 my ( $Self, %Param ) = @_; 39 40 # This filter is not needed if there is no TicketID. 41 return 1 if !$Param{TicketID}; 42 43 # check needed stuff 44 for (qw(JobConfig GetParam UserID)) { 45 if ( !$Param{$_} ) { 46 $Self->{CommunicationLogObject}->ObjectLog( 47 ObjectLogType => 'Message', 48 Priority => 'Error', 49 Key => 'Kernel::System::PostMaster::Filter::FollowUpArticleVisibilityCheck', 50 Value => "Need $_!", 51 ); 52 return; 53 } 54 } 55 56 # Only run if we have a follow-up article with SenderType 'customer'. 57 # It could be that follow-ups have a different SenderType like 'system' for 58 # automatic notifications. In these cases there is no need to hide them. 59 # See also bug#10182 for details. 60 if ( 61 !$Param{GetParam}->{'X-OTRS-FollowUp-SenderType'} 62 || $Param{GetParam}->{'X-OTRS-FollowUp-SenderType'} ne 'customer' 63 ) 64 { 65 return 1; 66 } 67 68 my %Ticket = $Kernel::OM->Get('Kernel::System::Ticket')->TicketGet( 69 TicketID => $Param{TicketID}, 70 UserID => $Param{UserID}, 71 ); 72 73 # Check if it is a known customer, otherwise use email address from CustomerUserID field of the ticket. 74 my %CustomerData = $Kernel::OM->Get('Kernel::System::CustomerUser')->CustomerUserDataGet( 75 User => $Ticket{CustomerUserID}, 76 ); 77 my $CustomerEmailAddress = $CustomerData{UserEmail} || $Ticket{CustomerUserID}; 78 79 # Email sender address 80 my $SenderAddress = $Param{GetParam}->{'X-Sender'}; 81 82 # Email Reply-To address for forwarded emails 83 my $ReplyToAddress; 84 if ( $Param{GetParam}->{ReplyTo} ) { 85 $ReplyToAddress = $Self->{ParserObject}->GetEmailAddress( 86 Email => $Param{GetParam}->{ReplyTo}, 87 ); 88 } 89 90 # check if current sender is customer (do nothing) 91 if ( $CustomerEmailAddress && $SenderAddress ) { 92 return 1 if lc $CustomerEmailAddress eq lc $SenderAddress; 93 } 94 95 my @References = $Self->{ParserObject}->GetReferences(); 96 97 my $ArticleObject = $Kernel::OM->Get('Kernel::System::Ticket::Article'); 98 99 # Get all internal email articles sent by agents. 100 my @MetaArticleIndex = $ArticleObject->ArticleList( 101 TicketID => $Param{TicketID}, 102 CommunicationChannel => 'Email', 103 SenderType => 'agent', 104 IsVisibleForCustomer => 0, 105 ); 106 return 1 if !@MetaArticleIndex; 107 108 my $ArticleBackendObject = $ArticleObject->BackendForChannel( ChannelName => 'Email' ); 109 110 # check if current sender got an internal forward 111 my $IsInternalForward; 112 ARTICLE: 113 for my $MetaArticle ( reverse @MetaArticleIndex ) { 114 115 my $Article = { 116 $ArticleBackendObject->ArticleGet( %{$MetaArticle} ) 117 }; 118 119 # check recipients 120 next ARTICLE if !$Article->{To}; 121 122 # check based on recipient addresses of the article 123 my @ToEmailAddresses = $Self->{ParserObject}->SplitAddressLine( 124 Line => $Article->{To}, 125 ); 126 my @CcEmailAddresses = $Self->{ParserObject}->SplitAddressLine( 127 Line => $Article->{Cc}, 128 ); 129 my @EmailAdresses = ( @ToEmailAddresses, @CcEmailAddresses ); 130 131 EMAIL: 132 for my $Email (@EmailAdresses) { 133 my $Recipient = $Self->{ParserObject}->GetEmailAddress( 134 Email => $Email, 135 ); 136 if ( lc $Recipient eq lc $SenderAddress ) { 137 $IsInternalForward = 1; 138 last ARTICLE; 139 } 140 if ( $ReplyToAddress && lc $Recipient eq lc $ReplyToAddress ) { 141 $IsInternalForward = 1; 142 last ARTICLE; 143 } 144 } 145 146 # check based on Message-ID of the article 147 for my $Reference (@References) { 148 if ( $Article->{MessageID} && $Article->{MessageID} eq $Reference ) { 149 $IsInternalForward = 1; 150 last ARTICLE; 151 } 152 } 153 } 154 155 return 1 if !$IsInternalForward; 156 157 $Param{GetParam}->{'X-OTRS-FollowUp-IsVisibleForCustomer'} = $Param{JobConfig}->{IsVisibleForCustomer} // 0; 158 $Param{GetParam}->{'X-OTRS-FollowUp-SenderType'} = $Param{JobConfig}->{SenderType} || 'customer'; 159 160 return 1; 161} 162 1631; 164