Fetch email Addresses from plesk
continuous-integration/drone/push Build is failing Details

This commit is contained in:
Philipp Lang 2023-06-19 17:02:15 +02:00
parent 6fd16a7dfe
commit c5bd8bdbb9
2 changed files with 171 additions and 0 deletions

View File

@ -0,0 +1,128 @@
<?php
namespace App\Mailgateway\Types;
use App\Maildispatcher\Data\MailEntry;
use App\Mailman\Exceptions\MailmanServiceException;
use App\Mailman\Support\MailmanService;
use Illuminate\Http\Client\PendingRequest;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Http;
class PleskType extends Type
{
public string $url;
public string $user;
public string $password;
public function setParams(array $params): static
{
$this->url = data_get($params, 'url');
$this->user = data_get($params, 'user');
$this->password = data_get($params, 'password');
return $this;
}
public static function name(): string
{
return 'Plesk';
}
public function works(): bool
{
$response = $this->client()->get('/server');
return 200 === $response->status() && $response->json('panel_version');
}
/**
* {@inheritdoc}
*/
public static function fields(): array
{
return [
[
'name' => 'url',
'label' => 'URL',
'type' => 'text',
'storeValidator' => 'required|max:255',
'updateValidator' => 'required|max:255',
'default' => '',
],
[
'name' => 'user',
'label' => 'Benutzer',
'type' => 'text',
'storeValidator' => 'required|max:255',
'updateValidator' => 'required|max:255',
'default' => '',
],
[
'name' => 'password',
'label' => 'Passwort',
'type' => 'password',
'storeValidator' => 'required|max:255',
'updateValidator' => 'nullable|max:255',
'default' => '',
],
];
}
public function search(string $name, string $domain, string $email): ?MailEntry
{
$list = $this->service()->getLists()->first(fn ($list) => $list->fqdnListname === "{$name}@{$domain}");
throw_if(!$list, MailmanServiceException::class, "List for {$name}@{$domain} not found");
$member = $this->service()->members($list)->first(fn ($member) => $member->email === $email);
return $member ? MailEntry::from(['email' => $member->email]) : null;
}
public function add(string $name, string $domain, string $email): void
{
$list = $this->service()->getLists()->first(fn ($list) => $list->fqdnListname === "{$name}@{$domain}");
throw_if(!$list, MailmanServiceException::class, "List for {$name}@{$domain} not found");
$this->service()->addMember($list, $email);
}
/**
* {@inheritdoc}
*/
public function list(string $name, string $domain): Collection
{
$response = $this->client()->post('cli/mail/call', [
'params' => [
'--info',
"{$name}@{$domain}",
],
]);
throw_unless(200 === $response->status(), PleskException::class, "Mail-Adressen für {$name}@{$domain} konnten nicht aus Plesk abgerufen werden.");
$output = collect(explode("\n", $response->json('stdout')))->first(fn ($line) => 1 === preg_match('/^Group member\(s\):/', $line));
throw_unless(null !== $output, PleskException::class, 'Mail-Adressen nicht in Response vorhanden');
$mails = trim(preg_replace('/^Group member\(s\):/', '', $output));
return collect(explode(' ', $mails))->map(fn ($mail) => MailEntry::from(['email' => $mail]));
}
public function remove(string $name, string $domain, string $email): void
{
$list = $this->service()->getLists()->first(fn ($list) => $list->fqdnListname === "{$name}@{$domain}");
throw_if(!$list, MailmanServiceException::class, "List for {$name}@{$domain} not found");
$member = $this->service()->members($list)->first(fn ($member) => $member->email === $email);
throw_if(!$member, MailmanServiceException::class, 'Member for removing not found');
$this->service()->removeMember($member);
}
private function service(): MailmanService
{
return app(MailmanService::class)->setCredentials($this->url, $this->user, $this->password);
}
private function client(): PendingRequest
{
return Http::withOptions(['base_uri' => $this->url])->withBasicAuth($this->user, $this->password);
}
}

View File

@ -0,0 +1,43 @@
<?php
namespace Tests\Feature\Mailgateway;
use App\Mailgateway\Types\PleskType;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\Http;
use Tests\TestCase;
class PleskTypeTest extends TestCase
{
use DatabaseTransactions;
public function testCheckIfWorks(): void
{
Http::fake([
'https://example.com:8443/api/v2/server' => Http::response('{ "platform": "Unix", "hostname": "cateringpro.de", "guid": "bbc63535-00f4-4cf5-b1ca-d4e53a87c1c0", "panel_version": "18.0.52", "panel_revision": "a3b74dbc9de2e47afd4e532d02fa7759b29d3fa5", "panel_build_date": "2023-05-16", "panel_update_version": "3", "extension_version": "1.6.6", "extension_release": "215" }', 200),
]);
$this->withoutExceptionHandling();
$type = app(PleskType::class)->setParams(['url' => 'https://example.com:8443/api/v2/', 'user' => 'root', 'password' => 'secret']);
$this->assertTrue($type->works());
Http::assertSentCount(1);
Http::assertSent(fn ($request) => $request->hasHeader('Authorization', 'Basic '.base64_encode('root:secret')) && 'https://example.com:8443/api/v2/server' === $request->url());
}
public function testItGetsEmailAddresses(): void
{
Http::fake([
'https://example.com:8443/api/v2/cli/mail/call' => Http::response('{"code": 0, "stdout": "Mailname: test\nDomain: praxis-marketingagentur.de\nMailbox: true\nPassword type: sym\nMbox quota: Default value (Unlimited)\nMailgroup: true\nGroup member(s): philipp@zoomyboy.de philipp+test@zoomyboy.de \nAttachment files: Empty\nAutoresponders: Disabled\nAntivirus mail checking: Disabled\nDescription: \n\nSUCCESS: Gathering information for \'test@praxis-marketingagentur.de\' complete", "stderr": "" }', 200),
]);
$this->withoutExceptionHandling();
$type = app(PleskType::class)->setParams(['url' => 'https://example.com:8443/api/v2/', 'user' => 'root', 'password' => 'secret']);
$mails = $type->list('text', 'example.com');
$this->assertCount(2, $mails);
$this->assertEquals('philipp@zoomyboy.de', $mails->get(0)->email);
$this->assertEquals('philipp+test@zoomyboy.de', $mails->get(1)->email);
Http::assertSentCount(1);
Http::assertSent(fn ($request) => $request->hasHeader('Authorization', 'Basic '.base64_encode('root:secret')) && 'https://example.com:8443/api/v2/cli/mail/call' === $request->url() && ['--info', 'text@example.com'] === $request['params']);
}
}