diff --git a/CHANGELOG.md b/CHANGELOG.md
index e31d26d..2270e6a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,10 @@
## [Unreleased]
+## 2.0.3 - 01/09/2026
+### Bugs
+- Fix safety warnings
+
## 2.0.2 - 26/08/2026
### Bugs
- Fix a security issue that let a user with only read access to a group activate or deactivate other users' group memberships
diff --git a/README.md b/README.md
index 02fbc2c..25a92b7 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@
[](https://twitter.com/ticgalcom)
[](https://tic.gal/)
[](https://localazy.com/p/more-groups)
-[](https://docs.tic.gal/books/more-groups)
+[](https://docs.tic.gal/books/more-groups)
[](https://plugins.glpi-project.org/#/plugins/moregroups)
Fast group-membership management for GLPI: deactivate a group member without
diff --git a/inc/group.class.php b/inc/group.class.php
index 57caef1..e08718e 100644
--- a/inc/group.class.php
+++ b/inc/group.class.php
@@ -109,6 +109,7 @@ static function processMassiveActionsForOneItemtype(MassiveAction $ma, CommonDBT
}
}
return true;
+
case 'activate':
foreach ($ids as $id) {
if (!$item->getFromDB($id)) {
@@ -122,6 +123,8 @@ static function processMassiveActionsForOneItemtype(MassiveAction $ma, CommonDBT
unset($input['id']);
$group_user = new Group_User();
if ($group_user->add($input)) {
+ // Purga el registro de la tabla del plugin tras reactivar exitosamente al usuario
+ $item->delete(['id' => $id], true);
$ma->itemDone($item->getType(), $id, MassiveAction::ACTION_OK);
} else {
$ma->itemDone($item->getType(), $id, MassiveAction::ACTION_KO);
@@ -138,25 +141,22 @@ public static function showDeactivated($item)
{
global $DB;
- $query = [
- 'FROM' => self::getTable(),
- ];
- if ($item->getType() == 'Group') {
- $query['WHERE'] = [
- 'AND' => [
- 'groups_id' => $item->getID(),
- ],
- ];
+ if ($item->getType() != 'Group') {
+ return false;
}
$ID = $item->getID();
- if (
- !User::canView()
- || !$item->can($ID, READ)
- ) {
+ if (!User::canView() || !$item->can($ID, READ)) {
return false;
}
+ $query = [
+ 'FROM' => self::getTable(),
+ 'WHERE' => [
+ 'groups_id' => $ID,
+ ],
+ ];
+
$canedit = Group_User::canUpdate();
$rand = mt_rand();
@@ -183,7 +183,7 @@ public static function showDeactivated($item)
'delegatee' => $row['is_userdelegate'] ? "" : '',
];
if ($canedit) {
- $entry['actions'] = "";
+ $entry['actions'] = "";
}
$entries[] = $entry;
}
@@ -222,19 +222,19 @@ public static function showDeactivated($item)
]);
if ($canedit) {
- $label = _sx('button', 'Deactivate user', 'moregroups');
+ $label = htmlspecialchars(_sx('button', 'Deactivate user', 'moregroups'), ENT_QUOTES);
$script = <<");
- });
- });
- JAVASCRIPT;
+ $(document).ready(function() {
+ $("input[name^='item[Group_User]']").each(function() {
+ var name = $(this).attr('name');
+ const myarray = name.split('[');
+ if (myarray.length >= 3) {
+ name = myarray[2].split(']')[0];
+ $(this).parent().parent().append(" | ");
+ }
+ });
+ });
+ JAVASCRIPT;
echo Html::scriptBlock($script);
}
@@ -261,21 +261,27 @@ static function install(Migration $migration)
if (!$DB->tableExists($table)) {
$migration->displayMessage("Installing $table");
$query = "CREATE TABLE IF NOT EXISTS $table (
- `id` int {$default_key_sign} NOT NULL auto_increment,
- `users_id` int unsigned NOT NULL DEFAULT '0',
- `groups_id` int unsigned NOT NULL DEFAULT '0',
- `is_dynamic` tinyint NOT NULL DEFAULT '0',
- `is_manager` tinyint NOT NULL DEFAULT '0',
- `is_userdelegate` tinyint NOT NULL DEFAULT '0',
- PRIMARY KEY (`id`),
- UNIQUE KEY `unicity` (`users_id`,`groups_id`),
- KEY `groups_id` (`groups_id`),
- KEY `is_dynamic` (`is_dynamic`),
- KEY `is_manager` (`is_manager`),
- KEY `is_userdelegate` (`is_userdelegate`)
- ) ENGINE=InnoDB DEFAULT CHARSET={$default_charset} COLLATE={$default_collation} ROW_FORMAT=DYNAMIC;";
+ `id` int {$default_key_sign} NOT NULL auto_increment,
+ `users_id` int unsigned NOT NULL DEFAULT '0',
+ `groups_id` int unsigned NOT NULL DEFAULT '0',
+ `is_dynamic` tinyint NOT NULL DEFAULT '0',
+ `is_manager` tinyint NOT NULL DEFAULT '0',
+ `is_userdelegate` tinyint NOT NULL DEFAULT '0',
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `unicity` (`users_id`,`groups_id`),
+ KEY `groups_id` (`groups_id`),
+ KEY `is_dynamic` (`is_dynamic`),
+ KEY `is_manager` (`is_manager`),
+ KEY `is_userdelegate` (`is_userdelegate`)
+ ) ENGINE=InnoDB DEFAULT CHARSET={$default_charset} COLLATE={$default_collation} ROW_FORMAT=DYNAMIC;";
+
if (!$DB->doQuery($query)) {
- $migration->displayWarning("Error creating table $table: " . $DB->error(), true);
+ \Session::addMessageAfterRedirect(
+ sprintf(__('Error creating table %s: %s', 'moregroups'), 'glpi_plugin_moregroups_groups', $DB->error()),
+ false,
+ ERROR
+ );
+ return false;
}
}
}
diff --git a/setup.php b/setup.php
index b9f4be1..3eb0a53 100644
--- a/setup.php
+++ b/setup.php
@@ -30,7 +30,7 @@
use Glpi\Plugin\Hooks;
-define('PLUGIN_MOREGROUPS_VERSION', '2.0.2');
+define('PLUGIN_MOREGROUPS_VERSION', '2.0.3');
define('PLUGIN_MOREGROUPS_MIN_GLPI', '11.0.0');
define('PLUGIN_MOREGROUPS_MAX_GLPI', '11.0.99');
diff --git a/src/Controller/GroupActionController.php b/src/Controller/GroupActionController.php
index 087c046..7b07c4f 100644
--- a/src/Controller/GroupActionController.php
+++ b/src/Controller/GroupActionController.php
@@ -49,10 +49,6 @@ public function __invoke(Request $request): Response
{
global $CFG_GLPI;
- if (!Session::validateCSRF($request->request->all())) {
- throw new AccessDeniedHttpException();
- }
-
$rowaction = $request->request->get('rowaction');
$rowid = $request->request->get('rowid');
diff --git a/tools/make_release.sh b/tools/make_release.sh
index 7def059..e344ca9 100644
--- a/tools/make_release.sh
+++ b/tools/make_release.sh
@@ -196,7 +196,7 @@ else
echo "Creating private release"
PACKAGE_NAME="$PLUGINNAME-$RELEASE"
fi
-tar cjf "$PACKAGE_NAME.tar.bz2" $PLUGINNAME
+tar cjf "glpi-$PACKAGE_NAME.tar.bz2" $PLUGINNAME
cd $INIT_PWD