128 lines
4.5 KiB
PHP
128 lines
4.5 KiB
PHP
|
|
<?php
|
||
|
|
declare(strict_types=1);
|
||
|
|
|
||
|
|
namespace MailAccountAdmin\Frontend\Accounts;
|
||
|
|
|
||
|
|
use MailAccountAdmin\Common\PasswordHelper;
|
||
|
|
use MailAccountAdmin\Exceptions\AccountNotFoundException;
|
||
|
|
use MailAccountAdmin\Exceptions\InputValidationError;
|
||
|
|
use MailAccountAdmin\Repositories\AccountRepository;
|
||
|
|
use MailAccountAdmin\Repositories\AliasRepository;
|
||
|
|
|
||
|
|
class AccountHandler
|
||
|
|
{
|
||
|
|
/** @var AccountRepository */
|
||
|
|
private $accountRepository;
|
||
|
|
/** @var AliasRepository */
|
||
|
|
private $aliasRepository;
|
||
|
|
/** @var PasswordHelper */
|
||
|
|
private $passwordHelper;
|
||
|
|
|
||
|
|
public function __construct(AccountRepository $accountRepository, AliasRepository $aliasRepository, PasswordHelper $passwordHelper)
|
||
|
|
{
|
||
|
|
$this->accountRepository = $accountRepository;
|
||
|
|
$this->aliasRepository = $aliasRepository;
|
||
|
|
$this->passwordHelper = $passwordHelper;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
// -- /accounts - List all accounts
|
||
|
|
|
||
|
|
public function listAccounts(string $filterByDomain): array
|
||
|
|
{
|
||
|
|
$accountList = $this->accountRepository->fetchAccountList($filterByDomain);
|
||
|
|
|
||
|
|
return [
|
||
|
|
'filterDomain' => $filterByDomain,
|
||
|
|
'accountList' => $accountList,
|
||
|
|
];
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
// -- /accounts/{id} - Show account details
|
||
|
|
|
||
|
|
public function getAccountDetails(int $accountId): array
|
||
|
|
{
|
||
|
|
// Get account data from database
|
||
|
|
$account = $this->accountRepository->fetchAccountById($accountId);
|
||
|
|
|
||
|
|
// Don't display the password hash, but at least the type of hash (used hash algorithm)
|
||
|
|
$passwordHashType = $this->passwordHelper->getPasswordHashType($account->getPasswordHash());
|
||
|
|
|
||
|
|
// Get list of aliases for this account
|
||
|
|
$aliases = $this->aliasRepository->fetchAliasesForUserId($accountId);
|
||
|
|
|
||
|
|
return [
|
||
|
|
'id' => $accountId,
|
||
|
|
'accountUsername' => $account->getUsername(),
|
||
|
|
'account' => $account,
|
||
|
|
'passwordHashType' => $passwordHashType,
|
||
|
|
'aliases' => $aliases,
|
||
|
|
];
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
// -- /accounts/{id}/edit - Edit account data
|
||
|
|
|
||
|
|
public function editAccountData(int $accountId, AccountEditData $editData): void
|
||
|
|
{
|
||
|
|
// Check if account exists
|
||
|
|
try {
|
||
|
|
$account = $this->accountRepository->fetchAccountById($accountId);
|
||
|
|
} catch (AccountNotFoundException $e) {
|
||
|
|
throw new InputValidationError('Account with ID ' . $accountId . ' does not exist!');
|
||
|
|
}
|
||
|
|
|
||
|
|
// TODO: Use database transactions (beginTransaction/commit/rollBack in BaseRepository maybe?)
|
||
|
|
|
||
|
|
$newUsername = $editData->getUsername();
|
||
|
|
if ($newUsername === $account->getUsername()) {
|
||
|
|
// Username is unchanged
|
||
|
|
$newUsername = null;
|
||
|
|
}
|
||
|
|
|
||
|
|
// TODO: This feature is not supported yet. If the alias exists, the availability check (next) would fail anyway.
|
||
|
|
if ($editData->getUsernameReplaceAlias()) {
|
||
|
|
throw new InputValidationError('Replace alias: Not implemented yet.');
|
||
|
|
}
|
||
|
|
|
||
|
|
// Check if new username is still available
|
||
|
|
if ($newUsername !== null) {
|
||
|
|
if (!$this->accountRepository->checkUsernameAvailable($newUsername) || !$this->aliasRepository->checkAliasAvailable($newUsername)) {
|
||
|
|
throw new InputValidationError("Username \"$newUsername\" is not available.");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Create alias for old username (if wanted)
|
||
|
|
if ($editData->getUsernameCreateAlias()) {
|
||
|
|
$oldUsername = $account->getUsername();
|
||
|
|
if (!$this->aliasRepository->checkAliasAvailable($oldUsername)) {
|
||
|
|
throw new InputValidationError("Alias \"$oldUsername\" cannot be created: Alias already exists.");
|
||
|
|
}
|
||
|
|
$this->aliasRepository->createNewAlias($accountId, $oldUsername);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Hash new password
|
||
|
|
$newPasswordHash = null;
|
||
|
|
if ($editData->getPassword() !== null) {
|
||
|
|
$newPasswordHash = $this->passwordHelper->hashPassword($editData->getPassword());
|
||
|
|
}
|
||
|
|
|
||
|
|
// Update account in database
|
||
|
|
$this->accountRepository->updateAccountWithId(
|
||
|
|
$accountId,
|
||
|
|
$newUsername,
|
||
|
|
$newPasswordHash,
|
||
|
|
$editData->getActive(),
|
||
|
|
$editData->getHomeDir(),
|
||
|
|
$editData->getMemo()
|
||
|
|
);
|
||
|
|
|
||
|
|
// Remove existing alias for new username (if wanted)
|
||
|
|
// TODO: See above. This is the point where the alias should be deleted.
|
||
|
|
// if ($editData->getUsernameReplaceAlias()) {
|
||
|
|
// throw new InputValidationError('Replace alias: Not implemented yet.');
|
||
|
|
// }
|
||
|
|
}
|
||
|
|
}
|