Implement account edit; add SessionHelper, PasswordHelper and ActionResult

This commit is contained in:
Lexi / Zoe 2021-08-15 17:40:35 +02:00
parent 32add30c9d
commit 6ace072841
Signed by: binaryDiv
GPG key ID: F8D4956E224DA232
15 changed files with 637 additions and 68 deletions

View file

@ -0,0 +1,127 @@
<?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.');
// }
}
}