Skip to content

Commit 050d88c

Browse files
feat: add LocalAccountProvider for extracting account info from request payload
refs conjoon/conjoon#23
1 parent ba89d99 commit 050d88c

File tree

2 files changed

+222
-0
lines changed

2 files changed

+222
-0
lines changed
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<?php
2+
3+
/**
4+
* conjoon
5+
* php-lib-conjoon
6+
* Copyright (C) 2023 Thorsten Suckow-Homberg https://github.com/conjoon/php-lib-conjoon
7+
*
8+
* Permission is hereby granted, free of charge, to any person
9+
* obtaining a copy of this software and associated documentation
10+
* files (the "Software"), to deal in the Software without restriction,
11+
* including without limitation the rights to use, copy, modify, merge,
12+
* publish, distribute, sublicense, and/or sell copies of the Software,
13+
* and to permit persons to whom the Software is furnished to do so,
14+
* subject to the following conditions:
15+
*
16+
* The above copyright notice and this permission notice shall be included
17+
* in all copies or substantial portions of the Software.
18+
*
19+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
21+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22+
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
23+
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24+
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
25+
* USE OR OTHER DEALINGS IN THE SOFTWARE.
26+
*/
27+
28+
declare(strict_types=1);
29+
30+
namespace Conjoon\Illuminate\Auth\LocalMailAccount;
31+
32+
use Conjoon\Illuminate\Auth\Imap\DefaultImapUserProvider;
33+
use Conjoon\Illuminate\Auth\ImapUser;
34+
use Conjoon\Mail\Client\Data\MailAccount;
35+
use Illuminate\Http\Request;
36+
37+
/**
38+
* Auth provider that expects required mailserver configurations to be available
39+
* with the payload ("x-cnmail-data"-header).
40+
*/
41+
class LocalAccountProvider extends DefaultImapUserProvider
42+
{
43+
/**
44+
* @var string
45+
*/
46+
private $payload;
47+
48+
/**
49+
* @var string
50+
*/
51+
private $mailAccountId;
52+
53+
54+
public function __construct(Request $request)
55+
{
56+
$this->payload = $request->header("x-cnmail-data");
57+
$this->mailAccountId = $request->route('mailAccountId');
58+
}
59+
60+
61+
public function getUser(string $username, string $password): ?ImapUser
62+
{
63+
$config = $this->decodePayload($this->payload);
64+
$mailAccount = $this->createMailAccount($config);
65+
66+
return new ImapUser($username, $password, $mailAccount);
67+
}
68+
69+
private function createMailAccount(array $config): MailAccount
70+
{
71+
$merged = array_merge($config, [
72+
"id" => $this->mailAccountId,
73+
"name" => $this->mailAccountId,
74+
]);
75+
return new MailAccount($merged);
76+
}
77+
78+
private function decodePayload(string $payload): array
79+
{
80+
return json_decode(base64_decode($payload), true);
81+
}
82+
83+
}
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
<?php
2+
3+
/**
4+
* conjoon
5+
* php-lib-conjoon
6+
* Copyright (C) 2023 Thorsten Suckow-Homberg https://github.com/conjoon/php-lib-conjoon
7+
*
8+
* Permission is hereby granted, free of charge, to any person
9+
* obtaining a copy of this software and associated documentation
10+
* files (the "Software"), to deal in the Software without restriction,
11+
* including without limitation the rights to use, copy, modify, merge,
12+
* publish, distribute, sublicense, and/or sell copies of the Software,
13+
* and to permit persons to whom the Software is furnished to do so,
14+
* subject to the following conditions:
15+
*
16+
* The above copyright notice and this permission notice shall be included
17+
* in all copies or substantial portions of the Software.
18+
*
19+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
21+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22+
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
23+
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24+
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
25+
* USE OR OTHER DEALINGS IN THE SOFTWARE.
26+
*/
27+
28+
declare(strict_types=1);
29+
30+
namespace Tests\Conjoon\Illuminate\Auth\Imap;
31+
32+
use Conjoon\Illuminate\Auth\Imap\DefaultImapUserProvider;
33+
use Conjoon\Illuminate\Auth\LocalMailAccount\LocalAccountProvider;
34+
use Conjoon\Illuminate\Auth\ImapUser;
35+
use Illuminate\Http\Request;
36+
use ReflectionClass;
37+
use Tests\TestCase;
38+
39+
/**
40+
* Tests LocalAccountProvider.
41+
*/
42+
class LocalAccountProviderTest extends TestCase
43+
{
44+
public function testClass()
45+
{
46+
$request = $this->getMockBuilder(Request::class)
47+
->onlyMethods(["header", "route"])
48+
->disableOriginalConstructor()
49+
->getMock();
50+
51+
$request->expects($this->once())->method("header")->with("x-cnmail-data")->willReturn("headerpayload");
52+
$request->expects($this->once())->method("route")->with("mailAccountId")->willReturn("routeId");
53+
54+
$provider = new LocalAccountProvider($request);
55+
$this->assertInstanceOf(DefaultImapUserProvider::class, $provider);
56+
57+
$payload = $this->makeAccessible($provider, "payload", true);
58+
$mailAccountId = $this->makeAccessible($provider, "mailAccountId", true);
59+
60+
$this->assertSame("headerpayload", $payload->getValue($provider));
61+
$this->assertSame("routeId", $mailAccountId->getValue($provider));
62+
}
63+
64+
65+
public function testDecodePayload()
66+
{
67+
$provider = new LocalAccountProvider(new Request());
68+
$decodePayload = $this->makeAccessible($provider, "decodePayload");
69+
70+
$target = ["encoded" => "json"];
71+
$str = base64_encode(json_encode($target));
72+
73+
$this->assertSame($target, $decodePayload->invokeArgs($provider, [$str]));
74+
}
75+
76+
77+
public function testGetUser()
78+
{
79+
$request = $this->getMockBuilder(Request::class)
80+
->onlyMethods(["header", "route"])
81+
->disableOriginalConstructor()
82+
->getMock();
83+
84+
$request->expects($this->once())->method("route")->with("mailAccountId")->willReturn("routeId");
85+
86+
$conf = [
87+
"from" => ["address" => "", "name" => "name"],
88+
"replyTo" => ["address" => "", "name" => "name"],
89+
"inbox_address" => "address",
90+
"inbox_port" => 8080,
91+
"inbox_user" => "user",
92+
"inbox_password" => "pw",
93+
"outbox_address" => "address",
94+
"outbox_port" => 8080,
95+
"outbox_user" => "user",
96+
"outbox_password" => "pw",
97+
"inbox_ssl" => true,
98+
"outbox_secure" => "tls"
99+
];
100+
101+
$request->expects($this->once())->method("header")->with("x-cnmail-data")->willReturn(
102+
base64_encode(json_encode($conf))
103+
);
104+
105+
$provider = new LocalAccountProvider($request);
106+
107+
$user = $provider->getUser("username", "password");
108+
$this->assertInstanceOf(ImapUser::class, $user);
109+
110+
$this->assertNull($user->getMailAccount("routeIdNotAvailable"));
111+
$account = $user->getMailAccount("routeId");
112+
113+
$toArray = $account->toArray();
114+
115+
foreach ($conf as $key => $value) {
116+
$this->assertSame($value, $toArray[$key]);
117+
}
118+
119+
$this->assertSame("routeId", $toArray["id"]);
120+
$this->assertSame("routeId", $toArray["name"]);
121+
122+
}
123+
124+
125+
protected function makeAccessible($inst, $name, $isProperty = false)
126+
{
127+
$refl = new ReflectionClass($inst);
128+
129+
$name = $isProperty
130+
? $refl->getProperty($name)
131+
: $refl->getMethod($name);
132+
133+
$name->setAccessible(true);
134+
135+
return $name;
136+
}
137+
138+
139+
}

0 commit comments

Comments
 (0)