# --
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
# --
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
# the enclosed file COPYING for license information (GPL). If you
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
# --
package Kernel::System::MailAccount;
use strict;
use warnings;
our @ObjectDependencies = (
'Kernel::Config',
'Kernel::System::DB',
'Kernel::System::Log',
'Kernel::System::Main',
'Kernel::System::Valid',
'Kernel::System::Cache',
);
=head1 NAME
Kernel::System::MailAccount - to manage mail accounts
=head1 DESCRIPTION
All functions to manage the mail accounts.
=head1 PUBLIC INTERFACE
=head2 new()
Don't use the constructor directly, use the ObjectManager instead:
my $MailAccountObject = $Kernel::OM->Get('Kernel::System::MailAccount');
=cut
sub new {
my ( $Type, %Param ) = @_;
# allocate new hash for object
my $Self = {};
bless( $Self, $Type );
$Self->{CacheType} = 'MailAccount';
$Self->{CacheTTL} = 60 * 60 * 24 * 20; # 20 days
return $Self;
}
=head2 MailAccountAdd()
adds a new mail account
$MailAccount->MailAccountAdd(
Login => 'mail',
Password => 'SomePassword',
Host => 'pop3.example.com',
Type => 'POP3',
IMAPFolder => 'Some Folder', # optional, only valid for IMAP-type accounts
ValidID => 1,
Trusted => 0,
DispatchingBy => 'Queue', # Queue|From
QueueID => 12,
UserID => 123,
);
=cut
sub MailAccountAdd {
my ( $Self, %Param ) = @_;
# check needed stuff
for (qw(Login Password Host ValidID Trusted DispatchingBy QueueID UserID)) {
if ( !defined $Param{$_} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "$_ not defined!"
);
return;
}
}
for (qw(Login Password Host Type ValidID UserID)) {
if ( !$Param{$_} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Need $_!"
);
return;
}
}
# check if dispatching is by From
if ( $Param{DispatchingBy} eq 'From' ) {
$Param{QueueID} = 0;
}
elsif ( $Param{DispatchingBy} eq 'Queue' && !$Param{QueueID} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Need QueueID for dispatching!"
);
return;
}
# only set IMAP folder on IMAP type accounts
# fallback to 'INBOX' if none given
if ( $Param{Type} =~ m{ IMAP .* }xmsi ) {
if ( !defined $Param{IMAPFolder} || !$Param{IMAPFolder} ) {
$Param{IMAPFolder} = 'INBOX';
}
}
else {
$Param{IMAPFolder} = '';
}
# get database object
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
# sql
return if !$DBObject->Do(
SQL =>
'INSERT INTO mail_account (login, pw, host, account_type, valid_id, comments, queue_id, '
. ' imap_folder, trusted, create_time, create_by, change_time, change_by)'
. ' VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, current_timestamp, ?, current_timestamp, ?)',
Bind => [
\$Param{Login}, \$Param{Password}, \$Param{Host}, \$Param{Type},
\$Param{ValidID}, \$Param{Comment}, \$Param{QueueID}, \$Param{IMAPFolder},
\$Param{Trusted}, \$Param{UserID}, \$Param{UserID},
],
);
# delete cache
$Kernel::OM->Get('Kernel::System::Cache')->CleanUp(
Type => $Self->{CacheType},
);
return if !$DBObject->Prepare(
SQL => 'SELECT id FROM mail_account WHERE login = ? AND host = ? AND account_type = ?',
Bind => [ \$Param{Login}, \$Param{Host}, \$Param{Type} ],
);
my $ID;
while ( my @Row = $DBObject->FetchrowArray() ) {
$ID = $Row[0];
}
return $ID;
}
=head2 MailAccountGetAll()
returns an array of all mail account data
my @MailAccounts = $MailAccount->MailAccountGetAll();
(returns list of the fields for each account: ID, Login, Password, Host, Type, QueueID, Trusted, IMAPFolder, Comment, DispatchingBy, ValidID)
=cut
sub MailAccountGetAll {
my ( $Self, %Param ) = @_;
# check cache
my $CacheKey = 'MailAccountGetAll';
my $Cache = $Kernel::OM->Get('Kernel::System::Cache')->Get(
Type => $Self->{CacheType},
Key => $CacheKey,
);
return @{$Cache} if $Cache;
# get database object
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
# sql
return if !$DBObject->Prepare(
SQL =>
'SELECT id, login, pw, host, account_type, queue_id, imap_folder, trusted, comments, valid_id, '
. ' create_time, change_time FROM mail_account',
);
my @Accounts;
while ( my @Data = $DBObject->FetchrowArray() ) {
my %Data = (
ID => $Data[0],
Login => $Data[1],
Password => $Data[2],
Host => $Data[3],
Type => $Data[4] || 'POP3', # compat for old setups
QueueID => $Data[5],
IMAPFolder => $Data[6],
Trusted => $Data[7],
Comment => $Data[8],
ValidID => $Data[9],
CreateTime => $Data[10],
ChangeTime => $Data[11],
);
if ( $Data{QueueID} == 0 ) {
$Data{DispatchingBy} = 'From';
}
else {
$Data{DispatchingBy} = 'Queue';
}
# only return IMAP folder on IMAP type accounts
# fallback to 'INBOX' if none given
if ( $Data{Type} =~ m{ IMAP .* }xmsi ) {
if ( defined $Data{IMAPFolder} && !$Data{IMAPFolder} ) {
$Data{IMAPFolder} = 'INBOX';
}
}
else {
$Data{IMAPFolder} = '';
}
push @Accounts, \%Data;
}
# set cache
$Kernel::OM->Get('Kernel::System::Cache')->Set(
Type => $Self->{CacheType},
TTL => $Self->{CacheTTL},
Key => $CacheKey,
Value => \@Accounts,
);
return @Accounts;
}
=head2 MailAccountGet()
returns a hash of mail account data
my %MailAccount = $MailAccount->MailAccountGet(
ID => 123,
);
(returns: ID, Login, Password, Host, Type, QueueID, Trusted, IMAPFolder, Comment, DispatchingBy, ValidID)
=cut
sub MailAccountGet {
my ( $Self, %Param ) = @_;
# check needed stuff
if ( !$Param{ID} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Need ID!"
);
return;
}
# check cache
my $CacheKey = join '::', 'MailAccountGet', 'ID', $Param{ID};
my $Cache = $Kernel::OM->Get('Kernel::System::Cache')->Get(
Type => $Self->{CacheType},
Key => $CacheKey,
);
return %{$Cache} if $Cache;
# get database object
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
# sql
return if !$DBObject->Prepare(
SQL =>
'SELECT login, pw, host, account_type, queue_id, imap_folder, trusted, comments, valid_id, '
. ' create_time, change_time FROM mail_account WHERE id = ?',
Bind => [ \$Param{ID} ],
);
my %Data;
while ( my @Data = $DBObject->FetchrowArray() ) {
%Data = (
ID => $Param{ID},
Login => $Data[0],
Password => $Data[1],
Host => $Data[2],
Type => $Data[3] || 'POP3', # compat for old setups
QueueID => $Data[4],
IMAPFolder => $Data[5],
Trusted => $Data[6],
Comment => $Data[7],
ValidID => $Data[8],
CreateTime => $Data[9],
ChangeTime => $Data[10],
);
}
if ( $Data{QueueID} == 0 ) {
$Data{DispatchingBy} = 'From';
}
else {
$Data{DispatchingBy} = 'Queue';
}
# only return IMAP folder on IMAP type accounts
# fallback to 'INBOX' if none given
if ( $Data{Type} =~ m{ IMAP .* }xmsi ) {
if ( defined $Data{IMAPFolder} && !$Data{IMAPFolder} ) {
$Data{IMAPFolder} = 'INBOX';
}
}
else {
$Data{IMAPFolder} = '';
}
# set cache
$Kernel::OM->Get('Kernel::System::Cache')->Set(
Type => $Self->{CacheType},
TTL => $Self->{CacheTTL},
Key => $CacheKey,
Value => \%Data,
);
return %Data;
}
=head2 MailAccountUpdate()
update a new mail account
$MailAccount->MailAccountUpdate(
ID => 1,
Login => 'mail',
Password => 'SomePassword',
Host => 'pop3.example.com',
Type => 'POP3',
IMAPFolder => 'Some Folder', # optional, only valid for IMAP-type accounts
ValidID => 1,
Trusted => 0,
DispatchingBy => 'Queue', # Queue|From
QueueID => 12,
UserID => 123,
);
=cut
sub MailAccountUpdate {
my ( $Self, %Param ) = @_;
# check needed stuff
for (qw(ID Login Password Host Type ValidID Trusted DispatchingBy QueueID UserID)) {
if ( !defined $Param{$_} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Need $_!"
);
return;
}
}
# check if dispatching is by From
if ( $Param{DispatchingBy} eq 'From' ) {
$Param{QueueID} = 0;
}
elsif ( $Param{DispatchingBy} eq 'Queue' && !$Param{QueueID} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Need QueueID for dispatching!"
);
return;
}
# only set IMAP folder on IMAP type accounts
# fallback to 'INBOX' if none given
if ( $Param{Type} =~ m{ IMAP .* }xmsi ) {
if ( !defined $Param{IMAPFolder} || !$Param{IMAPFolder} ) {
$Param{IMAPFolder} = 'INBOX';
}
}
else {
$Param{IMAPFolder} = '';
}
# sql
return if !$Kernel::OM->Get('Kernel::System::DB')->Do(
SQL => 'UPDATE mail_account SET login = ?, pw = ?, host = ?, account_type = ?, '
. ' comments = ?, imap_folder = ?, trusted = ?, valid_id = ?, change_time = current_timestamp, '
. ' change_by = ?, queue_id = ? WHERE id = ?',
Bind => [
\$Param{Login}, \$Param{Password}, \$Param{Host}, \$Param{Type},
\$Param{Comment}, \$Param{IMAPFolder}, \$Param{Trusted}, \$Param{ValidID},
\$Param{UserID}, \$Param{QueueID}, \$Param{ID},
],
);
# delete cache
$Kernel::OM->Get('Kernel::System::Cache')->CleanUp(
Type => $Self->{CacheType},
);
return 1;
}
=head2 MailAccountDelete()
deletes a mail account
$MailAccount->MailAccountDelete(
ID => 123,
);
=cut
sub MailAccountDelete {
my ( $Self, %Param ) = @_;
# check needed stuff
if ( !$Param{ID} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Need ID!"
);
return;
}
# sql
return if !$Kernel::OM->Get('Kernel::System::DB')->Do(
SQL => 'DELETE FROM mail_account WHERE id = ?',
Bind => [ \$Param{ID} ],
);
# delete cache
$Kernel::OM->Get('Kernel::System::Cache')->CleanUp(
Type => $Self->{CacheType},
);
return 1;
}
=head2 MailAccountList()
returns a list (Key, Name) of all mail accounts
my %List = $MailAccount->MailAccountList(
Valid => 0, # just valid/all accounts
);
=cut
sub MailAccountList {
my ( $Self, %Param ) = @_;
# check cache
my $CacheKey = join '::', 'MailAccountList', ( $Param{Valid} ? 'Valid::1' : '' );
my $Cache = $Kernel::OM->Get('Kernel::System::Cache')->Get(
Type => $Self->{CacheType},
Key => $CacheKey,
);
return %{$Cache} if $Cache;
# get valid object
my $ValidObject = $Kernel::OM->Get('Kernel::System::Valid');
my $Where = $Param{Valid}
? 'WHERE valid_id IN ( ' . join ', ', $ValidObject->ValidIDsGet() . ' )'
: '';
# get database object
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
return if !$DBObject->Prepare(
SQL => "SELECT id, host, login FROM mail_account $Where",
);
my %Data;
while ( my @Row = $DBObject->FetchrowArray() ) {
$Data{ $Row[0] } = "$Row[1] ($Row[2])";
}
# set cache
$Kernel::OM->Get('Kernel::System::Cache')->Set(
Type => $Self->{CacheType},
TTL => $Self->{CacheTTL},
Key => $CacheKey,
Value => \%Data,
);
return %Data;
}
=head2 MailAccountBackendList()
returns a list of usable backends
my %List = $MailAccount->MailAccountBackendList();
=cut
sub MailAccountBackendList {
my ( $Self, %Param ) = @_;
my $Directory = $Kernel::OM->Get('Kernel::Config')->Get('Home') . '/Kernel/System/MailAccount/';
my @List = $Kernel::OM->Get('Kernel::System::Main')->DirectoryRead(
Directory => $Directory,
Filter => '*.pm',
);
my %Backends;
for my $File (@List) {
# remove .pm
$File =~ s/^.*\/(.+?)\.pm$/$1/;
my $GenericModule = "Kernel::System::MailAccount::$File";
# try to load module $GenericModule
if ( eval "require $GenericModule" ) { ## no critic
if ( eval { $GenericModule->new() } ) {
$Backends{$File} = $File;
}
}
}
return %Backends;
}
=head2 MailAccountFetch()
fetch emails by using backend
my $Ok = $MailAccount->MailAccountFetch(
Login => 'mail',
Password => 'SomePassword',
Host => 'pop3.example.com',
Type => 'POP3', # POP3,POP3s,IMAP,IMAPS
Trusted => 0,
DispatchingBy => 'Queue', # Queue|From
QueueID => 12,
UserID => 123,
);
=cut
sub MailAccountFetch {
my ( $Self, %Param ) = @_;
# check needed stuff
for (qw(Login Password Host Type Trusted DispatchingBy QueueID UserID)) {
if ( !defined $Param{$_} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Need $_!"
);
return;
}
}
# load backend
my $GenericModule = "Kernel::System::MailAccount::$Param{Type}";
# try to load module $GenericModule
if ( !$Kernel::OM->Get('Kernel::System::Main')->Require($GenericModule) ) {
return;
}
# fetch mails
my $Backend = $GenericModule->new();
return $Backend->Fetch(%Param);
}
=head2 MailAccountCheck()
Check inbound mail configuration
my %Check = $MailAccount->MailAccountCheck(
Login => 'mail',
Password => 'SomePassword',
Host => 'pop3.example.com',
Type => 'POP3', # POP3|POP3S|IMAP|IMAPS
Timeout => '60',
Debug => '0',
);
=cut
sub MailAccountCheck {
my ( $Self, %Param ) = @_;
# check needed stuff
for (qw(Login Password Host Type Timeout Debug)) {
if ( !defined $Param{$_} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Need $_!"
);
return;
}
}
# load backend
my $GenericModule = "Kernel::System::MailAccount::$Param{Type}";
# try to load module $GenericModule
if ( !$Kernel::OM->Get('Kernel::System::Main')->Require($GenericModule) ) {
return;
}
# check if connect is successful
my $Backend = $GenericModule->new();
my %Check = $Backend->Connect(%Param);
if ( $Check{Successful} ) {
return ( Successful => 1 );
}
else {
return (
Successful => 0,
Message => $Check{Message}
);
}
}
1;
=head1 TERMS AND CONDITIONS
This software is part of the OTRS project (L).
This software comes with ABSOLUTELY NO WARRANTY. For details, see
the enclosed file COPYING for license information (GPL). If you
did not receive this file, see L.
=cut