Compare commits

...

2 commits

Author SHA1 Message Date
Benjamin Renard 6c74b2a719
Auth Db: add add_user method ad CLI command 2024-02-04 11:05:03 +01:00
Benjamin Renard 20461e3e47
Auth Db: use helper methods to retrieve data instead of FPDO raw methods 2024-02-04 11:02:55 +01:00
2 changed files with 100 additions and 15 deletions

View file

@ -3,6 +3,7 @@
namespace EesyPHP\Auth;
use EesyPHP\App;
use EesyPHP\Cli;
use EesyPHP\Log;
use Exception;
@ -52,6 +53,7 @@ class Db extends Backend {
'users_table' => 'users',
'username_field' => 'username',
'password_field' => 'password',
'password_hash_algo' => 'default',
'exposed_fields' => array('name', 'mail'),
)
);
@ -67,6 +69,9 @@ class Db extends Backend {
self :: $username_field = App::get('auth.db.username_field', null, 'string');
self :: $password_field = App::get('auth.db.password_field', null, 'string');
self :: $exposed_fields = App::get('auth.db.exposed_fields', null, 'array');
if (App :: get('cli.enabled'))
Cli :: add_command('add_user', ['\\EesyPHP\\Auth\\Db', 'cli_add_user'], 'Add user');
return true;
}
@ -86,13 +91,11 @@ class Db extends Backend {
public static function get_user($username) {
self :: connect();
try {
$query = self :: $class :: $fpdo -> from(self :: $users_table)
-> select(null)
-> select(self :: $exposed_fields)
-> where(self :: $username_field, $username);
$result = $query -> execute();
$info = $result -> fetch();
$info = self :: $class :: get_one(
self :: $users_table,
[self :: $username_field => $username],
self :: $exposed_fields
);
if ($info === false)
return null;
return new User($username, '\\EesyPHP\\Auth\\Db', $info);
@ -112,20 +115,78 @@ class Db extends Backend {
public static function check_password($user, $password) {
self :: connect();
try {
$query = self :: $class :: $fpdo -> from(self :: $users_table)
-> select(null)
-> select(self :: $password_field)
-> where(self :: $username_field, $user->username);
$result = $query -> execute();
$info = $result -> fetch();
$info = self :: $class :: get_one(
self :: $users_table,
[self :: $username_field => $user->username],
[self :: $password_field]
);
if ($info === false)
return false;
return password_verify($password, $info['password']);
return password_verify($password, $info[self :: $password_field]);
}
catch (Exception $e) {
Log :: error("Error retrieving user %s password from database: %s", $user, $e->getMessage());
}
return false;
}
/**
* Add user in database
* @param array $info User info with at least username, password (clear) and all required exposed
* fields
* @return bool
*/
public static function add_user($info) {
$values = [
App::get('auth.db.username_field') => $info['username'],
App::get('auth.db.password_field') => password_hash(
$info['password'],
constant('PASSWORD_'.strtoupper(App::get('auth.db.password_hash_algo')))
),
];
foreach($info as $field => $value) {
if (!$value) {
Log :: error("add_user: field %s is missing", $field);
return false;
}
}
foreach(App :: get('auth.db.exposed_fields') as $field)
if (isset($info[$field]) && $info[$field])
$values[$field] = $info[$field];
if (self :: $class :: insert(self :: $users_table, $values)) {
Log :: info('add_user(%s): user added', $values['username']);
return true;
}
Log :: error('add_user(%s): error adding user', $values['username']);
return false;
}
/**
* CLI command to add user
* @param array $command_args Command arguments
* @return bool
*/
public static function cli_add_user($command_args) {
$info = ['username' => null, 'password' => null];
foreach($info as $field => $value) {
while(!$value) {
$value = Cli::ask_user("Please enter user $field: ", $field == 'password');
if (empty($value))
print("Invalid value\n");
}
$info[$field] = $value;
}
foreach(self :: $exposed_fields as $field) {
$value = readline("Please enter user $field: ");
if (empty($value))
continue;
$info[$field] = $value;
}
if (self :: add_user($info)) {
printf("User %s added\n", $info['username']);
return true;
}
Log :: fatal("Error occurred adding user %s", $info['username']);
}
}

View file

@ -444,4 +444,28 @@ Additional parameters:
exit(1);
}
/**
* Helper method to ask user to enter value from STDIN
* @param string $prompt Prompt message
* @param boolean $password Set to true if you ask for a password (value not displayed)
* @param array $extra_args Extra arguments used to compute prompt message
* @return string User input
*/
public static function ask_user($prompt, $password=false, ...$extra_args) {
if ($extra_args)
$prompt = call_user_func_array(
'sprintf',
array_merge(array($prompt), $extra_args)
);
if ($password) {
print($prompt);
system('stty -echo');
$password = trim(fgets(STDIN));
system('stty echo');
print("\n");
return $password;
}
return readline($prompt);
}
}