Skip to content

Commit

Permalink
support quota admin
Browse files Browse the repository at this point in the history
  • Loading branch information
docjyJ committed Oct 28, 2024
1 parent ee73ccc commit bd6d5d4
Show file tree
Hide file tree
Showing 34 changed files with 14,857 additions and 14,435 deletions.
42 changes: 8 additions & 34 deletions lib/Controller/ApiUsersController.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
namespace OCA\Nextmail\Controller;

use OCA\Nextmail\Db\Transaction;
use OCA\Nextmail\Models\AccountRole;
use OCA\Nextmail\Models\EmailType;
use OCA\Nextmail\Db\UsersManager;
use OCA\Nextmail\Models\UserEntity;
use OCA\Nextmail\ResponseDefinitions;
use OCA\Nextmail\Settings\Admin;
Expand All @@ -20,7 +19,6 @@
use OCP\AppFramework\OCSController;
use OCP\DB\Exception;
use OCP\IRequest;
use OCP\IUserManager;
use Psr\Log\LoggerInterface;

/**
Expand All @@ -31,8 +29,8 @@ class ApiUsersController extends OCSController {
public function __construct(
string $appName,
IRequest $request,
private readonly Transaction $tr,
private readonly IUserManager $ncUserManager,
private readonly Transaction $tr,
private readonly UsersManager $um,
private readonly LoggerInterface $logger,
) {
parent::__construct($appName, $request);
Expand Down Expand Up @@ -60,7 +58,7 @@ public function getUsers(): DataResponse {

/**
* Update the user of the server number `id`
* @param string $srv The server number
* @param ?string $srv The server number
* @param string $usr The user ID
* @param bool $admin Whether the user is an admin
* @param int|null $quota The user quota
Expand All @@ -73,35 +71,11 @@ public function getUsers(): DataResponse {
#[AuthorizedAdminSetting(Admin::class)]
#[OpenAPI(scope: OpenAPI::SCOPE_ADMINISTRATION)]
#[ApiRoute(verb: 'PUT', url: '/users/{usr}')]
public function updateUser(string $usr, string $srv, bool $admin, ?int $quota): DataResponse {
public function updateUser(string $usr, ?string $srv, bool $admin, ?int $quota): DataResponse {
try {
$i_user = $this->ncUserManager->get($usr);
if ($i_user !== null) {
$users = $this->tr->selectAccount($i_user->getUID(), [AccountRole::User, AccountRole::Admin]);
$user = UserEntity::fromIUser($srv, $i_user, $admin, $quota);
if (count($users) === 0) {
$this->tr->insertAccount(
$user->id,
$user->server_id,
$user->name,
$user->hash,
$user->getRoleEnum(),
$user->quota
);
} else {
$this->tr->updateAccount(
$user->id,
$user->name,
$user->getRoleEnum(),
$user->hash,
$user->quota
);
}
$this->tr->deleteEmail($user->id, EmailType::Primary);
if ($user->primaryEmail !== null) {
$this->tr->insertEmail($user->id, $user->primaryEmail, EmailType::Primary);
}
$this->tr->commit();
$user = $this->um->updateFromStarch($usr, $srv, $admin, $quota);
$this->um->commit();
if ($user !== null) {
return new DataResponse($user->jsonSerialize());
} else {
throw new OCSNotFoundException();
Expand Down
13 changes: 7 additions & 6 deletions lib/Db/Transaction.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,28 +107,29 @@ public function selectAccount(?string $id = null, array $role = []): array {
}

/** @throws Exception */
public function insertAccount(string $id, string $server_id, string $name, ?string $hash, AccountRole $role, ?int $quota): void {
public function insertAccount(string $id, string $name, AccountRole $role, ?string $server_id, ?string $hash, ?int $quota): void {
$q = $this->getTransactionBuilder();
$q->insert(SchAccount::TABLE)
->values([
SchAccount::ID => $q->createNamedParameter($id),
SchServer::ID => $q->createNamedParameter($server_id),
SchAccount::NAME => $q->createNamedParameter($name),
SchAccount::HASH => $hash !== null ? $q->createNamedParameter(self::password($hash)) : $q->createNamedParameter(null, IQueryBuilder::PARAM_NULL),
SchAccount::ROLE => $q->createNamedParameter($role->value),
SchAccount::QUOTA => $quota !== null ? $q->createNamedParameter(null, IQueryBuilder::PARAM_NULL) : $q->createNamedParameter($quota, IQueryBuilder::PARAM_INT),
SchServer::ID => $server_id !== null ? $q->createNamedParameter($server_id) : $q->createNamedParameter(null, IQueryBuilder::PARAM_NULL),
SchAccount::HASH => $hash !== null ? $q->createNamedParameter(self::password($hash)) : $q->createNamedParameter(null, IQueryBuilder::PARAM_NULL),
SchAccount::QUOTA => $quota !== null ? $q->createNamedParameter($quota, IQueryBuilder::PARAM_INT) : $q->createNamedParameter(null, IQueryBuilder::PARAM_NULL),
]);
$this->execute($q);
}

/** @throws Exception */
public function updateAccount(string $id, string $name, AccountRole $role, ?string $hash, ?int $quota): void {
public function updateAccount(string $id, string $name, AccountRole $role, ?string $server_id, ?string $hash, ?int $quota): void {
$q = $this->getTransactionBuilder();
$q->update(SchAccount::TABLE)
->set(SchAccount::NAME, $q->createNamedParameter($name))
->set(SchAccount::ROLE, $q->createNamedParameter($role->value))
->set(SchServer::ID, $server_id !== null ? $q->createNamedParameter($server_id) : $q->createNamedParameter(null, IQueryBuilder::PARAM_NULL))
->set(SchAccount::HASH, $hash !== null ? $q->createNamedParameter(self::password($hash)) : $q->createNamedParameter(null, IQueryBuilder::PARAM_NULL))
->set(SchAccount::QUOTA, $quota !== null ? $q->createNamedParameter(null, IQueryBuilder::PARAM_NULL) : $q->createNamedParameter($quota, IQueryBuilder::PARAM_INT))
->set(SchAccount::QUOTA, $quota !== null ? $q->createNamedParameter($quota, IQueryBuilder::PARAM_INT) : $q->createNamedParameter(null, IQueryBuilder::PARAM_NULL))
->where($q->expr()->eq(SchAccount::ID, $q->createNamedParameter($id)));
$this->execute($q);
}
Expand Down
98 changes: 98 additions & 0 deletions lib/Db/UsersManager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<?php

namespace OCA\Nextmail\Db;

use OCA\Nextmail\Models\AccountRole;
use OCA\Nextmail\Models\EmailType;
use OCA\Nextmail\Models\UserEntity;
use OCA\Nextmail\SchemaV1\SchAccount;
use OCP\DB\Exception;
use OCP\IUser;
use OCP\IUserManager;

readonly class UsersManager {
public function __construct(
private IUserManager $userManager,
private Transaction $tr,
) {
}

/** @throws Exception */
private function buildQuery(IUser $i_user, bool $isNew, ?string $server_id = null, bool $admin = false, ?int $quota = null): UserEntity {
$user = UserEntity::fromIUser($i_user, $server_id, $admin, $quota);
if ($isNew) {
$this->tr->insertAccount(
$user->id,
$user->name,
$user->getRoleEnum(),
$user->server_id,
$user->hash,
$user->quota
);
} else {
$this->tr->updateAccount(
$user->id,
$user->name,
$user->getRoleEnum(),
$user->server_id,
$user->hash,
$user->quota
);
}
$this->tr->deleteEmail($user->id, EmailType::Primary);
if ($user->primaryEmail !== null) {
$this->tr->insertEmail($user->id, $user->primaryEmail, EmailType::Primary);
}
return $user;
}

/**
* @return array{new: bool, srv: ?string, admin: bool, quota: ?int}
* @throws Exception
*/
private function loadData(string $uid): array {
$users = $this->tr->selectAccount($uid, [AccountRole::User, AccountRole::Admin]);
return is_array($users[0]) ? [
'new' => false,
'srv' => is_string($users[0][SchAccount::ID]) ? $users[0][SchAccount::ID] : null,
'admin' => $users[0][SchAccount::ROLE] === AccountRole::Admin,
'quota' => is_int($users[0][SchAccount::QUOTA]) ? $users[0][SchAccount::QUOTA] : null
] : [
'new' => true,
'srv' => null,
'admin' => false,
'quota' => null
];
}

/** @throws Exception */
public function updateAllIUser(): void {
foreach ($this->userManager->search('') as $i_user) {
$this->updateIUser($i_user);
}
}

/** @throws Exception */
public function updateIUser(IUser $i_user): void {
$userData = $this->loadData($i_user->getUID());
$this->buildQuery($i_user, $userData['new'], $userData['srv'], $userData['admin'], $userData['quota']);
}

/** @throws Exception */
public function updateFromStarch(string $uid, ?string $srv, bool $admin, ?int $quota): ?UserEntity {
$i_user = $this->userManager->get($uid);
return $i_user !== null ? $this->buildQuery(
$i_user,
$this->loadData($uid)['new'],
$srv,
$admin,
$quota
) : null;
}

/** @throws Exception */
public function commit(): void {
$this->tr->commit();
}

}
42 changes: 4 additions & 38 deletions lib/Event/PasswordChangedListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,7 @@

namespace OCA\Nextmail\Event;

use OCA\Nextmail\Db\Transaction;
use OCA\Nextmail\Models\AccountRole;
use OCA\Nextmail\Models\EmailType;
use OCA\Nextmail\Models\UserEntity;
use OCA\Nextmail\SchemaV1\SchAccount;
use OCA\Nextmail\Db\UsersManager;
use OCP\DB\Exception;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventListener;
Expand All @@ -17,7 +13,7 @@
*/
readonly class PasswordChangedListener implements IEventListener {
public function __construct(
private Transaction $tr,
private UsersManager $um,
) {
}

Expand All @@ -26,37 +22,7 @@ public function __construct(
* @throws Exception
*/
public function handle(Event $event): void {
$i_user = $event->getUser();
$users = $this->tr->selectAccount($i_user->getUID(), [AccountRole::User, AccountRole::Admin]);
$array = count($users) === 1 && is_array($users[0]) ? $users[0] : [];
$user = UserEntity::fromIUser(
is_string($array[SchAccount::ID]) ? $array[SchAccount::ID] : '',
$i_user,
$array[SchAccount::ROLE] === AccountRole::Admin,
is_int($array[SchAccount::QUOTA]) ? $array[SchAccount::QUOTA] : null
);
if (count($users) === 0) {
$this->tr->insertAccount(
$user->id,
$user->server_id,
$user->name,
$user->hash,
$user->getRoleEnum(),
$user->quota
);
} else {
$this->tr->updateAccount(
$user->id,
$user->name,
$user->getRoleEnum(),
$user->hash,
$user->quota
);
}
$this->tr->deleteEmail($user->id, EmailType::Primary);
if ($user->primaryEmail !== null) {
$this->tr->insertEmail($user->id, $user->primaryEmail, EmailType::Primary);
}
$this->tr->commit();
$this->um->updateIUser($event->getUser());
$this->um->commit();
}
}
42 changes: 4 additions & 38 deletions lib/Event/UserChangedListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,7 @@

namespace OCA\Nextmail\Event;

use OCA\Nextmail\Db\Transaction;
use OCA\Nextmail\Models\AccountRole;
use OCA\Nextmail\Models\EmailType;
use OCA\Nextmail\Models\UserEntity;
use OCA\Nextmail\SchemaV1\SchAccount;
use OCA\Nextmail\Db\UsersManager;
use OCP\DB\Exception;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventListener;
Expand All @@ -17,7 +13,7 @@
*/
readonly class UserChangedListener implements IEventListener {
public function __construct(
private Transaction $tr,
private UsersManager $um,
) {
}

Expand All @@ -26,37 +22,7 @@ public function __construct(
* @throws Exception
*/
public function handle(Event $event): void {
$i_user = $event->getUser();
$users = $this->tr->selectAccount($i_user->getUID(), [AccountRole::User, AccountRole::Admin]);
$array = count($users) === 1 && is_array($users[0]) ? $users[0] : [];
$user = UserEntity::fromIUser(
is_string($array[SchAccount::ID]) ? $array[SchAccount::ID] : '',
$i_user,
$array[SchAccount::ROLE] === AccountRole::Admin,
is_int($array[SchAccount::QUOTA]) ? $array[SchAccount::QUOTA] : null
);
if (count($users) === 0) {
$this->tr->insertAccount(
$user->id,
$user->server_id,
$user->name,
$user->hash,
$user->getRoleEnum(),
$user->quota
);
} else {
$this->tr->updateAccount(
$user->id,
$user->name,
$user->getRoleEnum(),
$user->hash,
$user->quota
);
}
$this->tr->deleteEmail($user->id, EmailType::Primary);
if ($user->primaryEmail !== null) {
$this->tr->insertEmail($user->id, $user->primaryEmail, EmailType::Primary);
}
$this->tr->commit();
$this->um->updateIUser($event->getUser());
$this->um->commit();
}
}
42 changes: 4 additions & 38 deletions lib/Event/UserCreateListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,7 @@

namespace OCA\Nextmail\Event;

use OCA\Nextmail\Db\Transaction;
use OCA\Nextmail\Models\AccountRole;
use OCA\Nextmail\Models\EmailType;
use OCA\Nextmail\Models\UserEntity;
use OCA\Nextmail\SchemaV1\SchAccount;
use OCA\Nextmail\Db\UsersManager;
use OCP\DB\Exception;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventListener;
Expand All @@ -17,7 +13,7 @@
*/
readonly class UserCreateListener implements IEventListener {
public function __construct(
private Transaction $tr,
private UsersManager $um,
) {
}

Expand All @@ -26,37 +22,7 @@ public function __construct(
* @throws Exception
*/
public function handle(Event $event): void {
$i_user = $event->getUser();
$users = $this->tr->selectAccount($i_user->getUID(), [AccountRole::User, AccountRole::Admin]);
$array = count($users) === 1 && is_array($users[0]) ? $users[0] : [];
$user = UserEntity::fromIUser(
is_string($array[SchAccount::ID]) ? $array[SchAccount::ID] : '',
$i_user,
$array[SchAccount::ROLE] === AccountRole::Admin,
is_int($array[SchAccount::QUOTA]) ? $array[SchAccount::QUOTA] : null
);
if (count($users) === 0) {
$this->tr->insertAccount(
$user->id,
$user->server_id,
$user->name,
$user->hash,
$user->getRoleEnum(),
$user->quota
);
} else {
$this->tr->updateAccount(
$user->id,
$user->name,
$user->getRoleEnum(),
$user->hash,
$user->quota
);
}
$this->tr->deleteEmail($user->id, EmailType::Primary);
if ($user->primaryEmail !== null) {
$this->tr->insertEmail($user->id, $user->primaryEmail, EmailType::Primary);
}
$this->tr->commit();
$this->um->updateIUser($event->getUser());
$this->um->commit();
}
}
Loading

0 comments on commit bd6d5d4

Please sign in to comment.