Repository: glpi-project/glpi (PHP)

Issue:
Allow over-quota "No" can be bypassed
### Code of Conduct

- [x] I agree to follow this project's Code of Conduct

### Is there an existing issue for this?

- [x] I have searched the existing issues

### Version

11.0.2

### Bug description

Hello
If the setting for "Allow over-quota" for a licence is set to "No", we can't assign new items to it from the licence.

<img width="1007" height="714" alt="Image" src="https://github.com/user-attachments/assets/7805d60d-8e0f-4682-8447-90679d1fc7bd" />

<img width="1241" height="314" alt="Image" src="https://github.com/user-attachments/assets/e7fd59c0-29c3-4cc3-ae11-31113f3193cc" />

But we can assign a new item from the item directly, exemple with a user :

<img width="1343" height="674" alt="Image" src="https://github.com/user-attachments/assets/83b7cdba-b5d9-43b3-8312-4d57ebcfaf5b" />

<img width="966" height="675" alt="Image" src="https://github.com/user-attachments/assets/12435f33-594a-40db-8505-a58ad495bfe8" />

And the licence is over assigned

<img width="1101" height="346" alt="Image" src="https://github.com/user-attachments/assets/38d33ad5-7cf5-4d76-b423-612c215398f6" />

### Relevant log output

```shell

```

### Page URL

_No response_

### Steps To reproduce

1. Create a licence with with over quota disable
2. Assign items to the licence with the maximum quota allowed
3. Assign this licence from the items directly
4. Quota is bypassed

### Your GLPI setup information

_No response_

### Anything else?

_No response_


Discussion: Please try with latest release.
I just updated to 11.0.4 (i use the docker version), and nothing changed.



Fix (patch):
diff --git a/src/SoftwareLicense_User.php b/src/SoftwareLicense_User.php
index 0f8288a0cc5..013e2993f19 100644
--- a/src/SoftwareLicense_User.php
+++ b/src/SoftwareLicense_User.php
@@ -52,6 +52,47 @@ class SoftwareLicense_User extends CommonDBRelation
 
     public static $checkItem_2_Rights = self::HAVE_SAME_RIGHT_ON_ITEM;
 
+    public function prepareInputForAdd($input)
+    {
+        if (
+            !isset($input['softwarelicenses_id'])
+            || !is_numeric($input['softwarelicenses_id'])
+            || !isset($input['users_id'])
+        ) {
+            trigger_error('softwarelicenses_id and users_id are mandatory', E_USER_WARNING);
+            return false;
+        }
+
+        $softwarelicenses_id = (int) $input['softwarelicenses_id'];
+
+        $license = new SoftwareLicense();
+        if (!$license->getFromDB($softwarelicenses_id)) {
+            trigger_error(sprintf('Unable to load software license %d', $softwarelicenses_id), E_USER_WARNING);
+            return false;
+        }
+
+        // Check quota if not unlimited (-1) and over-quota not allowed
+        if (
+            $license->getField('number') != -1
+            && !$license->getField('allow_overquota')
+        ) {
+            // Count current assignments (users + items)
+            $count = self::countForLicense($softwarelicenses_id);
+            $count += Item_SoftwareLicense::countForLicense($softwarelicenses_id);
+
+            if ($count >= $license->getField('number')) {
+                Session::addMessageAfterRedirect(
+                    __s('Maximum number of items reached for this license.'),
+                    false,
+                    ERROR
+                );
+                return false;
+            }
+        }
+
+        return parent::prepareInputForAdd($input);
+    }
+
     public static function getTypeName($nb = 0)
     {
         return SoftwareLicense::getTypeName($nb);