Integrates email storage backends (IMAP and Google Apps) as almost-normal email redir...
authorVincent Zanotti <vincent.zanotti@polytechnique.org>
Sat, 22 Mar 2008 19:54:08 +0000 (20:54 +0100)
committerVincent Zanotti <vincent.zanotti@polytechnique.org>
Sat, 22 Mar 2008 19:54:08 +0000 (20:54 +0100)
Signed-off-by: Vincent Zanotti <vincent.zanotti@polytechnique.org>
ChangeLog
include/emails.inc.php
include/googleapps.inc.php
modules/email.php
modules/googleapps.php
modules/register.php
templates/admin/utilisateurs.tpl
templates/emails/redirect.tpl

index d9c720e..8f8cf9d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -14,6 +14,7 @@ New:
 
     * Emails:
         - Imap mail storage can be activated/deactivated from interface    -VZA
+        - Mail storage backends are now integrated with redirections       -VZA
 
     * Lists:
         - Unsure mails are moderated                                       -FRU
index 357dd0d..0157690 100644 (file)
@@ -257,6 +257,105 @@ class EmailRedirection extends Email
     }
 }
 
+// class EmailStorage {{{1
+// Implementation of Email for email storage backends from Polytechnique.org.
+class EmailStorage extends Email
+{
+    // Shortname to realname mapping for known mail storage backends.
+    private $display_names = array(
+        'imap'       => 'Accès de secours aux emails (IMAP)',
+        'googleapps' => 'Compte GMail / Google Apps',
+    );
+
+    // Retrieves the current list of actives storages.
+    private function get_storages()
+    {
+        $res = XDB::query("SELECT  mail_storage
+                             FROM  auth_user_md5
+                            WHERE  user_id = {?}", $this->uid);
+        return new FlagSet($res->fetchOneCell());
+    }
+
+    // Updates the list of active storages.
+    private function set_storages($storages)
+    {
+        XDB::execute("UPDATE  auth_user_md5
+                         SET  mail_storage = {?}
+                       WHERE  user_id = {?}", $storages->flags(), $this->uid);
+    }
+
+    // Returns the list of allowed storages for the @p user.
+    static public function get_allowed_storages($uid)
+    {
+        global $globals;
+        $storages = array();
+
+        // Google Apps storage is available for users with valid Google Apps account.
+        require_once 'googleapps.inc.php';
+        if ($globals->mailstorage->googleapps_domain &&
+            GoogleAppsAccount::account_status($uid) == 'active') {
+            $storages[] = 'googleapps';
+        }
+
+        // IMAP storage is always visible to administrators, and is allowed for
+        // everyone when the service is marked as 'active'.
+        if ($globals->mailstorage->imap_active || S::has_perms()) {
+            $storages[] = 'imap';
+        }
+
+        return $storages;
+    }
+
+
+    public function __construct($uid, $name)
+    {
+        $this->uid = $uid;
+        $this->email = $name;
+        $this->display_email = (isset($this->display_names[$name]) ? $this->display_names[$name] : $name);
+
+        $storages = $this->get_storages();
+        $this->sufficient = ($name == 'googleapps');
+        $this->active = $storages->hasFlag($name);
+        $this->broken = false;
+        $this->disabled = false;
+        $this->rewrite = '';
+        $this->panne = $this->last = $this->panne_level = 0;
+    }
+
+    public function activate()
+    {
+        if (!$this->active) {
+            $storages = $this->get_storages();
+            $storages->addFlag($this->email);
+            $this->set_storages($storages);
+            $this->active = true;
+        }
+    }
+
+    public function deactivate()
+    {
+        if ($this->active) {
+            $storages = $this->get_storages();
+            $storages->rmFlag($this->email);
+            $this->set_storages($storages);
+            $this->active = false;
+        }
+
+    }
+
+    // Source rewrite can't be enabled for email storage addresses.
+    public function set_rewrite($rewrite) {}
+
+    // Email storage are not supposed to be broken, hence not supposed to be
+    // cleaned-up.
+    public function clean_errors() {}
+
+    // Capabilities.
+    public function has_rewrite() { return false; }
+    public function is_removable() { return false; }
+    public function has_disable() { return false; }
+}
+
 // class Redirect {{{1
 // Redirect is a placeholder class for an user's active redirections (third-party
 // redirection email, or Polytechnique.org mail storages).
@@ -275,7 +374,9 @@ class Redirect
     public function __construct($_uid)
     {
         $this->uid = $_uid;
+        $this->bogo = new Bogo($_uid);
 
+        // Adds third-party email redirections.
         $res = XDB::iterRow("SELECT  email, flags, rewrite, panne, last, panne_level
                                FROM  emails
                               WHERE  uid = {?} AND flags != 'filter'", $_uid);
@@ -283,7 +384,11 @@ class Redirect
         while ($row = $res->next()) {
             $this->emails[] = new EmailRedirection($_uid, $row);
         }
-        $this->bogo = new Bogo($_uid);
+
+        // Adds local email storage backends.
+        foreach (EmailStorage::get_allowed_storages($_uid) as $storage) {
+            $this->emails[] = new EmailStorage($_uid, $storage);
+        }
     }
 
     // public function other_active() {{{2
@@ -483,69 +588,5 @@ class Redirect
     }
 }
 
-// class MailStorage {{{1
-class MailStorage {
-    protected $uid;
-    protected $name;
-    protected $storage;
-
-    public function __construct($_uid, $_name)
-    {
-        $this->uid = $_uid;
-        $this->name = $_name;
-
-        $res = XDB::query("SELECT  mail_storage
-                             FROM  auth_user_md5
-                            WHERE  user_id = {?}", $this->uid);
-        $this->storages = new FlagSet($res->fetchOneCell());
-    }
-
-    public function disable()
-    {
-        $this->storages->rmFlag($this->name);
-        XDB::execute("UPDATE  auth_user_md5
-                         SET  mail_storage = {?}
-                       WHERE  user_id = {?}", $this->storages->flags(), $this->uid);
-        return true;
-    }
-
-    public function enable()
-    {
-        $this->storages->addFlag($this->name);
-        XDB::execute("UPDATE  auth_user_md5
-                         SET  mail_storage = {?}
-                       WHERE  user_id = {?}", $this->storages->flags(), $this->uid);
-        return true;
-    }
-
-    public function active()
-    {
-        return $this->storages->hasFlag($this->name);
-    }
-}
-
-class MailStorageIMAP extends MailStorage {
-    public function __construct($_uid)
-    {
-        parent::__construct($_uid, 'imap');
-    }
-}
-
-class MailStorageGoogleApps extends MailStorage {
-    public function __construct($_uid)
-    {
-        parent::__construct($_uid, 'googleapps');
-    }
-
-    public function disable() {
-        $redirect = new Redirect(S::v('uid'));
-        if (!$redirect->other_active(NULL)) {
-            return false;
-        }
-
-        return parent::disable();
-    }
-}
-
 // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
 ?>
index dadbf03..e6cd099 100644 (file)
@@ -36,7 +36,7 @@ function post_queue_u_create($job) {
     $account = new GoogleAppsAccount($userid, $forlife);
     if ($account->activate_mail_redirection) {
         require_once('emails.inc.php');
-        $storage = new MailStorageGoogleApps($userid);
+        $storage = new EmailStorage($userid, 'googleapps');
         $storage->enable();
     }
 
@@ -78,7 +78,7 @@ function post_queue_u_update($job) {
         if ($account->active()) {
             // Re-adds the email redirection (if the user did request it).
             if ($account->activate_mail_redirection) {
-                $storage = new MailStorageGoogleApps($userid);
+                $storage = new EmailStorage($userid, 'googleapps');
                 $storage->enable();
             }
 
index 3ed0b7d..24a37fd 100644 (file)
@@ -231,26 +231,6 @@ class EmailModule extends PLModule
             $redirect->modify_one_email_redirect($email, $rewrite);
         }
 
-        if ($action == 'storage') {
-            if ($email == 'imap') {
-                $storage = new MailStorageIMAP(S::v('uid'));
-            } else if ($email == 'googleapps') {
-                $storage = new MailStorageGoogleApps(S::v('uid'));
-            } else {
-                $storage = NULL;
-            }
-
-            if ($storage) {
-                $subaction = @func_get_arg(3);
-                if ($subaction == 'active') {
-                    $storage->enable();
-                }
-                if ($subaction == 'inactive') {
-                    $storage->disable();
-                }
-            }
-        }
-
         if (Env::has('emailop')) {
             $actifs = Env::v('emails_actifs', Array());
             print_r(Env::v('emails_rewrite'));
@@ -286,12 +266,6 @@ class EmailModule extends PLModule
         $page->assign('alias', $res->fetchAllAssoc());
         $page->assign('emails',$redirect->emails);
 
-        $res = XDB::query(
-                "SELECT  mail_storage
-                   FROM  auth_user_md5
-                  WHERE  user_id = {?}", $uid);
-        $page->assign('storage', explode(',', $res->fetchOneCell()));
-
         require_once 'googleapps.inc.php';
         $page->assign('googleapps', GoogleAppsAccount::account_status($uid));
     }
index f02053b..a78ab6c 100644 (file)
@@ -52,10 +52,10 @@ class GoogleAppsModule extends PLModule
 
         if ($account->active()) {
             $redirect = new Redirect(S::v('uid'));
-            $page->assign('redirect_unique', !$redirect->other_active(NULL));
+            $page->assign('redirect_unique', !$redirect->other_active('googleapps'));
 
-            $storage = new MailStorageGoogleApps(S::v('uid'));
-            $page->assign('redirect_active', $storage->active());
+            $storage = new EmailStorage(S::v('uid'), 'googleapps');
+            $page->assign('redirect_active', $storage->active);
         }
 
         // Updates the Google Apps account as required.
@@ -76,8 +76,7 @@ class GoogleAppsModule extends PLModule
                 if ($account->pending_update_suspension) {
                     $page->trig("Ton compte est déjà en cours de désactivation.");
                 } else {
-                    $storage = new MailStorageGoogleApps(S::v('uid'));
-                    if ($storage->disable()) {
+                    if ($redirect->modify_one_email('googleapps', false) == SUCCESS) {
                         $account->suspend();
                         $page->trig("Ton compte Google Apps est dorénavant désactivé.");
                     } else {
@@ -192,7 +191,7 @@ class GoogleAppsModule extends PLModule
 
         if ($user) {
             $account = new GoogleAppsAccount($user);
-            $storage = new MailStorageGoogleApps($user);
+            $storage = new EmailStorage($user, 'googleapps');
 
             // Force synchronization of plat/al and Google Apps passwords.
             if ($action == 'forcesync' && $account->sync_password) {
@@ -204,7 +203,7 @@ class GoogleAppsModule extends PLModule
             // Displays basic account information.
             $page->assign('account', $account);
             $page->assign('admin_account', GoogleAppsAccount::is_administrator($user));
-            $page->assign('googleapps_storage', $storage->active());
+            $page->assign('googleapps_storage', $storage->active);
             $page->assign('user', $user);
 
             // Retrieves user's pending requests.
index 973993f..7d43a1b 100644 (file)
@@ -483,7 +483,7 @@ class RegisterModule extends PLModule
         }
         if (Post::v('imap')) {
             require_once 'emails.inc.php';
-            $storage = new MailStorageIMAP(S::v('uid'));
+            $storage = new EmailStorage(S::v('uid'), 'imap');
             $storage->enable();
         }
 
index 8950062..cca5bc1 100644 (file)
@@ -379,9 +379,9 @@ Pour ceci changer ses permissions en 'disabled'.
     {foreach item=mail from=$emails}
     {cycle assign=class values="impair,pair"}
     <tr class="{$class}">
-      {if $mail->active}
+      {if $mail->active && $mail->has_disable()}
         {assign var=actives value=true}
-      {elseif $mail->disabled}
+      {elseif $mail->disabled && $mail->has_disable()}
         {assign var=disabled value=true}
       {/if}
       <td class="titre">
@@ -402,7 +402,9 @@ Pour ceci changer ses permissions en 'disabled'.
         {if $mail->broken}<em> (en panne)</em></span>{/if}
       </td>
       <td class="action">
+        {if $mail->is_removable()}
         <a href="javascript:del_fwd('{$mail->email}')">delete</a>
+        {/if}
       </td>
     </tr>
     {if $mail->panne && $mail->panne neq "0000-00-00"}
index db74029..6277330 100644 (file)
   <div class="center">
     <table class="bicol" summary="Adresses de redirection">
       <tr>
-        <th>Email</th>
+        <th>Redirection</th>
         <th>Actif</th>
         <th>Réécriture</th>
         <th>&nbsp;</th>
              onclick="return removeRedirect(this, &quot;{$e->email}&quot;);" >
             {icon name=cross title="Supprimer"}
           </a>
+          {else}
+          {if $e->sufficient}<span class="remove_email"></span>{/if}
+          <a href="emails/redirect#{$e->email}">{icon name=information title="Plus d'informations"}</a>
           {/if}
         </td>
       </tr>
       {/foreach}
-      {if $googleapps eq 'active'}
-      <tr class="{cycle values="pair,impair"}">
-        <td><strong>Compte GMail / Google Apps</strong></td>
-        <td>
-          <input type="checkbox" value="googleapps" disabled="disabled"
-                 {if in_array('googleapps', $storage)}checked="checked"{/if} />
-        </td>
-        <td>-</td>
-        <td>
-          <a href="emails/redirect#googleapps">{icon name=information title="Plus d'informations"}</a>
-        </td>
-      </tr>
-      {/if}
       <script type="text/javascript">activeEnable(); showRemove();</script>
       <tr class="{cycle values="pair,impair"}"><td colspan="4">
         <form action="emails/redirect" method="post">
 </fieldset>
 {/if}
 
-{* TODO(vincent.zanotti): remove the following block of code when both IMAP and GApps will be active. *}
-{if in_array('imap', $storage) neq 0 or #globals.mailstorage.imap_active# or hasPerm('admin')}
-  {assign var=has_imap value=true}
-{else}
-  {assign var=has_imap value=false}
-{/if}
-{if $googleapps or #globals.mailstorage.googleapps_active# or hasPerm('admin')}
-  {assign var=has_googleapps value=true}
-{else}
-  {assign var=has_googleapps value=false}
-{/if}
-
-{if $has_imap or $has_googleapps}
+{if #globals.mailstorage.googleapps_active# or #globals.mailstorage.imap_active# or hasPerm('admin') or $googleapps}
 <h1>Tes comptes de stockage de courrier</h1>
 {/if}
-{if $has_imap}
+{if #globals.mailstorage.imap_active# or hasPerm('admin')}
 <p>
   Polytechnique.org te propose de conserver les mails que tu reçois, pendant une durée limitée (environ 30 jours).
   Grâce à ce service, tu disposes d'une sauvegarde de tes mails en secours, au cas où, par exemple, tu effacerais
 </p>
 
 <table class="bicol" summary="Compte de stockage">
-  <col width="75%" />
-  <col width="25%" />
+  <col width="55%" />
+  <col width="45%" />
   <tr>
     <th colspan="2">Compte de stockage</th>
   </tr>
       </a><br />Hébergé par Polytechnique.org
     </td>
     <td style="text-align: center; vertical-align: middle">
-      <form action="emails/redirect/storage/imap/{if in_array('imap', $storage)}inactive{else}active{/if}" method="post">
-        {if in_array('imap', $storage)}
-        <input type="submit" value="Désactiver" />
-        {else}
-        <input type="submit" value="Activer" />
-        {/if}
-      </form>
+      <a href="emails/redirect#line_imap">Voir l'état de la redirection vers l'IMAP</a>
     </td>
   </tr>
 </table>
 {/if}
 
-{if $has_googleapps}
+{if #globals.mailstorage.googleapps_active# or hasPerm('admin') or $googleapps}
 <br />
 <p>
   Grâce à un partenariat avec Google, Polytechnique.org te propose également un compte
 </p>
 
 <table class="bicol" summary="Compte de stockage" id="googleapps">
-  <col width="75%" />
-  <col width="25%" />
+  <col width="55%" />
+  <col width="45%" />
   <tr>
     <th colspan="2">Compte de stockage</th>
   </tr>
     {if $googleapps eq 'active'}
     <td>
       <a href="googleapps">
-        <strong>Redirection des emails vers GMail / Google Apps</strong>
+        <strong>Compte GMail / Google Apps</strong>
       </a><br />Hébergé par Google
     </td>
     <td style="text-align: center; vertical-align: middle">
-      <form action="emails/redirect/storage/googleapps/{if in_array('googleapps', $storage)}inactive{else}active{/if}" method="post">
-        {if in_array('googleapps', $storage)}
-        <input type="submit" value="Désactiver" />
-        {else}
-        <input type="submit" value="Activer" />
-        {/if}
-      </form>
+      Ton compte Google Apps est actif.<br />
+      <a href="emails/redirect#line_googleapps">Voir l'état de la redirection vers GMail</a>
     </td>
     {else}
     <td colspan="2">