Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F124997156
D5884.1779142123.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
5 KB
Referenced Files
None
Subscribers
None
D5884.1779142123.diff
View Options
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
@@ -14,10 +14,19 @@
'get:api/v4/users/%d/delegators',
];
+
+ private static function sessionTokenKey(string $scope): string
+ {
+ if ($scope == 'api') {
+ return "kolab_access_token";
+ }
+ return "kolab_access_token_$scope";
+ }
+
/**
* Makes a HTTP request to the Cockpit API
*/
- private static function request($method, $path, $query = [], $post = [])
+ private static function request(string $method, string $path, array $query = [], array $post = [], string $scope = 'api')
{
// Get the response from cache
if ($cache_key = self::cacheKey($method, $path)) {
@@ -43,10 +52,15 @@
\GuzzleHttp\Psr7\Request $request,
\GuzzleHttp\Psr7\Response $response = null,
$exception = null
- ) use (&$delay, $path) {
+ ) use (&$delay, $path, $scope) {
$code = $response?->getStatusCode();
$delay = 0;
+ // This will retry forever otherwise
+ if ($retries >= 5) {
+ return false;
+ }
+
if ($code === 429) {
$delay = ((int) array_first($response->getHeader('X-RateLimit-Remaining'))) ?: 5;
return true;
@@ -54,7 +68,7 @@
// Refresh token and try again
if ($code === 401 && $path != 'api/auth/login') {
- return self::refreshAccessToken();
+ return self::refreshAccessToken($scope);
}
return false;
@@ -65,16 +79,17 @@
));
$stack->push(\GuzzleHttp\Middleware::mapRequest(
- function (\GuzzleHttp\Psr7\Request $request) use ($rcube, $debug) {
+ function (\GuzzleHttp\Psr7\Request $request) use ($rcube, $debug, $scope) {
if (!str_starts_with($request->getUri()->getPath(), '/api/auth/login')) {
- if (!isset($_SESSION['kolab_access_token'])) {
- if (!self::refreshAccessToken()) {
+ $sessionTokenKey = self::sessionTokenKey($scope);
+ if (!isset($_SESSION[$sessionTokenKey])) {
+ if (!self::refreshAccessToken($scope)) {
// 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']);
+ if (isset($_SESSION[$sessionTokenKey])) {
+ $token = $rcube->decrypt($_SESSION[$sessionTokenKey]);
$request = $request->withHeader('Authorization', 'Bearer ' . $token);
}
}
@@ -140,7 +155,8 @@
$body = '';
}
- $rcube->raise_error(self::$lastError . ": {$body}", true);
+ //FIXME this turns a 401 into a 500 error for activesync, but some access denied error would be more appropriate
+ $rcube->raise_error(self::$lastError . ": {$body}", true, true);
}
} catch (\Exception $e) {
if ($e->getMessage() != 'Login failed') {
@@ -153,7 +169,7 @@
/**
* Get a new access token
*/
- private static function refreshAccessToken(): bool
+ private static function refreshAccessToken(string $scope): bool
{
$rcube = \rcube::get_instance();
$username = $rcube->get_user_name();
@@ -164,11 +180,15 @@
'password' => $password,
'mode' => 'fast',
];
+ if ($scope) {
+ $post['scope'] = $scope;
+ }
$response = self::request('POST', 'api/auth/login', [], $post);
if ($response && isset($response->access_token)) {
- $_SESSION['kolab_access_token'] = $rcube->encrypt($response->access_token);
+ $sessionTokenKey = self::sessionTokenKey($scope);
+ $_SESSION[$sessionTokenKey] = $rcube->encrypt($response->access_token);
$_SESSION['kolab_user_id'] = $response->id ?? null;
// This is the best moment to clear the client cache
@@ -249,7 +269,7 @@
$rcube = \rcube::get_instance();
if ($rcube->get_user_name() && $rcube->get_user_password()) {
- $response = self::request('GET', 'api/v4/config/webmail');
+ $response = self::request('GET', 'api/v4/config/webmail', [], [], 'config');
if ($response) {
return (array) $response;
@@ -265,7 +285,7 @@
private static function getUserId()
{
if (empty($_SESSION['kolab_user_id'])) {
- self::refreshAccessToken();
+ self::refreshAccessToken('api');
/*
$response = self::request('GET', 'api/auth/info');
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, May 18, 10:08 PM (2 d, 20 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18927386
Default Alt Text
D5884.1779142123.diff (5 KB)
Attached To
Mode
D5884: Use a token with the 'config' scope for the user config request
Attached
Detach File
Event Timeline