Skip to content

Commit e77dd57

Browse files
authored
blocklist fixes #1329 (#1330)
* blocklist fixes #1329 * fix linting issue
1 parent 2b161d4 commit e77dd57

File tree

5 files changed

+192
-7
lines changed

5 files changed

+192
-7
lines changed

.vscode/launch.json

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
{
2+
"version": "0.2.0",
3+
"configurations": [
4+
{
5+
"name": "Listen for Xdebug",
6+
"type": "php",
7+
"request": "launch",
8+
"port": 9003
9+
},
10+
{
11+
"name": "Launch currently open script",
12+
"type": "php",
13+
"request": "launch",
14+
"program": "${file}",
15+
"cwd": "${fileDirname}",
16+
"port": 0,
17+
"runtimeArgs": [
18+
"-dxdebug.start_with_request=yes"
19+
],
20+
"env": {
21+
"XDEBUG_MODE": "debug,develop",
22+
"XDEBUG_CONFIG": "client_port=${port}"
23+
}
24+
},
25+
{
26+
"name": "Launch Built-in web server",
27+
"type": "php",
28+
"request": "launch",
29+
"runtimeArgs": [
30+
"-dxdebug.mode=debug",
31+
"-dxdebug.start_with_request=yes",
32+
"-S",
33+
"localhost:8000"
34+
],
35+
"env": {
36+
"ENVIRONMENT": "dev"
37+
},
38+
"program": "${workspaceRoot}/src/index.php", // Updated to src directory
39+
"cwd": "${workspaceRoot}/src", // Updated working directory to src
40+
"port": 9003,
41+
"serverReadyAction": {
42+
"pattern": "Development Server \\(http://localhost:([0-9]+)\\) started",
43+
"uriFormat": "http://localhost:%s",
44+
"action": "openExternally"
45+
}
46+
}
47+
]
48+
}

RELEASENOTES.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# Release Notes
22

3+
### 4.4.3 (UNRELEASED)
4+
* Fix for blocklist capability working inconsistenly [#1329]
5+
36
### 4.4.2 (March 12, 2025)
47
* Support for Gather 2.0 added. [#1323]
58

src/app/Http/Middleware/CallBlocklist.php

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,34 @@ public function __construct(SettingsService $settings)
2929
public function handle(Request $request, Closure $next)
3030
{
3131
if ($this->settings->has("blocklist") &&
32-
strlen($this->settings->get("blocklist") > 0) &&
32+
strlen($this->settings->get("blocklist")) > 0 &&
3333
$request->has("Caller")) {
34+
$caller = $this->ensureLeadingPlus($request->get('Caller'));
35+
3436
$blocklistItems = explode(",", $this->settings->get('blocklist'));
3537
foreach ($blocklistItems as $blocklistItem) {
36-
if (str_starts_with($blocklistItem, $request->get('Caller'))) {
38+
$blocklistItem = $this->ensureLeadingPlus($blocklistItem);
39+
if (str_starts_with($blocklistItem, $caller)) {
3740
return response()->view('rejectCall')->header("Content-Type", "text/xml; charset=utf-8");
3841
}
3942
}
4043
}
4144

4245
return $next($request);
4346
}
47+
48+
/**
49+
* Ensures a phone number has a leading plus sign and no whitespace
50+
*
51+
* @param string $number
52+
* @return string
53+
*/
54+
private function ensureLeadingPlus(string $number): string
55+
{
56+
$number = trim($number);
57+
if (!str_starts_with($number, '+')) {
58+
return '+' . $number;
59+
}
60+
return $number;
61+
}
4462
}

src/app/Services/SettingsService.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
class SettingsService
1313
{
14-
private string $version = "4.4.2";
14+
private string $version = "4.4.3";
1515
private array $allowlist = [
1616
'announce_servicebody_volunteer_routing' => ['description' => '/helpline/announce_servicebody_volunteer_routing' , 'default' => false, 'overridable' => true, 'hidden' => false],
1717
'blocklist' => ['description' => '/general/blocklist' , 'default' => '', 'overridable' => true, 'hidden' => false],

src/tests/Feature/BlocklistTest.php

Lines changed: 120 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
<?php
2+
3+
use App\Services\SettingsService;
4+
25
beforeAll(function () {
36
putenv("ENVIRONMENT=test");
47
});
@@ -11,8 +14,10 @@
1114
});
1215

1316
test('test the blocklist with an exact match', function ($method) {
14-
$caller = "5557778888";
15-
$_SESSION['override_blocklist'] = $caller;
17+
$caller = "+15557778888";
18+
$settingsService = new SettingsService();
19+
$settingsService->set("blocklist", $caller);
20+
app()->instance(SettingsService::class, $settingsService);
1621
$response = $this->call($method, '/', [
1722
"Caller"=>$caller
1823
]);
@@ -22,9 +27,25 @@
2227
->assertSeeInOrderExact(["<?xml version='1.0' encoding='UTF-8'?><Response><Reject/></Response>"], false);
2328
})->with(['GET', 'POST']);
2429

30+
test('test the blocklist with multiple items and an exact match', function ($method) {
31+
$caller = "+15557778888,+15557778890";
32+
$settingsService = new SettingsService();
33+
$settingsService->set("blocklist", $caller);
34+
app()->instance(SettingsService::class, $settingsService);
35+
$response = $this->call($method, '/', [
36+
"Caller"=>"+15557778890"
37+
]);
38+
$response
39+
->assertStatus(200)
40+
->assertHeader("Content-Type", "text/xml; charset=utf-8")
41+
->assertSeeInOrderExact(["<?xml version='1.0' encoding='UTF-8'?><Response><Reject/></Response>"], false);
42+
})->with(['GET', 'POST']);
43+
2544
test('test the blocklist without a match', function ($method) {
26-
$caller = "5557778888";
27-
$_SESSION['override_blocklist'] = $caller;
45+
$caller = "+15557778888";
46+
$settingsService = new SettingsService();
47+
$settingsService->set("blocklist", $caller);
48+
app()->instance(SettingsService::class, $settingsService);
2849
$response = $this->call($method, '/', [
2950
"Caller"=>"5557778889"
3051
]);
@@ -33,3 +54,98 @@
3354
->assertHeader("Content-Type", "text/xml; charset=utf-8")
3455
->assertDontSee(["<?xml version='1.0' encoding='UTF-8'?><Response><Reject/></Response>"], false);
3556
})->with(['GET', 'POST']);
57+
58+
test('test the blocklist with whitespace in caller number', function ($method) {
59+
$caller = "+15557778888";
60+
$settingsService = new SettingsService();
61+
$settingsService->set("blocklist", $caller);
62+
app()->instance(SettingsService::class, $settingsService);
63+
$response = $this->call($method, '/', [
64+
"Caller" => " 15557778888 "
65+
]);
66+
$response
67+
->assertStatus(200)
68+
->assertHeader("Content-Type", "text/xml; charset=utf-8")
69+
->assertSeeInOrderExact(["<?xml version='1.0' encoding='UTF-8'?><Response><Reject/></Response>"], false);
70+
})->with(['GET', 'POST']);
71+
72+
test('test the blocklist with whitespace in blocklist entries', function ($method) {
73+
$caller = " +15557778888 , +15557778890 ";
74+
$settingsService = new SettingsService();
75+
$settingsService->set("blocklist", $caller);
76+
app()->instance(SettingsService::class, $settingsService);
77+
$response = $this->call($method, '/', [
78+
"Caller" => "+15557778890"
79+
]);
80+
$response
81+
->assertStatus(200)
82+
->assertHeader("Content-Type", "text/xml; charset=utf-8")
83+
->assertSeeInOrderExact(["<?xml version='1.0' encoding='UTF-8'?><Response><Reject/></Response>"], false);
84+
})->with(['GET', 'POST']);
85+
86+
test('test the blocklist with missing plus sign in caller number', function ($method) {
87+
$caller = "+15557778888";
88+
$settingsService = new SettingsService();
89+
$settingsService->set("blocklist", $caller);
90+
app()->instance(SettingsService::class, $settingsService);
91+
$response = $this->call($method, '/', [
92+
"Caller" => "15557778888"
93+
]);
94+
$response
95+
->assertStatus(200)
96+
->assertHeader("Content-Type", "text/xml; charset=utf-8")
97+
->assertSeeInOrderExact(["<?xml version='1.0' encoding='UTF-8'?><Response><Reject/></Response>"], false);
98+
})->with(['GET', 'POST']);
99+
100+
test('test the blocklist with missing plus sign in blocklist entries', function ($method) {
101+
$caller = "15557778888,15557778890";
102+
$settingsService = new SettingsService();
103+
$settingsService->set("blocklist", $caller);
104+
app()->instance(SettingsService::class, $settingsService);
105+
$response = $this->call($method, '/', [
106+
"Caller" => "+15557778890"
107+
]);
108+
$response
109+
->assertStatus(200)
110+
->assertHeader("Content-Type", "text/xml; charset=utf-8")
111+
->assertSeeInOrderExact(["<?xml version='1.0' encoding='UTF-8'?><Response><Reject/></Response>"], false);
112+
})->with(['GET', 'POST']);
113+
114+
test('test the blocklist with empty blocklist', function ($method) {
115+
$settingsService = new SettingsService();
116+
$settingsService->set("blocklist", "");
117+
app()->instance(SettingsService::class, $settingsService);
118+
$response = $this->call($method, '/', [
119+
"Caller" => "+15557778888"
120+
]);
121+
$response
122+
->assertStatus(200)
123+
->assertHeader("Content-Type", "text/xml; charset=utf-8")
124+
->assertDontSee(["<?xml version='1.0' encoding='UTF-8'?><Response><Reject/></Response>"], false);
125+
})->with(['GET', 'POST']);
126+
127+
test('test the blocklist with missing Caller parameter', function ($method) {
128+
$caller = "+15557778888";
129+
$settingsService = new SettingsService();
130+
$settingsService->set("blocklist", $caller);
131+
app()->instance(SettingsService::class, $settingsService);
132+
$response = $this->call($method, '/', []);
133+
$response
134+
->assertStatus(200)
135+
->assertHeader("Content-Type", "text/xml; charset=utf-8")
136+
->assertDontSee(["<?xml version='1.0' encoding='UTF-8'?><Response><Reject/></Response>"], false);
137+
})->with(['GET', 'POST']);
138+
139+
test('test the blocklist with partial match', function ($method) {
140+
$caller = "+15557778888";
141+
$settingsService = new SettingsService();
142+
$settingsService->set("blocklist", $caller);
143+
app()->instance(SettingsService::class, $settingsService);
144+
$response = $this->call($method, '/', [
145+
"Caller" => "+1555777888899"
146+
]);
147+
$response
148+
->assertStatus(200)
149+
->assertHeader("Content-Type", "text/xml; charset=utf-8")
150+
->assertDontSee(["<?xml version='1.0' encoding='UTF-8'?><Response><Reject/></Response>"], false);
151+
})->with(['GET', 'POST']);

0 commit comments

Comments
 (0)