Skip to content

Commit 942df37

Browse files
imorlandStyleCIBot
andauthored
[2.x] fix: validate mail settings for whitespace (#4251)
* fix: validate mail settings for whitespace * Apply fixes from StyleCI --------- Co-authored-by: StyleCI Bot <[email protected]>
1 parent fd556a1 commit 942df37

File tree

4 files changed

+181
-5
lines changed

4 files changed

+181
-5
lines changed

framework/core/src/Mail/MailgunDriver.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
class MailgunDriver implements DriverInterface
2020
{
21+
use ValidatesMailSettings;
22+
2123
public function availableSettings(): array
2224
{
2325
return [
@@ -33,7 +35,7 @@ public function availableSettings(): array
3335
public function validate(SettingsRepositoryInterface $settings, Factory $validator): MessageBag
3436
{
3537
return $validator->make($settings->all(), [
36-
'mail_mailgun_secret' => 'required',
38+
'mail_mailgun_secret' => ['required', $this->noWhiteSpace()],
3739
'mail_mailgun_domain' => 'required|regex:/^(?!\-)(?:[a-zA-Z\d\-]{0,62}[a-zA-Z\d]\.){1,126}(?!\d+)[a-zA-Z\d]{1,63}$/',
3840
'mail_mailgun_region' => 'required|in:api.mailgun.net,api.eu.mailgun.net',
3941
])->errors();

framework/core/src/Mail/SmtpDriver.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
class SmtpDriver implements DriverInterface
2020
{
21+
use ValidatesMailSettings;
22+
2123
public function __construct(
2224
protected EsmtpTransportFactory $factory
2325
) {
@@ -37,11 +39,11 @@ public function availableSettings(): array
3739
public function validate(SettingsRepositoryInterface $settings, Factory $validator): MessageBag
3840
{
3941
return $validator->make($settings->all(), [
40-
'mail_host' => 'required',
41-
'mail_port' => 'nullable|integer',
42+
'mail_host' => ['required', $this->noWhiteSpace()],
43+
'mail_port' => ['nullable', 'integer', $this->noWhiteSpace()],
4244
'mail_encryption' => 'nullable|in:tls,ssl,TLS,SSL',
43-
'mail_username' => 'nullable|string',
44-
'mail_password' => 'nullable|string',
45+
'mail_username' => ['nullable', 'string', $this->noWhiteSpace()],
46+
'mail_password' => ['nullable', 'string', $this->noWhiteSpace()],
4547
])->errors();
4648
}
4749

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
/*
4+
* This file is part of Flarum.
5+
*
6+
* For detailed copyright and license information, please view the
7+
* LICENSE file that was distributed with this source code.
8+
*/
9+
10+
namespace Flarum\Mail;
11+
12+
trait ValidatesMailSettings
13+
{
14+
/**
15+
* Returns a validation rule that checks for leading or trailing whitespace.
16+
*
17+
* @return callable
18+
*/
19+
protected function noWhitespace(): callable
20+
{
21+
return function ($attribute, $value, $fail) {
22+
if ($value !== trim($value)) {
23+
$fail('The '.str_replace('_', ' ', $attribute).' must not contain leading or trailing whitespace.');
24+
}
25+
};
26+
}
27+
}
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
<?php
2+
3+
/*
4+
* This file is part of Flarum.
5+
*
6+
* For detailed copyright and license information, please view the
7+
* LICENSE file that was distributed with this source code.
8+
*/
9+
10+
namespace Flarum\Tests\integration\api\settings;
11+
12+
use Flarum\Testing\integration\RetrievesAuthorizedUsers;
13+
use Flarum\Testing\integration\TestCase;
14+
use PHPUnit\Framework\Attributes\Test;
15+
16+
class MailSettingsTest extends TestCase
17+
{
18+
use RetrievesAuthorizedUsers;
19+
20+
/**
21+
* @inheritDoc
22+
*/
23+
protected function setUp(): void
24+
{
25+
parent::setUp();
26+
27+
$this->prepareDatabase([
28+
'users' => [
29+
$this->normalUser(),
30+
],
31+
]);
32+
}
33+
34+
#[Test]
35+
public function smtpDriverWithWhitespaceIsInvalidated()
36+
{
37+
$this->setting('mail_driver', 'smtp');
38+
$this->setting('mail_host', ' world');
39+
$this->setting('mail_port', ' 587 ');
40+
$this->setting('mail_encryption', 'tls');
41+
$this->setting('mail_username', 'user ');
42+
$this->setting('mail_password', ' password');
43+
44+
$mailSettingsResponse = $this->send(
45+
$this->request('GET', '/api/mail/settings', [
46+
'authenticatedAs' => 1,
47+
])
48+
);
49+
50+
$this->assertEquals(200, $mailSettingsResponse->getStatusCode());
51+
52+
$data = json_decode((string) $mailSettingsResponse->getBody(), true);
53+
54+
$this->assertFalse($data['data']['attributes']['sending']);
55+
56+
$this->assertArrayHasKey('errors', $data['data']['attributes']);
57+
58+
$this->assertArrayHasKey('mail_host', $data['data']['attributes']['errors']);
59+
$this->assertEquals('The mail host must not contain leading or trailing whitespace.', $data['data']['attributes']['errors']['mail_host'][0]);
60+
61+
$this->assertArrayHasKey('mail_port', $data['data']['attributes']['errors']);
62+
$this->assertEquals('The mail port must not contain leading or trailing whitespace.', $data['data']['attributes']['errors']['mail_port'][0]);
63+
64+
$this->assertArrayHasKey('mail_username', $data['data']['attributes']['errors']);
65+
$this->assertEquals('The mail username must not contain leading or trailing whitespace.', $data['data']['attributes']['errors']['mail_username'][0]);
66+
67+
$this->assertArrayHasKey('mail_password', $data['data']['attributes']['errors']);
68+
$this->assertEquals('The mail password must not contain leading or trailing whitespace.', $data['data']['attributes']['errors']['mail_password'][0]);
69+
}
70+
71+
#[Test]
72+
public function smtpDriverWithValidSettingsIsNotInvalidated()
73+
{
74+
$this->setting('mail_driver', 'smtp');
75+
$this->setting('mail_host', 'mail.example.com');
76+
$this->setting('mail_port', '587');
77+
$this->setting('mail_encryption', 'tls');
78+
$this->setting('mail_username', 'user');
79+
$this->setting('mail_password', 'password');
80+
81+
$mailSettingsResponse = $this->send(
82+
$this->request('GET', '/api/mail/settings', [
83+
'authenticatedAs' => 1,
84+
])
85+
);
86+
87+
$this->assertEquals(200, $mailSettingsResponse->getStatusCode());
88+
89+
$data = json_decode((string) $mailSettingsResponse->getBody(), true);
90+
91+
$this->assertEmpty($data['data']['attributes']['errors']);
92+
$this->assertTrue($data['data']['attributes']['sending']);
93+
}
94+
95+
#[Test]
96+
public function mailgunDriverWithWhitespaceIsInvalidated()
97+
{
98+
$this->setting('mail_driver', 'mailgun');
99+
$this->setting('mail_mailgun_secret', 'key ');
100+
$this->setting('mail_mailgun_domain', ' example.com');
101+
$this->setting('mail_mailgun_region', 'api.mailgun.net');
102+
103+
$mailSettingsResponse = $this->send(
104+
$this->request('GET', '/api/mail/settings', [
105+
'authenticatedAs' => 1,
106+
])
107+
);
108+
109+
$this->assertEquals(200, $mailSettingsResponse->getStatusCode());
110+
111+
$data = json_decode((string) $mailSettingsResponse->getBody(), true);
112+
113+
$this->assertFalse($data['data']['attributes']['sending']);
114+
115+
$this->assertArrayHasKey('errors', $data['data']['attributes']);
116+
117+
$this->assertArrayHasKey('mail_mailgun_secret', $data['data']['attributes']['errors']);
118+
$this->assertEquals('The mail mailgun secret must not contain leading or trailing whitespace.', $data['data']['attributes']['errors']['mail_mailgun_secret'][0]);
119+
120+
$this->assertArrayHasKey('mail_mailgun_domain', $data['data']['attributes']['errors']);
121+
$this->assertEquals('The mail mailgun domain field format is invalid.', $data['data']['attributes']['errors']['mail_mailgun_domain'][0]);
122+
}
123+
124+
#[Test]
125+
public function mailgunDriverWithValidSettingsIsNotInvalidated()
126+
{
127+
$this->setting('mail_driver', 'mailgun');
128+
$this->setting('mail_mailgun_secret', 'key');
129+
$this->setting('mail_mailgun_domain', 'example.com');
130+
$this->setting('mail_mailgun_region', 'api.mailgun.net');
131+
132+
$mailSettingsResponse = $this->send(
133+
$this->request('GET', '/api/mail/settings', [
134+
'authenticatedAs' => 1,
135+
])
136+
);
137+
138+
$this->assertEquals(200, $mailSettingsResponse->getStatusCode());
139+
140+
$data = json_decode((string) $mailSettingsResponse->getBody(), true);
141+
142+
$this->assertEmpty($data['data']['attributes']['errors']);
143+
$this->assertTrue($data['data']['attributes']['sending']);
144+
}
145+
}

0 commit comments

Comments
 (0)