diff --git a/config/defaults.inc.php b/config/defaults.inc.php index 14df04f7c7..f9fa25f422 100644 --- a/config/defaults.inc.php +++ b/config/defaults.inc.php @@ -384,6 +384,9 @@ // Mandatory: OAuth scopes to request (space-separated string) $config['oauth_scope'] = null; +// Optional: OAuth scopes specific to identity request (space-separated string) +$config['oauth_scope_identity'] = null; + // Optional: additional query parameters to send with login request (hash array) $config['oauth_auth_parameters'] = []; @@ -455,6 +458,7 @@ // $config['oauth_identity_uri'] = "https://graph.microsoft.com/v1.0/me"; // $config['oauth_identity_fields'] = ['email', 'userPrincipalName']; // $config['oauth_scope'] = "https://outlook.office365.com/IMAP.AccessAsUser.All https://outlook.office365.com/SMTP.Send User.Read offline_access"; +// $config['oauth_scope_identity'] = "https://graph.microsoft.com/IMAP.AccessAsUser.All SMTP.Send offline_access User.Read"; // $config['oauth_auth_parameters'] = ['nonce' => mt_rand()]; // ---------------------------------- diff --git a/program/include/rcmail_oauth.php b/program/include/rcmail_oauth.php index d942fbcc42..cc4a685797 100644 --- a/program/include/rcmail_oauth.php +++ b/program/include/rcmail_oauth.php @@ -161,6 +161,7 @@ public function __construct($options = []) 'language' => ['locale'], ]), 'scope' => $this->rcmail->config->get('oauth_scope', ''), + 'scope_identity' => $this->rcmail->config->get('oauth_scope_identity', ''), 'timeout' => $this->rcmail->config->get('oauth_timeout', 10), 'verify_peer' => $this->rcmail->config->get('oauth_verify_peer', true), 'auth_parameters' => $this->rcmail->config->get('oauth_auth_parameters', []), @@ -641,7 +642,14 @@ public function request_access_token($auth_code, $state = null) // request user identity (email) if (empty($username)) { - $fetched_identity = $this->fetch_userinfo($authorization); + if($this->options['scope_identity']) { + $this->mask_auth_data($data); + $refresh_response = $this->refresh_access_token($data, $this->options['scope_identity']); + $data_ident = $refresh_response['token']; + $authorization_ident = $refresh_response['authorization']; + } + + $fetched_identity = $this->fetch_userinfo($authorization_ident); $this->log_debug('fetched identity: %s', json_encode($fetched_identity, true)); @@ -720,11 +728,14 @@ public function request_access_token($auth_code, $state = null) * If successful, this will update the `oauth_token` entry in * session data. * + * @param array $token + * @param string $change_scope Optional, changes scope if specified + * * @return array|false Updated authorization data * * @see https://datatracker.ietf.org/doc/html/rfc6749#section-6 */ - public function refresh_access_token(array $token) + public function refresh_access_token(array $token, $change_scope = null) { $oauth_token_uri = $this->options['token_uri']; $oauth_client_id = $this->options['client_id']; @@ -741,6 +752,10 @@ public function refresh_access_token(array $token) 'client_secret' => $oauth_client_secret, ]; + if($change_scope) { + $form['scope'] = $change_scope; + } + if ($this->options['pkce']) { $form['code_verifier'] = $this->rcmail->decrypt($_SESSION['oauth_code_verifier']); }