Skip to content

Commit

Permalink
EntityImmutable
Browse files Browse the repository at this point in the history
  • Loading branch information
docjyJ committed Oct 7, 2024
1 parent 854cac1 commit c3ae222
Show file tree
Hide file tree
Showing 16 changed files with 209 additions and 195 deletions.
25 changes: 22 additions & 3 deletions compose.mysql.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
services:
mysql:
image: mariadb:10.6
hostname: database
command: --transaction-isolation=READ-COMMITTED --log-bin=binlog --binlog-format=ROW
ports:
- "127.0.0.1:3306:3306"
Expand All @@ -18,15 +19,31 @@ services:
timeout: 5s
retries: 3

nextcloud_init:
image: nextcloud:30
command: apache2 -v
volumes:
- nextcloud:/var/www/html:z
environment:
- MYSQL_HOST=database
- MYSQL_DATABASE=nextcloud
- MYSQL_USER=root
- MYSQL_PASSWORD=root
- NEXTCLOUD_ADMIN_USER=admin
- NEXTCLOUD_ADMIN_PASSWORD=admin
depends_on:
mysql:
condition: service_healthy

nextcloud:
image: nextcloud:apache
image: nextcloud:30
ports:
- "127.0.0.1:8080:80"
volumes:
- .:/var/www/html/custom_apps/stalwart:z
- nextcloud:/var/www/html:z
environment:
- MYSQL_HOST=mysql
- MYSQL_HOST=database
- MYSQL_DATABASE=nextcloud
- MYSQL_USER=root
- MYSQL_PASSWORD=root
Expand All @@ -35,6 +52,8 @@ services:
depends_on:
mysql:
condition: service_healthy
nextcloud_init:
condition: service_completed_successfully

phpmyadmin:
image: phpmyadmin
Expand All @@ -49,7 +68,7 @@ services:
condition: service_healthy

stalwart:
image: stalwartlabs/mail-server:latest
image: stalwartlabs/mail-server:v0.10.3
hostname: stalwart
ports:
- "127.0.0.1:9090:8080"
Expand Down
29 changes: 7 additions & 22 deletions lib/Controller/ApiController.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
use OCA\Stalwart\Db\ConfigManager;
use OCA\Stalwart\Db\EmailManager;
use OCA\Stalwart\Models\AccountEntity;
use OCA\Stalwart\Models\ConfigEntity;
use OCA\Stalwart\Models\EmailEntity;
use OCA\Stalwart\ResponseDefinitions;
use OCA\Stalwart\Settings\Admin;
Expand Down Expand Up @@ -43,16 +42,6 @@ public function __construct(
parent::__construct($appName, $request);
}

/** @return StalwartServerConfig */
private static function getConfigData(ConfigEntity $config): array {
return [
'id' => $config->cid,
'endpoint' => $config->endpoint,
'username' => $config->username,
'health' => $config->health->value,
];
}

/** @return StalwartServerUser */
private static function getUserDataWithoutMail(AccountEntity $account): array {
return [
Expand Down Expand Up @@ -84,7 +73,7 @@ private static function getUserData(EmailEntity $email): array {
#[ApiRoute(verb: 'GET', url: '/config')]
public function list(): DataResponse {
try {
return new DataResponse(array_map(fn ($c) => self::getConfigData($c), $this->configManager->list()));
return new DataResponse(array_map(fn ($c) => $c->toArrayData(), $this->configManager->list()));
} catch (Exception $config) {
$this->logger->error($config->getMessage(), ['exception' => $config]);
throw new OCSException($config->getMessage(), Http::STATUS_INTERNAL_SERVER_ERROR);
Expand All @@ -103,7 +92,7 @@ public function list(): DataResponse {
#[ApiRoute(verb: 'POST', url: '/config')]
public function post(): DataResponse {
try {
return new DataResponse(self::getConfigData($this->configManager->create()));
return new DataResponse($this->configManager->create()->toArrayData());
} catch (Exception $e) {
$this->logger->error($e->getMessage(), ['exception' => $e]);
throw new OCSException($e->getMessage(), Http::STATUS_INTERNAL_SERVER_ERROR);
Expand All @@ -125,7 +114,7 @@ public function post(): DataResponse {
public function get(int $cid): DataResponse {
try {
if ($config = $this->configManager->find($cid)) {
return new DataResponse(self::getConfigData($config));
return new DataResponse($config->toArrayData());
} else {
throw new OCSNotFoundException();
}
Expand Down Expand Up @@ -153,13 +142,9 @@ public function get(int $cid): DataResponse {
public function put(int $cid, string $endpoint, string $username, string $password): DataResponse {
try {
if ($config = $this->configManager->find($cid)) {
$config->endpoint = $endpoint;
$config->username = $username;
if ($password !== '') {
$config->password = $password;
}
$this->configManager->update($config);
return new DataResponse(self::getConfigData($config));
$config = $config->updateCredential($endpoint, $username, $password);
$config = $this->configManager->update($config);
return new DataResponse($config->toArrayData());
} else {
throw new OCSNotFoundException();
}
Expand All @@ -185,7 +170,7 @@ public function delete(int $cid): DataResponse {
try {
if ($config = $this->configManager->find($cid)) {
$this->configManager->delete($config);
return new DataResponse(self::getConfigData($config));
return new DataResponse($config->toArrayData());
} else {
throw new OCSNotFoundException();
}
Expand Down
4 changes: 1 addition & 3 deletions lib/Cron/CheckTask.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

namespace OCA\Stalwart\Cron;

use DateTime;
use OCA\Stalwart\Db\ConfigManager;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\BackgroundJob\TimedJob;
Expand All @@ -20,9 +19,8 @@ public function __construct(

/** @throws Exception */
protected function run(mixed $argument): void {
$now = new DateTime();
foreach ($this->configService->list() as $config) {
if ($config->expires <= $now) {
if ($config->hasExpired()) {
$this->configService->update($config);
}
}
Expand Down
23 changes: 13 additions & 10 deletions lib/Db/AccountManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ public function __construct(
) {
}

private static function getHashFromUser(IUser $user): string {
return preg_replace('/^[^$]*/', '', $user->getPasswordHash() ?? '') ?? '';
}

/**
* @return AccountEntity[]
* @throws Exception
Expand All @@ -28,7 +32,7 @@ public function list(ConfigEntity $config): array {
->where($q->expr()->eq('cid', $q->createNamedParameter($config->cid, IQueryBuilder::PARAM_INT)));
$result = $q->executeQuery();
$entities = [];
while ($account = ParseMixed::accuntEntity($config, $result->fetch())) {
while ($account = ParseMixed::accountEntity($config, $result->fetch())) {
$entities[] = $account;
}
$result->closeCursor();
Expand All @@ -43,16 +47,14 @@ public function find(ConfigEntity $config, string $uid): ?AccountEntity {
->where($q->expr()->eq('cid', $q->createNamedParameter($config->cid, IQueryBuilder::PARAM_INT)))
->andWhere($q->expr()->eq('uid', $q->createNamedParameter($uid)));
$result = $q->executeQuery();
$account = ParseMixed::accuntEntity($config, $result->fetch());
$account = ParseMixed::accountEntity($config, $result->fetch());
$result->closeCursor();
return $account;
}

/** @throws Exception */
public function createIndividual(ConfigEntity $config, IUser $user): AccountEntity {
$password = $user->getPasswordHash() ?? null;
$password = $password !== null ? preg_replace('/^[^|]*|/', '', $password) ?? $password : '';
$account = new AccountEntity($config, $user->getUID(), $user->getDisplayName(), $password);
$account = new AccountEntity($config, $user->getUID(), $user->getDisplayName(), self::getHashFromUser($user));
$this->db->beginTransaction();
try {
$q = $this->db->getQueryBuilder();
Expand Down Expand Up @@ -109,12 +111,12 @@ public function listUser(string $uid): array {
}

/** @throws Exception */
public function forceDelete(string $uid): void {
public function deleteUser(IUser $user): void {
$this->db->beginTransaction();
try {
$q = $this->db->getQueryBuilder();
$q->delete(AccountEntity::TABLE)
->where($q->expr()->eq('uid', $q->createNamedParameter($uid)))
->where($q->expr()->eq('uid', $q->createNamedParameter($user->getUID())))
->executeStatement();
$this->db->commit();
} catch (Exception $e) {
Expand All @@ -124,13 +126,14 @@ public function forceDelete(string $uid): void {
}

/** @throws Exception */
public function forceUpdatePassword(string $uid, string $password): void {
public function updateUser(IUser $user): void {
$this->db->beginTransaction();
try {
$q = $this->db->getQueryBuilder();
$q->update(AccountEntity::TABLE)
->set('password', $q->createNamedParameter($password))
->where($q->expr()->eq('uid', $q->createNamedParameter($uid)))
->set('password', $q->createNamedParameter(self::getHashFromUser($user)))
->set('display_name', $q->createNamedParameter($user->getDisplayName()))
->where($q->expr()->eq('uid', $q->createNamedParameter($user->getUID())))
->executeStatement();
$this->db->commit();
} catch (Exception $e) {
Expand Down
38 changes: 12 additions & 26 deletions lib/Db/ConfigManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace OCA\Stalwart\Db;

use DateTime;
use DateTimeImmutable;
use OCA\Stalwart\Models\ConfigEntity;
use OCA\Stalwart\Models\ServerStatus;
use OCA\Stalwart\ParseMixed;
Expand Down Expand Up @@ -49,17 +49,8 @@ public function list(): array {
}

/** @throws Exception */
public function update(ConfigEntity $config): void {
$heathResult = $this->apiService->challenge($config->endpoint, $config->username, $config->password);
$config->health = $heathResult[0];
$config->expires = $heathResult[1];
if ($heathResult[0] === ServerStatus::Success || $heathResult[0] === ServerStatus::NoAdmin) {
try {
$this->apiService->pushDataBase($config->cid, $config->endpoint, $config->username, $config->password);
} catch (\Exception $e) {
throw new Exception('Failed to push data to server', previous: $e);
}
}
public function update(ConfigEntity $config): ConfigEntity {
$config = $config->updateHealth($this->apiService->challenge($config));
$this->db->beginTransaction();
try {
$q = $this->db->getQueryBuilder();
Expand All @@ -72,6 +63,7 @@ public function update(ConfigEntity $config): void {
->where($q->expr()->eq('cid', $q->createNamedParameter($config->cid, IQueryBuilder::PARAM_INT)))
->executeStatement();
$this->db->commit();
return $config;
} catch (Exception $e) {
$this->db->rollBack();
throw $e;
Expand All @@ -80,28 +72,22 @@ public function update(ConfigEntity $config): void {

/** @throws Exception */
public function create(): ConfigEntity {
$config = new ConfigEntity(
0,
'',
'',
'',
ServerStatus::Invalid,
new DateTime(),
);
$date = new DateTimeImmutable();
$state = ServerStatus::Invalid;
$this->db->beginTransaction();
try {
$q = $this->db->getQueryBuilder();
$q->insert(ConfigEntity::TABLE)
->values([
'endpoint' => $q->createNamedParameter($config->endpoint),
'username' => $q->createNamedParameter($config->username),
'password' => $q->createNamedParameter($config->password),
'health' => $q->createNamedParameter($config->health->value),
'expires' => $q->createNamedParameter($config->expires, IQueryBuilder::PARAM_DATE),
'endpoint' => $q->createNamedParameter(''),
'username' => $q->createNamedParameter(''),
'password' => $q->createNamedParameter(''),
'health' => $q->createNamedParameter($state->value),
'expires' => $q->createNamedParameter($date, IQueryBuilder::PARAM_DATE),
])
->executeStatement();

$config->cid = $q->getLastInsertId();
$config = new ConfigEntity($q->getLastInsertId(), '', '', '', $state, $date);
$this->db->commit();
} catch (Exception $e) {
$this->db->rollBack();
Expand Down
14 changes: 6 additions & 8 deletions lib/Event/EmailChangedListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,12 @@ public function __construct(
* @throws Exception
*/
public function handle(Event $event): void {
if ($event->getFeature() === 'email') {
/** @psalm-suppress MixedAssignment */
$email = $event->getValue();
if (is_string($email)) {
$uid = $event->getUser()->getUID();
foreach ($this->accountManager->listUser($event->getUser()->getUID()) as $cid) {
$this->emailManager->setPrimary(new AccountEntity(new ConfigEntity($cid), $uid), $email);
}
$this->accountManager->updateUser($event->getUser());
$email = $event->getUser()->getEMailAddress();
if ($email !== null) {
$uid = $event->getUser()->getUID();
foreach ($this->accountManager->listUser($event->getUser()->getUID()) as $cid) {
$this->emailManager->setPrimary(new AccountEntity(new ConfigEntity($cid), $uid), $email);
}
}
}
Expand Down
7 changes: 1 addition & 6 deletions lib/Event/PasswordChangedListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,6 @@ public function __construct(
* @throws Exception
*/
public function handle(Event $event): void {
$password = $event->getUser()->getPasswordHash();
if ($password !== null) {
$this->accountManager->forceUpdatePassword(
$event->getUser()->getUID(),
preg_replace('/^[^|]*|/', '', $password) ?? $password);
}
$this->accountManager->updateUser($event->getUser());
}
}
2 changes: 1 addition & 1 deletion lib/Event/UserDeletedListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@ public function __construct(
* @throws Exception
*/
public function handle(Event $event): void {
$this->accountManager->forceDelete($event->getUser()->getUID());
$this->accountManager->deleteUser($event->getUser());
}
}
Loading

0 comments on commit c3ae222

Please sign in to comment.