diff --git a/config/hooks.php.dist b/config/hooks.php.dist index f0b14f95..292bd623 100644 --- a/config/hooks.php.dist +++ b/config/hooks.php.dist @@ -1,5 +1,4 @@ getInstance('Horde_Ldap'); - // try { - // $result = $ldap->search( - // $GLOBALS['conf']['ldap']['user']['basedn'], - // Horde_Ldap_Filter::create('uid', 'equals', $username), - // array('attributes' => array('mail')) - // ); - // if ($result->count()) { - // $entry = $result->shiftEntry(); - // return $entry->getValue('mail', 'single'); - // } - // } catch (Horde_Ldap_Exception $e) { - // } - // - // return $value; - // - // - // case 'fullname': - // // Examples on how to set the fullname. - // - // // Example #1: Set the fullname from the GECOS information in - // // the passwd file. - // if (is_null($username)) { - // return $value; - // } - // - // $user = $GLOBALS['registry']->getAuth('bare'); - // - // $array = posix_getpwnam($user); - // $gecos_array = explode(',', $array['gecos']); - // return empty($gecos_array) - // ? $user - // : $gecos_array[0]; - // - // - // // Example #2: Set the fullname from LDAP information. - // if (is_null($username)) { - // return $value; - // } - // - // $ldap = $GLOBALS['injector']->getInstance('Horde_Ldap'); - // try { - // $result = $ldap->search( - // $GLOBALS['conf']['ldap']['user']['basedn'], - // Horde_Ldap_Filter::create('uid', 'equals', $username), - // array('attributes' => array('cn', 'cn;lang-es')) - // ); - // if ($result->count()) { - // $entry = $result->shiftEntry(); - // return $entry->getValue('cn;lang-es', 'single') - // ?: $entry->getValue('cn', 'single'); - // } - // } catch (Horde_Ldap_Exception $e) { - // } - // - // return $username; - // } - // } +class Horde_Hooks +{ +// // PREFERENCES INIT: See above for documentation. +// public function prefs_init($pref, $value, $username, $scope_ob) +// { +// switch ($pref) { +// case 'from_addr': +// // Example from_addr init hook. This function assumes that you are +// // using an LDAP server and have it configured in the Horde +// // configuration. +// +// if (is_null($username)) { +// return $value; +// } +// +// $ldap = $GLOBALS['injector']->getInstance('Horde_Ldap'); +// try { +// $result = $ldap->search( +// $GLOBALS['conf']['ldap']['user']['basedn'], +// Horde_Ldap_Filter::create('uid', 'equals', $username), +// array('attributes' => array('mail')) +// ); +// if ($result->count()) { +// $entry = $result->shiftEntry(); +// return $entry->getValue('mail', 'single'); +// } +// } catch (Horde_Ldap_Exception $e) { +// } +// +// return $value; +// +// +// case 'fullname': +// // Examples on how to set the fullname. +// +// // Example #1: Set the fullname from the GECOS information in +// // the passwd file. +// if (is_null($username)) { +// return $value; +// } +// +// $user = $GLOBALS['registry']->getAuth('bare'); +// +// $array = posix_getpwnam($user); +// $gecos_array = explode(',', $array['gecos']); +// return empty($gecos_array) +// ? $user +// : $gecos_array[0]; +// +// +// // Example #2: Set the fullname from LDAP information. +// if (is_null($username)) { +// return $value; +// } +// +// $ldap = $GLOBALS['injector']->getInstance('Horde_Ldap'); +// try { +// $result = $ldap->search( +// $GLOBALS['conf']['ldap']['user']['basedn'], +// Horde_Ldap_Filter::create('uid', 'equals', $username), +// array('attributes' => array('cn', 'cn;lang-es')) +// ); +// if ($result->count()) { +// $entry = $result->shiftEntry(); +// return $entry->getValue('cn;lang-es', 'single') +// ?: $entry->getValue('cn', 'single'); +// } +// } catch (Horde_Ldap_Exception $e) { +// } +// +// return $username; +// } +// } - // // PREFERENCES CHANGE: See above for documentation. - // public function prefs_change($pref) - // { - // switch ($pref) { - // case 'theme': - // $GLOBALS['notification']->push('You changed your theme to ' . $GLOBALS['prefs']->getValue('theme') . '.'); - // break; - // } - // } +// // PREFERENCES CHANGE: See above for documentation. +// public function prefs_change($pref) +// { +// switch ($pref) { +// case 'theme': +// $GLOBALS['notification']->push('You changed your theme to ' . $GLOBALS['prefs']->getValue('theme') . '.'); +// break; +// } +// } - // // PREAUTHENTICATE HOOK: See above for description of format. - // public function preauthenticate($userId, $credentials) - // { - // // Example #1: Make Horde respect the Unix convention of not - // // allowing login when a file named /etc/nologin exist. - // return !file_exists('/etc/nologin'); - // - // - // // Example #2: Block access to Horde if the remote host exists in - // // the DNSBL. It requires the PEAR Net_DNSBL package. - // $dnsbl = new Net_DNSBL(); - // $dnsbl->setBlacklists(array( - // 'sbl-xbl.spamhaus.org', - // 'bl.spamcop.net' - // )); - // return !$dnsbl->isListed($_SERVER['REMOTE_ADDR']); - // - // - // // Example #3: Block access for user 'foo'. - // return ($userId != 'foo'); - // - // - // // Example #4: Create credentials needed by the LDAP Horde_Auth - // // driver for adding/deleting/updating users. - // $entry = array( - // 'dn' => 'uid=' . $userId . ',ou=People,dc=example.com', - // 'cn' => isset($credentials['user_fullname']) ? $credentials['user_fullname'] : $userId, - // 'sn' => $userId, - // 'objectclass' => array( - // 'top', - // 'person', - // 'qmailuser', - // 'CourierMailAccount', - // ), - // 'mailhost' => 'mail.example.com', - // 'mailMessageStore' => '/home/mail/' . $userId, - // 'homeDirectory' => '/home/mail/' . $userId, - // 'mailbox' => '/Maildir', - // 'homeDirectory' => '/Maildir', - // 'uid' => $userId, - // 'accountStatus' => 'active', - // 'mailQuota' => '104857600S', - // 'mail' => $userId, - // 'uidNumber' => 501, - // 'gidNumber' => 501, - // 'deliveryMode' => 'nolocal' - // ); - // - // // Need to check for new users (password) and edited users - // // (user_pass_2) - // if (isset($credentials['password'])) { - // $entry['userPassword'] = '{MD5}' . base64_encode(pack('H*', md5($credentials['password']))); - // } elseif (isset($credentials['user_pass_2'])) { - // $entry['userPassword'] = '{MD5}' . base64_encode(pack('H*', md5($credentials['user_pass_2']))); - // } - // $entry['deliveryMode'] = 'nolocal'; - // - // return array( - // 'userId' => $userId, - // 'credentials' => $entry - // ); - // } +// // PREAUTHENTICATE HOOK: See above for description of format. +// public function preauthenticate($userId, $credentials) +// { +// // Example #1: Make Horde respect the Unix convention of not +// // allowing login when a file named /etc/nologin exist. +// return !file_exists('/etc/nologin'); +// +// +// // Example #2: Block access to Horde if the remote host exists in +// // the DNSBL. It requires the PEAR Net_DNSBL package. +// $dnsbl = new Net_DNSBL(); +// $dnsbl->setBlacklists(array( +// 'sbl-xbl.spamhaus.org', +// 'bl.spamcop.net' +// )); +// return !$dnsbl->isListed($_SERVER['REMOTE_ADDR']); +// +// +// // Example #3: Block access for user 'foo'. +// return ($userId != 'foo'); +// +// +// // Example #4: Create credentials needed by the LDAP Horde_Auth +// // driver for adding/deleting/updating users. +// $entry = array( +// 'dn' => 'uid=' . $userId . ',ou=People,dc=example.com', +// 'cn' => isset($credentials['user_fullname']) ? $credentials['user_fullname'] : $userId, +// 'sn' => $userId, +// 'objectclass' => array( +// 'top', +// 'person', +// 'qmailuser', +// 'CourierMailAccount', +// ), +// 'mailhost' => 'mail.example.com', +// 'mailMessageStore' => '/home/mail/' . $userId, +// 'homeDirectory' => '/home/mail/' . $userId, +// 'mailbox' => '/Maildir', +// 'homeDirectory' => '/Maildir', +// 'uid' => $userId, +// 'accountStatus' => 'active', +// 'mailQuota' => '104857600S', +// 'mail' => $userId, +// 'uidNumber' => 501, +// 'gidNumber' => 501, +// 'deliveryMode' => 'nolocal' +// ); +// +// // Need to check for new users (password) and edited users +// // (user_pass_2) +// if (isset($credentials['password'])) { +// $entry['userPassword'] = '{MD5}' . base64_encode(pack('H*', md5($credentials['password']))); +// } elseif (isset($credentials['user_pass_2'])) { +// $entry['userPassword'] = '{MD5}' . base64_encode(pack('H*', md5($credentials['user_pass_2']))); +// } +// $entry['deliveryMode'] = 'nolocal'; +// +// return array( +// 'userId' => $userId, +// 'credentials' => $entry +// ); +// } - // // POSTAUTHENTICATE HOOK: See above for description of format. - // public function postauthenticate($userId, $credentials) - // { - // // Example #1: Validating the user's right to login to Horde by - // // by consulting group membership in an LDAP directory. That - // // way, if your Horde installation is configured to authenticate - // // against IMP which in turn authenticate via IMAP, it is still - // // possible to limit access to Horde by group membership. The - // // following example had been made with an MS Active Directory in - // // mind. Note that if the LDAP directory is unavailable or some - // // other error occur, authentication will fail. - // $ldapServer = 'ad.example.com'; - // $ldapPort = '389'; - // - // // Note that credential is sent plain-text in this case, so don't - // // use privileged account here or setup SSL (by using port 636 - // // above). - // $binddn = 'cn=WithoutPrivilege,dc=ulaval-dev,dc=ca'; - // $bindpw = 'Remember this is sent in the clear unless SSL is used'; - // $searchBase = 'ou=People,dc=example,dc=com'; - // - // // Attribute to match $userId against in search - // $userAttr = 'sAMAccountName'; - // - // // Group membership attribute, need to be all lowercase - // $groupAttr = 'memberof'; - // - // // Attribute to check for right to use Horde - // $groupdn = 'cn=HordeUser,ou=People,dc=example,dc=com'; - // $ret = false; - // - // $ds = @ldap_connect($ldapServer, $ldapPort); - // - // if (@ldap_bind($ds, $binddn, $bindpw)) { - // $searchResult = @ldap_search($ds, $searchBase, $userAttr . '=' . $userId, array($groupAttr), 0, 1, 5); - // if ($information = @ldap_get_entries($ds, $searchResult)) { - // // Make pattern case-insensitive - // $pattern = '/' . $groupdn . '/i'; - // foreach ($information[0][$groupAttr] as $group) { - // if (preg_match($pattern, $group)) { - // $ret = true; - // break; - // } - // } - // } - // } - // - // ldap_close($ds); - // - // return $ret; - // - // // Example #2: Providing a client certificate <-> horde username - // // store. - // // Normally, the following would be looked up in a persistent storage - // // backend. Note this example also stores a plaintext password to - // // avoid cluttering up the example. DO NOT DO THIS. If your x509 - // // client certificate setup requires that you still pass a password - // // to the IMAP server, the password MUST be stored encrypted. In this - // // example, we store a unique identifier for the certificate to add - // // an additional level of security. It wouldn't be too hard to create - // // a admin UI for managing client certificates and "registering" them - // // to the user. - // $mapping = array('user@example.com' => array( - // 'credentials' => array('password' => 'passw0rd'), 'certificate_id' => '123456')); - // - // if (empty($mapping[$userId]) || $credentials['certificate_id'] != $mapping[$userId]['certificate_id']) { - // return false; - // } - // - // return $mapping[$userId]['credentials']; - // } +// // POSTAUTHENTICATE HOOK: See above for description of format. +// public function postauthenticate($userId, $credentials) +// { +// // Example #1: Validating the user's right to login to Horde by +// // by consulting group membership in an LDAP directory. That +// // way, if your Horde installation is configured to authenticate +// // against IMP which in turn authenticate via IMAP, it is still +// // possible to limit access to Horde by group membership. The +// // following example had been made with an MS Active Directory in +// // mind. Note that if the LDAP directory is unavailable or some +// // other error occur, authentication will fail. +// $ldapServer = 'ad.example.com'; +// $ldapPort = '389'; +// +// // Note that credential is sent plain-text in this case, so don't +// // use privileged account here or setup SSL (by using port 636 +// // above). +// $binddn = 'cn=WithoutPrivilege,dc=ulaval-dev,dc=ca'; +// $bindpw = 'Remember this is sent in the clear unless SSL is used'; +// $searchBase = 'ou=People,dc=example,dc=com'; +// +// // Attribute to match $userId against in search +// $userAttr = 'sAMAccountName'; +// +// // Group membership attribute, need to be all lowercase +// $groupAttr = 'memberof'; +// +// // Attribute to check for right to use Horde +// $groupdn = 'cn=HordeUser,ou=People,dc=example,dc=com'; +// $ret = false; +// +// $ds = @ldap_connect($ldapServer, $ldapPort); +// +// if (@ldap_bind($ds, $binddn, $bindpw)) { +// $searchResult = @ldap_search($ds, $searchBase, $userAttr . '=' . $userId, array($groupAttr), 0, 1, 5); +// if ($information = @ldap_get_entries($ds, $searchResult)) { +// // Make pattern case-insensitive +// $pattern = '/' . $groupdn . '/i'; +// foreach ($information[0][$groupAttr] as $group) { +// if (preg_match($pattern, $group)) { +// $ret = true; +// break; +// } +// } +// } +// } +// +// ldap_close($ds); +// +// return $ret; +// +// // Example #2: Providing a client certificate <-> horde username +// // store. +// // Normally, the following would be looked up in a persistent storage +// // backend. Note this example also stores a plaintext password to +// // avoid cluttering up the example. DO NOT DO THIS. If your x509 +// // client certificate setup requires that you still pass a password +// // to the IMAP server, the password MUST be stored encrypted. In this +// // example, we store a unique identifier for the certificate to add +// // an additional level of security. It wouldn't be too hard to create +// // a admin UI for managing client certificates and "registering" them +// // to the user. +// $mapping = array('user@example.com' => array( +// 'credentials' => array('password' => 'passw0rd'), 'certificate_id' => '123456')); +// +// if (empty($mapping[$userId]) || $credentials['certificate_id'] != $mapping[$userId]['certificate_id']) { +// return false; +// } +// +// return $mapping[$userId]['credentials']; +// } - // // USERNAME HOOK: See above for description of format. - // public function authusername($userId, $toHorde) - // { - // // Example #1: Append the virtual domain to the username. - // // ex. $HTTP_HOST = 'mail.mydomain.com', $userId = 'myname' returns: - // // 'myname@mydomain.com' - // $vdomain = preg_replace('|^mail\.|i', '', getenv('HTTP_HOST')); - // $vdomain = Horde_String::lower($vdomain); - // - // if ($toHorde) { - // return $userId . '@' . $vdomain; - // } - // - // return (substr($userId, -strlen($vdomain)) == $vdomain) - // ? substr($userId, 0, -strlen($vdomain) - 1) - // : $userId; - // - // - // // Example #2: Map the LDAP "uid" back to the LDAP "mail" - // // attribute in case both are allowed user IDs for login. - // if (!$toHorde) { - // return $userId; - // } - // $ldapServer = 'localhost'; - // $ldapPort = '389'; - // $searchBase = 'dc=example,dc=com'; - // $binddn = 'cn=manager,' . $searchBase; - // $bindpw = 'PASSWORD'; - // - // $ds = @ldap_connect($ldapServer, $ldapPort); - // $searchResult = @ldap_search($ds, $searchBase, 'uid=' . $userId); - // $information = @ldap_get_entries($ds, $searchResult); - // if (($information !== false) && ($information['count'] > 0)) { - // $userId = $information[0]['mail'][0]; - // } - // return $userId; - // - // // Example #3: Essentially the same as Example #1, but in the reverse - // // direction. This is used, e.g., when using x509 client certificates - // // that provide the username as an email address and you want Horde - // // logins to be usernames only. - // // ex. $HTTP_HOST = 'mail.mydomain.com', $userId = 'myname' returns: - // // 'myname@mydomain.com' - // $vdomain = preg_replace('|^mail\.|i', '', getenv('HTTP_HOST')); - // $vdomain = Horde_String::lower($vdomain); - // - // if (!$toHorde) { - // return $userId . '@' . $vdomain; - // } else { - // return (substr($userId, -strlen($vdomain)) == $vdomain) - // ? substr($userId, 0, -strlen($vdomain) - 1) - // : $userId; - // } - // } +// // USERNAME HOOK: See above for description of format. +// public function authusername($userId, $toHorde) +// { +// // Example #1: Append the virtual domain to the username. +// // ex. $HTTP_HOST = 'mail.mydomain.com', $userId = 'myname' returns: +// // 'myname@mydomain.com' +// $vdomain = preg_replace('|^mail\.|i', '', getenv('HTTP_HOST')); +// $vdomain = Horde_String::lower($vdomain); +// +// if ($toHorde) { +// return $userId . '@' . $vdomain; +// } +// +// return (substr($userId, -strlen($vdomain)) == $vdomain) +// ? substr($userId, 0, -strlen($vdomain) - 1) +// : $userId; +// +// +// // Example #2: Map the LDAP "uid" back to the LDAP "mail" +// // attribute in case both are allowed user IDs for login. +// if (!$toHorde) { +// return $userId; +// } +// $ldapServer = 'localhost'; +// $ldapPort = '389'; +// $searchBase = 'dc=example,dc=com'; +// $binddn = 'cn=manager,' . $searchBase; +// $bindpw = 'PASSWORD'; +// +// $ds = @ldap_connect($ldapServer, $ldapPort); +// $searchResult = @ldap_search($ds, $searchBase, 'uid=' . $userId); +// $information = @ldap_get_entries($ds, $searchResult); +// if (($information !== false) && ($information['count'] > 0)) { +// $userId = $information[0]['mail'][0]; +// } +// return $userId; +// +// // Example #3: Essentially the same as Example #1, but in the reverse +// // direction. This is used, e.g., when using x509 client certificates +// // that provide the username as an email address and you want Horde +// // logins to be usernames only. +// // ex. $HTTP_HOST = 'mail.mydomain.com', $userId = 'myname' returns: +// // 'myname@mydomain.com' +// $vdomain = preg_replace('|^mail\.|i', '', getenv('HTTP_HOST')); +// $vdomain = Horde_String::lower($vdomain); +// +// if (!$toHorde) { +// return $userId . '@' . $vdomain; +// } else { +// return (substr($userId, -strlen($vdomain)) == $vdomain) +// ? substr($userId, 0, -strlen($vdomain) - 1) +// : $userId; +// } +// } - // // DAV USERNAME HOOK: See above for description of format. - // public function davusername($userId, $toHorde) - // { - // // Example: append realm to user name - // global $registry; - // - // if (!$userId) { - // return $userId; - // } - // - // $server = $registry->mail->server(); - // $realm = $server['hostspec']; - // if ($toHorde) { - // return (substr($userId, -strlen($realm)) == $realm) - // ? substr($userId, 0, -strlen($realm) - 1) - // : $userId; - // } - // - // return Horde_String::lower($userId) . '@' . $realm; - // } - // - // // The following hook examples may pick up the realm information from - // // above: - // // - // // public function pushapp() - // // { - // // if (strpos($_SERVER['REQUEST_URI'], '/rpc') && - // // preg_match('/@([^\/]*)/', $_SERVER['REQUEST_URI'], $m)) { - // // // Parse the domain part from the user name in the URL, and - // // // save it as the realm. - // // putenv('REALM=' . basename($m[1])); - // // } - // // } - // // - // // public function preauthenticate($userId, $credentials) - // // { - // // global $registry; - // // $result = array('userId' => $userId, 'credentials' => $credentials); - // // if ($credentials['authMethod'] == 'authenticate' && - // // strpos($_SERVER['REQUEST_URI'], '/rpc') && - // // ($realm = getenv('REALM'))) { - // // // If this was realm'ed RPC request, pick the correct server - // // // from IMP's backend configuration. - // // $servers = $registry - // // ->loadConfigFile('backends.php', 'servers', 'imp') - // // ->config['servers']; - // // foreach ($servers as $key => $server) { - // // if (empty($server['disabled']) && - // // $server['hostspec'] == $realm) { - // // $result['credentials']['server'] = $key; - // // break; - // // } - // // } - // // } - // // return $result; - // // } +// // DAV USERNAME HOOK: See above for description of format. +// public function davusername($userId, $toHorde) +// { +// // Example: append realm to user name +// global $registry; +// +// if (!$userId) { +// return $userId; +// } +// +// $server = $registry->mail->server(); +// $realm = $server['hostspec']; +// if ($toHorde) { +// return (substr($userId, -strlen($realm)) == $realm) +// ? substr($userId, 0, -strlen($realm) - 1) +// : $userId; +// } +// +// return Horde_String::lower($userId) . '@' . $realm; +// } +// +// // The following hook examples may pick up the realm information from +// // above: +// // +// // public function pushapp() +// // { +// // if (strpos($_SERVER['REQUEST_URI'], '/rpc') && +// // preg_match('/@([^\/]*)/', $_SERVER['REQUEST_URI'], $m)) { +// // // Parse the domain part from the user name in the URL, and +// // // save it as the realm. +// // putenv('REALM=' . basename($m[1])); +// // } +// // } +// // +// // public function preauthenticate($userId, $credentials) +// // { +// // global $registry; +// // $result = array('userId' => $userId, 'credentials' => $credentials); +// // if ($credentials['authMethod'] == 'authenticate' && +// // strpos($_SERVER['REQUEST_URI'], '/rpc') && +// // ($realm = getenv('REALM'))) { +// // // If this was realm'ed RPC request, pick the correct server +// // // from IMP's backend configuration. +// // $servers = $registry +// // ->loadConfigFile('backends.php', 'servers', 'imp') +// // ->config['servers']; +// // foreach ($servers as $key => $server) { +// // if (empty($server['disabled']) && +// // $server['hostspec'] == $realm) { +// // $result['credentials']['server'] = $key; +// // break; +// // } +// // } +// // } +// // return $result; +// // } - // // APPLICATION AUTHENTICATED HOOK: See above for format. - // public function appauthenticated() - // { - // // Code to run when an application is first authenticated - // } +// // APPLICATION AUTHENTICATED HOOK: See above for format. +// public function appauthenticated() +// { +// // Code to run when an application is first authenticated +// } - // // PRE-PUSH HOOK: See above for format. - // public function pushapp() - // { - // // Code to run immediately before the app is switched to horde - // } +// // PRE-PUSH HOOK: See above for format. +// public function pushapp() +// { +// // Code to run immediately before the app is switched to horde +// } - // // POST-PUSH HOOK: See above for format. - // public function pushapp_post() - // { - // // Code to run immediately after the app is successfully switched to - // // horde - // } +// // POST-PUSH HOOK: See above for format. +// public function pushapp_post() +// { +// // Code to run immediately after the app is successfully switched to +// // horde +// } - // // ADD CSS HOOK: See above for description of format. - // public function cssfiles($theme) - // { - // return array( - // '/file/path/to/css' => 'uri/to/css' - // ); - // } +// // ADD CSS HOOK: See above for description of format. +// public function cssfiles($theme) +// { +// return array( +// '/file/path/to/css' => 'uri/to/css' +// ); +// } - /** - * Modify the browser object. - * - * @param Horde_Core_Browser $browser The browser object. - */ - // public function browser_modify($browser) - // { - // // Example #1: Mark all browsers as mobile. Useful if this - // // particular Horde installation is dedicated solely to serving - // // mobile devices. - // $browser->setMobile(true); - // } + /** + * Modify the browser object. + * + * @param Horde_Core_Browser $browser The browser object. + */ +// public function browser_modify($browser) +// { +// // Example #1: Mark all browsers as mobile. Useful if this +// // particular Horde installation is dedicated solely to serving +// // mobile devices. +// $browser->setMobile(true); +// } - /** - * Allow altering or validating data submitted by a user during a signup - * request before any attempts are made to add them to the system. - * - * @param array $info TODO - * - * @return array TODO - */ - // public function signup_preprocess($info) - // { - // $info['user_name'] = Horde_String::lower($info['user_name']); - // return $info; - // } + /** + * Allow altering or validating data submitted by a user during a signup + * request before any attempts are made to add them to the system. + * + * @param array $info TODO + * + * @return array TODO + */ +// public function signup_preprocess($info) +// { +// $info['user_name'] = Horde_String::lower($info['user_name']); +// return $info; +// } - /** - * Callback when a signup is queued for administrative approval. - * - * @param string $userId The username. - * @param array $data TODO - */ - // public function signup_queued($userId, $data) - // { - // // Example #1: Send a notification message to the web server - // // administrator's e-mail address. - // $headers = array( - // 'To' => $_SERVER['SERVER_ADMIN'], - // 'From' => $_SERVER['SERVER_ADMIN'], - // 'Subject' => 'New ' . $GLOBALS['registry']->get('name', 'horde') . ' Signup' - // ); - // - // try { - // $extraFields = $GLOBALS['injector']->getInstance('Horde_Core_Hooks')->callHook('signup_getextra', 'horde'); - // } catch (Horde_Exception $e) {} - // - // $msg = _("A new signup has been received and is awaiting your approval.") . - // "\n\n" . - // $this->_signup_queued_walkdata($extraFields, $data) . - // "\n" . - // sprintf(_("You can approve this signup at %s"), Horde::url('admin/user.php', true, array('append_session' => -1))); - // - // $GLOBALS['injector']->getInstance('Horde_Mail')->send($_SERVER['SERVER_ADMIN'], $headers, $msg); - // } - // - // // Helper function for signup_queued Example #1 - // private function _signup_queued_walkdata($fields, $data) - // { - // $msg = ''; - // foreach ($data as $field => $value) { - // if (in_array($field, array('password', 'url'))) { - // continue; - // } - // - // if (is_array($value)) { - // $msg .= $this->_signup_queued_walkdata($fields, $value); - // } else { - // $field = isset($fields[$field]['label']) - // ? $fields[$field]['label'] - // : $field; - // $msg .= "$field: $value\n"; - // } - // } - // return $msg; - // } + /** + * Callback when a signup is queued for administrative approval. + * + * @param string $userId The username. + * @param array $data TODO + */ +// public function signup_queued($userId, $data) +// { +// // Example #1: Send a notification message to the web server +// // administrator's e-mail address. +// $headers = array( +// 'To' => $_SERVER['SERVER_ADMIN'], +// 'From' => $_SERVER['SERVER_ADMIN'], +// 'Subject' => 'New ' . $GLOBALS['registry']->get('name', 'horde') . ' Signup' +// ); +// +// try { +// $extraFields = $GLOBALS['injector']->getInstance('Horde_Core_Hooks')->callHook('signup_getextra', 'horde'); +// } catch (Horde_Exception $e) {} +// +// $msg = _("A new signup has been received and is awaiting your approval.") . +// "\n\n" . +// $this->_signup_queued_walkdata($extraFields, $data) . +// "\n" . +// sprintf(_("You can approve this signup at %s"), Horde::url('admin/user.php', true, array('append_session' => -1))); +// +// $GLOBALS['injector']->getInstance('Horde_Mail')->send($_SERVER['SERVER_ADMIN'], $headers, $msg); +// } +// +// // Helper function for signup_queued Example #1 +// private function _signup_queued_walkdata($fields, $data) +// { +// $msg = ''; +// foreach ($data as $field => $value) { +// if (in_array($field, array('password', 'url'))) { +// continue; +// } +// +// if (is_array($value)) { +// $msg .= $this->_signup_queued_walkdata($fields, $value); +// } else { +// $field = isset($fields[$field]['label']) +// ? $fields[$field]['label'] +// : $field; +// $msg .= "$field: $value\n"; +// } +// } +// return $msg; +// } - /** - * Provide any extra fields which need to be filled in when a - * non-registered user wishes to sign up. - * - * @return array An array containing the following keys: - * - desc: Any help text attached to the field - * - label: The text that the user will see attached to this field - * - params: Any allowed parameter to Horde_Form field types - * - readonly: (boolean) Whether this editable - * - required: (boolean) Whether this field is mandatory - * - type: Any allowed Horde_Form field type - */ - // public function signup_getextra() - // { - // // Example #1: A hypothetical case where we would want to store - // // extra information about a user into a turba sql address book. All - // // this example does is include the attributes.php file from turba. - // // NOTE: You NEED Turba to be correctly installed before you can use - // // this example. - // return $GLOBALS['registry']->loadConfigFile('attributes.php', 'attributes', 'turba')->config['attributes']; - // } + /** + * Provide any extra fields which need to be filled in when a + * non-registered user wishes to sign up. + * + * @return array An array containing the following keys: + * - desc: Any help text attached to the field + * - label: The text that the user will see attached to this field + * - params: Any allowed parameter to Horde_Form field types + * - readonly: (boolean) Whether this editable + * - required: (boolean) Whether this field is mandatory + * - type: Any allowed Horde_Form field type + */ +// public function signup_getextra() +// { +// // Example #1: A hypothetical case where we would want to store +// // extra information about a user into a turba sql address book. All +// // this example does is include the attributes.php file from turba. +// // NOTE: You NEED Turba to be correctly installed before you can use +// // this example. +// return $GLOBALS['registry']->loadConfigFile('attributes.php', 'attributes', 'turba')->config['attributes']; +// } - /** - * TODO - * - * @param string $userId The username. - * @param array $extra A hash with the extra information requested via - * the signup_getextra hook. - * @param string $password The password. - */ - // public function signup_addextra($userId, $extra, $password) - // { - // // Example #1: Continuation of Example #1 from signup_getextra(). - // // Here we connect to the database using the sql parameters - // // configured in $conf and store the extra fields in turba_objects, - // // using the $userId as the key for the object and values from the - // // $extra array. You could create your own sql syntax or code to - // // store this in whichever backend you require. - // // NOTE: You NEED Turba to be correctly installed before you can use - // // this example. It also assumes you are using an SQL backend. - // $db = $GLOBALS['injector']->getInstance('Horde_Db_Adapter'); - // - // $fields = $values = $markers = array(); - // foreach ($extra as $field => $value) { - // $fields[] = 'object_' . Horde_String::lower($field); - // $markers[] = '?'; - // $values[] = Horde_String::convertCharset($value, 'UTF-8', $db->getCharset()); - // } - // $fields[] = 'object_id'; - // $markers[] = '?'; - // $values[] = $userId; - // - // $query = 'INSERT INTO turba_objects ( owner_id, ' . implode(', ', $fields) . ')'; - // $query .= ' VALUES ( \'admin\', ' . implode(', ', $markers) . ')'; - // $db->insert($query, $values); - // } + /** + * TODO + * + * @param string $userId The username. + * @param array $extra A hash with the extra information requested via + * the signup_getextra hook. + * @param string $password The password. + */ +// public function signup_addextra($userId, $extra, $password) +// { +// // Example #1: Continuation of Example #1 from signup_getextra(). +// // Here we connect to the database using the sql parameters +// // configured in $conf and store the extra fields in turba_objects, +// // using the $userId as the key for the object and values from the +// // $extra array. You could create your own sql syntax or code to +// // store this in whichever backend you require. +// // NOTE: You NEED Turba to be correctly installed before you can use +// // this example. It also assumes you are using an SQL backend. +// $db = $GLOBALS['injector']->getInstance('Horde_Db_Adapter'); +// +// $fields = $values = $markers = array(); +// foreach ($extra as $field => $value) { +// $fields[] = 'object_' . Horde_String::lower($field); +// $markers[] = '?'; +// $values[] = Horde_String::convertCharset($value, 'UTF-8', $db->getCharset()); +// } +// $fields[] = 'object_id'; +// $markers[] = '?'; +// $values[] = $userId; +// +// $query = 'INSERT INTO turba_objects ( owner_id, ' . implode(', ', $fields) . ')'; +// $query .= ' VALUES ( \'admin\', ' . implode(', ', $markers) . ')'; +// $db->insert($query, $values); +// } - /** - * Alter the share list. - * - * @param string $userId TODO - * @param TODO $perm TODO - * @param string $owner TODO - * @param array $share_list TODO - * - * @return array The altered share list. - */ - // public function share_list($userId, $perm, $owner, $share_list) - // { - // return $share_list; - // } + /** + * Alter the share list. + * + * @param string $userId TODO + * @param TODO $perm TODO + * @param string $owner TODO + * @param array $share_list TODO + * + * @return array The altered share list. + */ +// public function share_list($userId, $perm, $owner, $share_list) +// { +// return $share_list; +// } - /** - * Hook called if a user tries to make an action that is under permission - * control that they don't have sufficient permissions for. It can be - * used to show the user a custom message including HTML code (via the - * notification system), or to interrupt the code flow and send the user - * to a different page. - * - * @param string $app Horde application. - * @param string $permission Permission that failed. - */ - // public function perms_denied($app, $permission) - // { - // // Example #1: Provide link to upgrade script in notification - // // message. - // $GLOBALS['notification']->push(sprintf('Permission denied. Click HERE to upgrade %s.', $app, $GLOBALS['registry']->get('name')), 'horde.error', array('content.raw')); - // } + /** + * Hook called if a user tries to make an action that is under permission + * control that they don't have sufficient permissions for. It can be + * used to show the user a custom message including HTML code (via the + * notification system), or to interrupt the code flow and send the user + * to a different page. + * + * @param string $app Horde application. + * @param string $permission Permission that failed. + */ +// public function perms_denied($app, $permission) +// { +// // Example #1: Provide link to upgrade script in notification +// // message. +// $GLOBALS['notification']->push(sprintf('Permission denied. Click HERE to upgrade %s.', $app, $GLOBALS['registry']->get('name')), 'horde.error', array('content.raw')); +// } - /** - * IMSP share init. TODO - * - * @param TODO $share_obj TODO - * @param string $app TODO - */ - // public function share_init($share_obj, $app) - // { - // global $cfgSources, $prefs, $session; - // - // // TODO: Move to turba? - // if (($app == 'turba') && - // (!empty($cfgSources['imsp']['use_shares']))) { - // // Only do this once per session or when this session variable - // // is purposely unset. - // if ($session->get('horde', 'imsp_synched')) { - // return; - // } - // - // $results = Net_IMSP_Utils::synchShares($share_obj, $cfgSources['imsp']); - // if (!$results instanceof PEAR_Error) { - // $session->set('horde', 'imsp_synched') = true; - // - // // Now deal with adding or removing address books from prefs. - // $dirty = false; - // $abooks = $prefs->getValue('addressbooks'); - // $abooks = empty($abooks) - // ? array() - // : explode("\n", $prefs->getValue('addressbooks')); - // - // if (count($results['removed'] > 0)) { - // foreach ($results['removed'] as $sharename) { - // $key = array_search($sharename, $abooks); - // if ($key === true) { - // unset($abooks[$key]); - // $dirty = true; - // } - // } - // } - // - // if (count($results['added']) > 0) { - // foreach ($results['added'] as $sharename) { - // if (array_search($sharename, $abooks) === false) { - // $abooks[] = $sharename; - // $dirty = true; - // } - // } - // } - // - // if ($dirty) { - // $result = $prefs->setValue('addressbooks', implode("\n", $abooks)); - // } - // - // // We have to save the connection info for the imsp server - // // since the share_modify hook will not occur from within - // // turba's context. - // $session->set('horde', 'imsp_config', $cfgSources['imsp']['params']); - // } - // } - // } + /** + * IMSP share init. TODO + * + * @param TODO $share_obj TODO + * @param string $app TODO + */ +// public function share_init($share_obj, $app) +// { +// global $cfgSources, $prefs, $session; +// +// // TODO: Move to turba? +// if (($app == 'turba') && +// (!empty($cfgSources['imsp']['use_shares']))) { +// // Only do this once per session or when this session variable +// // is purposely unset. +// if ($session->get('horde', 'imsp_synched')) { +// return; +// } +// +// $results = Net_IMSP_Utils::synchShares($share_obj, $cfgSources['imsp']); +// if (!$results instanceof PEAR_Error) { +// $session->set('horde', 'imsp_synched') = true; +// +// // Now deal with adding or removing address books from prefs. +// $dirty = false; +// $abooks = $prefs->getValue('addressbooks'); +// $abooks = empty($abooks) +// ? array() +// : explode("\n", $prefs->getValue('addressbooks')); +// +// if (count($results['removed'] > 0)) { +// foreach ($results['removed'] as $sharename) { +// $key = array_search($sharename, $abooks); +// if ($key === true) { +// unset($abooks[$key]); +// $dirty = true; +// } +// } +// } +// +// if (count($results['added']) > 0) { +// foreach ($results['added'] as $sharename) { +// if (array_search($sharename, $abooks) === false) { +// $abooks[] = $sharename; +// $dirty = true; +// } +// } +// } +// +// if ($dirty) { +// $result = $prefs->setValue('addressbooks', implode("\n", $abooks)); +// } +// +// // We have to save the connection info for the imsp server +// // since the share_modify hook will not occur from within +// // turba's context. +// $session->set('horde', 'imsp_config', $cfgSources['imsp']['params']); +// } +// } +// } - /** - * IMSP share modify. TODO - * - * @param TODO $share TODO - */ - // public function share_modify($share) - // { - // global $injector, $session, $share; - // - // $params = unserialize($share->get('params')); - // if (is_array($params) && - // !empty($params['source']) && - // ($params['source'] == 'imsp') && - // ($config = $session->get('horde', 'imsp_config'))) { - // // Ensure we don't try to change ownership. - // $params = @unserialize($share->get('params')); - // $bookName = $params['name']; - // if (strpos($bookName, $share->get('owner')) !== 0) { - // throw new Horde_Exception('Changing ownership of IMSP address books is not supported.'); - // } - // - // // Update the ACLS - // $perms = $share->getPermission(); - // $users = $injector->getInstance('Horde_Perms')->getUserPermissions(); - // foreach ($users as $user => $perm) { - // $acl = Net_IMSP_Utils::permsToACL($perm); - // $result = Net_IMSP_Utils::setACL($config, $bookName, $user, $acl); - // } - // } - // } + /** + * IMSP share modify. TODO + * + * @param TODO $share TODO + */ +// public function share_modify($share) +// { +// global $injector, $session, $share; +// +// $params = unserialize($share->get('params')); +// if (is_array($params) && +// !empty($params['source']) && +// ($params['source'] == 'imsp') && +// ($config = $session->get('horde', 'imsp_config'))) { +// // Ensure we don't try to change ownership. +// $params = @unserialize($share->get('params')); +// $bookName = $params['name']; +// if (strpos($bookName, $share->get('owner')) !== 0) { +// throw new Horde_Exception('Changing ownership of IMSP address books is not supported.'); +// } +// +// // Update the ACLS +// $perms = $share->getPermission(); +// $users = $injector->getInstance('Horde_Perms')->getUserPermissions(); +// foreach ($users as $user => $perm) { +// $acl = Net_IMSP_Utils::permsToACL($perm); +// $result = Net_IMSP_Utils::setACL($config, $bookName, $user, $acl); +// } +// } +// } - /** - * ActiveSync hook for determing a Horde username from an email address. - * - * @param string $email The email address - * - * @return string The username to use to authenticate to Horde with. - */ - // public function activesync_get_autodiscover_username($email) - // { - // return substr($email, 0, strpos($email, '@')); - // } + /** + * ActiveSync hook for determing a Horde username from an email address. + * + * @param string $email The email address + * + * @return string The username to use to authenticate to Horde with. + */ +// public function activesync_get_autodiscover_username($email) +// { +// return substr($email, 0, strpos($email, '@')); +// } - /** - * ActiveSync hook for overriding the XML output. Takes an array of - * autodiscover parameters and returns the raw XML string to send to the - * client. USING THIS HOOK MEANS YOU ARE RESPONSIBLE FOR SENDING CORRECT - * XML TO THE CLIENT. ACTIVESYNC WILL SEND THIS STRING AS-IS. ONLY USE THIS - * IF YOU KNOW WHAT YOU ARE DOING! - * - * @param array $params The array of available Autodiscover parameters. - * - * @return string The XML string. - */ - // public function activesync_autodiscover_xml(array $params) - // { - // } + /** + * ActiveSync hook for overriding the XML output. Takes an array of + * autodiscover parameters and returns the raw XML string to send to the + * client. USING THIS HOOK MEANS YOU ARE RESPONSIBLE FOR SENDING CORRECT + * XML TO THE CLIENT. ACTIVESYNC WILL SEND THIS STRING AS-IS. ONLY USE THIS + * IF YOU KNOW WHAT YOU ARE DOING! + * + * @param array $params The array of available Autodiscover parameters. + * + * @return string The XML string. + */ +// public function activesync_autodiscover_xml(array $params) +// { +// } - /** - * ActiveSync hook for modifying the various Autodiscover values before - * the XML string is build by the ActiveSync server code. Use, e.g., if you - * need to alter the value of the host before sending it to the client. - * - * @param array $params The array of Autodiscover parameters. - * - * @return array The possibly modified array of Autodiscover parameters. - */ - // public function activesync_autodiscover_parameters(array $params) - // { - // return $params; - // } + /** + * ActiveSync hook for modifying the various Autodiscover values before + * the XML string is build by the ActiveSync server code. Use, e.g., if you + * need to alter the value of the host before sending it to the client. + * + * @param array $params The array of Autodiscover parameters. + * + * @return array The possibly modified array of Autodiscover parameters. + */ +// public function activesync_autodiscover_parameters(array $params) +// { +// return $params; +// } - /** - * Activesync hook for providing additional checks before allowing a device - * to be paired with the server for the first time. - * - * @param Horde_ActiveSync_Device $device The device object. - * - * @return boolean|integer True on success (device passed checks) or a - * Horde_ActiveSync_Status:: constant on failure. - */ - // public function activesync_create_device(Horde_ActiveSync_Device $device) - // { - // return true; - // } + /** + * Activesync hook for providing additional checks before allowing a device + * to be paired with the server for the first time. + * + * @param Horde_ActiveSync_Device $device The device object. + * + * @return boolean|integer True on success (device passed checks) or a + * Horde_ActiveSync_Status:: constant on failure. + */ +// public function activesync_create_device(Horde_ActiveSync_Device $device) +// { +// return true; +// } - /** - * ActiveSync hook for providing additional policy checks on a device - * after it has already been paired. Useful for enforcing things like - * only allowing certain user agents to connect. - * - * @param Horde_ActiveSync_Device $device The device object. - * - * @return boolean|integer True on success (device passed checks) or a - * Horde_ActiveSync_Status:: constant on failure. - */ - // public function activesync_device_check(Horde_ActiveSync_Device $device) - // { - // return true; - // } + /** + * ActiveSync hook for providing additional policy checks on a device + * after it has already been paired. Useful for enforcing things like + * only allowing certain user agents to connect. + * + * @param Horde_ActiveSync_Device $device The device object. + * + * @return boolean|integer True on success (device passed checks) or a + * Horde_ActiveSync_Status:: constant on failure. + */ +// public function activesync_device_check(Horde_ActiveSync_Device $device) +// { +// return true; +// } - /** - * Hook for providing custom X509 certificate validation routines. You can - * parse the $cert handle provided and/or use any of the available SSL - * enviroment variables provided in $_SERVER by your webserver to determine - * if the certificate should be honored. - * - * @param mixed $cert The certificate string or handle. - * - * @return boolean True if the certificate is valid. - */ - // public function x509_validate($cert) - // { - // $parsed = openssl_x509_parse($cert); - // return ($parsed['issuer']['CN'] == 'My CA CN'); - // } + /** + * Hook for providing custom X509 certificate validation routines. You can + * parse the $cert handle provided and/or use any of the available SSL + * enviroment variables provided in $_SERVER by your webserver to determine + * if the certificate should be honored. + * + * @param mixed $cert The certificate string or handle. + * + * @return boolean True if the certificate is valid. + */ +// public function x509_validate($cert) +// { +// $parsed = openssl_x509_parse($cert); +// return ($parsed['issuer']['CN'] == 'My CA CN'); +// } - /** - * Hook for modifying the device object prior to request processing. The - * device object is fully populated here, so you have access to all - * properties: - * - id: The device id. - * - policykey: The device's policy key, if provisioned. - * - userAgent: The device's user agent string. - * - multiplex: Bitmask for forced multiplex collections. - * @see Horde_ActiveSync_Device - * - version: The EAS version in use by the device. - * - properties: A hash containing the following key/values (note that not - * all devices provide all values): - * - Horde_ActiveSync_Device::MODEL: => The model name. - * - Horde_ActiveSync_Device::IMEI: => The device's IMEI #. - * - Horde_ActiveSync_Device::NAME: => The device's common - * name. - * - Horde_ActiveSync_Device::OS: => The device's OS. - * - Horde_ActiveSync_Device::OS_LANGUAGE => The language. - * - Horde_ActiveSync_Device::PHONE_NUMBER => The phone number. - * - * @param Horde_ActiveSync_Device $device The device object. - * - * @return Horde_ActiveSync_Device The possibly modified device object. - */ - // public function activesync_device_modify(Horde_ActiveSync_Device $device) - // { - // // EXAMPLES for forcing certain device to force multiplexed - // // collections for collection types they don't support multiple - // // collections for. Note that this doesn't apply to email folders, - // // which are NEVER sent multiplexed. Other device properties can also - // // be set here as needed. Remember these are EXAMPLES and should not - // // be blindly used without understanding what they do. - // // - // // NOTE: The Horde_ActiveSync library already determines this based - // // on some userAgent and version sniffing. You should only - // // perform this here if it doesn't work for you, or you have - // // discovered a device that doesn't fit the logic. - // THESE EXAMPLES ARE NO LONGER NECESSARY since Horde_ActiveSync 2.19.2 - // - // // For android devices that don't advertise the android version we have - // // to manually set the multiplex flag if we want to force any. E.g., - // // the Galaxy Note 3 doesn't support multiple collections. - // // NOTE: You can use any device property you want to determine which - // // device to alter. So E.g., if you wanted only specific devices you could - // // use the IMEI value like $device->properties[Horde_ActiveSync_Device::IMEI] - // switch (strtoupper($device->userAgent)) { - // case 'SAMSUNG-SM-N900V/101.403': - // case 'SAMSUNG-SM-N900V/101.40402': - // // Note 3, Android 4.3 or 4.4 - // $device->multiplex = Horde_ActiveSync_Device::MULTIPLEX_NOTES | - // Horde_ActiveSync_Device::MULTIPLEX_CONTACTS | - // Horde_ActiveSync_Device::MULTIPLEX_CALENDAR | - // Horde_ActiveSync_Device::MULTIPLEX_TASKS; - // // We know it's an Android and can guess at the OS version. - // $device->clientType = 'Android'; - // $device->{Horde_ActiveSync_Device::OS} = '4.4.2'; - // break; - // case 'HLTEVZW/KOT49H': - // case 'MYSID/JLS36I': // Nine on a Verizon Galaxy Nexus flashed with CM. - // // This is from Nine running on a Verizon Note 3. The userAgent will - // // likely be different for different carriers (at least until Nine - // // identifies itself better) so use this section as a template for - // // other carriers if needed. - // $device->multiplex = 0; - // $device->clientType = 'Android'; - // break; - // } - // return $device; - // } + /** + * Hook for modifying the device object prior to request processing. The + * device object is fully populated here, so you have access to all + * properties: + * - id: The device id. + * - policykey: The device's policy key, if provisioned. + * - userAgent: The device's user agent string. + * - multiplex: Bitmask for forced multiplex collections. + * @see Horde_ActiveSync_Device + * - version: The EAS version in use by the device. + * - properties: A hash containing the following key/values (note that not + * all devices provide all values): + * - Horde_ActiveSync_Device::MODEL: => The model name. + * - Horde_ActiveSync_Device::IMEI: => The device's IMEI #. + * - Horde_ActiveSync_Device::NAME: => The device's common + * name. + * - Horde_ActiveSync_Device::OS: => The device's OS. + * - Horde_ActiveSync_Device::OS_LANGUAGE => The language. + * - Horde_ActiveSync_Device::PHONE_NUMBER => The phone number. + * + * @param Horde_ActiveSync_Device $device The device object. + * + * @return Horde_ActiveSync_Device The possibly modified device object. + */ + // public function activesync_device_modify(Horde_ActiveSync_Device $device) + // { + // // EXAMPLES for forcing certain device to force multiplexed + // // collections for collection types they don't support multiple + // // collections for. Note that this doesn't apply to email folders, + // // which are NEVER sent multiplexed. Other device properties can also + // // be set here as needed. Remember these are EXAMPLES and should not + // // be blindly used without understanding what they do. + // // + // // NOTE: The Horde_ActiveSync library already determines this based + // // on some userAgent and version sniffing. You should only + // // perform this here if it doesn't work for you, or you have + // // discovered a device that doesn't fit the logic. + // THESE EXAMPLES ARE NO LONGER NECESSARY since Horde_ActiveSync 2.19.2 + // + // // For android devices that don't advertise the android version we have + // // to manually set the multiplex flag if we want to force any. E.g., + // // the Galaxy Note 3 doesn't support multiple collections. + // // NOTE: You can use any device property you want to determine which + // // device to alter. So E.g., if you wanted only specific devices you could + // // use the IMEI value like $device->properties[Horde_ActiveSync_Device::IMEI] + // switch (strtoupper($device->userAgent)) { + // case 'SAMSUNG-SM-N900V/101.403': + // case 'SAMSUNG-SM-N900V/101.40402': + // // Note 3, Android 4.3 or 4.4 + // $device->multiplex = Horde_ActiveSync_Device::MULTIPLEX_NOTES | + // Horde_ActiveSync_Device::MULTIPLEX_CONTACTS | + // Horde_ActiveSync_Device::MULTIPLEX_CALENDAR | + // Horde_ActiveSync_Device::MULTIPLEX_TASKS; - /** - * Hook for filtering message data before sending from a EAS client. - * - * @param array $params An array of parameters: - * - raw: (Horde_ActiveSync_Rfc822) Raw message sent from the client. - * - imap_msg: (Horde_ActiveSync_Imap_Message) The IMAP message if this - * is a SMART request. - * - parent: (string) The folder that imap_msg is contained in. - * - reply: (boolean) If true, this is a SMART_REPLY. - * - forward: (boolean) If true, this is a SMART_FORWARD - * - * @return mixed boolean|Horde_ActiveSync_Mime - */ - // public function activesync_email_presend(array $params) - // { - // // Example for filtering any attachments for viruses. - // // Tested with clamdscan 0.98.4 (though clamscan would work as well - // // if the daemon is not configured). - // // (requires Horde_ActiveSync >= 2.19.0) - // $mime = new Horde_ActiveSync_Mime($params['raw']->getMimeObject()); - // foreach ($mime->contentTypeMap() as $id => $type) { - // if ($mime->isAttachment($id, $type)) { - // $tmp = Horde::getTempFile(); - // $stream = $mime->getPart($id)->getContents(array('stream' => true)); - // rewind($stream); - // file_put_contents($tmp, $stream); - // $clamscan = '/path/to/clamdscan'; - // exec($clamscan . ' --silent ' . escapeshellarg($tmp), $output, $return_var); - // switch ($return_var) { - // case 1: - // // Virus found. - // // We can throw an exception to prevent the email from being - // // sent altogether, or we can return a Horde_ActiveSync_Mime - // // object with the offending attachment(s) removed. - // //throw new Horde_ActiveSync_Exception_EmailFatalFailure('Virus found. Attachment will not be added to the compose message.'); - // - // $updated = true; - // $part = new Horde_Mime_Part(); - // $part->setType('text/plain'); - // $part->setContents(sprintf( - // _("An attachment named %s was removed by Horde_ActiveSync due to a virus being detected."), - // $mime->getPart($id)->getName(true)) - // ); - // $mime->removePart($id); - // $mime->addPart($part); - // break; - // case 2: - // return false; - // } - // } - // - // return true; - // } + // // We know it's an Android and can guess at the OS version. + // $device->clientType = 'Android'; + // $device->{Horde_ActiveSync_Device::OS} = '4.4.2'; + // break; + // case 'HLTEVZW/KOT49H': + // case 'MYSID/JLS36I': // Nine on a Verizon Galaxy Nexus flashed with CM. + // // This is from Nine running on a Verizon Note 3. The userAgent will + // // likely be different for different carriers (at least until Nine + // // identifies itself better) so use this section as a template for + // // other carriers if needed. + // $device->multiplex = 0; + // $device->clientType = 'Android'; + // break; + // } + // return $device; + // } - /** - * Hook for altering the mailbox list sent to the client. - * - * @param array $mailboxList A hash of mailbox arrays, keyed by mailbox name - * and having the following array keys: - * 'd' => the delimiter - * 'label' => mailbox lable - * 'level' => nesting level - * 'ob' => A Horde_Imap_Client_Mailbox object - * 'subscribed' => boolean indicating subscription status. - * - * @return array An array of mailboxes to send to the client. Structure of - * array is the same as the array passed in. - */ - // public function activesync_mailboxlist(array $mailboxList) - // { - // // Example for filtering out any shared mailboxes. Assumes that - // // shared mailboxes are prefixed with 'shared/' where '/' is the delimter. + /** + * Hook for filtering message data before sending from a EAS client. + * + * @param array $params An array of parameters: + * - raw: (Horde_ActiveSync_Rfc822) Raw message sent from the client. + * - imap_msg: (Horde_ActiveSync_Imap_Message) The IMAP message if this + * is a SMART request. + * - parent: (string) The folder that imap_msg is contained in. + * - reply: (boolean) If true, this is a SMART_REPLY. + * - forward: (boolean) If true, this is a SMART_FORWARD + * + * @return mixed boolean|Horde_ActiveSync_Mime + */ + // public function activesync_email_presend(array $params) + // { + // // Example for filtering any attachments for viruses. + // // Tested with clamdscan 0.98.4 (though clamscan would work as well + // // if the daemon is not configured). + // // (requires Horde_ActiveSync >= 2.19.0) + // $mime = new Horde_ActiveSync_Mime($params['raw']->getMimeObject()); + // foreach ($mime->contentTypeMap() as $id => $type) { + // if ($mime->isAttachment($id, $type)) { + // $tmp = Horde::getTempFile(); + // $stream = $mime->getPart($id)->getContents(array('stream' => true)); + // rewind($stream); + // file_put_contents($tmp, $stream); + // $clamscan = '/path/to/clamdscan'; + // exec($clamscan . ' --silent ' . escapeshellarg($tmp), $output, $return_var); + // switch ($return_var) { + // case 1: + // // Virus found. + // // We can throw an exception to prevent the email from being + // // sent altogether, or we can return a Horde_ActiveSync_Mime + // // object with the offending attachment(s) removed. + // //throw new Horde_ActiveSync_Exception_EmailFatalFailure('Virus found. Attachment will not be added to the compose message.'); + // + // $updated = true; + // $part = new Horde_Mime_Part(); + // $part->setType('text/plain'); + // $part->setContents(sprintf( + // _("An attachment named %s was removed by Horde_ActiveSync due to a virus being detected."), + // $mime->getPart($id)->getName(true)) + // ); + // $mime->removePart($id); + // $mime->addPart($part); + // break; + // case 2: + // return false; + // } + // } + // + // return true; + // } + + /** + * Hook for altering the mailbox list sent to the client. + * + * @param array $mailboxList A hash of mailbox arrays, keyed by mailbox name + * and having the following array keys: + * 'd' => the delimiter + * 'label' => mailbox lable + * 'level' => nesting level + * 'ob' => A Horde_Imap_Client_Mailbox object + * 'subscribed' => boolean indicating subscription status. + * + * @return array An array of mailboxes to send to the client. Structure of + * array is the same as the array passed in. + */ + // public function activesync_mailboxlist(array $mailboxList) + // { + // // Example for filtering out any shared mailboxes. Assumes that + // // shared mailboxes are prefixed with 'shared/' where '/' is the delimter. // $filtered = array(); // foreach ($mailboxList as $key => $mbox) { // if (strpos($mbox['label'], 'shared' . $mbox['d']) === 0) { @@ -1250,37 +1249,36 @@ if (!class_exists('Horde_Hooks')) { // } // return $filtered; - // } + // } - /** - * Hook for altering the provisioning requirement more atomically than can be - * done via the permissions interface. - * - * @param Horde_ActiveSync_Device $device The device object. - * @param string $user The authenticating user. - * - * @return mixed The provisioning constant to enforce for this request. If - * no forced provisioning, -1 is returned. - */ - // public function activesync_provisioning_check(Horde_ActiveSync_Device $device, $user) - // { - // // Simple example for setting the provisioning requirement to force - // // provisioning for Windows 8 Mail, while leaving other situations - // // unchanged. This could easily be extended to provide more detailed - // // checks such as certain username/device combinations etc.. - // if (strpos($device->userAgent, 'WindowsMail/') === 0) { - // return Horde_ActiveSync::PROVISIONING_FORCE; - // } + /** + * Hook for altering the provisioning requirement more atomically than can be + * done via the permissions interface. + * + * @param Horde_ActiveSync_Device $device The device object. + * @param string $user The authenticating user. + * + * @return mixed The provisioning constant to enforce for this request. If + * no forced provisioning, -1 is returned. + */ + // public function activesync_provisioning_check(Horde_ActiveSync_Device $device, $user) + // { + // // Simple example for setting the provisioning requirement to force + // // provisioning for Windows 8 Mail, while leaving other situations + // // unchanged. This could easily be extended to provide more detailed + // // checks such as certain username/device combinations etc.. + // if (strpos($device->userAgent, 'WindowsMail/') === 0) { + // return Horde_ActiveSync::PROVISIONING_FORCE; + // } - // // Example for working around Windows 10 Mail.app broken provisioning - // // support. This allows Mail.app to connect UNPROVISIONED regardless - // // of the provisioning setting of the server. - // if (strpos($device->userAgent, 'MSFT-WIN-3') === 0 && - // strpos($device->properties[Horde_ActiveSync_Device::NAME], 'DESKTOP') === 0) { - // return Horde_ActiveSync::PROVISIONING_NONE; - // } - // return -1; - // } + // // Example for working around Windows 10 Mail.app broken provisioning + // // support. This allows Mail.app to connect UNPROVISIONED regardless + // // of the provisioning setting of the server. + // if (strpos($device->userAgent, 'MSFT-WIN-3') === 0 && + // strpos($device->properties[Horde_ActiveSync_Device::NAME], 'DESKTOP') === 0) { + // return Horde_ActiveSync::PROVISIONING_NONE; + // } + // return -1; + // } - } }