InfraGuard

Rôles, équipes et responsables

Les rôles et les équipes ne sont que des libellés informatifs — seul le niveau ouvre l’accès —, ainsi que le sélecteur de responsable combinant utilisateurs et équipes.

Vue d’ensemble — à quoi cela sert

Les rôles et les équipes sont des libellés informatifs servant à classer les personnes. La seule et unique chose qui ouvre l’accès aux écrans et aux actions est le niveau (user_level). Ce qu’un utilisateur peut voir, et ce qu’il a le droit d’enregistrer ou de supprimer, est décidé à 100 % par le niveau ; les rôles (« DBA », « DevOps », « Sécurité ») et les équipes (« Équipe Infrastructure », « Équipe Sécurité ») sont des étiquettes d’affichage et d’organisation qui n’accordent absolument aucune permission.

Le modèle de permissions reste ainsi simple. Pour donner à quelqu’un des pouvoirs d’administrateur, vous relevez son niveau — vous ne changez pas son rôle. Étiqueter un utilisateur « Sécurité » n’ouvre pas les écrans de sécurité ; son niveau doit être Personnel (5) ou supérieur.

Cet article couvre trois sujets :

  1. Les rôles (infr_role) — six intitulés de poste (DBA, DevOps, Sécurité, Administrateur, Personnel, Développeur).
  2. Les équipes (infr_team) — des unités organisationnelles, utilisées pour l’appartenance des utilisateurs et la responsabilité des actifs.
  3. Le sélecteur de responsable — une liste déroulante combinée qui permet d’affecter soit un utilisateur, soit une équipe, avec App\Support\Owners comme source de vérité unique. Le champ « responsable » des Instances, du Matériel et du Stockage l’utilise.

Contrôle d’accès = le niveau (user_level) uniquement. Les rôles et les équipes n’ouvrent aucune permission de manière programmatique. Voir Comprendre les niveaux (RBAC) pour le système de niveaux.

Quand l’utiliser

Disposition de l’écran

/admin/users (Administration ▸ Utilisateurs et rôles) comporte deux onglets.

Onglet Contenu
Utilisateurs Liste des utilisateurs (identifiant · nom · e-mail · rôle · équipe · niveau · statut · dernière connexion) + CRUD en modale
Équipes Liste des équipes (nom · couleur · responsable · description · nombre de membres) + CRUD en modale

La modale d’édition d’un utilisateur comporte des sélecteurs niveau / rôle / équipe, suivis de cette indication :

Le niveau régit l’accès — Démo (lecture), Personnel (exploitation), Administrateur (tout). Le rôle est un simple libellé.

Comment l’utiliser

Les rôles — des intitulés de poste

Le référentiel des rôles compte six entrées, insérées ou mises à jour de façon idempotente par key grâce à InfrRoleSeeder.

key Libellé Jeton de couleur seq
dba DBA info 10
devops DevOps accent 20
security Sécurité crit 30
admin Administrateur warn 40
staff Personnel muted 50
developer Développeur good 60

Le rôle admin (libellé « Administrateur ») n’a rien à voir avec le niveau administrateur (10). Un rôle n’est qu’un libellé : un utilisateur dont le rôle est « Administrateur » mais dont le niveau est Démo (1) ne peut rien enregistrer. À l’inverse, un administrateur de niveau 10 dispose de toute l’administration même avec un rôle vide.

Les équipes — des unités organisationnelles

Les équipes se gèrent librement en CRUD dans l’onglet Équipes. Les quatre équipes de la semence :

Nom Couleur Description
Équipe Infrastructure accent Exploitation serveurs / réseau / stockage
Équipe Sécurité crit Détection · réponse · blocage
Équipe Développement good Développement de services · déploiement
Équipe DBA info Exploitation de bases de données · optimisation

Champs d’édition d’une équipe :

Champ Signification
Nom (name) Obligatoire. Nom de l’équipe
Couleur (color) Teinte du badge (accent/crit/good/info/muted …)
Responsable (lead_user_id) Un utilisateur (facultatif)
Description (description) Texte libre
Actif (is_active) Les équipes inactives sont masquées dans le sélecteur de responsable

Le sélecteur de responsable — utilisateurs et équipes réunis

Les actifs (instances serveur, matériel, stockage) possèdent un champ « responsable » qui peut désigner soit une personne, soit une équipe. Les règles de ce sélecteur combiné se trouvent dans App\Support\Owners (la SOT).

Forme de stockage = deux colonnes

La table de l’actif enregistre le responsable dans deux colonnes.

Colonne Signification
owner_id Clé primaire entière d’un utilisateur ou d’une équipe
owner_type 'user' ou 'team'

Forme d’échange côté front = une chaîne ref unique

Le navigateur (formulaires, filtres) échange owner_type et owner_id sous la forme d’une seule chaîne.

user:5     → user id 5
team:3     → team id 3

Les options d’amorçage (Owners::options()) renvoient les deux groupes pour le rendu en optgroup (cache de 20 secondes). Les utilisateurs clôturés (is_close=1) et les équipes inactives (is_active=0) sont exclus.

{
  "users": [ { "ref": "user:5", "id": 5, "name": "Jane Doe" } ],
  "teams": [ { "ref": "team:3", "id": 3, "name": "Infra Team" } ]
}

Découpage / reconstruction côté serveur

Assistant Comportement
Owners::split($ref) "user:5" → ['user', 5]. Format incorrect → ['user', 0] (= sans affectation)
Owners::ref($ownerId, $ownerType) (5, 'user') → "user:5". ownerId vide → null
Owners::resolveName($ownerId, $ownerType) Nom affiché sur les cartes et les listes (null s’il n’y en a pas, cache de 20 secondes)
Owners::flush() Invalide le cache après une modification d’utilisateur ou d’équipe

Par exemple, le contrôleur d’enregistrement des instances procède ainsi :

// ref du responsable ("user:5"/"team:3") → owner_id + owner_type
[$ownerType, $ownerId] = Owners::split($request->input('owner_ref'));
$payload['owner_id']   = $ownerId ?: null;
$payload['owner_type'] = $ownerId ? $ownerType : 'user';   // 'user' par défaut si non renseigné

La même ref sert au filtrage par responsable : la requête de liste découpe le paramètre owner (user:5/team:3) avec split() et restreint à WHERE owner_id = ? AND owner_type = ?.

Le sélecteur de responsable est réutilisé à l’identique sur les écrans d’actifs Instances, Matériel et Stockage et fichiers. Affecter une équipe comme responsable place l’équipe entière sur la ligne de responsabilité (ce qui résiste au départ de n’importe quelle personne).

Avatar · initiales · couleur

L’avatar affiché à côté d’un libellé est généré à partir du nom par RolePolicy.

Sources de données

Table Rôle
infr_role Référentiel des rôles (6 libellés informatifs) — key·name·color·seq·is_active
infr_team Référentiel des équipes — name·color·lead_user_id·description·is_active·seq
users Utilisateurs — user_level (décide de l’accès), role_id (nullable), team_id (nullable)
tables d’actifs Responsable enregistré dans les deux colonnes owner_id + owner_type (user/team) (Instances/Matériel/Stockage, etc.)

Assistants SOT :

Accès

Garde-fous (protection du dernier administrateur)

Situation Résultat
Rétrograder / désactiver / supprimer le dernier administrateur actif Refusé — « Le dernier administrateur actif ne peut pas être rétrogradé, désactivé ou supprimé. »
Abaisser ou désactiver son propre niveau d’administrateur Refusé — « Vous ne pouvez pas rétrograder ni désactiver votre propre accès administrateur. »
Se supprimer soi-même Refusé — « Vous ne pouvez pas vous supprimer vous-même. »
Identifiant déjà utilisé Refusé — « Cet identifiant est déjà utilisé. »

Dépannage et FAQ

Q. J’ai donné à quelqu’un le rôle « Sécurité » mais les écrans de sécurité ne s’ouvrent pas. Les rôles sont des libellés ; ils n’ouvrent aucune permission. Les écrans de sécurité (essentiellement en lecture) exigent un niveau — faites-le passer à Personnel (5) ou au-delà. Voir Niveaux RBAC.

Q. Un utilisateur ou une équipe manque dans la liste déroulante des responsables. Les utilisateurs clôturés (is_close=1) et les équipes inactives (is_active=0) sont exclus du sélecteur. Réactivez l’utilisateur ou l’équipe ; si la liste est périmée, attendez l’expiration du cache de 20 secondes (Owners::flush() l’invalide immédiatement).

Q. Si je supprime une équipe, ses membres disparaissent-ils ? Non. Les utilisateurs subsistent ; seul leur team_id devient null (sans affectation). La référence owner_type='team' d’un actif est indépendante : l’actif n’est donc pas supprimé non plus (son responsable affiché devient simplement vide).

Q. J’ai enregistré un responsable mais aucun nom ne s’affiche. resolveName() dispose d’un cache de 20 secondes. Si vous venez de renommer quelque chose, cela se rafraîchit sous peu. Vérifiez également que le format de la ref est bien user:5/team:3 — un format cassé est traité par split() comme sans affectation (user:0).

Q. Un utilisateur peut-il avoir deux rôles ? Non. role_id est une valeur unique (nullable). S’il vous faut aussi un regroupement organisationnel, utilisez une équipe (également une valeur unique).

Voir aussi

사용자 · 팀 관리
사용자 · 팀 관리