Add Create service for Mailman dispatcher type
continuous-integration/drone/push Build is failing Details

This commit is contained in:
philipp lang 2023-07-17 16:50:05 +02:00
parent 3d7e49965a
commit 9e00eed6c1
11 changed files with 76 additions and 192 deletions

View File

@ -16,10 +16,11 @@ class StoreAction
*/
public function handle(array $input): void
{
Maildispatcher::create([
$dispatcher = Maildispatcher::create([
...$input,
'filter' => (object) $input['filter'],
]);
$dispatcher->gateway->type->createList($dispatcher->name, $dispatcher->gateway->domain);
ResyncAction::dispatch();
}

View File

@ -53,6 +53,10 @@ class LocalType extends Type
]);
}
public function createList(string $name, string $domain): void
{
}
public function remove(string $name, string $domain, string $email): void
{
Localmaildispatcher::where('from', "{$name}@{$domain}")->where('to', $email)->delete();

View File

@ -13,12 +13,14 @@ class MailmanType extends Type
public string $url;
public string $user;
public string $password;
public string $owner;
public function setParams(array $params): static
{
$this->url = data_get($params, 'url');
$this->user = data_get($params, 'user');
$this->password = data_get($params, 'password');
$this->owner = data_get($params, 'owner', '');
return $this;
}
@ -63,6 +65,14 @@ class MailmanType extends Type
'updateValidator' => 'nullable|max:255',
'default' => '',
],
[
'name' => 'owner',
'label' => 'E-Mail-Adresse des Eigentümers',
'type' => 'email',
'storeValidator' => 'required|max:255',
'updateValidator' => 'required|max:255',
'default' => '',
],
];
}
@ -98,6 +108,11 @@ class MailmanType extends Type
$this->service()->removeMember($member);
}
public function createList(string $name, string $domain): void
{
$this->service()->createList("{$name}@{$domain}");
}
private function getList(string $name, string $domain): MailingList
{
$list = $this->service()->getLists()->first(fn ($list) => $list->fqdnListname === "{$name}@{$domain}");
@ -108,6 +123,6 @@ class MailmanType extends Type
private function service(): MailmanService
{
return app(MailmanService::class)->setCredentials($this->url, $this->user, $this->password);
return app(MailmanService::class)->setCredentials($this->url, $this->user, $this->password)->setOwner($this->owner);
}
}

View File

@ -20,6 +20,8 @@ abstract class Type
abstract public function add(string $name, string $domain, string $email): void;
abstract public function createList(string $name, string $domain): void;
abstract public function remove(string $name, string $domain, string $email): void;
/**

View File

@ -1,51 +0,0 @@
<?php
namespace App\Mailman\Actions;
use App\Mailman\MailmanSettings;
use App\Mailman\Support\MailmanService;
use Inertia\Inertia;
use Inertia\Response;
use Lorisleiva\Actions\Concerns\AsAction;
class SettingIndexAction
{
use AsAction;
/**
* @return array<string, string|bool|null>
*/
public function handle(MailmanSettings $settings): array
{
return [
'is_active' => $settings->is_active,
'base_url' => $settings->base_url,
'username' => $settings->username,
'all_list' => $settings->all_list,
'all_parents_list' => $settings->all_parents_list,
'active_leaders_list' => $settings->active_leaders_list,
'passive_leaders_list' => $settings->passive_leaders_list,
'password' => '',
];
}
public function asController(MailmanSettings $settings): Response
{
session()->put('menu', 'setting');
session()->put('title', 'Mailman-Einstellungen');
if ($settings->is_active) {
$state = app(MailmanService::class)->fromSettings($settings)->check();
$lists = app(MailmanService::class)->fromSettings($settings)->getLists();
} else {
$state = null;
$lists = [];
}
return Inertia::render('setting/Mailman', [
'data' => $this->handle($settings),
'state' => $state,
'lists' => $lists,
]);
}
}

View File

@ -1,80 +0,0 @@
<?php
namespace App\Mailman\Actions;
use App\Mailman\MailmanSettings;
use App\Mailman\Support\MailmanService;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Http\RedirectResponse;
use Lorisleiva\Actions\ActionRequest;
use Lorisleiva\Actions\Concerns\AsAction;
class SettingSaveAction
{
use AsAction;
/**
* @param array<string, string> $input
*/
public function handle(array $input): void
{
$settings = app(MailmanSettings::class);
$settings->fill([
'base_url' => $input['base_url'] ?? null,
'username' => $input['username'] ?? null,
'password' => $input['password'] ?? null,
'all_list' => $input['all_list'] ?? null,
'all_parents_list' => $input['all_parents_list'] ?? null,
'active_leaders_list' => $input['active_leaders_list'] ?? null,
'passive_leaders_list' => $input['passive_leaders_list'] ?? null,
'is_active' => $input['is_active'] ?? false,
]);
$settings->save();
}
/**
* @return array<string, string>
*/
public function rules(): array
{
return [
'base_url' => 'required_if:is_active,true',
'username' => 'required_if:is_active,true',
'password' => 'required_if:is_active,true',
];
}
/**
* @return array<string, string>
*/
public function getValidationMessages(): array
{
return [
'base_url.required_if' => 'URL ist erforderlich.',
'username.required_if' => 'Benutzername ist erforderlich.',
'password.required_if' => 'Passwort ist erforderlich.',
];
}
public function afterValidator(Validator $validator, ActionRequest $request): void
{
if (false === $request->is_active || !$request->filled(['base_url', 'username', 'password'])) {
return;
}
$result = app(MailmanService::class)->setCredentials($request->input('base_url'), $request->input('username'), $request->input('password'))->check();
if (!$result) {
$validator->errors()->add('mailman', 'Verbindung fehlgeschlagen.');
}
}
public function asController(ActionRequest $request): RedirectResponse
{
$this->handle($request->all());
return redirect()->back();
}
}

View File

@ -1,53 +0,0 @@
<?php
namespace App\Mailman;
use App\Mailman\Actions\SettingIndexAction;
use App\Mailman\Actions\SettingSaveAction;
use App\Setting\Contracts\Indexable;
use App\Setting\Contracts\Storeable;
use App\Setting\LocalSettings;
class MailmanSettings extends LocalSettings implements Storeable, Indexable
{
public ?string $base_url;
public ?string $username;
public ?string $password;
public bool $is_active;
public ?string $all_list;
public ?string $all_parents_list;
public ?string $active_leaders_list;
public ?string $passive_leaders_list;
public static function group(): string
{
return 'mailman';
}
public static function slug(): string
{
return 'mailman';
}
public static function indexAction(): string
{
return SettingIndexAction::class;
}
public static function storeAction(): string
{
return SettingSaveAction::class;
}
public static function title(): string
{
return 'Mailman';
}
}

View File

@ -5,7 +5,6 @@ namespace App\Mailman\Support;
use App\Mailman\Data\MailingList;
use App\Mailman\Data\Member;
use App\Mailman\Exceptions\MailmanServiceException;
use App\Mailman\MailmanSettings;
use Illuminate\Http\Client\ConnectionException;
use Illuminate\Http\Client\PendingRequest;
use Illuminate\Support\Facades\Http;
@ -17,6 +16,7 @@ class MailmanService
private string $baseUrl;
private string $username;
private string $password;
private string $owner;
public function setCredentials(string $baseUrl, string $username, string $password): self
{
@ -27,9 +27,36 @@ class MailmanService
return $this;
}
public function fromSettings(MailmanSettings $settings): self
public function setOwner(string $owner): self
{
return $this->setCredentials($settings->base_url, $settings->username, $settings->password);
$this->owner = $owner;
return $this;
}
public function createList(string $mailAddress): MailingList
{
$response = $this->http()->post('/lists', [
'fqdn_listname' => $mailAddress,
]);
throw_unless(201 === $response->status(), MailmanServiceException::class, 'Creating list failed');
$list = $this->getLists()->first(fn ($list) => $list->fqdnListname === $mailAddress);
$response = $this->http()->patch("/lists/{$list->listId}/config", [
'advertised' => 'False',
'respond_to_post_requests' => 'False',
'send_goodbye_message' => 'False',
'send_welcome_message' => 'False',
'admin_immed_notify' => 'True',
]);
throw_unless(204 === $response->status(), MailmanServiceException::class, 'Updating list config failed');
$response = $this->http()->post('/members', [
'list_id' => $list->listId,
'subscriber' => $this->owner,
'role' => 'owner',
]);
throw_unless(201 === $response->status(), MailmanServiceException::class, 'Creating list owner failed');
return $list;
}
public function check(): bool

View File

@ -4,7 +4,6 @@ namespace App\Setting;
use App\Invoice\InvoiceSettings;
use App\Mailgateway\MailgatewaySettings;
use App\Mailman\MailmanSettings;
use Illuminate\Support\ServiceProvider;
class SettingServiceProvider extends ServiceProvider
@ -27,7 +26,6 @@ class SettingServiceProvider extends ServiceProvider
public function boot()
{
app(SettingFactory::class)->register(InvoiceSettings::class);
app(SettingFactory::class)->register(MailmanSettings::class);
app(SettingFactory::class)->register(MailgatewaySettings::class);
}
}

View File

@ -26,7 +26,7 @@
<template v-for="(field, index) in getType(model.type.cls).fields">
<f-text
:key="index"
v-if="field.type === 'text' || field.type === 'password'"
v-if="field.type === 'text' || field.type === 'password' || field.type === 'email'"
:label="field.label"
:type="field.type"
:name="field.name"

View File

@ -120,4 +120,25 @@ class ServiceTest extends TestCase
$this->assertCount($totals->count(), $result->toArray());
Http::assertSentCount($totals->chunk(10)->count());
}
public function testItCanCreateLists(): void
{
Http::fakeSequence()
->push('', 201)
->push(json_encode([
'entries' => [
MailmanListRequestFactory::new()->create(['list_id' => 'test.example.com', 'fqdn_listname' => 'test@example.com']),
],
'start' => 0,
'total_size' => 0,
]), 200)
->push('', 204)
->push('', 201);
$service = app(MailmanService::class)->setCredentials('http://mailman.test/api/', 'user', 'secret')->setOwner('test@zoomyboy.de');
$list = $service->createList('test@example.com');
$this->assertInstanceOf(MailingList::class, $list);
Http::assertSent(fn ($request) => 'http://mailman.test/api/lists' === $request->url() && 'POST' === $request->method());
}
}