Changeset View
Changeset View
Standalone View
Standalone View
src/app/Backends/IMAP.php
<?php | <?php | ||||
namespace App\Backends; | namespace App\Backends; | ||||
use App\Domain; | |||||
use App\Group; | use App\Group; | ||||
use App\Resource; | use App\Resource; | ||||
use App\SharedFolder; | use App\SharedFolder; | ||||
use App\User; | use App\User; | ||||
class IMAP | class IMAP | ||||
{ | { | ||||
/** @const array Group settings used by the backend */ | /** @const array Group settings used by the backend */ | ||||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | public static function createUser(User $user): bool | ||||
$config = self::getConfig(); | $config = self::getConfig(); | ||||
$imap = self::initIMAP($config); | $imap = self::initIMAP($config); | ||||
$mailbox = self::toUTF7('user/' . $user->email); | $mailbox = self::toUTF7('user/' . $user->email); | ||||
// Mailbox already exists | // Mailbox already exists | ||||
if (self::folderExists($imap, $mailbox)) { | if (self::folderExists($imap, $mailbox)) { | ||||
$imap->closeConnection(); | $imap->closeConnection(); | ||||
self::createDefaultFolders($user); | |||||
return true; | return true; | ||||
} | } | ||||
// Create the mailbox | // Create the mailbox | ||||
if (!$imap->createFolder($mailbox)) { | if (!$imap->createFolder($mailbox)) { | ||||
\Log::error("Failed to create mailbox {$mailbox}"); | \Log::error("Failed to create mailbox {$mailbox}"); | ||||
$imap->closeConnection(); | $imap->closeConnection(); | ||||
return false; | return false; | ||||
Show All 15 Lines | public static function createUser(User $user): bool | ||||
} | } | ||||
// Set quota | // Set quota | ||||
$quota = $user->countEntitlementsBySku('storage') * 1048576; | $quota = $user->countEntitlementsBySku('storage') * 1048576; | ||||
if ($quota) { | if ($quota) { | ||||
$imap->setQuota($mailbox, ['storage' => $quota]); | $imap->setQuota($mailbox, ['storage' => $quota]); | ||||
} | } | ||||
self::createDefaultFolders($user); | |||||
$imap->closeConnection(); | $imap->closeConnection(); | ||||
return true; | return true; | ||||
} | } | ||||
/** | /** | ||||
* Create default folders for the user. | |||||
* | |||||
* @param \App\User $user User | |||||
*/ | |||||
public static function createDefaultFolders(User $user): void | |||||
{ | |||||
if ($defaultFolders = \config('imap.default_folders')) { | |||||
$config = self::getConfig(); | |||||
// Log in as user to set private annotations and subscription state | |||||
$imap = self::initIMAP($config, $user->email); | |||||
foreach ($defaultFolders as $name => $folderconfig) { | |||||
try { | |||||
$mailbox = self::toUTF7($name); | |||||
self::createFolder($imap, $mailbox, true, $folderconfig['metadata']); | |||||
} catch (\Exception $e) { | |||||
\Log::warning("Failed to create the default folder" . $e->getMessage()); | |||||
} | |||||
} | |||||
$imap->closeConnection(); | |||||
} | |||||
} | |||||
/** | |||||
* Delete a mailbox. | * Delete a mailbox. | ||||
* | * | ||||
* @param \App\User $user User | * @param \App\User $user User | ||||
* | * | ||||
* @return bool True if a mailbox was deleted successfully, False otherwise | * @return bool True if a mailbox was deleted successfully, False otherwise | ||||
* @throws \Exception | * @throws \Exception | ||||
*/ | */ | ||||
public static function deleteUser(User $user): bool | public static function deleteUser(User $user): bool | ||||
▲ Show 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | class IMAP | ||||
public static function createResource(Resource $resource): bool | public static function createResource(Resource $resource): bool | ||||
{ | { | ||||
$config = self::getConfig(); | $config = self::getConfig(); | ||||
$imap = self::initIMAP($config); | $imap = self::initIMAP($config); | ||||
$settings = $resource->getSettings(['invitation_policy', 'folder']); | $settings = $resource->getSettings(['invitation_policy', 'folder']); | ||||
$mailbox = self::toUTF7($settings['folder']); | $mailbox = self::toUTF7($settings['folder']); | ||||
// Mailbox already exists | $acl = null; | ||||
if (self::folderExists($imap, $mailbox)) { | |||||
$imap->closeConnection(); | |||||
return true; | |||||
} | |||||
// Create the shared folder | |||||
if (!$imap->createFolder($mailbox)) { | |||||
\Log::error("Failed to create mailbox {$mailbox}"); | |||||
$imap->closeConnection(); | |||||
return false; | |||||
} | |||||
// Set folder type | |||||
$imap->setMetadata($mailbox, ['/shared/vendor/kolab/folder-type' => 'event']); | |||||
// Set ACL | |||||
if (!empty($settings['invitation_policy'])) { | if (!empty($settings['invitation_policy'])) { | ||||
if (preg_match('/^manual:(\S+@\S+)$/', $settings['invitation_policy'], $m)) { | if (preg_match('/^manual:(\S+@\S+)$/', $settings['invitation_policy'], $m)) { | ||||
self::aclUpdate($imap, $mailbox, ["{$m[1]}, full"]); | $acl = ["{$m[1]}, full"]; | ||||
} | } | ||||
} | } | ||||
self::createFolder($imap, $mailbox, false, ['/shared/vendor/kolab/folder-type' => 'event'], $acl); | |||||
$imap->closeConnection(); | $imap->closeConnection(); | ||||
return true; | return true; | ||||
} | } | ||||
/** | /** | ||||
* Update a resource. | * Update a resource. | ||||
▲ Show 20 Lines • Show All 77 Lines • ▼ Show 20 Lines | class IMAP | ||||
{ | { | ||||
$config = self::getConfig(); | $config = self::getConfig(); | ||||
$imap = self::initIMAP($config); | $imap = self::initIMAP($config); | ||||
$settings = $folder->getSettings(['acl', 'folder']); | $settings = $folder->getSettings(['acl', 'folder']); | ||||
$acl = !empty($settings['acl']) ? json_decode($settings['acl'], true) : null; | $acl = !empty($settings['acl']) ? json_decode($settings['acl'], true) : null; | ||||
$mailbox = self::toUTF7($settings['folder']); | $mailbox = self::toUTF7($settings['folder']); | ||||
// Mailbox already exists | self::createFolder($imap, $mailbox, false, ['/shared/vendor/kolab/folder-type' => $folder->type], $acl); | ||||
if (self::folderExists($imap, $mailbox)) { | |||||
$imap->closeConnection(); | |||||
return true; | |||||
} | |||||
// Create the mailbox | |||||
if (!$imap->createFolder($mailbox)) { | |||||
\Log::error("Failed to create mailbox {$mailbox}"); | |||||
$imap->closeConnection(); | |||||
return false; | |||||
} | |||||
// Set folder type | |||||
$imap->setMetadata($mailbox, ['/shared/vendor/kolab/folder-type' => $folder->type]); | |||||
// Set ACL | |||||
self::aclUpdate($imap, $mailbox, $acl); | |||||
$imap->closeConnection(); | $imap->closeConnection(); | ||||
return true; | return true; | ||||
} | } | ||||
/** | /** | ||||
* Update a shared folder. | * Update a shared folder. | ||||
▲ Show 20 Lines • Show All 127 Lines • ▼ Show 20 Lines | public static function verifyAccount(string $username): bool | ||||
return true; | return true; | ||||
} | } | ||||
$imap->closeConnection(); | $imap->closeConnection(); | ||||
return false; | return false; | ||||
} | } | ||||
/** | /** | ||||
* Check if an account is set up | |||||
* | |||||
* @param string $username User login (email address) | |||||
* | |||||
* @return bool True if an account exists and is set up, False otherwise | |||||
*/ | |||||
public static function verifyDefaultFolders(string $username): bool | |||||
{ | |||||
$config = self::getConfig(); | |||||
$imap = self::initIMAP($config, $username); | |||||
foreach (\config('imap.default_folders') as $mb => $_metadata) { | |||||
$mailbox = self::toUTF7($mb); | |||||
if (!self::folderExists($imap, $mailbox)) { | |||||
$imap->closeConnection(); | |||||
return false; | |||||
} | |||||
} | |||||
$imap->closeConnection(); | |||||
return true; | |||||
} | |||||
/** | |||||
* Check if we can connect to the imap server | * Check if we can connect to the imap server | ||||
* | * | ||||
* @return bool True on success | * @return bool True on success | ||||
*/ | */ | ||||
public static function healthcheck(): bool | public static function healthcheck(): bool | ||||
{ | { | ||||
$config = self::getConfig(); | $config = self::getConfig(); | ||||
$imap = self::initIMAP($config); | $imap = self::initIMAP($config); | ||||
Show All 40 Lines | public static function aclCleanup(string $ident, string $domain = ''): void | ||||
} | } | ||||
array_walk($folders, $callback); | array_walk($folders, $callback); | ||||
$imap->closeConnection(); | $imap->closeConnection(); | ||||
} | } | ||||
/** | /** | ||||
* Create a folder and set some default properties | |||||
* | |||||
* @param \rcube_imap_generic $imap The imap instance | |||||
* @param string $mailbox Mailbox name | |||||
* @param bool $subscribe Subscribe to the folder | |||||
* @param array $metadata Metadata to set on the folder | |||||
* @param array $acl Acl to set on the folder | |||||
* | |||||
* @return bool True when having a folder created, False if it already existed. | |||||
* @throws \Exception | |||||
*/ | |||||
private static function createFolder($imap, string $mailbox, $subscribe = false, $metadata = null, $acl = null) | |||||
{ | |||||
if (self::folderExists($imap, $mailbox)) { | |||||
return false; | |||||
} | |||||
if (!$imap->createFolder($mailbox)) { | |||||
throw new \Exception("Failed to create mailbox {$mailbox}"); | |||||
} | |||||
if ($acl) { | |||||
self::aclUpdate($imap, $mailbox, $acl, true); | |||||
} | |||||
if ($subscribe) { | |||||
$imap->subscribe($mailbox); | |||||
} | |||||
foreach ($metadata as $key => $value) { | |||||
$imap->setMetadata($mailbox, [$key => $value]); | |||||
} | |||||
return true; | |||||
} | |||||
/** | |||||
* Convert Kolab ACL into IMAP user->rights array | * Convert Kolab ACL into IMAP user->rights array | ||||
*/ | */ | ||||
private static function aclToImap($acl): array | private static function aclToImap($acl): array | ||||
{ | { | ||||
if (empty($acl)) { | if (empty($acl)) { | ||||
return []; | return []; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 124 Lines • Show Last 20 Lines |