Allow overwriting values in all mail accounts through an optional file /var/www/mail-overwrites.inc.php

This commit is contained in:
ralf 2022-03-29 19:38:31 +03:00
parent e8635be8c1
commit 22c8d8808f

View File

@ -22,7 +22,7 @@ use Horde_Mail_Transport_Smtphorde;
/** /**
* Mail accounts supports 3 types of accounts: * Mail accounts supports 3 types of accounts:
* *
* a) personal mail accounts either created by admin or user themselfs * a) personal mail accounts either created by admin or user themselves
* b) accounts for multiple users or groups created by admin * b) accounts for multiple users or groups created by admin
* c) configuration to administrate a mail-server * c) configuration to administrate a mail-server
* *
@ -90,7 +90,7 @@ use Horde_Mail_Transport_Smtphorde;
* @property-read int $acc_imap_timeout timeout for imap connection, default 20s * @property-read int $acc_imap_timeout timeout for imap connection, default 20s
* @property-read array $notif_folders folders user wants to be notified about new mails * @property-read array $notif_folders folders user wants to be notified about new mails
* *
* @todo remove comments from protected in __construct and db2data, once we require PHP 5.4 (keeping class contect in closures) * You can overwrite values in all mail accounts by creating a file /var/www/mail-overwrites.inc.php, see method getParamOverwrites.
*/ */
class Account implements \ArrayAccess class Account implements \ArrayAccess
{ {
@ -245,14 +245,11 @@ class Account implements \ArrayAccess
/** /**
* Constructor * Constructor
* *
* Should be protected, but php5.3 does NOT keep class context in closures.
* So 'til we require 5.4, it is public BUT SHOULD NOT BE USED!
*
* @param array $params * @param array $params
* @param int $called_for=null if set access to given user (without smtp credentials!), * @param int $called_for=null if set access to given user (without smtp credentials!),
* default current user AND read username/password from current users session * default current user AND read username/password from current users session
*/ */
/*protected*/ function __construct(array $params, $called_for=null) protected function __construct(array $params, $called_for=null)
{ {
// read credentials from database // read credentials from database
$params += Credentials::read($params['acc_id'], null, $called_for ? array(0, $called_for) : $called_for, $this->on_login); $params += Credentials::read($params['acc_id'], null, $called_for ? array(0, $called_for) : $called_for, $this->on_login);
@ -362,6 +359,40 @@ class Account implements \ArrayAccess
} }
} }
/**
* Get params incl. overwrites from /var/www/mail-overwrites.inc.php:
*
* $overwrites = [
* 'mail.mycompany.com' => [ // overwrites all mail-accounts with acc_imap_host='mail.mycompany.com'
* 'acc_imap_host' => 'other host or IP',
* // further imap, smtp or mail settings to use, instead what's in the DB
* ],
* // other imap-server to overwrite ...
* ];
*
* @return array
*/
function getParamOverwrites()
{
static $overwrites = null;
if (!isset($overwrites))
{
if (file_exists($f='/var/www/mail-overwrites.inc.php'))
{
include($f);
}
else
{
$overwrites = [];
}
}
if (isset($overwrites[$this->acc_imap_host]))
{
return array_merge($this->params, $overwrites[$this->acc_imap_host]);
}
return $this->params;
}
/** /**
* Get new Horde_Imap_Client imap server object * Get new Horde_Imap_Client imap server object
* *
@ -378,8 +409,9 @@ class Account implements \ArrayAccess
if (is_null($func_overload)) $func_overload = extension_loaded('mbstring') ? ini_get('mbstring.func_overload') : 0; if (is_null($func_overload)) $func_overload = extension_loaded('mbstring') ? ini_get('mbstring.func_overload') : 0;
if ($func_overload) throw new Api\Exception\AssertionFailed('Fatal Error: EGroupware requires mbstring.func_overload=0 set in your php.ini!'); if ($func_overload) throw new Api\Exception\AssertionFailed('Fatal Error: EGroupware requires mbstring.func_overload=0 set in your php.ini!');
$class = $this->params['acc_imap_type']; $params = $this->getParamOverwrites();
$this->imapServer = new $class($this->params, $_adminConnection, $_timeout); $class = $params['acc_imap_type'];
$this->imapServer = new $class($params, $_adminConnection, $_timeout);
// if Credentials class told us to run something on successful login, tell it to Imap class // if Credentials class told us to run something on successful login, tell it to Imap class
if ($this->on_login) if ($this->on_login)
@ -429,7 +461,7 @@ class Account implements \ArrayAccess
} }
/** /**
* Factory method to instanciate smtp server object * Factory method to instantiate smtp server object
* *
* @return Smtp * @return Smtp
*/ */
@ -437,12 +469,13 @@ class Account implements \ArrayAccess
{ {
if (!isset($this->smtpServer)) if (!isset($this->smtpServer))
{ {
$class = $this->params['acc_smtp_type']; $params = $this->getParamOverwrites();
$this->smtpServer = new $class($this->params); $class = $params['acc_smtp_type'];
$this->smtpServer = new $class($params);
$this->smtpServer->editForwardingAddress = false; $this->smtpServer->editForwardingAddress = false;
$this->smtpServer->host = $this->params['acc_smtp_host']; $this->smtpServer->host = $params['acc_smtp_host'];
$this->smtpServer->port = $this->params['acc_smtp_port']; $this->smtpServer->port = $params['acc_smtp_port'];
switch($this->params['acc_smtp_ssl']) switch($params['acc_smtp_ssl'])
{ {
case self::SSL_TLS: case self::SSL_TLS:
$this->smtpServer->host = 'tlsv1://'.$this->smtpServer->host; $this->smtpServer->host = 'tlsv1://'.$this->smtpServer->host;
@ -453,11 +486,11 @@ class Account implements \ArrayAccess
case self::SSL_STARTTLS: case self::SSL_STARTTLS:
$this->smtpServer->host = 'tls://'.$this->smtpServer->host; $this->smtpServer->host = 'tls://'.$this->smtpServer->host;
} }
$this->smtpServer->smtpAuth = !empty($this->params['acc_smtp_username']); $this->smtpServer->smtpAuth = !empty($params['acc_smtp_username']);
$this->smtpServer->username = $this->params['acc_smtp_username'] ?? null; $this->smtpServer->username = $params['acc_smtp_username'] ?? null;
$this->smtpServer->password = $this->params['acc_smtp_password'] ?? null; $this->smtpServer->password = $params['acc_smtp_password'] ?? null;
$this->smtpServer->defaultDomain = $this->params['acc_domain']; $this->smtpServer->defaultDomain = $params['acc_domain'];
$this->smtpServer->loginType = $this->params['acc_imap_login_type'] ?? null; $this->smtpServer->loginType = $params['acc_imap_login_type'] ?? null;
} }
return $this->smtpServer; return $this->smtpServer;
} }
@ -471,8 +504,9 @@ class Account implements \ArrayAccess
{ {
if (!isset($this->smtpTransport)) if (!isset($this->smtpTransport))
{ {
$params = $this->getParamOverwrites();
$secure = false; $secure = false;
switch($this->acc_smtp_ssl & ~self::SSL_VERIFY) switch($params['acc_smtp_ssl'] & ~self::SSL_VERIFY)
{ {
case self::SSL_STARTTLS: case self::SSL_STARTTLS:
$secure = 'tls'; // Horde uses 'tls' for STARTTLS, not ssl connection with tls version >= 1 and no sslv2/3 $secure = 'tls'; // Horde uses 'tls' for STARTTLS, not ssl connection with tls version >= 1 and no sslv2/3
@ -488,10 +522,10 @@ class Account implements \ArrayAccess
Api\Preferences::setlocale(LC_MESSAGES); Api\Preferences::setlocale(LC_MESSAGES);
$this->smtpTransport = new Horde_Mail_Transport_Smtphorde(array( $this->smtpTransport = new Horde_Mail_Transport_Smtphorde(array(
'username' => $this->acc_smtp_username, 'username' => $params['acc_smtp_username'],
'password' => $this->acc_smtp_password, 'password' => $params['acc_smtp_password'],
'host' => $this->acc_smtp_host, 'host' => $params['acc_smtp_host'],
'port' => $this->acc_smtp_port, 'port' => $params['acc_smtp_port'],
'secure' => $secure, 'secure' => $secure,
'debug' => self::SMTP_DEBUG_LOG, 'debug' => self::SMTP_DEBUG_LOG,
//'timeout' => self::TIMEOUT, //'timeout' => self::TIMEOUT,
@ -509,7 +543,7 @@ class Account implements \ArrayAccess
* @param boolean $replace_placeholders =false should placeholders like {{n_fn}} be replaced * @param boolean $replace_placeholders =false should placeholders like {{n_fn}} be replaced
* @param string $field ='name' what to return as value: "ident_(realname|org|email|signature)" or default "name"=result from identity_name * @param string $field ='name' what to return as value: "ident_(realname|org|email|signature)" or default "name"=result from identity_name
* @param int $user =null account_id to use if not current user * @param int $user =null account_id to use if not current user
* @return Iterator ident_id => identity_name of identity * @return \Iterator ident_id => identity_name of identity
*/ */
public static function identities($account, $replace_placeholders=true, $field='name', $user=null) public static function identities($account, $replace_placeholders=true, $field='name', $user=null)
{ {
@ -818,7 +852,7 @@ class Account implements \ArrayAccess
* *
* To get $this->params you need to call getUserData before! It is never automatically loaded. * To get $this->params you need to call getUserData before! It is never automatically loaded.
* *
* @param type $name * @param string $name
* @return mixed * @return mixed
*/ */
public function __get($name) public function __get($name)
@ -843,7 +877,7 @@ class Account implements \ArrayAccess
/** /**
* Give read access to protected parameters in $this->params * Give read access to protected parameters in $this->params
* *
* @param type $name * @param string $name
* @return mixed * @return mixed
*/ */
public function __isset($name) public function __isset($name)
@ -984,7 +1018,7 @@ class Account implements \ArrayAccess
* @param int $acc_id * @param int $acc_id
* @param int $called_for =null if set admin access to given user, default current user * @param int $called_for =null if set admin access to given user, default current user
* AND read username/password from current users session, 0: find accounts from all users * AND read username/password from current users session, 0: find accounts from all users
* @return email_account * @return self
* @throws Api\Exception\NotFound if account was not found (or not valid for current user) * @throws Api\Exception\NotFound if account was not found (or not valid for current user)
*/ */
public static function read($acc_id, $called_for=null) public static function read($acc_id, $called_for=null)
@ -1058,7 +1092,7 @@ class Account implements \ArrayAccess
{ {
if (isset($data[$name])) if (isset($data[$name]))
{ {
$data[$name] = self::$db->from_bool($data[$name]); $data[$name] = Api\Db::from_bool($data[$name]);
} }
} }
if (isset($data['account_id']) && !is_array($data['account_id'])) if (isset($data['account_id']) && !is_array($data['account_id']))
@ -1288,7 +1322,7 @@ class Account implements \ArrayAccess
// store notification folders // store notification folders
Notifications::write($data['acc_id'], $data['notify_save_default'] ? 0 : Notifications::write($data['acc_id'], $data['notify_save_default'] ? 0 :
($data['called_for'] ? $data['called_for'] : $GLOBALS['egw_info']['user']['account_id']), ($data['called_for'] ?: $GLOBALS['egw_info']['user']['account_id']),
(array)$data['notify_folders']); (array)$data['notify_folders']);
// store domain of an account for all user like before as "mail_suffix" config // store domain of an account for all user like before as "mail_suffix" config
@ -1351,9 +1385,9 @@ class Account implements \ArrayAccess
self::$db->delete(self::TABLE, array('acc_id' => $acc_id), __LINE__, __FILE__, self::APP); self::$db->delete(self::TABLE, array('acc_id' => $acc_id), __LINE__, __FILE__, self::APP);
// invalidate caches // invalidate caches
foreach((array)$acc_id as $acc_id) foreach((array)$acc_id as $id)
{ {
self::cache_invalidate($acc_id); self::cache_invalidate($id);
} }
return self::$db->affected_rows(); return self::$db->affected_rows();
} }
@ -1392,7 +1426,7 @@ class Account implements \ArrayAccess
* @param int|boolean $offset =false offset or false to return all * @param int|boolean $offset =false offset or false to return all
* @param int $num_rows =0 number of rows to return, 0=default from prefs (if $offset !== false) * @param int $num_rows =0 number of rows to return, 0=default from prefs (if $offset !== false)
* @param boolean $replace_placeholders =true should placeholders like {{n_fn}} be replaced * @param boolean $replace_placeholders =true should placeholders like {{n_fn}} be replaced
* @return Iterator with acc_id => acc_name or Account objects * @return \Iterator with acc_id => acc_name or Account objects
*/ */
public static function search($only_current_user=true, $just_name=true, $order_by=null, $offset=false, $num_rows=0, $replace_placeholders=true) public static function search($only_current_user=true, $just_name=true, $order_by=null, $offset=false, $num_rows=0, $replace_placeholders=true)
{ {
@ -1484,7 +1518,7 @@ class Account implements \ArrayAccess
{ {
return $just_name == 'params' ? $row : $row[$just_name]; return $just_name == 'params' ? $row : $row[$just_name];
} }
elseif ($just_name) if ($just_name)
{ {
return self::identity_name($row, false, $account_id); return self::identity_name($row, false, $account_id);
} }
@ -1503,7 +1537,7 @@ class Account implements \ArrayAccess
* @param boolean $smtp =false false: usable for IMAP, true: usable for SMTP * @param boolean $smtp =false false: usable for IMAP, true: usable for SMTP
* @param boolean $return_id =false true: return acc_id, false return account object * @param boolean $return_id =false true: return acc_id, false return account object
* @param boolean $log_no_default =true true: error_log if no default found, false be silent * @param boolean $log_no_default =true true: error_log if no default found, false be silent
* @return Account|null * @return Account|int|null
*/ */
static function get_default($smtp=false, $return_id=false, $log_no_default=true) static function get_default($smtp=false, $return_id=false, $log_no_default=true)
{ {
@ -1677,7 +1711,7 @@ class Account implements \ArrayAccess
/** /**
* Get memberships of current or given user incl. our 0=Everyone * Get memberships of current or given user incl. our 0=Everyone
* *
* @param type $user * @param int $user=null
* @return array * @return array
*/ */
protected static function memberships($user=null) protected static function memberships($user=null)
@ -1686,7 +1720,7 @@ class Account implements \ArrayAccess
$memberships = $GLOBALS['egw']->accounts->memberships($user, true); $memberships = $GLOBALS['egw']->accounts->memberships($user, true);
$memberships[] = $user; $memberships[] = $user;
$memberships[] = 0; // marks accounts valid for everyone $memberships[] = 0; // marks account valid for everyone
return $memberships; return $memberships;
} }