[dev] [patch] patches for vacation

Martin Luethi horde at humbapa.ch
Fri Jan 30 02:28:21 PST 2004


hi list,

attached are some patches for vacation

you can test the patches under:
host: http://mail.humbapa.ch
user: test at humbapa.ch
pass: 2004

sql.php.diff:
- works now with realms and custom-driver
- new methode checkConfig (the other drivers have it already)
- creates a new entry in db, if no entry exists
- methode _getUserDetails returns now subject and message
- some code clean-up (mostly sql-queries)

conf.xml.diff:
- add norealm to the qmail-driver
- add hordeauth to all drivers
- hordeauth is now configstring. if set to 'full' the username will
  be used unmodified

main.php.diff:
- modified to work with hordeauth='full'

main.inc.diff:
- modified to work with hordeauth='full'


g. tinu
-------------- next part --------------
Index: sql.php
===================================================================
RCS file: /repository/vacation/lib/Driver/sql.php,v
retrieving revision 1.17
diff -u -r1.17 sql.php
--- sql.php	23 Jan 2004 13:05:58 -0000	1.17
+++ sql.php	28 Jan 2004 10:22:50 -0000
@@ -24,6 +24,37 @@
     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,pass_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]['pass_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.
@@ -37,18 +68,19 @@
      */
     function setVacation($user, $realm, $password, $message, $alias)
     {
-        /* _connect() will die with Horde::fatal() upon failure. */
-        $this->_connect();
+        // Make sure the configuration file is correct
+        if (!$this->checkConfig($realm)) {
+            return false;
+        }
 
-        // Split message into parts to get subject.
-        $myarray = explode("\n", $message);
+        /* _connect() will die with Horde::fatal() upon failure. */
+        $this->_connect($realm);
 
         /* Determine if $message contains Subject: and if it does
          * split it. */
-        if (strstr($myarray[0], 'Subject:')) {
-            $mysubject = $myarray[0];
-            $myarray[0] = '';
-            $mymessage = implode('', $myarray);
+        if (preg_match("/^Subject: ([^\n]+)\n(.+)$/s", $message, $m='')) {
+            $mysubject = $m[1];
+            $mymessage = $m[2];
         } else {
             $mysubject = '';
             $mymessage = $message;
@@ -57,24 +89,36 @@
         // 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 .= ' FROM ' . $this->params[$realm]['table'];
+        $query .= ' WHERE ' . $this->params[$realm]['user_col'] . ' = ' . $this->_db->quote($myuser);
+        $query .= ' AND ' . $this->params[$realm]['pass_col'] . ' = ' . $this->_db->quote(md5($password));
+        $result = $this->_db->query($query);
+        if (!is_a($result, 'PEAR_Error')) {
+            $query = 'INSERT INTO ' . $this->params[$realm]['table'];
+            $query .= ' ( ' . $this->params[$realm]['vacation'];
+            $query .= ' , ' . $this->params[$realm]['user_col'];
+            $query .= ' , ' . $this->params[$realm]['pass_col'] . ' ) ';
+            $query .= ' VALUES ( ' . $this->_db->quote('n');
+            $query .= ' , ' . $this->_db->quote($user);
+            $query .= ' , ' . $this->_db->quote(md5($password)) . ' ) ';
+            $result = $this->_db->query($query);
+        }
+
         /* Build the SQL query. */
-        $query = 'UPDATE ' . $this->params['table'];
-        $query .= ' SET ' . $this->params['vacation'] . ' = ' . $this->_db->quote('y');
-        $query .= ' WHERE ' . $this->params['user_col'] . ' = ' . $this->_db->quote($myuser);
-        $query .= ' AND ' . $this->params['pass_col'] . ' = ' . $this->_db->quote(md5($password));
-
-        $query1 = 'UPDATE ' . $this->params['table'];
-        $query1 .= ' SET ' . $this->params['message'] . ' = ' . $this->_db->quote($mymessage);
-        $query1 .= ' ,  ' . $this->params['subject'] . ' = ' . $this->_db->quote($mysubject);
-        $query1 .= ' WHERE ' . $this->params['user_col'] . ' = ' . $this->_db->quote($myuser);
-        $query1 .= ' AND ' . $this->params['pass_col'] . ' = ' . $this->_db->quote(md5($password));
+        $query = 'UPDATE ' . $this->params[$realm]['table'];
+        $query .= ' SET ' . $this->params[$realm]['vacation'] . ' = ' . $this->_db->quote('y');
+        $query .= ' , ' . $this->params[$realm]['message'] . ' = ' . $this->_db->quote($mymessage);
+        $query .= ' , ' . $this->params[$realm]['subject'] . ' = ' . $this->_db->quote($mysubject);
+        $query .= ' WHERE ' . $this->params[$realm]['user_col'] . ' = ' . $this->_db->quote($myuser);
+        $query .= ' AND ' . $this->params[$realm]['pass_col'] . ' = ' . $this->_db->quote(md5($password));
 
         /* Execute the query. */
         $result = $this->_db->query($query);
-        $result1 = $this->_db->query($query1);
 
-        if (!is_a($result, 'PEAR_Error') && !is_a($result1, 'PEAR_Error')) {
-            if ($result === DB_OK && $result1 === DB_OK) {
+        if (!is_a($result, 'PEAR_Error')) {
+            if ($result === DB_OK) {
                 $this->_disconnect();
                 return true;
             } else {
@@ -85,8 +129,6 @@
             $this->_disconnect();
             return false;
         }
-        $this->_disconnect();
-        return false;
     }
 
     /**
@@ -100,18 +142,22 @@
      */
     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();
+        $this->_connect($realm);
 
         // Build username.
         $myuser = $this->_buildUsername($user, $realm);
 
         /* Build the SQL query. */
-        $query = 'UPDATE ' . $this->params['table'];
-        $query .= ' SET ' . $this->params['vacation'] . ' = ' . $this->_db->quote('n');
-        $query .= ' ,  ' . $this->params['message'] . ' = ' . $this->_db->quote('');
-        $query .= ' WHERE ' . $this->params['user_col'] . ' = ' . $this->_db->quote($myuser);
-        $query .= ' AND ' . $this->params['pass_col'] . ' = ' . $this->_db->quote(md5($password));
+        $query = 'UPDATE ' . $this->params[$realm]['table'];
+        $query .= ' SET ' . $this->params[$realm]['vacation'] . ' = ' . $this->_db->quote('n');
+        $query .= ' WHERE ' . $this->params[$realm]['user_col'] . ' = ' . $this->_db->quote($myuser);
+        $query .= ' AND ' . $this->params[$realm]['pass_col'] . ' = ' . $this->_db->quote(md5($password));
 
         /* Execute the query. */
         $result = $this->_db->query($query);
@@ -128,8 +174,6 @@
             $this->_disconnect();
             return false;
         }
-        $this->_disconnect();
-        return false;
     }
 
     /**
@@ -143,36 +187,42 @@
      */
     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();
+        $this->_connect($realm);
 
         // Build username.
         $myuser = $this->_buildUsername($user, $realm);
 
         /* Build the SQL query. */
-        $query = 'SELECT ' . $this->params['vacation'] . ' AS vacation, ' . $this->params['message'] . ' AS message';
-        $query .= ' FROM ' . $this->params['table'];
-        $query .= ' WHERE ' . $this->params['user_col'] . ' = ' . $this->_db->quote($myuser);
-        $query .= ' AND ' . $this->params['pass_col'] . ' = ' . $this->_db->quote(md5($password));
+        $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);
+        $query .= ' AND ' . $this->params[$realm]['pass_col'] . ' = ' . $this->_db->quote(md5($password));
 
         /* 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();
-                $result->free();
                 return false;
             }
+        } else {
+            $this->_disconnect();
+            return false;
         }
-
-        $this->_disconnect();
-        return false;
     }
 
     /**
@@ -181,17 +231,20 @@
      *
      * @return   boolean   True or False based on success of connect
      */
-    function _connect()
+    function _connect($realm)
     {
         if (!$this->_connected) {
-            Horde::assertDriverConfig($this->params, 'server',
+            // 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($this->params,
-                                      array('persistent' => !empty($this->_params['persistent'])));
+            $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__);
             }
-------------- next part --------------
Index: conf.xml
===================================================================
RCS file: /repository/vacation/config/conf.xml,v
retrieving revision 1.4
diff -u -r1.4 conf.xml
--- conf.xml	26 Jan 2004 08:56:42 -0000	1.4
+++ conf.xml	29 Jan 2004 08:46:26 -0000
@@ -28,7 +28,7 @@
      <configsection name="default">
       <configstring name="host" desc="Hostname where the FTP server is running on">localhost</configstring>
       <configinteger name="port" desc="Port that the FTP server is using">21</configinteger>
-      <configboolean name="hordeauth" desc="Check this if the user's login password is the right password, and you don't want them to have to confirm it">false</configboolean>
+      <configstring name="hordeauth" required="false" desc="If this parameter is present and true, then the user doesn't have to confirm his password. If this parameter is 'full', the username will be used unmodified. Otherwise, everything after and including the first @ in the username will be stripped before attempting authentication."></configstring>
       <configboolean name="norealm" desc="Check this if the domain information shouldn't be added to the email address in .forward files">false</configboolean>
       <configenum name="dbtype" desc="The type of database file to use">empty
        <values>
@@ -56,6 +56,8 @@
      <configsection name="default">
       <configstring name="host" desc="Hostname where the FTP server is running on">localhost</configstring>
       <configinteger name="port" desc="Port that the FTP server is using">21</configinteger>
+      <configstring name="hordeauth" required="false" desc="If this parameter is present and true, then the user doesn't have to confirm his password. If this parameter is 'full', the username will be used unmodified. Otherwise, everything after and including the first @ in the username will be stripped before attempting authentication."></configstring>
+      <configboolean name="norealm" desc="Check this if the domain information shouldn't be added to the email address in .forward files">false</configboolean>
      </configsection>
     </configsection>
    </case>
@@ -112,6 +114,7 @@
         <configstring name="vacation" desc="Vacation message yes or no">vacation</configstring>
        </case>
       </configswitch>
+      <configstring name="hordeauth" required="false" desc="If this parameter is present and true, then the user doesn't have to confirm his password. If this parameter is 'full', the username will be used unmodified. Otherwise, everything after and including the first @ in the username will be stripped before attempting authentication."></configstring>
      </configsection>
     </configsection>
    </case>
@@ -132,6 +135,7 @@
       <configstring name="basedn" desc="Basedn">ou=mailaccount,dc=example,dc=com</configstring>
       <configstring name="userdn" required="false" desc="Userdn"></configstring>
       <configstring name="vacation" desc="The attribute to search for. If it exists it defines the vacation message">autoreply</configstring>
+      <configstring name="hordeauth" required="false" desc="If this parameter is present and true, then the user doesn't have to confirm his password. If this parameter is 'full', the username will be used unmodified. Otherwise, everything after and including the first @ in the username will be stripped before attempting authentication."></configstring>
      </configsection>
     </configsection>
    </case>
-------------- next part --------------
Index: main.php
===================================================================
RCS file: /repository/vacation/main.php,v
retrieving revision 1.38
diff -u -r1.38 main.php
--- main.php	17 Jan 2004 22:57:49 -0000	1.38
+++ main.php	29 Jan 2004 08:45:37 -0000
@@ -19,10 +19,16 @@
 $split = explode('@', Auth::getAuth());
 $user = @$split[0];
 $realm = @$split[1];
-if (empty($realm)) {
+if (empty($realm) || !@is_array($driver->params[$realm])) {
     $realm = 'default';
 }
 
+// Check if hordeauth is set to 'full'
+$hordeauth = $driver->getParam('hordeauth', $realm);
+if ($hordeauth === 'full') {
+        $user = Auth::getAuth();
+}
+
 $submit = Util::getFormData('submit', false);
 
 if ($submit) {
@@ -32,20 +38,21 @@
                             'horde.warning');
     }
 
-    // Check for refused usernames, using current horde username.
-    if (in_array($user, $conf['user']['refused'])) {
-        $notification->push(sprintf(_("You can't change the vacation notice for %s."), $user), 'horde.error');
-        $vacationmode = 'error';
-    }
-
-    if ($driver->getParam('hordeauth', $realm)) {
-        $password = Auth::getCredential('password');
-    } else {
+    // Check for password
+    if (empty($hordeauth)) {
         $password = Util::getFormData('password', false);
         if (empty($password)) {
             $notification->push(_("You must give your password"), 'horde.warning');
             $vacationmode = 'error';
         }
+    } else {
+        $password = Auth::getCredential('password');
+    }
+
+    // Check for refused usernames, using current horde username.
+    if (in_array($user, $conf['user']['refused'])) {
+        $notification->push(sprintf(_("You can't change the vacation notice for %s."), $user), 'horde.error');
+        $vacationmode = 'error';
     }
 
     // Call the requested function.
-------------- next part --------------
Index: main.inc
===================================================================
RCS file: /repository/vacation/templates/main/main.inc,v
retrieving revision 1.21
diff -u -r1.21 main.inc
--- main.inc	16 Sep 2003 23:08:48 -0000	1.21
+++ main.inc	29 Jan 2004 08:46:01 -0000
@@ -1,9 +1,10 @@
+<?php $curhordeauth = $driver->getParam('hordeauth', $realm); ?>
 <script language="JavaScript" type="text/javascript">
 <!--
 
 function submit_form()
 {
-<?php if (!$driver->getParam('hordeauth', $realm)): ?>
+<?php if (empty($curhordeauth)): ?>
     if (document.vacation.password.value == "") {
         alert('<?php echo addslashes(_("You must provide your password")) ?>');
         document.vacation.password.focus();
@@ -64,7 +65,7 @@
 <div class="light">
 <br />
 
-<?php if (!$driver->getParam('hordeauth', $realm)): ?>
+<?php if (empty($curhordeauth)): ?>
 <?php echo _("For your protection and safety, you must identify yourself with your login password to verify this change.") ?>
 <?php echo _("Then submit the form so that your vacation notice can be updated.") ?>
 <br />


More information about the dev mailing list