[Tickets #1326] NEW: Postfixadmin's vacation integration

bugs at bugs.horde.org bugs at bugs.horde.org
Mon Feb 7 19:27:59 PST 2005


DO NOT REPLY TO THIS MESSAGE. THIS EMAIL ADDRESS IS NOT MONITORED.

Ticket URL: http://bugs.horde.org/ticket/?id=1326
-----------------------------------------------------------------------
 Ticket     | 1326
 Created By | riv at cbn.net.id
 Summary    | Postfixadmin's vacation integration
 Queue      | Vacation
 Version    | HEAD
 State      | New
 Priority   | 3. High
 Type       | Enhancement
 Owners     | 
-----------------------------------------------------------------------


riv at cbn.net.id (2005-02-07 19:27) wrote:

Hi, I create a patch for vacation to use postfixadmin's vacation module

Here's the diff :

diff -urN vacation/config/conf.xml
/usr/local/www/data/files/vacation/config/conf.xml
--- vacation/config/conf.xml	Thu Nov 11 02:20:07 2004
+++ /usr/local/www/data/files/vacation/config/conf.xml	Tue Feb  8 09:01:51
2005
@@ -139,6 +139,38 @@
      </configsection>
     </configsection>
    </case>
+   <case name="postfixadmin" desc="Postfix mailer based MySQL driver">
+    <configdescription>
+     If not using realms (multiple domains or virtual hosting) then there
is
+     only one possible default configuration.
+     Even if you are using realms/hosting, you have to set a default
+     configuration.  This may be overriden by realm/domain specific values
by
+     defining additional arrays, one per realm/domain, with the
realm/domain
+     name as the key instead of the key 'default'. This not possible with
this
+     interface though.
+    </configdescription>
+    <configsection name="params">
+     <configsection name="default">
+      <configsql switchname="driverconfig">
+       <configstring name="table" desc="Database
table">vacation</configstring>
+       <configstring name="user_col" desc="Column which contains user
names">email</configstring>
+       <configstring name="message" desc="Column with vacation
message">body</configstring>
+       <configstring name="subject" desc="Column with vacation
subject">subject</configstring>
+       <configstring name="vacation" desc="Vacation message yes or
no">active</configstring>
+       <configstring name="vacdom" desc="Vacation domain in postfixadmin's
config.inc.php">autoreply.example.com</configstring>
+      </configsql>
+      <configenum name="hordeauth" desc="Should we log the user
automatically
+      in with the username and password he uses to login to Horde?">
+       <values>
+        <value desc="No">false</value>
+        <value desc="Yes, with the full username">full</value>
+        <value desc="Yes, but with everything after the @ stripped from
the
+        username">true</value>
+       </values>
+      </configenum>
+     </configsection>
+    </configsection>
+   </case>
   </configswitch>
  </configsection>
 
diff -urN vacation/lib/Driver/postfixadmin.php
/usr/local/www/data/files/vacation/lib/Driver/postfixadmin.php
--- vacation/lib/Driver/postfixadmin.php	Thu Jan  1 07:00:00 1970
+++ /usr/local/www/data/files/vacation/lib/Driver/postfixadmin.php	Tue Feb 
8 08:57:58 2005
@@ -0,0 +1,288 @@
+<?php
+/**
+ * $Horde: vacation/lib/Driver/postfixadmin.php,v 1.0 2005/01/03 14:35:41
jan Exp $
+ *
+ * Vacation_Driver_postfixadmin:: implements the Vacation_Driver API for
SQL servers.
+ *
+ * @author  Riv Octovahriz <riv at cbn.net.id>
+ * @version $Revision: 1.0 $
+ * @since   Vacation 2.1
+ * @package Vacation
+ */
+class Vacation_Driver_postfixadmin extends Vacation_Driver {
+
+    /** SQL connection object. */
+    var $_db;
+
+    /** Boolean which contains the state of the SQL connection. */
+    var $_connected = false;
+
+    /**
+     * Check if the realm has a specific configuration. If not, try to
+     * fall back on the default configuration. If still not a valid
+     * configuration then exit with an error.
+     *
+     * @param string    $realm      The realm of the user, or "default" if
none.
+     *                              Note: passed by reference so we can
change
+     *                              its value.
+     */
+    function checkConfig(&$realm)
+    {
+        // If no realm passed in, or no table config for the realm
+        // passed in, then we fall back to the default realm
+        if (empty($realm) || empty($this->params[$realm]['table'])) {
+            $realm = 'default';
+        }
+
+        // If still no table,user_col,message,subject,vacation then we have
a misconfigured module.
+        if (empty($this->params[$realm]['table']) ||
+            empty($this->params[$realm]['user_col']) ||
+            empty($this->params[$realm]['message']) ||
+            empty($this->params[$realm]['subject']) ||
+            empty($this->params[$realm]['vacation']) ) {
+            $this->err_str = _("The vacation application is not properly
configured.");
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Enable a vacation message for a user.
+     *
+     * @param string    $user      The username to enable vacation for.
+     * @param string    $realm     The realm of the user.
+     * @param string    $password  The password of the user.
+     * @param string    $message   The message to install.
+     * @param string    $alias     The email alias for vacation to use --
+     *                             Not yet implemented.
+     *
+     * @return boolean  Returns true on success, false on error.
+     */
+    function setVacation($user, $realm, $password, $message, $alias)
+    {
+        // Make sure the configuration file is correct
+        if (!$this->checkConfig($realm)) {
+            return false;
+        }
+
+        /* _connect() will die with Horde::fatal() upon failure. */
+        $this->_connect($realm);
+
+        /* Determine if $message contains Subject: and if it does
+         * split it. */
+        if (preg_match("/^Subject: ([^\n]+)\n(.+)$/s", $message, $m='')) {
+            $mysubject = $m[1];
+            $mymessage = $m[2];
+        } else {
+            $mysubject = '';
+            $mymessage = $message;
+        }
+
+        // Build username.
+        $myuser = $this->_buildUsername($user, $realm);
+
+        // Check if an entry already exists and create one otherwise
+        $query = 'SELECT ' . $this->params[$realm]['vacation'] . ' AS
vacation';
+	$query .= ' , domain ';
+        $query .= ' FROM ' . $this->params[$realm]['table'];
+        $query .= ' WHERE ' . $this->params[$realm]['user_col'] . ' = ' .
$this->_db->quote($myuser);
+        $result = $this->_db->query($query);
+        if (!is_a($result, 'PEAR_Error')) {
+	    $query = 'UPDATE alias';
+	    $query .= ' SET goto = concat(concat(goto,","),concat(goto,"@' .
$this->params[$realm]['vacdom'] . '"))';
+	    $query .= ' , modified=NOW()';
+	    $query .= ' WHERE address = ' . $this->_db->quote($myuser);
+	    $result = $this->_db->query($query);
+        }
+
+        /* Build the SQL query. */
+	$query = 'SELECT domain FROM alias WHERE address = ' .
$this->_db->quote($myuser);
+	$result = $this->_db->query($query);	
+	$query = 'INSERT INTO ' . $this->params[$realm]['table'];
+	$query .= ' ( ' . $this->params[$realm]['user_col'];
+	$query .= ' , ' . $this->params[$realm]['subject'];
+	$query .= ' , ' . $this->params[$realm]['message'];
+	$query .= ' , domain ';
+	$query .= ' , created )';
+	$query .= ' VALUES ( ' . $this->_db->quote($myuser);
+	$query .= ' , ' . $this->_db->quote($mysubject);
+	$query .= ' , ' . $this->_db->quote($mymessage);
+	$query .= ' , SUBSTRING_INDEX(' . $this->_db->quote($myuser) . ', "@",
-1)';
+	$query .= ' , NOW() )';
+	 
+        /* Execute the query. */
+        $result = $this->_db->query($query);
+
+        if (!is_a($result, 'PEAR_Error')) {
+            if ($result === DB_OK) {
+                $this->_disconnect();
+                return true;
+            } else {
+                $this->_disconnect();
+                return false;
+            }
+        } else {
+            $this->_disconnect();
+            return false;
+        }
+    }
+
+    /**
+     * Disable the vacation message for a user.
+     *
+     * @param string    $user      The username of the user.
+     * @param string    $realm     The realm of the user.
+     * @param string    $password  The password of the user.
+     *
+     * @return boolean  Returns true on success, false on error.
+     */
+    function unsetVacation($user, $realm, $password)
+    {
+        // Make sure the configuration file is correct
+        if (!$this->checkConfig($realm)) {
+            return false;
+        }
+
+        /* _connect() will die with Horde::fatal() upon failure. */
+        $this->_connect($realm);
+
+        // Build username.
+        $myuser = $this->_buildUsername($user, $realm);
+
+        /* Build the SQL query. */
+	$query = 'UPDATE alias';
+	$query .= ' SET goto = ' . $this->_db->quote($myuser); 
+	$query .= ' WHERE address = ' . $this->_db->quote($myuser);
+	$result = $this->_db->query($query);
+
+	$query = 'DELETE FROM ' . $this->params[$realm]['table'];
+	$query .= ' WHERE ' . $this->params[$realm]['user_col'] . ' = ' .
$this->_db->quote($myuser);
+
+        /* Execute the query. */
+        $result = $this->_db->query($query);
+
+        if (!is_a($result, 'PEAR_Error')) {
+            if ($result === DB_OK) {
+                $this->_disconnect();
+                return true;
+            } else {
+                $this->_disconnect();
+                return false;
+            }
+        } else {
+            $this->_disconnect();
+            return false;
+        }
+    }
+
+    /**
+     * Retrieve the current vacation details for the user.
+     *
+     * @param   $user        The username for which to retrieve details.
+     * @param   $realm       The realm (domain) for the user.
+     * @param   $password    The password of the user.
+     *
+     * @return  mixed        Vacation details or false.
+     */
+    function _getUserDetails($user, $realm, $password)
+    {
+        // Make sure the configuration file is correct
+        if (!$this->checkConfig($realm)) {
+            return false;
+        }
+
+        /* _connect() will die with Horde::fatal() upon failure. */
+        $this->_connect($realm);
+
+        // Build username.
+        $myuser = $this->_buildUsername($user, $realm);
+
+        /* Build the SQL query. */
+        $query = 'SELECT ' . $this->params[$realm]['vacation'] . ' AS
vacation';
+        $query .= ' , ' . $this->params[$realm]['message'] . ' AS
message';
+        $query .= ' , ' . $this->params[$realm]['subject'] . ' AS
subject';
+        $query .= ' FROM ' . $this->params[$realm]['table'];
+        $query .= ' WHERE ' . $this->params[$realm]['user_col'] . ' = ' .
$this->_db->quote($myuser);
+
+        /* Execute the query. */
+        $result = $this->_db->query($query);
+
+        if (!is_a($result, 'PEAR_Error')) {
+            $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
+            if (is_array($row)) {
+                $this->_disconnect();
+                $row['message'] = 'Subject: ' . $row['subject'] . "\n" .
$row['message'];
+                return $row;
+            } else {
+                $this->_disconnect();
+                return false;
+            }
+        } else {
+            $this->_disconnect();
+            return false;
+        }
+    }
+
+    /**
+     * Do an SQL connect and login as user with privilege to change
+     * vacation.
+     *
+     * @return   boolean   True or False based on success of connect
+     */
+    function _connect($realm)
+    {
+        if (!$this->_connected) {
+            // Build the params array to pass to DB
+            $_args = array_merge($this->params, $this->params[$realm]);
+
+            Horde::assertDriverConfig($_args, 'server',
+                array('phptype', 'hostspec', 'username', 'database',
'table'),
+                'vacation authentication SQL');
+
+            /* Connect to the SQL server using the supplied parameters. */
+            require_once 'DB.php';
+            $this->_db = &DB::connect($_args,
+                                      array('persistent' =>
!empty($_args['persistent'])));
+            if (is_a($this->_db, 'PEAR_Error')) {
+                Horde::fatal(PEAR::raiseError(_("Unable to connect to SQL
server.")), __FILE__, __LINE__);
+            }
+
+            $this->_db->setOption('portability', DB_PORTABILITY_LOWERCASE |
DB_PORTABILITY_ERRORS);
+
+            $this->_connected = true;
+        }
+
+        return true;
+    }
+
+    /**
+     * Disconnect from the SQL server and clean up the connection.
+     *
+     * @return boolean true on success, false on failure.
+     */
+    function _disconnect()
+    {
+        if ($this->_connected) {
+            $this->_connected = false;
+            return $this->_db->disconnect();
+        }
+
+        return true;
+    }
+
+    /**
+     * Builds a username based on presense of realm
+     * @return string user at realm or user
+     */
+    function _buildUsername($user, $realm)
+    {
+        if ($realm === 'default' ||
+            $realm === '') {
+            return $user;
+        } else {
+            return $user . "@" . $realm;
+        }
+    }
+
+}
diff -urN vacation/lib/Driver.php
/usr/local/www/data/files/vacation/lib/Driver.php
--- vacation/lib/Driver.php	Mon Jan  3 21:35:40 2005
+++ /usr/local/www/data/files/vacation/lib/Driver.php	Tue Feb  8 08:57:48
2005
@@ -95,10 +95,12 @@
 
         // Check vacation flag.
         if ($current_details['vacation'] === 'y' ||
-            $current_details['vacation'] === 'Y') {
+            $current_details['vacation'] === 'Y' ||
+	    $current_details['vacation'] === '1') {
             return 'Y';
         } elseif ($current_details['vacation'] === 'n' ||
-                  $current_details['vacation'] === 'N') {
+		  $current_details['vacation'] === 'N' ||
+                  $current_details['vacation'] === '0') {
             return 'N';
         } else {
             return false;





More information about the bugs mailing list