diff --git a/php/inc_fx_eve_acces.php b/php/inc_fx_eve_acces.php
index 853084e..d72b89b 100644
--- a/php/inc_fx_eve_acces.php
+++ b/php/inc_fx_eve_acces.php
@@ -97,7 +97,7 @@ function fxEveAccesGetRoles($blnActifOnly = true)
return $objDatabase->fxGetResults($sql);
}
-/** Kits proposables par un promoteur (role_delegable = 1, hors migration_legacy). */
+/** Kits proposables par un promoteur (role_delegable = 1, hors migration_legacy / kit total). */
function fxEveAccesGetDelegableRoles()
{
global $objDatabase;
@@ -116,11 +116,18 @@ function fxEveAccesGetDelegableRoles()
return array();
}
+ // MSIN-4478 — jamais offrir un kit total (rapports / argent / tout) en invitation promoteur.
+ $strNoGrantsAll = '';
+ if (fxEveAccesHasGrantsAllColumn()) {
+ $strNoGrantsAll = ' AND role_grants_all = 0';
+ }
+
$sql = "SELECT role_id, role_code, role_label_fr, role_label_en, role_description_fr
FROM inscriptions_eve_roles
WHERE role_actif = 1
AND role_delegable = 1
AND role_code <> 'migration_legacy'
+ $strNoGrantsAll
ORDER BY role_tri ASC, role_label_fr ASC";
$tab = $objDatabase->fxGetResults($sql);
@@ -142,8 +149,9 @@ function fxEveAccesRoleIsDelegable($intRoleId)
return false;
}
+ $strGrantsCol = fxEveAccesHasGrantsAllColumn() ? ', role_grants_all' : ', 0 AS role_grants_all';
$row = $objDatabase->fxGetRow(
- "SELECT role_id, role_code, role_delegable, role_actif
+ "SELECT role_id, role_code, role_delegable, role_actif $strGrantsCol
FROM inscriptions_eve_roles WHERE role_id = $intRoleId LIMIT 1"
);
if ($row === null || intval($row['role_actif']) !== 1) {
@@ -152,6 +160,10 @@ function fxEveAccesRoleIsDelegable($intRoleId)
if (($row['role_code'] ?? '') === 'migration_legacy') {
return false;
}
+ // MSIN-4478 — kit total = non délégable (même si la case est cochée en BD).
+ if (intval($row['role_grants_all'] ?? 0) === 1) {
+ return false;
+ }
return intval($row['role_delegable'] ?? 0) === 1;
}
diff --git a/sql/MSIN-4478-eve-acces-kit-total-pas-delegable.sql b/sql/MSIN-4478-eve-acces-kit-total-pas-delegable.sql
new file mode 100644
index 0000000..850f969
--- /dev/null
+++ b/sql/MSIN-4478-eve-acces-kit-total-pas-delegable.sql
@@ -0,0 +1,9 @@
+-- MSIN-4478 — Sécurité : kit total jamais délégable
+-- Contexte : un kit role_grants_all=1 + role_delegable=1 donnait tous les droits (rapports, argent…) à un invité
+-- Notes : exécution UNIQUEMENT sur dev préprod ; autres env = Navicat structure + sync_static_db
+-- Idempotent
+
+UPDATE inscriptions_eve_roles
+SET role_delegable = 0
+WHERE role_grants_all = 1
+ AND role_delegable = 1;
diff --git a/superadm/php/inc_fx_eve_acces_admin.php b/superadm/php/inc_fx_eve_acces_admin.php
index 01a1941..82b0113 100644
--- a/superadm/php/inc_fx_eve_acces_admin.php
+++ b/superadm/php/inc_fx_eve_acces_admin.php
@@ -510,9 +510,9 @@ function fxEveAccesAdminSaveRole($arrData, $arrPermKeys)
if ($blnCodeLocked) {
$blnGrantsAll = 1;
}
- // MSIN-4460 — Kit total n'interdit plus la delegation : c'est le super admin qui decide.
- // Kits systeme uniquement : jamais redistribuables par un promoteur.
- if ($blnCodeLocked || in_array($strCode, array('owner', 'qr_debug'), true)) {
+ // MSIN-4478 — kit total + kits systeme : jamais redistribuables par un promoteur
+ // (évite qu'une invitation donne rapports / argent / tout).
+ if ($blnCodeLocked || $blnGrantsAll || in_array($strCode, array('owner', 'qr_debug'), true)) {
$blnDelegable = 0;
}
@@ -961,7 +961,7 @@ function fxEveAccesAdminRenderKitForm($intRoleId, $strError = '')
Délégable par le promoteur (invitation équipe)
- Le promoteur pourra assigner ce kit à un membre invité. Indépendant de « Kit total » — c’est vous qui choisissez.
+ Le promoteur pourra assigner ce kit à un membre invité. Impossible si « Kit total » est coché (MSIN-4478).
@@ -1101,7 +1101,15 @@ function fxEveAccesAdminRenderKitForm($intRoleId, $strError = '')
if (blnAll) {
$('.perm-checkbox').prop('checked', false);
}
- // MSIN-4460 — Ne plus forcer / desactiver « delegable » quand Kit total est coche.
+ // MSIN-4478 — Kit total = jamais délégable (invitation ne doit pas donner tout).
+ var $deleg = $('#role_delegable');
+ if ($deleg.length && !$deleg.prop('disabled')) {
+ if (blnAll) {
+ $deleg.prop('checked', false).prop('disabled', true);
+ } else {
+ $deleg.prop('disabled', false);
+ }
+ }
}
$('#role_grants_all').on('change', syncGrantsAllUi);