Files
server/usr/share/psa-horde/imp/config/hooks.php.dist
2026-01-07 20:52:11 +01:00

787 lines
27 KiB
Plaintext

<?php
/**
* IMP Hooks configuration file.
*
* THE HOOKS PROVIDED IN THIS FILE ARE EXAMPLES ONLY. DO NOT ENABLE THEM
* BLINDLY IF YOU DO NOT KNOW WHAT YOU ARE DOING. YOU HAVE TO CUSTOMIZE THEM
* TO MATCH YOUR SPECIFIC NEEDS AND SYSTEM ENVIRONMENT.
*
* For more information please see the horde/config/hooks.php.dist file.
*
* $Id: a70eb0b3eb1a2dda4789ff83e249943b05f39816 $
*/
class IMP_Hooks
{
/**
* AUTHENTICATION HOOK: pre-authentication actions.
*
* See horde/config/hooks.php.dist for more information.
*
* IMP uses the following credentials:
* - password: (string) The password for mail server authentication.
* - server: (string) [optional] Use this server key (see
* config/backends.php).
* - transparent: (boolean) If $credentials['authMethod'] is
* 'transparent', and you want IMP to use the
* userId/credentials generated in the preauthenticate
* hook, this must be true. If false, IMP will instead
* try to authenticate using hordeauth.
*
* The following credentials will exist in $credentials, but changing
* these values has no effect on authentication:
* - imp_server_key: (string; 'authenticate' only) The backend server
* key selected on the login page.
*/
// public function preauthenticate($userId, $credentials)
// {
// switch ($credentials['authMethod']) {
// case 'admin':
// return true;
//
// case 'authenticate':
// // Example: Load-balance - pick IMAP server based on first
// // letter in username. Server entries 'server_[a-z]' must
// // be defined in config/backends.local.php.
//
// // $credentials['server'] = 'server_' . substr($userId, 0, 1);
// // return array(
// // 'credentials' => $credentials,
// // 'userId' => $userId
// // );
//
// return true;
//
// case 'transparent':
// // Example: Always login as 'demo' user, with password 'demo'.
//
// // return array(
// // 'credentials' => array(
// // 'password' => 'demo',
// // 'transparent' => true
// // ),
// // 'userId' => 'demo'
// // );
//
// return true;
// }
// }
/**
* AUTHENTICATION HOOK: post-authentication actions.
*
* See horde/config/hooks.php.dist for more information.
* See preauthenticate() above for the list of credentials available.
*/
// public function postauthenticate($userId, $credentials)
// {
// return true;
// }
/**
* PREFERENCE INIT: Set preference values on login.
*
* See horde/config/hooks.php.dist for more information.
*
* MAKE SURE YOU ACTIVATE THE INIT HOOK IN config/prefs.local.php!
*/
// public function prefs_init($pref, $value, $username, $scope_ob)
// {
// switch ($pref) {
// case 'add_source':
// // Dynamically set the add_source preference.
//
// // Example: Useful hook when using a Turba source with shares
// // enabled (i.e. the example localsql configuration).
// return is_null($username)
// ? $value
// : $GLOBALS['registry']->call('contacts/getDefaultShare');
//
//
// case 'search_fields':
// case 'search_sources':
// // Dynamically set the search_fields/search_sources preferences.
//
// // Example #1: Use the list of sources defined in the contacts
// // application (e.g. Turba).
// if (!is_null($username) &&
// $GLOBALS['registry']->hasMethod('contacts/sources')) {
// $sources = $GLOBALS['registry']->call('contacts/sources');
//
// if ($pref == 'search_fields') {
// $out = array();
// foreach (array_keys($sources) as $source) {
// $out[$source] = array();
// foreach ($GLOBALS['registry']->call('contacts/fields', array($source)) as $key => $val){
// if ($val['search']) {
// $out[$source][] = $key;
// }
// }
// }
// } else {
// $out = array_keys($sources);
// }
//
// return json_encode($out);
// }
//
// return $value;
// }
// }
/**
* Perform actions on compose attachments.
*
* @param IMP_Compose_Attachment $atc The attachment object.
*
* @throws IMP_Compose_Exception
*/
public function compose_attachment(IMP_Compose_Attachment $atc)
{
// // Example: Do a virus scan on the attachment, and reject attachment
// // if a virus is found.
// // This example uses the open source ClamAV binary (tested with
// // v0.96). See: http://www.clamav.net/
// $clamscan = '/path/to/clamscan';
// exec($clamscan . ' --quiet ' . escapeshellarg($atc->tmpfile), $output, $return_var);
//
// switch ($return_var) {
// case 1:
// // Virus found.
// throw IMP_Compose_Exception::createAndLog('INFO', 'Virus found in uploaded attachment. Attachment will not be added to the compose message.');
//
// case 2:
// // Error occurred.
// Horde::log('Unknown error when scanning message for virus.', 'INFO');
// break;
// }
}
/**
* Check compose e-mail recipient before sending.
*
* @param Horde_Mail_Rfc822_Address $addr The address object.
*
* @return mixed If an error, an array with the following possible keys:
* - msg: (string) The error text.
* - level: (string; OPTIONAL) Either 'bad' (DEFAULT) or 'warn'.
*/
// public function compose_addr(Horde_Mail_Rfc822_Address $addr)
// {
// // Example #1: Only allow sending to local addresses (the
// // "example.com" domain.
// if ($addr->host != 'example.com') {
// return array(
// 'msg' => 'Can only send to addresses at example.com.',
// 'level' => 'bad'
// );
// }
//
//
// // Example #2: Require valid domain (i.e. disallow bare usernames).
// if (!strlen($addr->host)) {
// return array(
// 'msg' => sprintf('"%s" is missing the domain name.', $addr->mailbox),
// 'level' => 'bad'
// );
// }
// }
/**
* Checks the raw text of the outoging compose message for words that
* might indicate an attachment is present, and issues a warning if no
* attachments are indeed present.
*
* If this hook is not defined, this check is not performed.
*
* This hook is run at most once per message.
*
* @return array A list of words to search for in the body text.
*/
// public function attach_body_check($body)
// {
// /* List of words to search for. */
// return array(
// 'attachment', 'attached'
// );
// }
/**
* Perform an action before a message has been sent.
*
* If an exception is thrown, sending is cancelled and the exception text
* will be shown to the user in an error message.
*
* @param Horde_Mime_Part $message The message content object.
* @param Horde_Mime_Headers $headers The message headers object.
* @param IMP_Compose $compose The compose object.
*
* @throws IMP_Compose_Exception
*/
// public function pre_sent($message, $headers, $compose)
// {
// // Example #1: Add custom headers to outgoing message.
// $custom_hdrs = array();
//
// /* Add information on organization to which the sender belongs.
// * Not standardized for use in e-mail, but generally recognized.
// * See RFC 2076 [3.7]; RFC 1036 [2.2.8] */
// $custom_hdrs['Organization'] = 'Example Corp.';
//
// // Add the IP of the remote browser
// $custom_hdrs['X-Originating-IP'] = $_SERVER['REMOTE_ADDR'];
//
// // Add the Browser information of the remote browser
// $custom_hdrs['X-Remote-Browser'] = $_SERVER['HTTP_USER_AGENT'];
//
// foreach ($custom_hdrs as $key => $val) {
// $headers->addHeader($key, $val);
// }
// }
/**
* Perform an action after a message has been sent successfully.
*
* @param Horde_Mime_Part $message The message content object.
* @param Horde_Mime_Headers $headers The message headers object.
*/
// public function post_sent($message, $headers)
// {
// // Do action here -- no return value from this hook.
// }
/**
* Dynamically create the contents of the message trailer text.
*
* @param boolean $html If true, the trailer text to be
* used in the HTML part. If null is
* returned, the plaintext trailer
* text will be used.
* @param IMP_Prefs_Identity $identity The identity object of the sender.
* @param Horde_Mail_Rfc822_List $to The list of addresses the message
* is being sent to.
*
* @return string The trailer text to be used.
*/
// public function trailer(
// $html,
// IMP_Prefs_Identity $identity,
// Horde_Mail_Rfc822_List $to
// )
// {
// // Example #1: Static trailer text.
// if ($html) {
// return "<hr /><div>This message was sent using IMP.</div>";
// } else {
// return "--------------------------------\n" .
// "This message was sent using IMP.";
// }
//
//
// // Example #2: Set the trailer from the system taglines file,
// // located at "/usr/share/tagline" (generated by the "TaRT" utility;
// // See: http://sourceforge.net/projects/linuxtart/).
// return file_get_contents('/usr/share/tagline');
//
//
// // Example #3: Set the trailer using the LDAP directory (entry
// // 'ispmanDomainSignature').
// $vdomain = Horde_String::lower(preg_replace('|^.*?\.|i', '', getenv('HTTP_HOST')));
// $ldapServer = 'localhost';
// $ldapPort = '389';
// $searchBase = 'ispmanDomain=' . $vdomain . ",o=ispman";
//
// $ds = @ldap_connect($ldapServer, $ldapPort);
// $searchResult = @ldap_search($ds, $searchBase, 'uid=' . $vdomain);
// $information = @ldap_get_entries($ds, $searchResult);
// $trailer = $information[0]['ispmandomainsignature'][0];
// @ldap_close($ds);
//
// return $trailer;
// }
/**
* Add additional message flags in the message listing screen for a
* mailbox.
*
* @param array $data The overview information for a message as returned
* from the IMP_Mailbox_List::getMailboxArray() call
* (see lib/Mailbox/List.php for documentation on the
* structure of the array).
*
* @return array An array of additional flags to add. These flags must be
* defined in the 'msgflags' preference. On error, return
* an empty array.
*/
// public function msglist_flags($data)
// {
// // Example #1: Add a icon if the message was sent from a user within
// // the same domain.
// $flags = array();
//
// if (($from_ob = $data['envelope']->from[0]) &&
// ($from_ob->host == 'example.com')) {
// /* The '$indomain' flag in this example must have already been
// * created in the 'msgflags' preference. */
// $flags = array('$indomain');
// }
//
// return $flags;
// }
/**
* If message content filtering is enabled (see 'filtering' preference),
* this defines the message filtering configuration.
*
* @return array An array with the following keys:
* - replacement: (string) The string filtered words will be replaced
* with.
* - words: (array) The list of words to filter.
*/
public function msg_filter()
{
return array(
'replacement' => '****',
'words' => array(
'poop'
)
);
}
/**
* Alter access permissions for a mailbox.
*
* The better way to accomplish this is to directly manipulate the ACLs
* on the IMAP server (admins can do this via the ACL management page in
* IMP's preferences). However, if ACL is not available on the remote
* server, or mailbox permissions need to be dynamically altered, this
* hook can be used instead.
*
* NOTE: This hook is only called once during a user's session - the
* results of this hook are cached within the session.
*
* @param IMP_Mailbox $mailbox The mailbox.
* @param Horde_Imap_Client_Data_Acl $acl The mailbox ACL.
*/
// public function mbox_acl(IMP_Mailbox $mailbox,
// Horde_Imap_Client_Data_Acl $acl)
// {
// // Example #1: Make the 'Foo' mailbox a "fixed" folder (can't be
// // renamed or deleted).
// if ($mailbox == 'Foo') {
// unset($acl[Horde_Imap_Client::ACL_DELETEMBOX]);
// }
//
//
// // Example #2: Make the 'Bar' mailbox read-only.
// if ($mailbox == 'Bar') {
// unset(
// $acl[Horde_Imap_Client::ACL_DELETEMBOX],
// $acl[Horde_Imap_Client::ACL_DELETEMSGS],
// $acl[Horde_Imap_Client::ACL_EXPUNGE],
// $acl[Horde_Imap_Client::ACL_INSERT],
// $acl[Horde_Imap_Client::ACL_SEEN],
// $acl[Horde_Imap_Client::ACL_WRITE]
// );
// }
// }
/**
* When a mailbox is opened in IMP, allow redirection based on the mailbox
* name.
*
* @param string $mailbox The mailbox which the user has opened.
*
* @return string A valid page within a Horde application which will be
* placed in a "Location" header to redirect the client.
* Return an empty string if the user is not to be
* redirected.
*/
// public function mbox_redirect($mailbox)
// {
// // Example #1: Redirect to various Horde apps based on the mailbox
// // name.
// if ((stripos($mailbox, "INBOX/Calendar") !== false) ||
// preg_match("!^user/[^/]+/Calendar!", $mailbox)) {
// return Horde::url('', false, array('app' => 'kronolith'));
// } elseif ((stripos($mailbox, "INBOX/Tasks") !== false) ||
// preg_match("!^user/[^/]+/Tasks!", $mailbox)) {
// return Horde::url('', false, array('app' => 'nag'));
// } elseif ((strpos($mailbox, "INBOX/Notes") !== false) ||
// preg_match("!^user/[^/]+/Notes!", $mailbox)) {
// return Horde::url('', false, array('app' => 'mnemo'));
// } elseif ((strpos($mailbox, "INBOX/Contacts") !== false) ||
// preg_match("!^user/[^/]+/Contacts!", $mailbox)) {
// return Horde::url('', false, array('app' => 'turba'));
// }
//
// return '';
//
//
// // Example #2: Kolab defaults.
// $type = $GLOBALS['injector']->getInstance('Horde_Kolab_Storage')
// ->getFolder($mailbox)->getType();
// switch ($type) {
// case 'event':
// return Horde::url('', false, array('app' => 'kronolith'));
//
// case 'task':
// return Horde::url('', false, array('app' => 'nag'));
//
// case 'note':
// return Horde::url('', false, array('app' => 'mnemo'));
//
// case 'contact':
// return Horde::url('', false, array('app' => 'turba'));
//
// case 'prefs':
// return $GLOBALS['registry']->getServiceLink('prefs', 'horde');
//
// default:
// return '';
// }
// }
/**
* Allow a custom mailbox icon to be specified for "standard" mailboxes
* ("Standard" means all mailboxes except the INBOX, sent-mail, and
* trash mailboxes.)
*
* @return array A list of mailboxes, with the name as keys and the
* values an array with 'icon' and 'alt' entries.
* If a mailbox name doesn't appear in the list, the
* default mailbox icon is displayed.
*/
// public function mbox_icons()
// {
// // Example #1: Default Kolab redirection scheme
// $types = $GLOBALS['injector']->getInstance('Horde_Kolab_Storage')
// ->getList()->getQuery()->listTypes();
//
// $icons = array();
// foreach ($types as $f => $type) {
// $t = preg_replace('/\.default$/', '', $type);
// switch ($t) {
// case 'event':
// $icons[$f] = array(
// 'alt' => _("Calendar"),
// 'icon' => Horde_Themes::img('kronolith.png', 'kronolith')
// );
// break;
//
// case 'task':
// $icons[$f] = array(
// 'alt' => _("Tasks"),
// 'icon' => Horde_Themes::img('nag.png', 'nag')
// );
// break;
//
// case 'note':
// $icons[$f] = array(
// 'alt' => _("Notes"),
// 'icon' => Horde_Themes::img('mnemo.png', 'mnemo')
// );
// break;
//
// case 'contact':
// $icons[$f] = array(
// 'alt' => _("Contacts"),
// 'icon' => Horde_Themes::img('turba.png', 'turba')
// );
// break;
//
// case 'h-prefs':
// $icons[$f] = array(
// 'alt' => _("Preferences"),
// 'icon' => Horde_Themes::img('prefs.png', 'horde')
// );
// break;
// }
// }
//
// return $icons;
// }
/**
* Dynamically alter a mailbox display label.
*
* @param string $mbox The mailbox name.
* @param string $label The current label.
*
* @return string The display label for $mbox.
*/
// public function mbox_label($mbox, $label)
// {
// // Example #1: Show 'foo' as 'bar'
// return ($mbox == 'foo')
// ? 'bar'
// : $label;
// }
/**
* Override sort preferences for a mailbox.
*
* @param IMP_Prefs_Sort_Sortpref $ob A sortpref object.
*/
// public function mbox_sort($ob)
// {
// // The sortpref object has two properties that can be set - 'sortby'
// // and 'sortdir'. These properties will already contain the default
// // values if there is no specific sort preferences defined for a
// // mailbox (the mailbox can be found in the 'mbox' property).
//
// // Example #1: Assume that the 'sortdir' preference defaults to an
// // ascending sort. However, the sort direction is desired to be
// // descending for date searches (i.e. newest messages first).
// if ($ob->sortdir_default &&
// in_array($ob->sortby, array(Horde_Imap_Client::SORT_SEQUENCE, IMP::IMAP_SORT_DATE))) {
// $ob->sortdir = 1;
// }
// }
/**
* Determine whether to prompt a user to send a Message Disposition
* Notification (MDN; a/k/a read-receipt) if their preferences require
* a prompt. Useful if MDNs should automatically be sent for a certain
* subset of messages, e.g. e-mail addresses within the domain.
*
* @param Horde_Mime_Headers $headers A headers object.
*
* @return boolean Should the user be prompted to send a MDN?
*/
// public function mdn_check($headers)
// {
// // Example #1: Don't require MDN prompt if the message is sent by
// // someone within the same domain (NOTE: this does no checking on
// // spoofed e-mail addresses; further verification should probably
// // be done before automatically sending out a MDN).
// $from = $headers->getOb('from');
// return (strcasecmp($from['host'], 'example.com') !== 0);
// }
/**
* Allow additional information to be added/edited from the data that is
* passed to the mailbox display template:
* basic: imp/templates/basic/mailbox/mailbox.html
* dynamic: imp/templates/dynamic/msglist_[horiz|vert].html
*
* If you are going to add new columns, you also have to update these
* fields:
* basic: imp/lib/Basic/Mailbox.php to specify the column width.
* dynamic: imp/themes/dynamic/screen.css to specify the column width.
*
* @param array $msgs The mailbox data.
*
* @return array The altered array to use in the template.
*/
// public function mailboxarray($msgs)
// {
// // Example #1: Adds a 'foo' entry to each message element.
// switch ($GLOBALS['registry']->getView()) {
// case Horde_Registry::VIEW_BASIC:
// case Horde_Registry::VIEW_DYNAMIC:
// foreach (array_keys($msgs) as $key) {
// $msgs[$key]['foo'] = true;
// }
// break;
// }
//
// return $msg;
// }
/**
* Dynamically disable composing messages.
*
* @return boolean Is composing disabled?
*/
// public function disable_compose()
// {
// // Example #1: Entirely disable composition.
// return false;
// }
/**
* Hide IMAP mailboxes in folder listings.
*
* @param string $mailbox The mailbox name.
*
* @return boolean If false, do not display the mailbox.
*/
// public function display_folder($mailbox)
// {
// // Example #1: Do not display the mailbox 'Foo'.
// return ($mailbox != 'Foo');
//
//
// // Example #2: Kolab default
// $types = $GLOBALS['injector']->getInstance('Horde_Kolab_Storage')
// ->getList()->getQuery()->listTypes();
// return empty($types[$mailbox]) || ($types[$mailbox] == 'mail');
// }
/**
* Perform an action after messages have been reported as spam/innocent.
*
* @param string $action Either 'spam' or 'innocent'.
* @param IMP_Indices $indices The list of indices that have been
* reported as spam/innocent.
*/
// public function post_spam($action, $indices)
// {
// // Example #1: Copy messages to a (not)spam mailbox. This is the
// // full mailbox name.
// $targetMbox = 'foo';
//
// $imp_message = $GLOBALS['injector']->getInstance('IMP_Message');
// $imp_message->copy($targetMbox, 'copy', $indices, array('create' => true));
// }
/**
* Determine quota for a user.
*
* @param array $params Parameters for the function, set in backends.php.
*
* @return array Tuple with two members:
* - first: disk space used (in bytes)
* - second: maximum disk space (in bytes)
*/
// public function quota($params = null)
// {
// // Example #1: Sample function for returning the quota.
// // Uses the PECL ssh2 extension.
// // Requires the 'command' parameter to be defined in backends.php,
// // which defines the quota reporting function to run on the SSH
// // host.
// $imap_ob = $GLOBALS['injector']->getInstance('IMP_Factory_Imap')->create();
// $host = $imap_ob->getParam('hostspec');
// $user = $params['host'];
// $pass = $imap_ob->getParam('password');
// $command = $params['command'];
//
// $session = ssh2_connect($host);
// if (!$session) {
// throw new IMP_Exception(_("Connection to server failed."));
// }
//
// if (!ssh2_auth_password($session, $user, $pass)) {
// throw new IMP_Exception(_("Authentication failed."));
// }
//
// $stream = ssh2_exec($session, $command, false);
// stream_set_blocking($stream, true);
//
// $quota = preg_split('/\s+/', trim(stream_get_contents($stream)), 2);
// return array($quota[1] * 1024, $quota[2] * 1024);
// }
/**
* Retrieves public S/MIME keys of message recipients.
*
* The hook will be called first when searching for the keys, and further
* lookup techniques will only be used if the hook throws an exception or
* returns an empty result.
*
* @param string $address The email address of the recipient.
*
* @return string The base64-encoded public S/MIME key that matches the
* email address.
*/
// public function smime_key($address)
// {
// $ldapServer = 'localhost';
// $ldapPort = 389;
// $searchBase = 'ou=users,dc=example,dc=com';
// $binddn = 'uid=admin,dc=example,dc=com';
// $bindpw = 'secret';
// $attribute = 'simepublickey';
//
// if (!@ldap_connect($ldapServer, $ldapPort)) {
// return;
// }
// if (!@ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3)) {
// return;
// }
// if (!@ldap_bind($ds, $binddn, $bindpw)) {
// return;
// }
//
// $searchResult = @ldap_search($ds, $searchBase, 'mail=' . $address);
// $information = @ldap_get_entries($ds, $searchResult);
// ldap_close($ds);
//
// if ($information === false || $information['count'] == 0) {
// return;
// }
//
// return $information[0][$attribute][0];
// }
/**
* Retrieves public PGP keys of message recipients.
*
* The hook will be called first when searching for the keys, and further
* lookup techniques will only be used if the hook throws an exception or
* returns an empty result.
*
* @param string $address The email address of the recipient.
* @param string $keyid The PGP key id of the recipient.
*
* @return string The base64-encoded public PGP key that matches either
* the email address or the fingerprint.
*/
// public function pgp_key($address, $keyid)
// {
// $ldapServer = 'localhost';
// $ldapPort = 389;
// $searchBase = 'ou=users,dc=example,dc=com';
// $binddn = 'uid=admin,dc=example,dc=com';
// $bindpw = 'secret';
// $attribute = 'pgppublickey';
//
// if (!@ldap_connect($ldapServer, $ldapPort)) {
// return;
// }
// if (!@ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3)) {
// return;
// }
// if (!@ldap_bind($ds, $binddn, $bindpw)) {
// return;
// }
//
// $searchResult = @ldap_search($ds, $searchBase, 'mail=' . $address);
// $information = @ldap_get_entries($ds, $searchResult);
// ldap_close($ds);
//
// if ($information === false || $information['count'] == 0) {
// return;
// }
//
// return $information[0][$attribute][0];
// }
}