--- /dev/null
+<?php
+/* CONFIG START. DO NOT CHANGE ANYTHING IN OR AFTER THIS LINE. */
+// $Horde: horde/config/conf.xml,v 1.74.2.5 2005/03/22 11:40:14 jan Exp $
+$conf['storage']['admins'] = array('andrew.klang@v-office.biz');
+$conf['storage']['params']['hostspec'] = 'localhost';
+$conf['storage']['params']['basedn'] = 'dc=alkaloid,dc=net';
+$conf['storage']['params']['binddn'] = 'uid=Horde,ou=Service Accounts,dc=alkaloid,dc=net';
+$conf['storage']['params']['password'] = 'InsaneMasses';
+$conf['storage']['params']['version'] = '3';
+$conf['storage']['params']['uid'] = 'mail';
+$conf['storage']['params']['objectclass'] = array('hordePerson');
+$conf['storage']['params']['filter_type'] = 'objectclass';
+$conf['storage']['driver'] = 'ldap';
+/* CONFIG END. DO NOT CHANGE ANYTHING IN OR BEFORE THIS LINE. */
--- /dev/null
+<?xml version="1.0"?>
+<!-- $Horde: horde/config/conf.xml,v 1.74.2.5 2005/03/22 11:40:14 jan Exp $ -->
+<configuration>
+<!-- <configtab name="storage" desc="Storage Backend"> -->
+ <configsection name="auth">
+ <configheader>Shout Storage</configheader>
+ <configlist name="admins" desc="Which users should be treated as
+ super-administrators (root, super-user) by Shout?"/>
+ <configswitch name="driver" desc="What backend should we use for
+ authenticating users to Horde?">
+
+ <case name="ldap" desc="LDAP authentication">
+ <configsection name="params">
+ <configstring name="hostspec" desc="The hostname of the LDAP
+ server">localhost</configstring>
+ <configstring name="basedn" desc="The base DN for the LDAP server"/>
+ <configstring name="binddn" required="false" desc="The DN used to
+ bind to the LDAP server"/>
+ <configstring name="password" required="false" desc="The password
+ used to bind to the LDAP server"/>
+ <configenum name="version" desc="LDAP Protocol Version">3
+ <values>
+ <value desc="LDAPv2 (Deprecated)">2</value>
+ <value desc="LDAPv3">3</value>
+ </values>
+ </configenum>
+ <configstring name="uid" desc="The username search key"/>
+ <configswitch name="filter_type" desc="How to specify a filter for
+ the user lists">objectclass
+ <case name="objectclass" desc="One or more objectclass filters">
+ <configlist name="objectclass" desc="The objectclass filter used
+ to search for users. Can be a single objectclass or a list."/>
+ </case>
+ <case name="free" desc="A complete LDAP filter expression">
+ <configstring name="filter" desc="The LDAP RFC formatted filter
+ used to search for users."/>
+ </case>
+ </configswitch>
+ </configsection>
+ </case>
+ </configswitch>
+ </configsection>
+<!-- </configtab> -->
+</configuration>
+
--- /dev/null
+<?php
+if (!defined(SHOUT_BASE)) {
+ define(SHOUT_BASE, dirname($_SELF['PHP_SELF']));
+}
+
+require_once SHOUT_BASE . "/lib/base.php";
+
+# instantiate driver
+
+# Get list of available contexts from the driver
+$contexts = $shout->getContexts();
+if (is_a($contexts, 'PEAR_Error')) {
+ $notification->push(_("Internal error viewing requested page"),
+ 'horde.error');
+}
+# Print the contexts
+foreach($contexts as $context) {
+ print "$context<br>\n";
+}
\ No newline at end of file
--- /dev/null
+<?php
+/**
+ * $Horde: shout/index.php,v 0.1 2005/06/28 10:35:46 ben Exp $
+ *
+ * Copyright 2005 Ben Klang <ben@alkaloid.net>
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ */
+
+define('SHOUT_BASE', dirname(__FILE__));
+$shout_configured = (@is_readable(SHOUT_BASE . '/config/conf.php') &&
+ @is_readable(SHOUT_BASE . '/config/prefs.php'));
+
+// if (!$shout_configured) {
+// require SHOUT_BASE . '/../lib/Test.php';
+// Horde_Test::configFilesMissing('Shout', SHOUT_BASE,
+// array('conf.php', 'prefs.php'));
+// }
+
+require SHOUT_BASE . '/contexts.php';
\ No newline at end of file
--- /dev/null
+<?php
+/**
+ * Shout_Driver:: defines an API for implementing storage backends for Shout.
+ *
+ * $Horde: shout/lib/Driver.php,v 0.01 2005/06/28 11:15:03 ben Exp $
+ *
+ * Copyright 2005 Ben Klang <ben@alkaloid.net>
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author Ben Klang <ben@alkaloid.net>
+ * @version $Revision$
+ * @since Shout 0.1
+ * @package Shout
+ */
+
+// {{{ Shout_Driver class
+class Shout_Driver {
+
+ // {{{ Class local variables
+ /**
+ * Hash containing connection parameters.
+ *
+ * @var array $_params
+ */
+ var $_params = array();
+ // }}}
+
+ // {{{ Shout_Driver constructor
+ function Shout_Driver($params = array())
+ {
+ $this->_params = $params;
+ }
+ // }}}
+
+ // {{{ getContexts method
+ /**
+ * Get a list of contexts from the backend and filter for which contexts
+ * the current user can read/write
+ *
+ * @return array Contexts valid for this user
+ *
+ * @access public
+ */
+ function getContexts()
+ {
+ return PEAR::raiseError(_("Not implemented."));
+ }
+ // }}}
+
+ // {{{ factory method
+ /**
+ * Attempts to return a concrete Shout_Driver instance based on
+ * $driver.
+ *
+ * @param string $driver The type of the concrete Shout_Driver subclass
+ * to return. The class name is based on the storage
+ * driver ($driver). The code is dynamically
+ * included.
+ *
+ * @param array $params (optional) A hash containing any additional
+ * configuration or connection parameters a
+ * subclass might need.
+ *
+ * @return mixed The newly created concrete Shout_Driver instance, or
+ * false on an error.
+ */
+ function &factory($driver = null, $params = null)
+ {
+ if (is_null($driver)) {
+ $driver = $GLOBALS['conf']['storage']['driver'];
+ }
+
+ $driver = basename($driver);
+
+ if (is_null($params)) {
+ $params = Horde::getDriverConfig('storage', $driver);
+ }
+
+ require_once dirname(__FILE__) . '/Driver/' . $driver . '.php';
+ $class = 'Shout_Driver_' . $driver;
+ if (class_exists($class)) {
+ return $shout = &new $class($params);
+ } else {
+ return false;
+ }
+ }
+ // }}}
+
+ // {{{ singleton method
+ /**
+ * Attempts to return a reference to a concrete Shout_Driver
+ * instance based on $driver. It will only create a new instance
+ * if no Shout_Driver instance with the same parameters currently
+ * exists.
+ *
+ * This method must be invoked as: $var = &Shout_Driver::singleton()
+ *
+ * @param string $driver The type of concrete Shout_Driver subclass
+ * to return. The is based on the storage
+ * driver ($driver). The code is dynamically
+ * included.
+ * @param array $params (optional) A hash containing any additional
+ * configuration or connection parameters a
+ * subclass might need.
+ *
+ * @return mixed The created concrete Shout_Driver instance, or false
+ * on error.
+ */
+ function &singleton($driver = null, $params = null)
+ {
+ static $instances;
+
+ if (is_null($driver)) {
+ $driver = $GLOBALS['conf']['storage']['driver'];
+ }
+
+ if (is_null($params)) {
+ $params = Horde::getDriverConfig('storage', $driver);
+ }
+
+ if (!isset($instances)) {
+ $instances = array();
+ }
+
+ $signature = serialize(array($driver, $params));
+ if (!isset($instances[$signature])) {
+ $instances[$signature] = &Shout_Driver::factory($driver, $params);
+ }
+
+ return $instances[$signature];
+ }
+}
+// }}}
\ No newline at end of file
--- /dev/null
+<?php
+
+// {{{ Shout_Driver_ldap class
+class Shout_Driver_ldap extends Shout_Driver
+{
+
+ // {{{ Class local variables
+ /**
+ * Handle for the current database connection.
+ * @var object LDAP $_LDAP
+ */
+ var $_LDAP;
+
+ /**
+ * Boolean indicating whether or not we're connected to the LDAP
+ * server.
+ * @var boolean $_connected
+ */
+ var $_connected = false;
+ // }}}
+
+ // {{{ Shout_Driver_ldap constructor
+ /**
+ * Constructs a new Shout LDAP driver object.
+ *
+ * @param array $params A hash containing connection parameters.
+ */
+ function Shout_Driver_ldap($params = array())
+ {
+ parent::Shout_Driver($params);
+ $this->_connect();
+ }
+ // }}}
+
+ // {{{ getContexts method
+ /**
+ * Get a list of contexts from the backend and filter for which contexts
+ * the current user can read/write
+ *
+ * @return array Contexts valid for this user
+ *
+ * @access public
+ */
+ function getContexts()
+ {
+ # Collect all the possible contexts from the backend
+ $res = ldap_search($this->_LDAP,
+ SHOUT_ASTERISK_BRANCH.','.$this->_params['basedn'],
+ '(&(objectClass=asteriskObject)(objectClass=vofficeCustomer))',
+ array('context'));
+ if (!$res) {
+ return PEAR::raiseError("Unable to locate any customers " .
+ "underneath ".SHOUT_ASTERISK_BRANCH.",".$this->_params['basedn']) .
+ "matching those search filters";
+ }
+ # Get the list of valid contexts for this user
+ # Possibly create the idea of an Asterisk Global Admin in the
+ # permissions system where an arbitrary user has permissions in all
+ # contexts
+
+
+ $entries = array();
+ $res = ldap_get_entries($this->_LDAP, $res);
+ $i = 0;
+ while ($i < $res['count']) {
+ $entries[] = $res[$i]['context'][0];
+ $i++;
+ }
+ # return the array
+ return $entries;
+ }
+ // }}}
+
+
+
+ // {{{
+ function getUserPhoneNumbers($username, $context = null)
+ {
+ $userfilter = "(".$this->userkey."=".$username.",".
+ $this->usersOU.",".$this->_params['basedn'].")";
+ $searchfilter = "(&".$userfilter;
+ foreach ($prefs["searchfilters"]["phoneuser"] as $filter) {
+ $searchfilter .= "($filter)";
+ }
+ $searchfilter .= ")";
+
+ $res = ldap_search($this->_LDAP, $this->_params['basedn'],
+$searchfilter,
+ array("userNumber"));
+ if (!res) {
+ return PEAR::raiseError("Unable to locate any LDAP entries for
+$searchfilter under ".$this->_params['basedn']);
+ }
+ // FIXME
+ }
+
+ // {{{ getUserVoicemailInfo method
+ /**
+ * Get the named user's voicemail particulars from LDAP
+ *
+ * @param string $extension Extension for which voicemail information should
+ * be returned
+ * @param optional string $context Context to which this extension belongs
+ *
+ * @return array Array containing voicemail options, user's name, email
+ * and pager addresses and PIN number
+ *
+ * @access public
+ */
+ function getUserVoicemailInfo($extension, $context = null)
+ {
+ $userfilter = "(&(objectClass=asteriskVoiceMailbox)(context=$context))";
+ $res = ldap_search($this->_LDAP, $this->_params['basedn'],
+$userfilter,
+ array('asteriskVoiceMailboxOptions', 'mail', 'asteriskPager',
+ 'voiceMailboxPin', 'cn'));
+ return $res;
+ }
+ // }}}
+
+ // {{{ _connect method
+ /**
+ * Attempts to open a connection to the LDAP server.
+ *
+ * @return boolean True on success; exits (Horde::fatal()) on error.
+ *
+ * @access private
+ */
+ function _connect()
+ {
+ if (!$this->_connected) {
+ # FIXME What else is needed for this assert?
+ Horde::assertDriverConfig($this->_params, 'storage',
+ array('hostspec', 'basedn', 'binddn', 'password'));
+
+ # FIXME Add other sane defaults here (mostly objectClass related)
+ if (!isset($this->_params['userObjectclass'])) {
+ $this->_params['userObjectclass'] = 'asteriskUser';
+ }
+
+ $this->_LDAP = ldap_connect($this->_params['hostspec'], 389); #FIXME
+ if (!$this->_LDAP) {
+ Horde::fatal("Unable to connect to LDAP server $hostname on
+$port", __FILE__, __LINE__); #FIXME: $port
+ }
+ $res = ldap_set_option($this->_LDAP, LDAP_OPT_PROTOCOL_VERSION,
+$this->_params['version']);
+ if (!$res) {
+ return PEAR::raiseError("Unable to set LDAP protocol version");
+ }
+ $res = ldap_bind($this->_LDAP, $this->_params['binddn'],
+$this->_params['password']);
+ if (!$res) {
+ return PEAR::raiseError("Unable to bind to the LDAP server.
+Check authentication credentials.");
+ }
+
+ $this->_connected = true;
+ }
+ return true;
+ }
+ // }}}
+}
\ No newline at end of file
--- /dev/null
+<?php
+
+@define(SHOUT_ASTERISK_BRANCH, "ou=Asterisk");
\ No newline at end of file
--- /dev/null
+<?php
+/**
+ * Shout base inclusion file.
+ *
+ * $Horde: shout/lib/base.php,v 0.1 2005/06/29 01:00:23 ben Exp $
+ *
+ * This file brings in all of the dependencies that every Shout
+ * script will need and sets up objects that all scripts use.
+ */
+
+// Check for a prior definition of HORDE_BASE (perhaps by an
+// auto_prepend_file definition for site customization).
+if (!defined('HORDE_BASE')) {
+ @define('HORDE_BASE', dirname(__FILE__) . '/../..');
+}
+// Load the Horde Framework core, and set up inclusion paths.
+require_once HORDE_BASE . '/lib/core.php';
+
+// Registry.
+$registry = &Registry::singleton();
+if (is_a(($pushed = $registry->pushApp('shout', !defined('AUTH_HANDLER'))),
+'PEAR_Error')) {
+ if ($pushed->getCode() == 'permission_denied') {
+ Horde::authenticationFailureRedirect();
+ }
+ Horde::fatal($pushed, __FILE__, __LINE__, false);
+}
+$conf = &$GLOBALS['conf'];
+@define('SHOUT_TEMPLATES', $registry->get('templates'));
+
+// Find the base file path of Shout.
+@define('SHOUT_BASE', dirname(__FILE__) . '/..');
+
+// Notification system.
+$notification = &Notification::singleton();
+$notification->attach('status');
+
+// Shout base libraries.
+require_once SHOUT_BASE . '/lib/Shout.php';
+require_once SHOUT_BASE . '/lib/Driver.php';
+
+$GLOBALS['shout'] = &Shout_Driver::singleton();
+
+// Horde libraries.
+require_once 'Horde/Help.php';
\ No newline at end of file
--- /dev/null
+<?php
+
+if (!defined(SHOUT_BASE)) {
+ define(SHOUT_BASE, dirname($_SERVER['PHP_SELF']));
+}
+
+define(SHOUT_TEMPLATES, $SHOUT_BASE . '/templates');
\ No newline at end of file
--- /dev/null
+<!DOCTYPE webproject>
+<webproject>
+ <project usePreviewPrefix="0" previewPrefix="" usePersistentBookmarks="0" name="Shout" encoding="iso 8859-1" enableEvents="true" >
+ <upload/>
+ <templates>templates/</templates>
+ <toolbars>toolbars/</toolbars>
+ <item url="" uploadstatus="2" />
+ <item modified_time="1120021726" url="templates/content_page" uploadstatus="2" />
+ <item url="templates/" uploadstatus="2" />
+ <item url="lib/" uploadstatus="2" />
+ <item url="lib/Driver/" uploadstatus="2" />
+ <item modified_time="1120027108" url="lib/Driver/ldap.php" uploadstatus="2" />
+ <item modified_time="1120026738" url="lib/base.php" uploadstatus="2" />
+ <item modified_time="1120022640" url="lib/Driver.php" uploadstatus="2" />
+ <item modified_time="1120025651" url="contexts.php" uploadstatus="2" />
+ <item modified_time="1120021933" url="index.php" uploadstatus="2" />
+ <uploadprofiles showtreeviews="true" defaultProfile="Shout" >
+ <profile remote_host="picasso.v-office.biz" remote_port="" remote_path="/srv/vhost/users/aklang/sites/intranet.v-office.biz/shout" remote_protocol="sftp" user="aklang" name="Shout" >
+ <uploadeditem upload_time="0" url="config/" />
+ <uploadeditem upload_time="1120022446" url="config/conf.xml" />
+ <uploadeditem upload_time="1120025616" url="contexts.php" />
+ <uploadeditem upload_time="1120021928" url="index.php" />
+ <uploadeditem upload_time="1120021874" url="index.php~" />
+ <uploadeditem upload_time="0" url="lib/" />
+ <uploadeditem upload_time="1120022595" url="lib/Driver.php" />
+ <uploadeditem upload_time="1120022560" url="lib/Driver.php~" />
+ <uploadeditem upload_time="0" url="lib/Driver/" />
+ <uploadeditem upload_time="1120027088" url="lib/Driver/ldap.php" />
+ <uploadeditem upload_time="1120026921" url="lib/Driver/ldap.php~" />
+ <uploadeditem upload_time="1120026672" url="lib/Shout.php" />
+ <uploadeditem upload_time="1120026697" url="lib/base.php" />
+ <uploadeditem upload_time="1120016080" url="lib/defines.php" />
+ <uploadeditem upload_time="1120027019" url="shout.webprj" />
+ <uploadeditem upload_time="0" url="templates/" />
+ <uploadeditem upload_time="1120013664" url="templates/content_page" />
+ </profile>
+ </uploadprofiles>
+ <debuggers>
+ <Gubed>
+ <serverhost>localhost</serverhost>
+ <serverport>8026</serverport>
+ <localbasedir/>
+ <serverbasedir/>
+ <useproxy>0</useproxy>
+ <listenport>8016</listenport>
+ <startsession>http://localhost/Gubed/StartSession.php?gbdScript=/%rfpp</startsession>
+ <defaultexecutionstate>0</defaultexecutionstate>
+ <displaydelay>0</displaydelay>
+ <errormask>0</errormask>
+ </Gubed>
+ <pathmapper/>
+ </debuggers>
+ <defaultDTD>-//w3c//dtd xhtml 1.0 strict//en</defaultDTD>
+ <item modified_time="1120021725" url="lib/defines.php" uploadstatus="1" />
+ <item modified_time="1120022441" url="config/conf.xml" uploadstatus="1" />
+ <item url="config/" uploadstatus="1" />
+ <item modified_time="1120026739" url="lib/Shout.php" uploadstatus="1" />
+ <author>Ben Klang</author>
+ <email>ben@alkaloid.net</email>
+ <debuggerclient>Gubed</debuggerclient>
+ <exclude cvsignore="true" >*~;*.webprj;CVS;</exclude>
+ <teamdata>
+ <taskleaders/>
+ <subprojectleaders/>
+ <mailinglist address="" />
+ </teamdata>
+ <events/>
+ <treestatus>
+ <openfolder url="lib" />
+ </treestatus>
+ </project>
+</webproject>
--- /dev/null
+<?php
+
+if (!defined(SHOUT_BASE)) {
+ define(SHOUT_BASE, dirname($_SELF['PHP_SELF']));
+}
+
+require_once SHOUT_BASE."/lib/defines.php";
+require_once SHOUT_BASE."/lib/base.php";
\ No newline at end of file