diff --git a/src/app/DataMigrator/Account.php b/src/app/DataMigrator/Account.php --- a/src/app/DataMigrator/Account.php +++ b/src/app/DataMigrator/Account.php @@ -42,7 +42,7 @@ * Object constructor * * Input can be a valid URI or "<username>:<password>". - * For proxy authentication use: "<proxy-user>**<username>" as username. + * For user impersonation use: ?user=<user> in the query part of the URI. * * @param string $input Account specification (URI) */ @@ -61,10 +61,6 @@ if (isset($url['user'])) { $this->username = urldecode($url['user']); - - if (strpos($this->username, '**')) { - list($this->username, $this->loginas) = explode('**', $this->username, 2); - } } if (isset($url['pass'])) { @@ -90,6 +86,10 @@ parse_str($url['query'], $this->params); } + if (!empty($this->params['user'])) { + $this->loginas = $this->params['user']; + } + if (strpos($this->loginas, '@')) { $this->email = $this->loginas; } elseif (strpos($this->username, '@')) { diff --git a/src/app/DataMigrator/IMAP.php b/src/app/DataMigrator/IMAP.php --- a/src/app/DataMigrator/IMAP.php +++ b/src/app/DataMigrator/IMAP.php @@ -35,7 +35,7 @@ $this->engine = $engine; // TODO: Move this to self::authenticate()? - $config = self::getConfig($account->username, $account->password, $account->uri); + $config = self::getConfig($account); $this->imap = self::initIMAP($config); } @@ -351,7 +351,7 @@ /** * Initialize IMAP connection and authenticate the user */ - private static function initIMAP(array $config, string $login_as = null): \rcube_imap_generic + private static function initIMAP(array $config): \rcube_imap_generic { $imap = new \rcube_imap_generic(); @@ -359,13 +359,6 @@ $imap->setDebug(true, 'App\Backends\IMAP::logDebug'); } - if ($login_as) { - $config['options']['auth_cid'] = $config['user']; - $config['options']['auth_pw'] = $config['password']; - $config['options']['auth_type'] = 'PLAIN'; - $config['user'] = $login_as; - } - $imap->connect($config['host'], $config['user'], $config['password'], $config['options']); if (!$imap->connected()) { @@ -382,9 +375,9 @@ /** * Get IMAP configuration */ - private static function getConfig($user, $password, $uri): array + private static function getConfig(Account $account): array { - $uri = \parse_url($uri); + $uri = \parse_url($account->uri); $default_port = 143; $ssl_mode = null; @@ -399,8 +392,8 @@ $config = [ 'host' => $uri['host'], - 'user' => $user, - 'password' => $password, + 'user' => $account->username, + 'password' => $account->password, 'options' => [ 'port' => !empty($uri['port']) ? $uri['port'] : $default_port, 'ssl_mode' => $ssl_mode, @@ -417,6 +410,14 @@ ], ]; + // User impersonation. Example URI: imap://admin:password@hostname:143?user=user%40domain.tld + if ($account->loginas) { + $config['options']['auth_cid'] = $config['user']; + $config['options']['auth_pw'] = $config['password']; + $config['options']['auth_type'] = 'PLAIN'; + $config['user'] = $account->loginas; + } + return $config; } diff --git a/src/tests/BackendsTrait.php b/src/tests/BackendsTrait.php --- a/src/tests/BackendsTrait.php +++ b/src/tests/BackendsTrait.php @@ -233,9 +233,10 @@ 'password' => $account->password, ]; + $login_as = $account->params['user'] ?? null; $config = array_merge($getConfig->invoke(null), $config); - $this->clients[$clientId] = $initIMAP->invokeArgs(null, [$config]); + $this->clients[$clientId] = $initIMAP->invokeArgs(null, [$config, $login_as]); } return $this->clients[$clientId]; diff --git a/src/tests/Feature/DataMigrator/IMAPTest.php b/src/tests/Feature/DataMigrator/IMAPTest.php --- a/src/tests/Feature/DataMigrator/IMAPTest.php +++ b/src/tests/Feature/DataMigrator/IMAPTest.php @@ -109,8 +109,11 @@ $uri = 'imap://' . $uri; } - $src = new Account(str_replace('://', '://john%40kolab.org:simple123@', $uri)); - $dst = new Account(str_replace('://', '://jack%40kolab.org:simple123@', $uri)); + // Let's test with impersonation now + $adminUser = \config('services.imap.admin_login'); + $adminPass = \config('services.imap.admin_password'); + $src = new Account(str_replace('://', "://$adminUser:$adminPass@", $uri) . '?user=john%40kolab.org'); + $dst = new Account(str_replace('://', "://$adminUser:$adminPass@", $uri) . '?user=jack%40kolab.org'); // Add some mails to the source account $srcMessages = $this->imapList($src, 'INBOX');