Hey there!
I was able to solve mine by replacing instead of extending.
I disabled the CRUD on all roles and implemented the CRUD creating a folder structure to replace it inside config folder. Like this:
config/
âapi/
----content/
------examples.get.php
------example.post.php
------example.get.php
------example/
--------[âŚall].get.php
--------[âŚall].delete.php
Please mind the usage of plural and singular wording but that was just for my case. I believe itâs possible to use the same model name changing accordingly!
Also, dont forget to create a Public role (no permissions needed) and assign it to the Public API in âSettings â API & Security â Public API access permissions for unauthenticated requests.â
<----------------->
When a URI parameter is necessary, a folder must be created with php files for the REST verbs inside it.
You may realize that I made two GET files for the same model: âexample.get.phpâ and âexample/[âŚall].get.phpâ.
That is to completly mimic the original code which replied with the last created item if no ID is provided on the URI parameter.
The code for each file is basically the same as the one on core code (/api/modules/Content/api.php) but with small changes concerning the security I intended.
Some were removed (verification that user can access model data using âisAllowedâ) and some were addedâŚ
To access the query parameters, I placed the following on the top of the php file:
parse_str($_SERVER[âQUERY_STRINGâ], $params);
With that, $params will be an array with all the parameters after the â?â on the URL requested
For the singular model, we also need to use this:
$id = $API_ARGS[0];
This will get you the ID when you provide it in the URI string, before the â?â if used
<----------------->
To filter the response only to the items that were created by the user requesting if they have a âbasicâ role, I placed the following code right before the system call to the default results:
if ($role == âbasicâ) {
$options[âfilterâ][â_cbyâ] = $by;
//or this:
//$filter[â_cbyâ] = $by;
//depending if is plural or singular model
//analyze the code you copy to be sure
}
That â$byâ variable had to be assigned in a differente way because â$app->helper(âauthâ)->getUser()â object didnt provide the user ID.
So, I used this piece of code also on the start of the php file:
$username = $app->helper(âauthâ)->getUser()[âuserâ];
$user = $app->dataStorage->findOne(âsystem/usersâ, [âuserâ => $username]);
$by = $user[â_idâ];
$role = $app->helper(âauthâ)->getUser(âroleâ);
<----------------->
Because getUser() didnt provide user ID, I also had to change something important on the POST php file (example.post.php).
On the system request from the core code, it goes like this:
$item = $app->module(âcontentâ)->saveItem($model[ânameâ], $data, [âuserâ => $app->helper(âauthâ)->getUser()]);
Since getUser() doesnt have the â_idâ field, we have to provide a complete user object like this:
$item = $app->module(âcontentâ)->saveItem($model[ânameâ], $data, [âuserâ => $user]);
With this, the content created will have the â_cbyâ field correctly filled to be compared on the GETs.
<----------------->
Important to note that, if you copy from the core files, you also need to place this at the start of the php file:
$app = $this;
$model = âexamplesâ;
Because the code on core files is using similar variables on the rest of the code and instead of changing it, we can reuse it 
<----------------->
I also created an auth.php on the root of config/api to handle the login with user/password or API key.
It works good but in terms of security it needs work because the API key wont change regularly unless changed manually.
Probably I can do it programatically at each login/request but for now, I didnt implemented it because of time and being small project without many security concerns.
I saw some JWT code on the core files that indicate that something may be worked on but no implementation for nowâŚ
In conclusion, it would be great to have that extend functionality, login through API with user/pass and JWT tokens (and/or cookies) but its also doable with this solutions.
Im sorry for the long post and hope to help somebody that come accross thisâŚ
You can contact or reply if you need some help making it happen to your situation!