Files
api/services/nginx/app/routes/vehiclesRoute.php
T
Jepp9350 3ad09e9367 Fix type comparison in vehicle deletion logic
Ensure correct comparison between customer ID and user number by explicitly casting both to integers. This prevents potential logical errors when checking permissions for vehicle deletion.
2025-04-09 15:55:31 +02:00

324 lines
14 KiB
PHP

<?php
namespace routes;
use classes\authentication;
use objects\customer_vehicles_o;
use objects\logs_o;
use objects\products_o;
use objects\users_o;
use traits\route_t;
class vehiclesRoute
{
use route_t;
public function run(): void
{
$this->get('/vehicles', function () {
// Require the user to be logged in
global $response;
$this->requirePermission('list_own_vehicles');
// Get the user object
$user = (new authentication())->get_user();
// Check if the request was successful
if ($user) {
// Log the incident
(new logs_o())->add('vehicles', 'global', 1, $user->id, 'LIST_OWN_VEHICLES', 'Successfully listed own vehicles');
// Return the list of the user's vehicles
$vehicles_o = new customer_vehicles_o();
// Check if the user is allowed to list other user's vehicles
if (!$user->hasPermission('list_vehicles_other')) {
$restrict = [
'customer_id' => (int)$user->customer_number->value(),
];
}
$response->success(
$vehicles_o->listObjectsWithPaginationIfSet(
function ($vehicle) use ($user) {
// Return the object as an array
return [
...(new customer_vehicles_o())->select($vehicle['id'])->asArray(),
];
},
$vehicles_o->forceRestrictFilters([
...$restrict ?? []
])
)
);
} else {
// Log the incident
(new logs_o())->add('vehicles', 'global', 1, 0, 'LIST_OWN_VEHICLES', 'No user found, or invalid session');
// Return an error
$response->error('Invalid session', 400);
}
},
[
'list_own_vehicles' => 'List own vehicles',
'list_vehicles_other' => 'List other users vehicles',
]
);
$this->post('/vehicles', function () {
// Require the user to be logged in
global $response;
$this->requirePermission('add_vehicle');
// Get the user object
$user = (new authentication())->get_user();
// Check if the request was successful
if ($user) {
// Require the parameters
self::requireParameters([
'type',
'reg',
'wash_subscription',
]);
// Set the customer_id to the one from the user
$target_user = $user;
// Check if customer_id is set
if (self::isParametersSet([
'customer_id',
])) {
// Check if the customer_id is the same as the current user
if ((int)$user->customer_number->value() !== (int)self::getParameter('customer_id')) {
// Check if the user has permission to add vehicles to other users
if (!$user->hasPermission('add_vehicle_other')) {
// Log the incident
(new logs_o())->add('vehicles', 'global', 1, $user->id, 'ADD_VEHICLE', 'User tried to add a vehicle to another user');
// Return an error
$response->error('You are not allowed to add vehicles to other users', 403);
} else {
// Set the customer_id to the one from the request
$target_user = (new users_o());
$target_user->getUserByCustomerNumber((int)self::getParameter('customer_id'));
}
}
}
// Validate the parameters
self::requireType(
self::getParameter('reg'),
self::type_string()
);
self::requireType(
self::getParameter('type'),
self::type_int()
);
self::requireType(
self::getParameter('wash_subscription'),
self::type_bool()
);
// Get the parameters
$reg = (string)self::getParameter('reg');
$type = (int)self::getParameter('type');
$subscription = (bool)self::getParameter('wash_subscription');
// Create a new vehicle
$vehicle = new customer_vehicles_o();
$vehicle->add(
$target_user->customer_number->value(),
$type,
$reg,
$subscription ? 1 : 0
);
// Log the incident
(new logs_o())->add('vehicles', 'global', 1, $user->id, 'ADD_VEHICLE', 'Successfully added vehicle');
// Return the new vehicle
$response->success(
$vehicle->asArray()
);
} else {
// Log the incident
(new logs_o())->add('vehicles', 'global', 1, 0, 'ADD_VEHICLE', 'No user found, or invalid session');
// Return an error
$response->error('Invalid session', 401);
}
},
[
'add_vehicle' => 'Add a vehicle to own vehicles',
'add_vehicle_other' => 'Add a vehicle to another users vehicles',
]
);
$this->put('/vehicles', function () {
// Require the user to be logged in
global $response;
$this->requirePermission('edit_vehicle');
// Get the user object
$user = (new authentication())->get_user();
// Check if the request was successful
if ($user) {
// Log the incident
(new logs_o())->add('vehicles', 'global', 1, $user->id, 'EDIT_VEHICLE', 'User edited a vehicle');
// Get the request data
self::requireParameters([
'id'
]);
$id = (int)self::getParameter('id');
// Get the vehicle object
$vehicle = (new customer_vehicles_o())->select($id);
// Check if the vehicle exists
if (!$vehicle->exists()) {
// Log the incident
(new logs_o())->add('vehicles', 'global', 1, $user->id, 'EDIT_VEHICLE', 'Vehicle not found');
// Return an error
$response->error('Vehicle not found', 404);
}
// Check if the user is allowed to edit the vehicle
if ($vehicle->customer_id->value() !== (int)$user->customer_number->value()) {
// Check if the user has permission to edit other users vehicles
if (!$user->hasPermission('edit_vehicle_other')) {
// Log the incident
(new logs_o())->add('vehicles', 'global', 1, $user->id, 'EDIT_VEHICLE', 'User tried to edit a vehicle from another user');
// Return an error
$response->error('You are not allowed to edit vehicles from other users', 403);
}
}
// Check all the fields, and if they are set, validate and set them
if (self::isParametersSet(['type'])) {
$type = (int)self::getParameter('type');
// Make sure the type is an integer
self::requireType($type, self::type_int());
self::requireMinValue($type, 1);
// Make sure the type is a valid type
$products_o = new products_o();
$products_o->select((int)$type);
if (!$products_o->exists() || !$products_o->subscription_allowed->value()) {
// Log the incident
(new logs_o())->add('vehicles', 'global', 1, $user->id, 'EDIT_VEHICLE', 'Invalid type');
// Return an error
$response->error('Invalid type', 400);
}
// Set the type
$vehicle->type->set(
(int)$type
);
}
if (self::isParametersSet(['reg'])) {
$reg = (string)self::getParameter('reg');
self::requireType($reg, self::type_string());
self::requireMinLength('reg', 2);
self::requireMaxLength('reg', 12);
// Set the registration number
$vehicle->reg->set($reg);
}
if (self::isParametersSet(['wash_subscription'])) {
$subscription = (bool)self::getParameter('wash_subscription');
self::requireType($subscription, self::type_bool());
// Set the wash subscription
$vehicle->wash_subscription->set($subscription ? 1 : 0);
}
// Return the vehicle
$response->success(
$vehicle->asArray()
);
} else {
// Log the incident
(new logs_o())->add('vehicles', 'global', 1, 0, 'EDIT_VEHICLE', 'No user found, or invalid session');
// Return an error
$response->error('Invalid session', 401);
}
},
[
'edit_vehicle' => 'Edit a vehicle',
'edit_vehicle_other' => 'Edit a vehicle from another user'
]
);
$this->delete('/vehicles', function () {
// Require the user to be logged in
global $response;
$this->requirePermission('delete_vehicle');
// Get the user object
$user = (new authentication())->get_user();
// Check if the request was successful
if ($user) {
// Log the incident
(new logs_o())->add('vehicles', 'global', 1, $user->id, 'DELETE_VEHICLE', 'User deleted a vehicle');
// Get the request data
self::requireParameters([
'id'
]);
$id = (int)self::getParameter('id');
// Get the vehicle object
$vehicle = (new customer_vehicles_o())->select($id);
// Check if the vehicle exists
if (!$vehicle->exists()) {
// Log the incident
(new logs_o())->add('vehicles', 'global', 1, $user->id, 'DELETE_VEHICLE', 'Vehicle not found');
// Return an error
$response->error('Vehicle not found', 404);
}
// Check if the user is allowed to delete the vehicle
if ((int)$vehicle->customer_id->value() !== (int)$user->customer_number->value()) {
// Check if the user has permission to delete other users vehicles
if (!$user->hasPermission('delete_vehicle_other')) {
// Log the incident
(new logs_o())->add('vehicles', 'global', 1, $user->id, 'DELETE_VEHICLE', 'User tried to delete a vehicle from another user');
// Return an error
$response->error('You are not allowed to delete vehicles from other users', 403);
}
}
// Delete the vehicle
$vehicle->delete();
// Return success
$response->success(
[
'success' => true,
'message' => 'Vehicle deleted successfully'
]
);
} else {
// Log the incident
(new logs_o())->add('vehicles', 'global', 1, 0, 'DELETE_VEHICLE', 'No user found, or invalid session');
// Return an error
$response->error('Invalid session', 401);
}
},
[
'delete_vehicle' => 'Delete a vehicle',
'delete_vehicle_other' => 'Remove (delete) a vehicle from another user'
]
);
}
private function getData(mixed $data, $response)
{
if (!isset($data['type'])) {
$response->error('Type is required', 400);
}
if (!isset($data['reg'])) {
$response->error('Registration number is required', 400);
}
if (!isset($data['notes'])) {
$response->error('Notes is required', 400);
}
return $data;
}
private function validateRegistrationNumber(mixed $reg, $response): void
{
if (!preg_match('/^[A-Z0-9]{4,10}$/', $reg)) {
$response->error('Invalid registration number, it must be 4-10 characters long, and only contain uppercase letters and numbers', 400);
}
}
private function validateType(mixed $type, $response): void
{
// Make sure the type is more than 2 characters
if (strlen($type) < 2) {
$response->error('Type is too short, it must be at least 2 characters', 400);
}
// Make sure the type is less than 50 characters
if (strlen($type) > 50) {
$response->error('Type is too long, it must be less than 50 characters', 400);
}
}
private function validateNotes(mixed $notes, $response): void
{
// If the notes are set, make sure they are less than 250 characters
if (isset($notes) && strlen($notes) > 250) {
$response->error('Notes are too long, they must be less than 250 characters', 400);
}
}
}