/register endpoint, permissions
Hi Maurits,
Once again, great job on a welcomed feature (/register endpoint and dbAuth.registerUser middleware config)!
Do you think if it would be feasible to add a config (or use the same dbAuth.registerUser config) that would allow us to specify what operations should be allowed on this endpoint (e.g.: allow-overwrite / unique, something like that) - maybe, failing if we try something that is not allowed, etc. ?
Scenario: I have a predefined user (let's call it "super-admin"). This super-admin user, after being logged in, will try to register a new user via the /register endpoint. Now, the api allows us to repeat this operation, basically adding the same user to the db multiple times. Could we stop this behaviour via a config option? This is just for discussion, and, maybe, future enhancement of this (really great) endpoint.
Cheers! Keep the good work comin'!
P.S.: or should we strictly control this via the UNIQUE descriptor in the DB schema? (somehow, I answered my own question, rhetorically. You can close this issue if it is of no real value to the project)
This super-admin user, after being logged in, will try to register a new user via the /register endpoint.
Yeah. this can happen.. or people can sign themselves up.
or should we strictly control this via the UNIQUE descriptor in the DB schema?
Yes, that would probably be the best option anyway.
Now, the api allows us to repeat this operation, basically adding the same user to the db multiple times.
I added an error if the user already exists (code 1020).
It certainly is of real value to the project, but since it is covered now, I'm closing it anyway.
Thank you for helping me create this functionality!
Hi, Thanks for the fast reply. I am a bit confused on this line from your reply ".. or people can sign themselves up.": how can the users sign themselves up? To be able to use the /register endpoint, we need to enable dbAuth middleware, right? And by enabling dbAuth middleware, we need to pass the authentication to access the /register endpoint (which implies that we already have a username/password set up). Isn't this situation self-excluding? Just asking.
P.S.: great job on the /password endpoint. If you could come up with a mechanism for password-reset, that would make the user registration/auth/recovery cycle complete.
Keep it up!
And by enabling dbAuth middleware, we need to pass the authentication to access the /register endpoint
No, right now the register endpoint is public. Because I can see a system where people sign themselves up.
You say that there is also a case where people with specific permissions can sign others up.
That would probably mean that there is also a case where people with specific permissions can set passwords for other users.
How to define those conditions for the required permissions?
I was thinking:
'registerCondition' => 'admin,eq,1',
'passwordCondition' => 'admin,eq,1',
And for the reset, we need the username to be an email and we need a token and a reset endpoint.
Maybe we can have a single superuser condition for both, or for even more complex situations a userLevelColumn (int) that needs to be higher in order to control password resets. I'm just thinking out loud.
I'm thinking the superuser condition that allows user creation and password resets will do for now.
I did some changes in my src/Tqdev/PhpCrudApi/Middleware/DbAuthMiddleware.php
Put this with the username/password from body
$userlevel = (isset($body->userlevel) && is_numeric ($body->userlevel)) ? $body->userlevel : 0;
Added some more fields for the config
$userLevelColumnName = $this->getProperty('userLevelColumn', 'userlevel');
$userLevelColumn = $table->getColumn($userLevelColumnName);
$registerUserLevel = $this->getProperty('registerUserLevel', 0);
After the check that registerUser is true, I added this
if ($registerUserLevel > 0) {
if (!isset($_SESSION['user'][$usernameColumnName]))
return $this->responder->error(ErrorCode::AUTHENTICATION_FAILED, $username);
if ($_SESSION['user'][$userLevelColumnName] < $registerUserLevel)
return $this->responder->error(ErrorCode::AUTHENTICATION_FAILED, $username);
}
And finally to add the userlevel to the database I added this
$data[$userLevelColumnName] = $userlevel;
Just have to make new errorcodes for those two errors now.
In the config, I can now add
'dbAuth.registerUserLevel' => 5, // Only userlevel 5 or above can register users
'dbAuth.userLevelColumn' => 'userlevel', // If I want to use another column name
If no registerUserLevel is set, the default is 0 (everybody can register, even if they are not logged in)