Page MenuHomePhorge

D5874.1775381552.diff
No OneTemporary

Authored By
Unknown
Size
6 KB
Referenced Files
None
Subscribers
None

D5874.1775381552.diff

diff --git a/plugins/kolab/Kolab/Client.php b/plugins/kolab/Kolab/Client.php
--- a/plugins/kolab/Kolab/Client.php
+++ b/plugins/kolab/Kolab/Client.php
@@ -36,46 +36,53 @@
$stack = new \GuzzleHttp\HandlerStack();
$stack->setHandler(\GuzzleHttp\choose_handler());
- if (!str_starts_with($path, 'api/auth/login')) {
- $stack->push(\GuzzleHttp\Middleware::retry(
- function (
- int $retries,
- \GuzzleHttp\Psr7\Request $request,
- \GuzzleHttp\Psr7\Response $response = null,
- $exception = null
- ) {
- $maxRetries = 2;
-
- if ($retries >= $maxRetries) {
- return false;
- }
-
- if ($response && $response->getStatusCode() === 401) {
- self::refreshAccessToken();
- return true;
- }
+ $delay = 0;
+ $stack->push(\GuzzleHttp\Middleware::retry(
+ function (
+ int $retries,
+ \GuzzleHttp\Psr7\Request $request,
+ \GuzzleHttp\Psr7\Response $response = null,
+ $exception = null
+ ) use (&$delay, $path) {
+ $code = $response?->getStatusCode();
+ $delay = 0;
+
+ if ($code === 429) {
+ $delay = ((int) array_first($response->getHeader('X-RateLimit-Remaining'))) ?: 5;
+ return true;
+ }
- return false;
- },
- function (int $retries) {
- return 0; // no delay on retry
+ // Refresh token and try again
+ if ($code === 401 && $path != 'api/auth/login') {
+ return self::refreshAccessToken();
}
- ));
- }
+
+ return false;
+ },
+ function (int $retries) use ($delay) {
+ return $delay;
+ }
+ ));
$stack->push(\GuzzleHttp\Middleware::mapRequest(
function (\GuzzleHttp\Psr7\Request $request) use ($rcube, $debug) {
- if ($debug) {
- self::requestDebug($request);
- }
-
if (!str_starts_with($request->getUri()->getPath(), '/api/auth/login')) {
+ if (!isset($_SESSION['kolab_access_token'])) {
+ if (!self::refreshAccessToken()) {
+ // Prevent from sending the request if we don't have a valid token
+ throw new \Exception('Login failed');
+ }
+ }
if (isset($_SESSION['kolab_access_token'])) {
$token = $rcube->decrypt($_SESSION['kolab_access_token']);
- return $request->withHeader('Authorization', 'Bearer ' . $token);
+ $request = $request->withHeader('Authorization', 'Bearer ' . $token);
}
}
+ if ($debug) {
+ self::requestDebug($request);
+ }
+
return $request;
}
));
@@ -136,15 +143,17 @@
$rcube->raise_error(self::$lastError . ": {$body}", true);
}
} catch (\Exception $e) {
- self::$lastError = $e->getMessage();
- $rcube->raise_error($e, true, false);
+ if ($e->getMessage() != 'Login failed') {
+ self::$lastError = $e->getMessage();
+ $rcube->raise_error($e, true, false);
+ }
}
}
/**
* Get a new access token
*/
- private static function refreshAccessToken()
+ private static function refreshAccessToken(): bool
{
$rcube = \rcube::get_instance();
$username = $rcube->get_user_name();
@@ -161,7 +170,14 @@
if ($response && isset($response->access_token)) {
$_SESSION['kolab_access_token'] = $rcube->encrypt($response->access_token);
$_SESSION['kolab_user_id'] = $response->id ?? null;
+
+ // This is the best moment to clear the client cache
+ self::cacheClear();
+
+ return true;
}
+
+ return false;
}
/**
@@ -378,6 +394,10 @@
{
$rcube = \rcube::get_instance();
+ if (empty($rcube->user?->ID)) {
+ return null;
+ }
+
if ($type = $rcube->config->get('kolab_client_cache')) {
$ttl = $rcube->config->get('kolab_client_cache_ttl', '10m');
return $rcube->get_cache('kolab_client', $type, $ttl);
diff --git a/plugins/kolab/kolab.php b/plugins/kolab/kolab.php
--- a/plugins/kolab/kolab.php
+++ b/plugins/kolab/kolab.php
@@ -89,15 +89,15 @@
*/
public function loginAfterHook($args): array
{
- // This is the best moment to clear the client cache
- Kolab\Client::cacheClear();
-
- // Handle client timezone argument in SSO return from Cockpit
- // @TODO: We could also pass timezone via a claim in the OAuth token
- // Note: It is currently possible to get the client timezone only because we load
- // Cockpit page during the SSO redirect. If we change that (e.g. if we use cookies instead of browser storage,
- // which might be useful for better responsiveness) detecting timezone will not be possible.
if (!empty($_SESSION['oauth_token'])) {
+ // This is the best moment to clear the client cache when using SSO
+ Kolab\Client::cacheClear();
+
+ // Handle client timezone argument in SSO return from Cockpit
+ // @TODO: We could also pass timezone via a claim in the OAuth token
+ // Note: It is currently possible to get the client timezone only because we load
+ // Cockpit page during the SSO redirect. If we change that (e.g. if we use cookies instead of browser storage,
+ // which might be useful for better responsiveness) detecting timezone will not be possible.
$timezone = \rcube_utils::get_input_string('timezone', \rcube_utils::INPUT_GPC);
if ($timezone && preg_match('|^[a-z0-9/_+-]+$|i', $timezone)) {
$_SESSION['timezone'] = $timezone;

File Metadata

Mime Type
text/plain
Expires
Sun, Apr 5, 9:32 AM (4 h, 42 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18829405
Default Alt Text
D5874.1775381552.diff (6 KB)

Event Timeline