Initial revision
authorBen Klang <ben@alkaloid.net>
Wed, 29 Jun 2005 19:36:05 +0000 (19:36 +0000)
committerBen Klang <ben@alkaloid.net>
Wed, 29 Jun 2005 19:36:05 +0000 (19:36 +0000)
git-svn-id: https://svn.alkaloid.net/gpl/shout/trunk@32 06cd67b6-e706-0410-b29e-9de616bca6e9

config/conf.php [new file with mode: 0644]
config/conf.xml [new file with mode: 0644]
contexts.php [new file with mode: 0644]
index.php [new file with mode: 0644]
lib/Driver.php [new file with mode: 0644]
lib/Driver/ldap.php [new file with mode: 0644]
lib/Shout.php [new file with mode: 0644]
lib/base.php [new file with mode: 0644]
lib/defines.php [new file with mode: 0644]
shout.webprj [new file with mode: 0644]
templates/content_page [new file with mode: 0644]

diff --git a/config/conf.php b/config/conf.php
new file mode 100644 (file)
index 0000000..4bcfc38
--- /dev/null
@@ -0,0 +1,14 @@
+<?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. */
diff --git a/config/conf.xml b/config/conf.xml
new file mode 100644 (file)
index 0000000..8da45a9
--- /dev/null
@@ -0,0 +1,45 @@
+<?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>
+
diff --git a/contexts.php b/contexts.php
new file mode 100644 (file)
index 0000000..a95ff84
--- /dev/null
@@ -0,0 +1,19 @@
+<?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
diff --git a/index.php b/index.php
new file mode 100644 (file)
index 0000000..09361b6
--- /dev/null
+++ b/index.php
@@ -0,0 +1,21 @@
+<?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
diff --git a/lib/Driver.php b/lib/Driver.php
new file mode 100644 (file)
index 0000000..6933f06
--- /dev/null
@@ -0,0 +1,135 @@
+<?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
diff --git a/lib/Driver/ldap.php b/lib/Driver/ldap.php
new file mode 100644 (file)
index 0000000..3895d7e
--- /dev/null
@@ -0,0 +1,163 @@
+<?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
diff --git a/lib/Shout.php b/lib/Shout.php
new file mode 100644 (file)
index 0000000..d43bdc1
--- /dev/null
@@ -0,0 +1,3 @@
+<?php
+
+@define(SHOUT_ASTERISK_BRANCH, "ou=Asterisk");
\ No newline at end of file
diff --git a/lib/base.php b/lib/base.php
new file mode 100644 (file)
index 0000000..6d968e2
--- /dev/null
@@ -0,0 +1,45 @@
+<?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
diff --git a/lib/defines.php b/lib/defines.php
new file mode 100644 (file)
index 0000000..79badd6
--- /dev/null
@@ -0,0 +1,7 @@
+<?php
+
+if (!defined(SHOUT_BASE)) {
+    define(SHOUT_BASE, dirname($_SERVER['PHP_SELF']));
+}
+
+define(SHOUT_TEMPLATES, $SHOUT_BASE . '/templates');
\ No newline at end of file
diff --git a/shout.webprj b/shout.webprj
new file mode 100644 (file)
index 0000000..4c2cc32
--- /dev/null
@@ -0,0 +1,72 @@
+<!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>
diff --git a/templates/content_page b/templates/content_page
new file mode 100644 (file)
index 0000000..66fd553
--- /dev/null
@@ -0,0 +1,8 @@
+<?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