l'extranet home made et Horde 5

::TOC::

L'objectif est d'avoir dans un extranet, un lien ayant pour texte "Vous avez X e-mails non lus". Le click sur ce lien renvoit vers le webmail de horde sans passer par la case authentification car l'utilisateur s'est déjà identifié sur l'extranet.

Comme ceci: extranetMailsNonLul.jpeg

Bien évidemment, il faut en prérequis que soit les identifiants mails soient les mêmes que l'extranet, ou bien les avoir stockés quelque part dans les paramètres de l'utilisateur.

J'ai fini de coder tout ça, je ne vais pas donner l'intégralité du code car ça n'a pas d’intérêt, c'est trop spécifique, mais je vais aborder ici les points suivants:

  • En PHP: compter le nombre de messages non lus dans une boite IMAP
  • S'authentifier de manière transparente sur horde depuis un autre site.

PHP - AJAX indiquer s'il y a des messages non lus dans une boite IMAP

Il faut avoir la lib php5-imap installée sur le serveur. Pour compter le nombre d'e-mails non lus dans une boite IMAP en php, j'ai écrit la function suivante:

  1. <?php
  2. function compteEMailsNonLusIMAP($hoteIMAP,$identifiantIMAP,$portIMAP,$passwordIMAP){
  3. /*
  4. * Retourne le nombre d'emails non lus dans une boite imap
  5. * Retourne false s'il y a une erreur
  6. *
  7. * Codé par Gnieark http://blog-du-grouik.tinad.fr en janvier 2013
  8. * license: http://blog-du-grouik.tinad.fr/pages/Mentions-l%C3%A9gales
  9. */
  10.  
  11.  
  12. //ouvrir connexion au serveur IMAP
  13. //le flag "readonly" évite que les messages soient considérés lus à cause de ce script
  14. $imapConn= imap_open('{'.$hoteImap.':'.$portIMAP.'/imap/readonly}', $identifiantIMAP, $passwordIMAP);
  15. if (FALSE === $imapConn) {
  16.  
  17. //La connexion au serveur de mails a échoué. Vérifiez vos paramètres!
  18. imap_close($imapConn);
  19. return false;
  20.  
  21. }else{
  22.  
  23. //besoin d'avoir le nombre de messages total de la boite mails pour la suite
  24. $info = imap_check($imapConn);
  25. if (FALSE !== $info) {
  26.  
  27. //télécharger les entetes des mails
  28. $mails = imap_fetch_overview($imapConn, "1:{$info->Nmsgs}", 0);
  29. $count=0;
  30. //compter les messages non lus
  31. foreach($mails as $lemail){
  32. if($lemail->seen == '0'){
  33. $count ++;
  34. }
  35. }
  36. imap_close($imapConn);
  37. //renvoyer le nombre d'emails non lus
  38. return $count;
  39.  
  40. }else{
  41. //'Impossible de lire le contenu de la boite mail'
  42. imap_close($imapConn);
  43. return false;
  44. }
  45. }
  46. }
  47. ?>

Accéder au webmail de horde de façon transparante

Pour accéder à horde de façon transparente, la manipulation est digne d'un script kiddie. Il suffit de faire le formulaire HTML servant à la page d'authentification, en mettant toutes les informations cachées dans des <input type="hidden"> et valider le formulaire avec la function javascript submit().

Bien évidemement avant ça, il faut que vous ayez un peu de code pour renseigner les variables $identifiantIMAP et $motDePasseIMAP

  1. <a onclick="document.forms['authWebmail'].submit();">E-mail</a>
  2. <form id="authWebmail" method="post" action="https://URL/DE/VOTRE/INSTALLATION/DE/HORDE/login.php">
  3. <input type="hidden" name="app" id="app" value="imp" />
  4. <input type="hidden" name="login_post" id="login_post" value="0" />
  5. <input type="hidden" name="url" value="https://URL/DE/VOTRE/INSTALLATION/DE/HORDE/imp/" />
  6. <input type="hidden" name="anchor_string" id="anchor_string" value="" />
  7.  
  8. <input type="hidden" name="horde_select_view" value="auto" />
  9. <input type="hidden" name="horde_user" value="<?php echo $identifiantIMAP; ?>" />
  10. <input type="hidden" name="horde_pass" value="<?php echo $motDePasseIMAP; ?>" />
  11. <input type="hidden" name="login_button" value="plop"/>
  12. </form>

Mixer le tout pour avoir un lien indiquant le nombre de mais non lus, renvoyant vers horde sans authentification.

En fonction du nombre d'e-mails et des capacités du serveur de courrier, l'éxécution du script qui compte les messages peut prendre quelques secondes. Il est judicieux d'afficher le nombre de messages non lus via un appel AJAX qui permettra à la page en cours de s'afficher quand même dans un délai raisonnable.

Le lien "E-mails" dans l'image ci dessus a le code HTML/javascript suivant:

  1. <a onclick="document.forms['authWebmail'].submit();">
  2. <img src="moteur/simpleWebmail/logo.png" alt="logo">E-mail
  3. <em id="leftmenu-emails" style="display: none;"></em>
  4. </a>
  5. <form id="authWebmail" method="post" action="https://URL/DE/VOTRE/INSTALLATION/DE/HORDE/login.php">
  6. <input type="hidden" name="app" id="app" value="imp" />
  7. <input type="hidden" name="login_post" id="login_post" value="0" />
  8. <input type="hidden" name="url" value="https://URL/DE/VOTRE/INSTALLATION/DE/HORDE/imp/" />
  9. <input type="hidden" name="anchor_string" id="anchor_string" value="" />
  10.  
  11. <input type="hidden" name="horde_select_view" value="auto" />
  12. <input type="hidden" name="horde_user" value="<?php echo $identifiantIMAP; ?>" />
  13. <input type="hidden" name="horde_pass" value="<?php echo $motDePasseIMAP; ?>" />
  14. <input type="hidden" name="login_button" value="plop"/>
  15. </form>
  16. <script type="text/javascript">
  17. <!--
  18. function Ajx()
  19. {
  20. var request = false;
  21. try {request = new ActiveXObject('Msxml2.XMLHTTP');}
  22. catch (err2) {try {request = new ActiveXObject('Microsoft.XMLHTTP');}
  23. catch (err3) {try {request = new XMLHttpRequest();}
  24. catch (err1) {request = false;}
  25. }
  26. }
  27. return request;
  28. }
  29. function afficheMailInfos()
  30. {
  31. var xhr = Ajx();
  32. xhr.onreadystatechange = function(){if(xhr.readyState == 4){
  33. if(xhr.status == 200) {
  34. if (xhr.responseText.substr(0,13) == "erreur -WARN-"){
  35. alert(xhr.responseText);
  36. die;
  37. }
  38. document.getElementById('leftmenu-emails').style.display='';
  39. document.getElementById('leftmenu-emails').innerHTML = xhr.responseText;
  40.  
  41. }else{
  42. document.getElementById('leftmenu-emails').innerHTML = "<font color=\"#FF0000\">Error code " + xhr.status + "</font>";
  43. }
  44. }};
  45. xhr.open("POST", '/URL/DU/SCRIPT/QUI/DONNE/LE/NOMBRE/DE/MAILS/NON/LUS.php', true);
  46. xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  47. xhr.send('act=balInfos');
  48. }
  49.  
  50. afficheMailInfos();
  51. //-->
  52. </script>

Conclusion

Le truc un peu crado de cette méthode c'est que le mot de passe IMAP se trouve du coup dans le code source de la page HTML. Je me console en me disant que horde et mon extranet sont en https.

Page top