Permettre un accès par IP ou plages d’IPs à des auteurs SPIP
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

107 lines
4.3 KiB

  1. # IPSet
  2. IPSet est un plugin pour SPIP qui permet de définir des IPs ou Plages d’IPs à des auteurs SPIP.
  3. Il utilise la librairie éponyme [IPSet de Wikimedia](https://github.com/wikimedia/IPSet).
  4. ## Principe général
  5. Le plugin permet de tester rapidement qu’une IP entrante fait partie d’une liste d’IPs ou de Plages d’IPs connues
  6. du site, et éventuellement de retrouver à quel auteur SPIP cette IP est définie.
  7. On s’appuie essentiellement sur 2 fonctions PHP de base :
  8. - `ipset_get()` retourne un IPSet avec l’ensemble des plages / IPs connues, que l’on peut tester avec l’IP du visiteur :
  9. ```php
  10. $ip = $GLOBALS['ip'];
  11. $ipset = ipset_get();
  12. if ($ipset->match($ip)) {
  13. // On connait cette IP
  14. }
  15. ```
  16. - `ipset_access_author()` va plus loin et retourne d’id_auteur éventuel associé à l’IP du visiteur,
  17. si on connait cette IP. Dans ce cas, une session anonyme est créé contenant les entrées `ip_id_auteur` et `ip_name`
  18. renseignées, qui correspondent à l’id_auteur et nom de l’auteur associé.
  19. ## Fonctionnement technique
  20. ### Champ `access_ips`
  21. Pour stocker les IPs / Plages d’IPs associées aux auteurs, le plugin ajoute un champ `access_ips` à la table `spip_auteurs` de SPIP.
  22. Une saisie dans le formulaire d’auteurs permet de renseigner ce champ.
  23. On peut définir une ou plusieurs adresses IPs ou plages d’IPs (séparées par des virgules),
  24. tel que :
  25. - `123.123.123.1, 123.123.123.2`
  26. - `123.123.123.0/28`
  27. Les plages d’IPs sont à fournir en [notation CIDR](https://fr.wikipedia.org/wiki/CIDR).
  28. Une vérification empêche d’utiliser deux fois la même IP ou plage d’IP sur différents auteurs.
  29. ### Méta `ipset`
  30. À chaque actualisation d’une IP dans le formulaire d’édition d’auteur, un cache méta (dans `spip_meta`) est mis à jour
  31. avec une définition IPSet de l’ensemble des IPs/Plages définies pour les auteurs du site.
  32. Au besoin, on peut vérifier rapidement qu’une IP visiteur du site fait partie de ce set d’IPs défini, en appelant
  33. la fonction `ipset_get()` qui retourne l’IPSet depuis ce cache méta (ou le calcule s’il n’existe pas).
  34. ### Cache disque `tmp/accessip`
  35. Lorsqu’on a besoin d’associer une IP à un auteur (par exemple pour afficher son nom dans le header du site ou
  36. pour des autorisations spécifiques), le calcul pour retrouver à quel auteur est associé une IP est plus gourmand
  37. (on doit recalculer un IPSet avec les IPs/Plages d’IPs de chaque auteur possible et le tester avec l’IP visiteur).
  38. Pour éviter ces calculs, on stocke l’association dans un cache disque lorsque l’on trouve qu’une IP est associée à un auteur
  39. Cela se fait par exemple lorsqu’on utilise la fonction `ipset_access_author()` :
  40. - s’il n’y a pas de session anonyme déjà pour cette IP, on teste
  41. - si l’IP est connue (l’IPSet global est validé)
  42. - si oui, on appelle `ipset_get_author($ip)` qui retourne l’id_auteur, en le cherchant soit en cache disque (dans `tmp/accessip/$ip`)
  43. soit en le calculant et en créant ce cache.
  44. - puis on crée une session anonyme pour ce visiteur.
  45. ### Cache disque `tmp/noflood`
  46. En même temps que le cache `tmp/accessip`, l’IP est ajouté dans `tmp/noflood/$ip` ce qui peut servir à se faire
  47. whitelister par des antispams.
  48. ### Génie `accessip`
  49. Un génie nettoie périodiquement les caches disques `tmp/accessip` et `tmp/noflood` des fichiers plus vieux que 7 jours.
  50. ## Exemples d’utilisation
  51. ### Autorisation
  52. Vérifier qu’on connait l’auteur : il est identifié ou a une IP connue :
  53. ```php
  54. function autoriser_exemple_acceder_dist($faire, $type, $id, $qui, $opt) {
  55. if ((!$qui or !$qui['id_auteur']) and !ipset_access_author()) {
  56. return false;
  57. }
  58. // ...
  59. return true;
  60. }
  61. ```
  62. ### Nom du visiteur en squelettes
  63. ```html
  64. <div class="small">
  65. <?php if (!isset($GLOBALS['visiteur_session']['statut'])) { ?>
  66. <?php if (ipset_access_author()) { ?>
  67. <span class="localisation">
  68. <i class="picto picto-user"></i><span> <?php echo $GLOBALS['visiteur_session']['ip_name']; ?></span>
  69. </span>
  70. <?php } ?>
  71. <a href="#URL_PAGE{login}" class="link-popin link-popin-login"><i class="picto picto-login"></i><span> <:exemple:lien_connexion:></span></a>
  72. <?php } else { ?>
  73. <a href="#URL_PAGE{compte}"><i class="picto picto-user"></i><span> <:exemple:lien_compte:></span></a>
  74. <?php } ?>
  75. </div>
  76. ```