Summary | Postfixadmin's vacation integration |
Queue | Vacation |
Queue Version | HEAD |
Type | Enhancement |
State | Rejected |
Priority | 1. Low |
Owners | |
Requester | riv (at) cbn (dot) net (dot) id |
Created | 02/08/2005 (7451 days ago) |
Due | |
Updated | 11/28/2005 (7158 days ago) |
Assigned | |
Resolved | 11/28/2005 (7158 days ago) |
Milestone | |
Patch | No |
State ⇒ Rejected
lot of duplicate code. If Vacation_Driver_sql is too inflexible at the
moment to be extended by the postfixadmin driver, feel free to patch
that driver too. Just make sure that you don't break it. ;-)
New Attachment: vacation-postifxadmin.patch.txt
have to do some modifications on the database itself, which i think
may cause postfixadmin to break
Here's the attached patch
Priority ⇒ 1. Low
State ⇒ Feedback
This looks like a lot of redundant code.
Beside that, please upload the patch as an attachment to this ticket.
Priority ⇒ 3. High
Type ⇒ Enhancement
Summary ⇒ Postfixadmin's vacation integration
Queue ⇒ Vacation
State ⇒ New
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@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@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;