Files
api/services/nginx/app/classes/authentication.php
T
Jeppe Bundgaard af6b89ff54 Enhance authentication logic for customers with default passwords
- Added a check to ensure customers with group ID other than 0 cannot use default passwords.
- Implemented logic to auto-set passwords to the last 4 digits of the customer number if no password is set.
- Updated method documentation to include an `@throws Exception` annotation.
2025-10-28 11:06:18 +01:00

149 lines
4.8 KiB
PHP

<?php
namespace classes;
use Exception;
use interfaces\authentication_i;
use objects\plate_scanners_o;
use objects\tokens_o;
use objects\users_o;
class authentication implements authentication_i
{
/**
* @throws Exception
*/
public function authenticate(int $customer_number, string $password): bool
{
// Get the customer from the database
$customer = (new users_o())->getUserByCustomerNumber($customer_number);
// Check if the customer exists
if (!$customer->exists()) {
return false;
}
// Check if the customer has a password
if (!$customer->hasPassword()) {
// Make sure the customer group is 0, to prevent higher privilege users from accessing the system through the default password.
if ((int)$customer->group_id->value() !== 0) {
return false;
}
// Does have a customer number, set the password to the last 4 digits of the customer number
if (!empty($customer->customer_number->value()) && strlen($customer->customer_number->value()) > 4) {
$customer->setPassword(substr($customer->customer_number->value(), -4));
}
}
// Check if the password is correct
if (!$this->match_passwords($password, $customer->getPassword())) {
return false;
}
return true;
}
public function match_passwords($password, $hash): bool
{
// Compare the password with the hash
return password_verify($password, $hash);
}
public function create_token(int $customer_number): string
{
// Create a token
$token = bin2hex(random_bytes(32));
// Get the user id
$user_id = (new users_o())->getUserByCustomerNumber($customer_number)->id;
// Save the token in the database
(new tokens_o())->create($user_id, $token, 'AUTH_TOKEN');
return $token;
}
public function create_employee_token(int $employee_id): string
{
// Create a token
$token = bin2hex(random_bytes(32));
// Save the token in the database
(new tokens_o())->create($employee_id, $token, 'AUTH_TOKEN');
return $token;
}
public function validate_token(string $token): bool
{
// Get the token from the database
$token = (new tokens_o())->getToken($token);
// Check if the token exists
if (!$token->id) {
return false;
}
return true;
}
/**
* @throws Exception
*/
public function get_user(): users_o|false
{
/**
* Get the user from the token
*/
// Get the token from the headers
$headers = getallheaders();
if (!isset($headers['Authorization'])) {
return false;
}
$token = $headers['Authorization'];
// Strip the Bearer prefix
$token = str_replace('Bearer ', '', $token);
// Get the token from the database
$token = (new tokens_o())->getToken($token);
// Check if the token exists
if (!$token->id) {
return false;
}
// Get the user from the database
return (new users_o())->getUserById($token->user_id->value());
}
public function get_plate_scanner(): plate_scanners_o|false
{
// Get the token from the headers
$headers = getallheaders();
$tmp = json_decode(file_get_contents('php://input'), true);
if (!isset($headers['Authorization']) && !isset($_GET['token']) && !isset($_POST['token']) && !isset($tmp['token'])) {
return false;
}
$token = $_GET['token'] ?? $headers['Authorization'] ?? $tmp['token'] ?? $_POST['token'];
// Strip the Bearer prefix (If the token is from the headers)
if (isset($headers['Authorization'])) {
$token = str_replace('Bearer ', '', $token);
}
// Get the token from the database
$token = (new plate_scanners_o())->getPlateScannerByApiKey($token);
// Check if the token exists
if (!isset($token->id)) {
return false;
}
// Get the plate scanner from the database
return $token;
}
public function hash_password($password): string
{
// Hash the password
return password_hash($password, PASSWORD_DEFAULT);
}
public function authenticateEmployee(int $user_id, string $password): bool
{
// Get the employee from the database
$employee = (new users_o())->getUserById($user_id);
// Check if the employee exists
if (!$employee->exists()) {
return false;
}
// Check if the password is correct
if (!$this->match_passwords($password, $employee->getPassword())) {
return false;
}
return true;
}
}