mirror of
https://github.com/mailcow/mailcow-dockerized.git
synced 2026-11-05 16:08:21 +00:00
[Web] imapsync: change the server of a sync source only with access to all its sync jobs
This commit is contained in:
5 files changed
+45
-1
No files matched your search
@@ -48,6 +48,12 @@ class SourceRepository extends Repository
|
||||
return (bool)$this->query("SELECT 1 FROM `imapsync` WHERE `source_id` = :id LIMIT 1", ['id' => $id])->fetchColumn();
|
||||
}
|
||||
|
||||
/** @return string[] mailboxes whose sync jobs use the source */
|
||||
public function jobMailboxes(int $id): array
|
||||
{
|
||||
return $this->query("SELECT DISTINCT `user2` FROM `imapsync` WHERE `source_id` = :id", ['id' => $id])->fetchAll(PDO::FETCH_COLUMN);
|
||||
}
|
||||
|
||||
public function isSuperAdmin(string $username): bool
|
||||
{
|
||||
return (bool)$this->query("SELECT 1 FROM `admin` WHERE `username` = :username AND `superadmin` = '1'",
|
||||
|
||||
@@ -121,7 +121,11 @@ class SourceService
|
||||
if ($writeTargets) {
|
||||
$this->applyScope($source, $input['scope'] ?? $current->scope, $input['domains'] ?? [], $input['users'] ?? []);
|
||||
}
|
||||
$this->repo->update($source, $writeTargets, self::connection($current) !== self::connection($source));
|
||||
$connectionChanged = self::connection($current) !== self::connection($source);
|
||||
if ($connectionChanged) {
|
||||
$this->requireAllJobsAccessible($source);
|
||||
}
|
||||
$this->repo->update($source, $writeTargets, $connectionChanged);
|
||||
$this->fetchToken($source);
|
||||
return $source;
|
||||
}
|
||||
@@ -200,6 +204,24 @@ class SourceService
|
||||
return $this->context->hasAcl('syncjobs') || $this->context->isAdmin();
|
||||
}
|
||||
|
||||
/**
|
||||
* The connection of a source only changes when the caller may access every mailbox whose sync jobs use it,
|
||||
* their stored passwords would go to the new server.
|
||||
*
|
||||
* @throws UserError imapsync_source_used_by_others
|
||||
*/
|
||||
private function requireAllJobsAccessible(Source $source): void
|
||||
{
|
||||
if ($this->context->hasAdminRights()) {
|
||||
return;
|
||||
}
|
||||
foreach ($this->repo->jobMailboxes((int)$source->id) as $mailbox) {
|
||||
if (!$this->context->canAccessMailbox($mailbox)) {
|
||||
throw new UserError('imapsync_source_used_by_others', [htmlspecialchars($source->name)]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @throws AccessDenied when the caller cannot see or edit the source */
|
||||
private function editable(int $id): Source
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user