Merge remote branch 'origin/master' into xnet_accounts
authorStéphane Jacob <sj@m4x.org>
Mon, 9 Aug 2010 00:01:40 +0000 (02:01 +0200)
committerStéphane Jacob <sj@m4x.org>
Mon, 9 Aug 2010 00:01:40 +0000 (02:01 +0200)
classes/user.php
classes/xnetpage.php
configs/mails.conf
htdocs/javascript/password.js
modules/xnet.php
modules/xnetgrp.php
templates/xnet/edit.tpl [new file with mode: 0644]
templates/xnet/skin.tpl
templates/xnetgrp/membres-del.tpl
templates/xnetgrp/membres-edit.tpl
templates/xnetgrp/unsubscription.mail.tpl [new file with mode: 0644]

index 1c22fef..b503dfe 100644 (file)
@@ -586,6 +586,23 @@ class User extends PlUser
                                   $this->id());
     }
 
+    public function groupCount()
+    {
+        return XDB::fetchOneCell('SELECT  COUNT(DISTINCT(asso_id))
+                                    FROM  group_members
+                                   WHERE  uid = {?}',
+                                 $this->id());
+    }
+
+    public function inGroup($asso_id)
+    {
+        $res = XDB::fetchOneCell('SELECT  COUNT(*)
+                                    FROM  group_members
+                                   WHERE  uid = {?} AND asso_id = {?}',
+                                 $this->id(), $asso_id);
+        return ($res > 0);
+    }
+
     /**
      * Clears a user.
      *  *always deletes in: account_lost_passwords, register_marketing,
index 2a63e16..12b50df 100644 (file)
@@ -43,6 +43,8 @@ class XnetPage extends PlPage
         }
         $this->addJsLink('jquery.js');
         $this->addJsLink('overlib.js');
+        $this->addJsLink('secure_hash.js');
+        $this->addJsLink('sha1.js');
         $this->addJsLink('wiki.js');
         $this->addJsLink('xorg.js');
         $this->setTitle('Les associations polytechniciennes');
@@ -81,6 +83,9 @@ class XnetPage extends PlPage
         $sub = array();
         $sub['tous les groupes'] = 'plan';
         $sub['documentation']     = 'Xnet';
+        if (S::user()->type == 'xnet') {
+            $sub['mon compte'] = 'member/edit';
+        }
         $sub['signaler un bug']   = array('href' => 'send_bug/'.$_SERVER['REQUEST_URI'], 'class' => 'popup_840x600');
         $menu["no_title"]   = $sub;
 
index 059b0d9..459d521 100644 (file)
@@ -62,6 +62,10 @@ cc=validation+googleapps@polytechnique.org
 [xnet_unsubscription]
 from="Gestion des groupes X sur Polytechnique.net" <support@polytechnique.org>
 
+[xnet_unsubscription_account]
+from=br@staff.polytechnique.org
+to=br@staff.polytechnique.org
+
 [registration]
 from="Webmaster Polytechnique.org" <web@polytechnique.org>
 to=registration+watch@staff.m4x.org
index 578e345..c91a50d 100644 (file)
@@ -21,6 +21,9 @@
 function hashResponse(password1, password2, hasConfirmation) {
     pw1 = $('[name=' + password1 + ']').val();
 
+    if (pw1 == '********') {
+        return true;
+    }
     if (hasConfirmation) {
         pw2 = $('[name=' + password2 + ']').val();
         if (pw1 != pw2) {
@@ -28,8 +31,6 @@ function hashResponse(password1, password2, hasConfirmation) {
             return false;
         }
         $('[name=' + password2 + ']').val('');
-    } else if (pw1 == '********') {
-        return true;
     }
 
     if (pw1.length < 6) {
index dbaa8a3..1f6dbf9 100644 (file)
@@ -33,6 +33,7 @@ class XnetModule extends PLModule
             'plan'        => $this->make_hook('plan',      AUTH_PUBLIC),
             'photo'       => $this->make_hook('photo',     AUTH_MDP),
             'autologin'   => $this->make_hook('autologin', AUTH_MDP),
+            'edit'        => $this->make_hook('edit',      AUTH_MDP, 'user'),
 
             'Xnet'        => $this->make_wiki_hook(),
         );
@@ -220,6 +221,60 @@ class XnetModule extends PLModule
         echo '$.ajax({ url: "'.$url.'?forceXml=1", dataType: "xml", success: function(xml) { $("body",xml).insertBefore("body"); $("body:eq(1)").remove(); }});';
         exit;
     }
+
+    function handler_edit(&$page)
+    {
+        global $globals;
+
+        $user = S::user();
+        if (empty($user)) {
+            return PL_NOT_FOUND;
+        }
+        if ($user->type != 'xnet') {
+            pl_redirect('index');
+        }
+
+        $page->changeTpl('xnet/edit.tpl');
+        if (Post::has('change')) {
+            S::assert_xsrf_token();
+
+            if ($user->groupCount() == 0 && Post::t('delete') == 'OUI') {
+                XDB::execute('DELETE FROM  accounts
+                                    WHERE  uid = {?}',
+                             $user->id());
+                pl_redirect('index');
+            }
+
+            // Convert user status to X
+            if (!Post::blank('login_X')) {
+                $forlife = $this->changeLogin($page, $user, Post::t('login_X'));
+                if ($forlife) {
+                    pl_redirect('index');
+                }
+            }
+
+            // Update user info
+            XDB::query('UPDATE  accounts
+                           SET  full_name = {?}, directory_name = {?}, display_name = {?},
+                                sex = {?}, email = {?}
+                         WHERE  uid = {?}',
+                       Post::t('full_name'), Post::t('directory_name'), Post::t('display_name'),
+                       (Post::t('sex') == 'male') ? 'male' : 'female', Post::t('email'), $user->id());
+            // If user is of type xnet and new password is given.
+            if (!Post::blank('pwhash')) {
+                XDB::query('UPDATE  accounts
+                               SET  password = {?}
+                             WHERE  uid = {?}',
+                           Post::t('pwhash'), $user->id());
+            }
+            if (XDB::affectedRows()) {
+                $page->trigSuccess('Données mises à jour.');
+            }
+        }
+
+        $page->addJsLink('password.js');
+        $page->assign('user', $user);
+    }
 }
 
 // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
index 12585a6..bce331c 100644 (file)
@@ -790,12 +790,11 @@ class XnetGrpModule extends PLModule
     {
         $page->changeTpl('xnetgrp/membres-del.tpl');
         $user = S::user();
-        $uid  = S::user()->id();
-        if (empty($uid)) {
+        if (empty($user)) {
             return PL_NOT_FOUND;
         }
         $page->assign('self', true);
-        $page->assign('user', $uid);
+        $page->assign('user', $user);
 
         if (!Post::has('confirm')) {
             return;
@@ -803,10 +802,18 @@ class XnetGrpModule extends PLModule
             S::assert_xsrf_token();
         }
 
+        $hasSingleGroup = ($user->groupCount() == 1);
+
         if ($this->unsubscribe($user)) {
-            $page->trigSuccess('Vous avez été désinscrit du groupe avec succès.');
+            $page->trigSuccess('Tu as été désinscrit du groupe avec succès.');
         } else {
-            $page->trigWarning('Vous avez été désinscrit du groupe, mais des erreurs se sont produites lors des désinscriptions des alias et des listes de diffusion.');
+            $page->trigWarning('Tu as été désinscrit du groupe, mais des erreurs se sont produites lors des désinscriptions des alias et des listes de diffusion.');
+        }
+        if ($user->type == 'xnet' && $hasSingleGroup && Post::has('accountDeletion')) {
+            XDB::execute('DELETE FROM  acounts
+                                WHERE  uid = {?}',
+                         $user->id());
+            $page->trigSuccess('Ton compte a bien été supprimé.');
         }
         $page->assign('is_member', is_member(true));
     }
@@ -818,6 +825,14 @@ class XnetGrpModule extends PLModule
         if (empty($user)) {
             return PL_NOT_FOUND;
         }
+
+        global $globals;
+
+        if (!$user->inGroup($globals->asso('id'))) {
+            pl_redirect('annuaire');
+        }
+
+        $page->assign('self', false);
         $page->assign('user', $user);
 
         if (!Post::has('confirm')) {
@@ -826,14 +841,36 @@ class XnetGrpModule extends PLModule
             S::assert_xsrf_token();
         }
 
+        $hasSingleGroup = ($user->groupCount() == 1);
+
         if ($this->unsubscribe($user)) {
             $page->trigSuccess("{$user->fullName()} a été désinscrit du groupe&nbsp;!");
         } else {
             $page->trigWarning("{$user->fullName()} a été désinscrit du groupe, mais des erreurs subsistent&nbsp;!");
         }
+
+        // Either deletes or notifies site administrators if it was the last group
+        // of a xnet account.
+        if ($user->type == 'xnet' && $hasSingleGroup) {
+            if ($user->state == 'pending') {
+                // If the user has never logged in the site, we delete her account.
+                XDB::execute('DELETE FROM  acounts
+                                    WHERE  uid = {?}',
+                             $user->id());
+            } else {
+                // It the user has already logged in the site, we notify site
+                // administrators that there is a new xnet account without any
+                // group.
+                $mailer = new PlMailer('xnetgrp/unsubscription.mail.tpl');
+                $mailer->assign('user', $user);
+                $mailer->assign('groupId', $globals->asso('id'));
+                $mailer->assign('groupName', $globals->asso('nom'));
+                $mailer->send();
+            }
+        }
     }
 
-    private function changeLogin(PlPage &$page, PlUser &$user, MMList &$mmlist, $login)
+    private function changeLogin(PlPage &$page, PlUser &$user, $login)
     {
         // Search the user's uid.
         $xuser = User::getSilent($login);
@@ -863,13 +900,17 @@ class XnetGrpModule extends PLModule
     {
         global $globals;
 
-        $page->changeTpl('xnetgrp/membres-edit.tpl');
-
         $user = User::getSilent($user);
         if (empty($user)) {
             return PL_NOT_FOUND;
         }
 
+        if (!$user->inGroup($globals->asso('id'))) {
+            pl_redirect('annuaire');
+        }
+
+        $page->changeTpl('xnetgrp/membres-edit.tpl');
+
         $mmlist = new MMList($user, $globals->asso('mail_domain'));
 
         if (Post::has('change')) {
@@ -877,7 +918,7 @@ class XnetGrpModule extends PLModule
 
             // Convert user status to X
             if (!Post::blank('login_X')) {
-                $forlife = $this->changeLogin($page, $user, $mmlist, Post::t('login_X'));
+                $forlife = $this->changeLogin($page, $user, Post::t('login_X'));
                 if ($forlife) {
                     pl_redirect('member/' . $forlife);
                 }
@@ -894,6 +935,13 @@ class XnetGrpModule extends PLModule
                            Post::t('full_name'), Post::t('directory_name'), Post::t('display_name'),
                            (Post::t('sex') == 'male') ? 'male' : 'female', Post::t('email'),
                            (Post::t('type') == 'xnet') ? 'xnet' : 'virtual', $user->id());
+                // If user is of type xnet and new password is given.
+                if (!Post::blank('pwhash') && Post::t('type') == 'xnet') {
+                    XDB::query('UPDATE  accounts
+                                   SET  password = {?}
+                                 WHERE  uid = {?}',
+                               Post::t('pwhash'), $user->id());
+                }
             } else if (!$user->perms) {
                 XDB::query('UPDATE  accounts
                                SET  email = {?}
@@ -901,7 +949,7 @@ class XnetGrpModule extends PLModule
                            Post::t('email'), $user->id());
             }
             if (XDB::affectedRows()) {
-                $page->trigSuccess('Données de l\'utilisateur mise à jour.');
+                $page->trigSuccess('Données de l\'utilisateur mises à jour.');
             }
 
             // Update group params for user
@@ -980,6 +1028,8 @@ class XnetGrpModule extends PLModule
             }
         }
 
+        $page->addJsLink('password.js');
+        $page->assign('onlyGroup', ($user->groupCount() == 1));
         $page->assign('user', $user);
         $page->assign('listes', $mmlist->get_lists($user->forlifeEmail()));
         $page->assign('alias', $user->emailAliases($globals->asso('mail_domain'), 'user', true));
diff --git a/templates/xnet/edit.tpl b/templates/xnet/edit.tpl
new file mode 100644 (file)
index 0000000..f00c1e7
--- /dev/null
@@ -0,0 +1,118 @@
+{**************************************************************************}
+{*                                                                        *}
+{*  Copyright (C) 2003-2010 Polytechnique.org                             *}
+{*  http://opensource.polytechnique.org/                                  *}
+{*                                                                        *}
+{*  This program is free software; you can redistribute it and/or modify  *}
+{*  it under the terms of the GNU General Public License as published by  *}
+{*  the Free Software Foundation; either version 2 of the License, or     *}
+{*  (at your option) any later version.                                   *}
+{*                                                                        *}
+{*  This program is distributed in the hope that it will be useful,       *}
+{*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *}
+{*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *}
+{*  GNU General Public License for more details.                          *}
+{*                                                                        *}
+{*  You should have received a copy of the GNU General Public License     *}
+{*  along with this program; if not, write to the Free Software           *}
+{*  Foundation, Inc.,                                                     *}
+{*  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA               *}
+{*                                                                        *}
+{**************************************************************************}
+
+<h1>
+  Édition de tes données dans l'annuaire
+</h1>
+
+<form method="post" action="{$platal->ns}edit">
+  {xsrf_token_field}
+  <table cellpadding="0" cellspacing="0" class='tinybicol'>
+    <tr id="prenom" class="impair">
+      <td class="titre">
+        Nom affiché&nbsp;:
+      </td>
+      <td>
+        <input type="text" value="{$user->displayName()}" name="display_name" size="40" />
+      </td>
+    </tr>
+    <tr class="impair">
+      <td class="titre">
+        Nom complet&nbsp;:
+      </td>
+      <td>
+        <input type="text" value="{$user->fullName()}" name="full_name" size="40" />
+      </td>
+    </tr>
+    <tr class="impair">
+      <td class="titre">
+        Nom annuaire&nbsp;:
+      </td>
+      <td>
+        <input type="text" value="{$user->directoryName()}" name="directory_name" size="40" />
+      </td>
+    </tr>
+    <tr id="sexe" class="impair">
+      <td class="titre">
+        Sexe&nbsp;:
+      </td>
+      <td>
+        <select name="sex">
+          <option value="male"{if !$user->isFemale()} selected="selected"{/if}>Homme</option>
+          <option value="female"{if $user->isFemale()} selected="selected"{/if}>Femme</option>
+        </select>
+      </td>
+    </tr>
+    <tr class="impair">
+      <td class="titre">
+        Email&nbsp;:
+      </td>
+      <td>
+        <input type="text" value="{$user->forlifeEmail()}" name="email" size="40" />
+      </td>
+    </tr>
+    <tr class="impair">
+      <td class="titre">Mot de passe&nbsp;:</td>
+      <td>
+        <input type="text" name="password1" size="10" maxlength="256" value="********" />
+        <input type="hidden" name="pwhash" value="" />
+      </td>
+    </tr>
+    <tr class="impair">
+      <td class="titre">Retape-le une fois&nbsp;:</td>
+      <td>
+        <input type="text" name="password2" size="10" maxlength="256" value="" />
+      </td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>{checkpasswd prompt="password1" submit="dummy_none"}</td>
+    </tr>
+    <tr id="make_X">
+      <td colspan="2">
+        <span id="make_X_cb">
+          <input type="checkbox" name="is_x" id="is_x" onclick="$('#make_X_cb').hide(); $('#make_X_login').show()" />
+          <label for="is_x">coche cette case si tu es en fait un X</label>
+        </span>
+        <span id="make_X_login" style="display: none">
+          <span class="titre">Identifiant (prenom.nom.promo)&nbsp;:</span>
+          <input type="text" name="login_X" value="" />
+        </span>
+      </td>
+    </tr>
+  </table>
+  {if $user->groupCount() eq 0}
+  <p>
+    Supprimer mon compte&nbsp;:&nbsp;<input type="text" name="delete" value="NON" size="3" maxlength="3" /><br />
+    <small>(Écrire « OUI » en majuscule pour que la suppression soit prise en compte.)</small>
+  </p>
+  {/if}
+
+  <div class="center">
+    <br />
+    <input type="submit" name='change' value="Valider ces changements" onclick="return hashResponse('password1', 'password2', true);" />
+    &nbsp;
+    <input type="reset" value="Annuler ces changements" />
+  </div>
+</form>
+
+{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
index b8a29af..d8d411f 100644 (file)
           {/foreach}
           {if t($asso)}{assign var=asso_id value=$asso->id}{/if}
           {if t($smarty.session.suid)}{assign var=suid value=true}{else}{assign var=suid value=false}{/if}
-          {if $asso && $is_admin ||
+          {if t($asso) && $is_admin ||
                       ($suid && ($smarty.session.suid.perms->hasFlag('admin') ||
                                                 $smarty.session.suid.may_update[$asso_id]))}
           <h1>Voir le site comme&hellip;</h1>
index 9bc5502..bbf0ee9 100644 (file)
@@ -20,7 +20,7 @@
 {*                                                                        *}
 {**************************************************************************}
 
-{if $smarty.post.confirm}
+{if t($smarty.post.confirm)}
 
 <p class="descr">
 {if !$self}
     {if $self}
     Êtes-vous sûr de vouloir vous désinscrire du groupe {$asso->nom} et de toutes
     les listes de diffusion associées&nbsp;?
+    {if $user->type eq 'xnet' && $user->groupCount() eq 1}
+    <br />C'est le seul groupe auquel tu es actuellement inscrit sur polytechnique.net.
+    Si, malgré cela, tu souhaites garder ton accès à Polytechnique.net, décoche la case
+    ci-dessous.<br />
+    <label><input type="checkbox" name="accountDeletion" checked="checked" />Supprimer mon compte.</label>
+    {/if}
     {else}
     Êtes-vous sûr de vouloir supprimer {$user->fullName()} du groupe,
     lui retirer tous les droits associés à son statut de membre
     et le désabonner de toutes les listes de diffusion du groupe&nbsp;?
     {/if}
     </p>
-    <input type='submit' name='confirm' value='Oui, je {if $self}me{else}le{/if} désinscris complètement du groupe !' />
+    <input type="submit" name="confirm" value="Oui, je {if $self}me{else}le{/if} désinscris complètement du groupe !" />
   </div>
 </form>
 
index 596f8ac..e73d521 100644 (file)
@@ -28,6 +28,7 @@
       document.getElementById('prenom').style.display = state;
       document.getElementById('sexe').style.display = state;
       document.getElementById('make_X').style.display = state;
+      document.getElementById('password').style.display = state;
   }
 
   function showXInput(box)
       </td>
     </tr>
     {if $user->type eq 'xnet'}
+    <tr class="impair" id="password">
+      <td class="titre">Mot de passe&nbsp;:</td>
+      <td>
+        <div style="float: left">
+          <input type="text" name="new_plain_password" size="10" maxlength="256" value="********" />
+          <input type="hidden" name="pwhash" value="" />
+        </div>
+        <div style="float: left; margin-top: 5px;">
+          {checkpasswd prompt="new_plain_password" submit="dummy_none"}
+        </div>
+        {if !$onlyGroup}
+        <div style="clear: both">
+          <small class="error">
+            Attention, cet utilisateur est inscrit à d'autres groupes, changer son mot de passe modifiera aussi ses accès aux autres groupes.
+          </small>
+        </div>
+        {/if}
+      </td>
+    </tr>
     <tr id="make_X">
       <td colspan="2">
         <span id="make_X_cb">
 
   <div class="center">
     <br />
-    <input type="submit" name='change' value="Valider ces changements" />
+    <input type="submit" name='change' value="Valider ces changements" onclick="return hashResponse('new_plain_password', false, false);" />
     &nbsp;
     <input type="reset" value="Annuler ces changements" />
   </div>
diff --git a/templates/xnetgrp/unsubscription.mail.tpl b/templates/xnetgrp/unsubscription.mail.tpl
new file mode 100644 (file)
index 0000000..2e8e722
--- /dev/null
@@ -0,0 +1,33 @@
+{**************************************************************************}
+{*                                                                        *}
+{*  Copyright (C) 2003-2010 Polytechnique.org                             *}
+{*  http://opensource.polytechnique.org/                                  *}
+{*                                                                        *}
+{*  This program is free software; you can redistribute it and/or modify  *}
+{*  it under the terms of the GNU General Public License as published by  *}
+{*  the Free Software Foundation; either version 2 of the License, or     *}
+{*  (at your option) any later version.                                   *}
+{*                                                                        *}
+{*  This program is distributed in the hope that it will be useful,       *}
+{*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *}
+{*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *}
+{*  GNU General Public License for more details.                          *}
+{*                                                                        *}
+{*  You should have received a copy of the GNU General Public License     *}
+{*  along with this program; if not, write to the Free Software           *}
+{*  Foundation, Inc.,                                                     *}
+{*  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA               *}
+{*                                                                        *}
+{**************************************************************************}
+
+{config_load file="mails.conf" section="xnet_unsubscription_account"}
+{if $mail_part eq 'head'}
+{from full=#from#}
+{to full=#to#}
+{subject text="Nouveau compte xnet sans groupe."}
+{elseif $mail_part eq 'wiki'}
+Bonjour,
+
+{$user->fullName()} (hruid : {$user->hruid}) vient d'être désinscrit du groupe {$groupName} (id : {$groupName}). Son compte a été conservé bien qu'il ne soit plus inscrit à aucun groupe.
+
+{* vim:set et sw=2 sts=2 sws=2: *}