Drupal, sous-domaines, affectation de rôle

  • warning: array_map(): Argument #2 should be an array in /var/www/titouille.ch/www/modules/system/system.module on line 1050.
  • warning: array_keys() expects parameter 1 to be array, null given in /var/www/titouille.ch/www/includes/theme.inc on line 1845.
  • warning: Invalid argument supplied for foreach() in /var/www/titouille.ch/www/includes/theme.inc on line 1845.
Portrait de titouille

Difficile de trouver un titre vraiment suggestif car l'explication sera surement longue. En voici les fondations :


Introduction

J'utilise actuellement drupal pour monter un projet personnel. Drupal offre beaucoup de possibilités, dont celle de monter des systèmes "multisites" en utilisant une seule installation. Mieux encore, drupal permet de partager à peu près tout ce qui est possible de partager : fichiers, modules, thèmes, et même les bases de données.

Sans rentrer dans le détail, les grandes lignes de mon projet sont de mettre en place un système avec les contraintes suivantes :

  1. Système multisites utilisant les sous-domaines
  2. L'utilisateur ne doit s'authentifier qu'une seule fois pour pouvoir accéder à tous les sites.
  3. Un utilisateur qui en fait la demande se verra attribuer un site sur lequel il aura des droits avancés (définis par des rôles)

Avec ce genre de contraintes, on peut par exemple imaginer un système à la myspace ou l'utilisateur fait une demande, son site est généré, puis il y a un accès sécurisé. Lorsqu'il navigue dans le système, si il est sur son propre site, il a des droits privilégiés, et si il est sur d'autres sous-domaines que le sien, il a un simple accès visiteur.

Les fondations sont maintenant posées. Passons aux solutionnements.

Système multisites

Le système de multisites avec drupal, c'est ok. Drupal offre tout ce qu'il faut pour pouvoir gérer des sous-domaines avec une seule installation de base.
Pour ce faire, il suffit d'aller dans le répertoire "sites" de l'installation, et créer des répertoires du genre "sousdomaine1.domaine.com", "sousdomaine2.domaine.com", "sousdomaine3.domaine.com", etc...

Dans chaque répertoire il faudra ensuite placer une copie du fichier "settings.php" de base (situé dans sites/default) et l'éditer en spécifiant les bonnes informations de base de données ($db_url) et de chemin d'accès ($base_url) pour créer ses sous-domaines. Regardez du côté de mon explication sur les virtual hosts et apache pour configurer votre serveur local Wink.


Authentification unique

Concernant l'authentification unique, il y a plusieurs choses à prendre en compte.


Partage de base de données

Tout d'abord, les utilisateurs de tous les sous-sites doivent être partagés entre tous les sites. Pour ce faire, il est nécessaire de partager certaines tables de la base de données de mon site principal avec les sites placés sur les sous-domaines.
Pour partager les bases de données, l'astuce se trouve également dans le fichier settings :
Pour le settings.php de mon site principal, rien de spécial, elle utilise sa propre base de données, qui contient également toutes les données partagées.
Pour les settings.php des sous-domaines, je vais modifier la variable $db_prefix pour forcer les sous-sites à aller chercher certaines données (tout ce qui concerne les utilisateurs et les accès) dans la base de données principale :

$db_prefix = array( 
	'default' => '',
	'authmap' => 'principal.',
	'locales_meta' => 'principal.',
	'locales_source' => 'principal.',
	'locales_target' => 'principal.',
	'path_access' => 'principal.',
	'permission' => 'principal.',
	'profile_fields' => 'principal.',
	'profile_values' => 'principal.',
	'role' => 'principal.',
	'role_weights' => 'principal.',
	'sequences' => 'principal.',
	'sessions' => 'principal.',
	'users' => 'principal.',
	'users_roles' => 'principal.'
	);

Le fait de mettre "principal." sur les tables citées va surcharger la valeur par défaut "default" qui elle spécifie d'aller chercher les infos dans la base de données valorisée dans $db_url.
Pour toutes les tables ayant un préfix "principal.", les sous-domaines iront chercher les données non pas dans leur base de données respectives mais dans la base de données du site principal.

Cette configuration me permet donc de partager tous les utilisateurs de tous les sites. Le profil de chacun existera et pourra être accessible à partir de tous les sous-domaines sans devoir le dupliquer dans chaque base de données.


Module singlesignon

Mais ça ne règle pas encore mon problème, c'est à dire une authentification unique de l'utilisateur pour la navigation sur tout le domaine, sous-sites inclus. Pour résoudre le problème, le module Singlesignon est disponible. Ce dernier permet de stocker les sessions de chaque sous-site dans une variable pour pouvoir les interchanger selon notre navigation. Il suffit simplement pour chaque sous-site de spécifier le nom du site principal sur le formulaire situé sur admin/settings/singlesignon.


Problème récurrent

Nous arrivons bientôt au bout de nos contraintes, mais le plus dur reste à faire.
Actuellement, si j'élève un utilisateur au rang d'administrateur d'un sous-site, il le sera pour tous les sites du système. Pourquoi ? tout simplement parce que les données utilisateurs sont partagées entre tous les sites.
Un exemple : l'utilisateur XYZ est élevé au rang d'administrateur. Il navigue sur sousdomaine1.domaine.com, le système va tester ses rôles en allant puiser les données dans la base de données principale et va lui donner les accès pour son rôle d'administrateur.
Imaginez maintenant le scénario pour les autres sous-domaines... il sera toujours identique, car si XYZ est administrateur, il l'es partout, peu importe le sous-domaine.


Module role_switch_domain

C'est maintenant qu'il a fallu ruser. Mon premier véritable module (avec finitions) pour Drupal réside dans cette question :

Comment élever un utilisateur à un rang supérieur, mais uniquement lorsqu'il est sur le site dont il a la charge ??

Mon premier module se nomme "role_switch_domain" et fonctionne de la manière suivante :

1. à l'installation, il prépare deux champs supplémentaires dans les champs de profils ([profile_rsd_site_key] et [profile_rsd_site_role]), et installe une variable [drupal_rsd_site_key] pour le site.

2. à l'utilisation, le module récupère la clé utilisateur [profile_rsd_site_key] si elle existe. Si c'est le cas, alors il récupère la clé du site [drupal_rsd_site_key] sur lequel l'utilisateur est en train de naviguer, et il les compare. Dans le cas ou les clés seraient identiques, alors le rôle [profile_rsd_site_role] spécifié dans le profil utilisateur est affecté à sa variable utilisateur, et il possède désormais les privilèges de [profile_rsd_site_role].

Quelques infos à savoir :

  • Le module doit être activé sur tous les sites qui veulent être soumis à ces tests.
  • Le rôle ajouté par le module n'est ajouté que de manière temporaire (dynamiquement). L'utilisateur ne possède jamais de rôle supplémentaire dans la base de données sinon il aurait accès à tous les sites.
  • Pour le désinstaller complètement d'un site, il faut passer par l'onglet uninstall (admin/build/modules/uninstall) après l'avoir désactivé.
  • Pour le désactiver intégralement du système, il faut utiliser la même procédure que la précédente sur tous les sites et supprimer de la base de données les 2 lignes concernant les champs "profile_rsd_*" dans la table profile_fields.





Voilà. Vous trouverez le module dans ma section ressources si vous êtes intéressé à l'utiliser. C'est mon premier module, donc soyez indulgent au niveau du codage. Il a le mérite de fonctionner et d'offrir une installation automatisée et une page d'administration Wink




role_switch_domain

Bonjour,
merci pour tes explications / multidomaine
concernant ton module, merci de me préciser pourquoi tu n'as pas utilisé le module domaine_access ?

Portrait de titouille

Concernant domain_access

Je n'ai connu que dernièrement ce module, mais il ne correspondait de toute façon pas vraiment à mes besoins (bien que je n'ai pas trop testé l'usage). A priori, il permet de partager le même contenu sur plusieurs sous-domaines (single database), alors que j'aimerai avoir une installation multi-site mais ou chaque sous-domaine utilise sa propre base de données, seule certaines tables sont partagées entre toutes.
Après, je préfèrerai passer par des vues MySQL pour permettre par exemple de récupérer des données de plusieurs sites ou alors de partager certaines données du site principal avec les sous-domaine (via table-wizard et une vue ce second exemple fonctionne très bien).

Mais comme expliqué, je n'ai pas vraiment poussé les recherches et tests sur domain_access car j'avais déjà pas mal avancé mon projet (que j'ai repris il y a 2 mois) lorsque j'ai découvert ce module. J'ai du réécrire un peu mon propre module pour qu'il fonctionne correctement. Il affecte maintenant le rôle dans la base de données lorsque l'utilisateur est connecté sur son propre domaine et supprime le rôle dès que l'utilisateur n'y est plus.

Thank u!

Very interesting Thank u!