Guard customer self-serve commands behind module flag

This commit is contained in:
Jeppe B
2026-06-02 09:14:57 +02:00
parent ec1988715d
commit eefa521fc5
2 changed files with 94 additions and 1 deletions
@@ -1418,7 +1418,7 @@ class moduleSelfServeRoute
return;
}
if ($allow_customer_self_serve) {
if ($allow_customer_self_serve && $this->isSelfServeModuleEnabled()) {
$customer_allowed = $requires_active_wash
? $this->canCustomerUseActiveSelfServeLane($lane, $customer_number)
: $this->canCustomerUseSelfServeLane($lane, $customer_number);
@@ -1452,6 +1452,15 @@ class moduleSelfServeRoute
$this->emitForbidden([...$elevated_permissions, self::CUSTOMER_SELFSERVE_PERMISSION]);
}
protected function isSelfServeModuleEnabled(): bool
{
try {
return (bool)(new selfserve())->config->enabled->getVariableValue();
} catch (\Throwable) {
return false;
}
}
protected function canCustomerUseSelfServeLane(selfserve_lane $lane, int $customer_number): bool
{
return $customer_number > 0
@@ -17,9 +17,12 @@ class SelfserveCustomerLaneAccessRouteHarness extends moduleSelfServeRoute
'list_own_department_selfserve_vehicle_conditions' => true,
];
public bool $laneEnabled = true;
public bool $moduleEnabled = true;
public bool $activeWashResult = false;
/** @var array<int,array{department_id:int,customer_number:int}> */
public array $activeWashChecks = [];
/** @var array<int,string> */
public array $forbiddenPermissions = [];
public function __construct()
{
@@ -42,11 +45,33 @@ class SelfserveCustomerLaneAccessRouteHarness extends moduleSelfServeRoute
return $this->canCustomerUseActiveSelfServeLane($lane, $customer_number);
}
protected function isSelfServeModuleEnabled(): bool
{
return $this->moduleEnabled;
}
protected function isLaneSelfServeOperationallyEnabled(selfserve_lane $lane): bool
{
return $this->laneEnabled;
}
protected function emitForbidden(array $permissions): void
{
$this->forbiddenPermissions = array_values($permissions);
throw new RuntimeException('forbidden');
}
public function requireCommandPermissionForTest(
selfserve_lane $lane,
int $customer_number,
string $command_permission,
bool $allow_customer_self_serve,
bool $requires_active_wash = false
): void {
$method = new ReflectionMethod(moduleSelfServeRoute::class, 'requireSelfServeLaneCommandPermission');
$method->invoke($this, $lane, $customer_number, $command_permission, $allow_customer_self_serve, $requires_active_wash);
}
protected function customerHasActiveSelfServeWashInDepartment(int $department_id, int $customer_number): bool
{
$this->activeWashChecks[] = [
@@ -157,3 +182,62 @@ it('blocks active wash operations for other customers', function (): void {
],
]);
});
it('denies customer self-serve command fallback when the self-serve module is disabled', function (): void {
$route = new SelfserveCustomerLaneAccessRouteHarness();
$route->moduleEnabled = false;
$lane = new SelfserveCustomerLaneAccessLaneFake(4, 12345679);
expect(fn() => $route->requireCommandPermissionForTest(
$lane,
12345679,
'modules_selfserve_lane_command_execute_stop',
true,
true
))->toThrow(RuntimeException::class, 'forbidden');
});
it('returns deterministic forbidden permissions when disabled module blocks customer self-serve command fallback', function (): void {
$route = new SelfserveCustomerLaneAccessRouteHarness();
$route->moduleEnabled = false;
$lane = new SelfserveCustomerLaneAccessLaneFake(4, 12345679);
try {
$route->requireCommandPermissionForTest(
$lane,
12345679,
'modules_selfserve_lane_command_execute_stop',
true,
true
);
} catch (RuntimeException $exception) {
expect($exception->getMessage())->toBe('forbidden');
}
expect($route->forbiddenPermissions)->toBe([
'modules_selfserve_lane_command_execute',
'modules_selfserve_lane_command_execute_stop',
'list_own_department_selfserve_vehicle_conditions',
]);
});
it('continues allowing operator self-serve commands when the self-serve module is disabled', function (): void {
$route = new SelfserveCustomerLaneAccessRouteHarness();
$route->moduleEnabled = false;
$route->permissions = [
'modules_selfserve_lane_command_execute' => true,
'modules_selfserve_lane_command_execute_stop' => true,
];
$lane = new SelfserveCustomerLaneAccessLaneFake(4, 12345679);
$route->requireCommandPermissionForTest(
$lane,
12345679,
'modules_selfserve_lane_command_execute_stop',
true,
true
);
expect($route->forbiddenPermissions)->toBe([]);
});