1034 lines
38 KiB
Plaintext
1034 lines
38 KiB
Plaintext
<?php
|
|
/**
|
|
* Horde 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.
|
|
*
|
|
* This file is where you define any hooks, for preferences or general Horde
|
|
* use, that your installation uses. The functions in this file can vastly
|
|
* change how your installation behaves, so make sure to test out any changes
|
|
* here before doing them in a production environment.
|
|
*
|
|
* Errors
|
|
* ======
|
|
* All critical/fatal errors should be reported by throwing a Horde_Exception
|
|
* object.
|
|
*
|
|
*
|
|
* Preferences Hooks
|
|
* =================
|
|
* Two types of preferences hooks are available.
|
|
*
|
|
* Setting value at login
|
|
* ----------------------
|
|
* If the 'hook' parameter is non-empty for a preference (config/prefs.php),
|
|
* the prefs_init hook will be run on login to allow alteration of the value.
|
|
* This hook receives the preference name, preference value, username, and
|
|
* the master scope object (Horde_Prefs_Scope) as parameters and uses the
|
|
* return value from the hook as the new preference value.
|
|
*
|
|
* Username will be null if the user is not authenticated.
|
|
*
|
|
* This hook is ONLY executed on login and preferences are cached during a
|
|
* users' session.
|
|
*
|
|
* NOTE: Because the prefs_init hook is called BEFORE the application is
|
|
* initialized, application data will not be available in this hook.
|
|
* If you want to alter preferences values based on application data,
|
|
* you should use the appauthenticated hook instead.
|
|
*
|
|
* On change
|
|
* ---------
|
|
* A hook named prefs_change will be called after a preference is altered.
|
|
* It is passed the preference name that has changed and does not expect a
|
|
* return value.
|
|
*
|
|
*
|
|
* Authentication Hooks
|
|
* ====================
|
|
* There are two special hooks called during the initial authentication
|
|
* of any Horde application responsible for authentication.
|
|
* These hooks are only called ONCE per session.
|
|
*
|
|
* preauthenticate
|
|
* ---------------
|
|
* This hook is used to dynamically alter the login credentials before
|
|
* authentication occurs.
|
|
*
|
|
* It is only called in Horde applications responsible for authentication.
|
|
*
|
|
* It is only called ONCE per session.
|
|
*
|
|
* If there is no active session, $userId and $credentials will be the values
|
|
* provided by the base Horde authentication driver. ($userId will often
|
|
* be empty in this situation.)
|
|
* For all other apps, $userId and $credentials will be the values of the
|
|
* currently logged on Horde user.
|
|
*
|
|
* Parameters in:
|
|
* $userId (string): User ID to be used for authentication.
|
|
* $credentials (array): The array of credentials to be used for
|
|
* authentication. The key 'authMethod' will contain
|
|
* the authentication event that triggered the hook.
|
|
* Possible values: 'authenticate', 'transparent', or
|
|
* 'admin'.
|
|
*
|
|
* The return value from this hook is as follows:
|
|
* [throw Horde_Auth_Exception] - Fatal error.
|
|
* false (boolean) - Authentication will fail.
|
|
* true (boolean) - Authentication will continue with no alteration of the
|
|
* user ID/credentials.
|
|
* (array) - Replace the credentials with the given key/values. Keys are
|
|
* 'userId' and 'credentials'. Only the keys defined will be
|
|
* altered.
|
|
*
|
|
* postauthenticate
|
|
* ----------------
|
|
* This hook is used to dynamically alter the login credentials after
|
|
* authentication occurs.
|
|
*
|
|
* It is only called in Horde applications responsible for authentication.
|
|
*
|
|
* It is only called ONCE per session.
|
|
*
|
|
* Parameters in:
|
|
* $userId (string): The Horde ID.
|
|
* $credentials (array): The array of credentials used for authentication.
|
|
*
|
|
* The return value from this hook is as follows:
|
|
* [throw Horde_Auth_Exception] - Fatal error.
|
|
* false (boolean) - Authentication will fail.
|
|
* true (boolean) - Authentication succeeds with no alteration of the
|
|
* credentials.
|
|
* (array) - Replace the credentials with the given value.
|
|
*
|
|
* authusername
|
|
* ------------
|
|
* This hook is used to dynamically convert between an authentication username
|
|
* and a Horde username.
|
|
*
|
|
* It is only available in the base Horde application.
|
|
*
|
|
* Parameters in:
|
|
* $userId (string): The username.
|
|
* $toHorde (boolean): If true, convert from authentication ID to Horde ID.
|
|
* Otherwise, do the reverse conversion.
|
|
*
|
|
* The return value from this hook is as follows:
|
|
* [throw Horde_Auth_Exception] - Fatal error.
|
|
* (string) - The converted username.
|
|
*
|
|
* x509_validate
|
|
* -------------
|
|
* This hook is called during initial authentication when using the X509 client
|
|
* certificate authentication driver. It provides a chance for custom logic to
|
|
* validate a certificate.
|
|
*
|
|
* Parameters in:
|
|
* $certificate (certificate handle): A handle to the certificate which can be
|
|
* passed to the openssl_x509 functions.
|
|
*
|
|
* The return value from this hook is as follows:
|
|
* [throw Horde_Auth_Exception] - Fatal error.
|
|
* boolean True if certificate passes our validation rules, otherwise false.
|
|
*
|
|
* Login Hooks
|
|
* ===========
|
|
*
|
|
* appauthenticated
|
|
* ----------------
|
|
* This hook is called after the initial application initialization is
|
|
* complete (the application will have passed authentication at this point).
|
|
*
|
|
* This hook is called for EVERY Horde application.
|
|
*
|
|
* This hook is only called ONCE per session.
|
|
*
|
|
* This hook takes no parameters and expects no return value. An Exception
|
|
* thrown from this hook will cause a fatal error.
|
|
*
|
|
*
|
|
* Application Initialization Hook
|
|
* ===============================
|
|
*
|
|
* pushapp
|
|
* -------
|
|
* This hook is called the first time an application is pushed onto the stack.
|
|
* It is passed no parameters and expects no return value.
|
|
* Any Exception thrown in this hook will cause a fatal error.
|
|
*
|
|
*
|
|
* AJAX Hooks
|
|
* ==========
|
|
* These are hooks that are available in any application that has an AJAX
|
|
* interface configured.
|
|
*
|
|
* ajaxaction_data
|
|
* ---------------
|
|
* This hook is used to alter the data returned from an AJAX action handler.
|
|
*
|
|
* Parameters in:
|
|
* $action (string): The AJAX action.
|
|
* $data (mixed): The AJAX action return data.
|
|
*
|
|
* The return value from this hook is as follows:
|
|
* [mixed] - The (altered) data to use as the AJAX action return data.
|
|
*
|
|
* ajaxaction_handle
|
|
* -----------------
|
|
* This hook is used to add user-defined AJAX action handlers to an
|
|
* application. It is called if no handler for the given action can be found
|
|
* in an application.
|
|
*
|
|
* Parameters in:
|
|
* $ajax (Horde_Core_Ajax_Application): The AJAX interface object for the
|
|
* application.
|
|
* $action (string): The AJAX action.
|
|
*
|
|
* The return value from this hook is as follows:
|
|
* [throw Horde_Exception] - Fatal error.
|
|
* [mixed] - The data to send to the browser (will be JSON encoded).
|
|
*
|
|
*
|
|
* CSS Hooks
|
|
* =========
|
|
*
|
|
* cssfiles
|
|
* --------
|
|
* This hook allows additional CSS stylesheets to be added to the page
|
|
* output.
|
|
*
|
|
* Parameters in:
|
|
* $theme (string): The current theme.
|
|
*
|
|
* The return value from this hook is as follows:
|
|
* [throw Horde_Exception] - Fatal error.
|
|
* [array] - An array of CSS files to add. Keys are the filesystem location,
|
|
* values are the URI location.
|
|
*
|
|
*
|
|
* ActiveSync Hooks
|
|
* ================
|
|
*
|
|
* activesync_autodiscover_parameters
|
|
* ----------------------------------
|
|
* This hook allows 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.
|
|
*
|
|
* Parameters in:
|
|
* $params (array): The array of Autodiscover parameters.
|
|
*
|
|
* The return value from this hook is as follows:
|
|
* [throw Horde_Exception] - Fatal error.
|
|
* [array] - The possibly modified array of Autodiscover parameters.
|
|
*
|
|
* activesync_autodiscover_xml
|
|
* ---------------------------
|
|
* This hook allows for overriding the autodiscovery XML output. 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!
|
|
*
|
|
* Parameters in:
|
|
* $params (array): The array of Autodiscover parameters.
|
|
*
|
|
* The return value from this hook is as follows:
|
|
* [throw Horde_Exception]- Fatal error.
|
|
* [string] The XML string to send directly to the client.
|
|
*
|
|
* activesync_get_autodiscover_username
|
|
* ------------------------------------
|
|
* This hook allows for custom rules to determine the authentication username
|
|
* from the email address provided by the client in an autodiscovery request.
|
|
*
|
|
* Parameters in:
|
|
* $email (string): The email address provided by the client.
|
|
*
|
|
* The return value from this hook is as follows:
|
|
* [throw Horde_Exception] - Fatal error.
|
|
* [string] The username to use for authentication to Horde.
|
|
*
|
|
* activesync_create_device
|
|
* ----------------------
|
|
* This hook allows additional checks to be performed during the first
|
|
* ActiveSync request for a new user/device combination.
|
|
*
|
|
* Parameters in:
|
|
* $device (Horde_ActiveSync_Device): The device object to be created.
|
|
*
|
|
* The return value from this hook is as follows:
|
|
* [throw Horde_Exception] - Fatal error.
|
|
* [boolean] A true value should be returned if the device passed all checks
|
|
* and should be allowed to be paired with the server.
|
|
* [integer] A Horde_ActiveSync_Status:: constant identifying the reason for
|
|
* disallowing the pairing.
|
|
*
|
|
* activesync_device_check
|
|
* -----------------------
|
|
* This hook allows the enforcement of arbitrary device policies like E.g.,
|
|
* not allowing certain user agents to connect, or only allowing certain user
|
|
* agents for certain users etc...
|
|
*
|
|
* Parameters in:
|
|
* $device (Horde_ActiveSync_Device): The device object.
|
|
*
|
|
* The return value from this hook is as follows:
|
|
* [throw Horde_Exception] - Fatal error.
|
|
* [boolean] A true value should be returned if the device passed all checks
|
|
* and should be allowed to be paired with the server.
|
|
* [integer] A Horde_ActiveSync_Status:: constant identifying the reason for
|
|
* disallowing the device.
|
|
*
|
|
* activesync_device_modify
|
|
* ------------------------
|
|
* This hook gives the chance to modify the device object before the request is
|
|
* handled. This can be used, for instance, in forcing certain devices to always
|
|
* use multiplexed collections for certain collection types, while other devices
|
|
* are allowed to use non-multiplexed collections.
|
|
*
|
|
* Parameters in:
|
|
* $device (Horde_ActiveSync_Device): The device object.
|
|
*
|
|
* The return value from this hook is as follows:
|
|
* [throw Horde_Exception] - Fatal error.
|
|
* [Horde_ActiveSync_Device] The possibly modified device object.
|
|
*
|
|
* TODO: groupldap, share_add, share_modify, share_remove
|
|
*
|
|
* $Id: 8b35628f6f8abfc39e8dfa34cacd77b5da13e230 $
|
|
*/
|
|
|
|
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;
|
|
// }
|
|
// }
|
|
|
|
|
|
// // 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'];
|
|
// }
|
|
|
|
|
|
// // 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: Convert username to all lowercase. This might be
|
|
// // necessary if an authentication backend is case insensitive to
|
|
// // take into account that Horde's preference system is case
|
|
// // sensitive.
|
|
// // ex. $userId = 'MyName' returns: 'myname'
|
|
// return $toHorde
|
|
// ? Horde_String::lower($userId)
|
|
// : $userId;
|
|
//
|
|
//
|
|
// // Example #3: 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 #4: 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;
|
|
// }
|
|
// }
|
|
|
|
|
|
// // 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
|
|
// }
|
|
|
|
|
|
// // 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'
|
|
// );
|
|
// }
|
|
|
|
|
|
/**
|
|
* 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;
|
|
// }
|
|
|
|
|
|
/**
|
|
* 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'];
|
|
// }
|
|
|
|
|
|
/**
|
|
* 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;
|
|
// }
|
|
|
|
|
|
/**
|
|
* 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 <a href="http://www.example.com/upgrade.php?app=%s">HERE</a> 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 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 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 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;
|
|
// }
|
|
|
|
|
|
/**
|
|
* 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)
|
|
// {
|
|
// // Example 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.
|
|
// // 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.
|
|
|
|
// // 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 prior to
|
|
// // KitKat so we have to force them all.
|
|
// if (empty($device->multiplex)) {
|
|
// switch (strtolower($device->userAgent)) {
|
|
// case 'SAMSUNG-SM-N900V/101.403':
|
|
// // Note 3, Android 4.3
|
|
// $device->multiplex = Horde_ActiveSync_Device::MULTIPLEX_NOTES |
|
|
// Horde_ActiveSync_Device::MULTIPLEX_CONTACTS |
|
|
// Horde_ActiveSync_Device::MULTIPLEX_CALENDAR |
|
|
// Horde_ActiveSync_Device::MULTIPLEX_TASKS;
|
|
// }
|
|
// }
|
|
|
|
// return $device;
|
|
// }
|
|
|
|
}
|