diff --git a/htdocs/admin/emailcollector_card.php b/htdocs/admin/emailcollector_card.php index 8dfafb19b63..462839245fa 100644 --- a/htdocs/admin/emailcollector_card.php +++ b/htdocs/admin/emailcollector_card.php @@ -107,6 +107,7 @@ $permissiondellink = $user->admin; // Used by the include of actions_dellink.inc $permissiontoadd = $user->admin; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php $debuginfo = ''; +$error = 0; /* @@ -121,8 +122,6 @@ if ($reshook < 0) { } if (empty($reshook)) { - $error = 0; - $permissiontoadd = 1; $permissiontodelete = 1; if (empty($backtopage)) { @@ -397,104 +396,112 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $connectstringsource = ''; $connectstringtarget = ''; - if (function_exists('imap_open')) { - // Note: $object->host has been loaded by the fetch - $usessl = 1; + // Note: $object->host has been loaded by the fetch + $usessl = 1; - $connectstringserver = $object->getConnectStringIMAP($usessl); + $connectstringserver = $object->getConnectStringIMAP($usessl); - if ($action == 'scan') { - if (!empty($conf->global->MAIN_IMAP_USE_PHPIMAP)) { - if ($object->acces_type == 1) { - // Mode OAUth2 with PHP-IMAP - require_once DOL_DOCUMENT_ROOT.'/core/lib/oauth.lib.php'; // define $supportedoauth2array - $keyforsupportedoauth2array = $object->oauth_service; - if (preg_match('/^.*-/', $keyforsupportedoauth2array)) { - $keyforprovider = preg_replace('/^.*-/', '', $keyforsupportedoauth2array); - } else { - $keyforprovider = ''; - } - $keyforsupportedoauth2array = preg_replace('/-.*$/', '', $keyforsupportedoauth2array); - $keyforsupportedoauth2array = 'OAUTH_'.$keyforsupportedoauth2array.'_NAME'; - - $OAUTH_SERVICENAME = (empty($supportedoauth2array[$keyforsupportedoauth2array]['name']) ? 'Unknown' : $supportedoauth2array[$keyforsupportedoauth2array]['name'].($keyforprovider ? '-'.$keyforprovider : '')); - - require_once DOL_DOCUMENT_ROOT.'/includes/OAuth/bootstrap.php'; - //$debugtext = "Host: ".$this->host."
Port: ".$this->port."
Login: ".$this->login."
Password: ".$this->password."
access type: ".$this->acces_type."
oauth service: ".$this->oauth_service."
Max email per collect: ".$this->maxemailpercollect; - //dol_syslog($debugtext); - - $storage = new DoliStorage($db, $conf); - - try { - $tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME); - $expire = true; - // Is token expired or will token expire in the next 30 seconds - // if (is_object($tokenobj)) { - // $expire = ($tokenobj->getEndOfLife() !== -9002 && $tokenobj->getEndOfLife() !== -9001 && time() > ($tokenobj->getEndOfLife() - 30)); - // } - // Token expired so we refresh it - if (is_object($tokenobj) && $expire) { - $credentials = new Credentials( - getDolGlobalString('OAUTH_'.$object->oauth_service.'_ID'), - getDolGlobalString('OAUTH_'.$object->oauth_service.'_SECRET'), - getDolGlobalString('OAUTH_'.$object->oauth_service.'_URLAUTHORIZE') - ); - $serviceFactory = new \OAuth\ServiceFactory(); - $oauthname = explode('-', $OAUTH_SERVICENAME); - // ex service is Google-Emails we need only the first part Google - $apiService = $serviceFactory->createService($oauthname[0], $credentials, $storage, array()); - // We have to save the token because Google give it only once - $refreshtoken = $tokenobj->getRefreshToken(); - $tokenobj = $apiService->refreshAccessToken($tokenobj); - $tokenobj->setRefreshToken($refreshtoken); - $storage->storeAccessToken($OAUTH_SERVICENAME, $tokenobj); - } - $tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME); - if (is_object($tokenobj)) { - $token = $tokenobj->getAccessToken(); - } else { - $object->error = "Token not found"; - return -1; - } - } catch (Exception $e) { - print $e->getMessage(); - } - - $cm = new ClientManager(); - $client = $cm->make([ - 'host' => $object->host, - 'port' => $object->port, - 'encryption' => 'ssl', - 'validate_cert' => true, - 'protocol' => 'imap', - 'username' => $object->login, - 'password' => $token, - 'authentication' => "oauth", - ]); + if ($action == 'scan') { + if (!empty($conf->global->MAIN_IMAP_USE_PHPIMAP)) { + if ($object->acces_type == 1) { + // Mode OAUth2 with PHP-IMAP + require_once DOL_DOCUMENT_ROOT.'/core/lib/oauth.lib.php'; // define $supportedoauth2array + $keyforsupportedoauth2array = $object->oauth_service; + if (preg_match('/^.*-/', $keyforsupportedoauth2array)) { + $keyforprovider = preg_replace('/^.*-/', '', $keyforsupportedoauth2array); } else { - // Mode login/pass with PHP-IMAP - $cm = new ClientManager(); - $client = $cm->make([ - 'host' => $object->host, - 'port' => $object->port, - 'encryption' => 'ssl', - 'validate_cert' => true, - 'protocol' => 'imap', - 'username' => $object->login, - 'password' => $object->password, - 'authentication' => "login", - ]); + $keyforprovider = ''; } + $keyforsupportedoauth2array = preg_replace('/-.*$/', '', $keyforsupportedoauth2array); + $keyforsupportedoauth2array = 'OAUTH_'.$keyforsupportedoauth2array.'_NAME'; + + $OAUTH_SERVICENAME = (empty($supportedoauth2array[$keyforsupportedoauth2array]['name']) ? 'Unknown' : $supportedoauth2array[$keyforsupportedoauth2array]['name'].($keyforprovider ? '-'.$keyforprovider : '')); + + require_once DOL_DOCUMENT_ROOT.'/includes/OAuth/bootstrap.php'; + //$debugtext = "Host: ".$this->host."
Port: ".$this->port."
Login: ".$this->login."
Password: ".$this->password."
access type: ".$this->acces_type."
oauth service: ".$this->oauth_service."
Max email per collect: ".$this->maxemailpercollect; + //dol_syslog($debugtext); + + $storage = new DoliStorage($db, $conf, $keyforprovider); + + try { + $tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME); + $expire = true; + // Is token expired or will token expire in the next 30 seconds + // if (is_object($tokenobj)) { + // $expire = ($tokenobj->getEndOfLife() !== -9002 && $tokenobj->getEndOfLife() !== -9001 && time() > ($tokenobj->getEndOfLife() - 30)); + // } + // Token expired so we refresh it + if (is_object($tokenobj) && $expire) { + $credentials = new Credentials( + getDolGlobalString('OAUTH_'.$object->oauth_service.'_ID'), + getDolGlobalString('OAUTH_'.$object->oauth_service.'_SECRET'), + getDolGlobalString('OAUTH_'.$object->oauth_service.'_URLAUTHORIZE') + ); + $serviceFactory = new \OAuth\ServiceFactory(); + $oauthname = explode('-', $OAUTH_SERVICENAME); + // ex service is Google-Emails we need only the first part Google + $apiService = $serviceFactory->createService($oauthname[0], $credentials, $storage, array()); + // We have to save the token because Google give it only once + $refreshtoken = $tokenobj->getRefreshToken(); + $tokenobj = $apiService->refreshAccessToken($tokenobj); + $tokenobj->setRefreshToken($refreshtoken); + $storage->storeAccessToken($OAUTH_SERVICENAME, $tokenobj); + } + $tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME); + if (is_object($tokenobj)) { + $token = $tokenobj->getAccessToken(); + } else { + $error++; + $morehtml .= "Token not found"; + } + } catch (Exception $e) { + $error++; + $morehtml .= $e->getMessage(); + } + + if (empty($object->login)) { + $error++; + $morehtml .= 'Error: Login is empty. Must be email owner when using MAIN_IMAP_USE_PHPIMAP and OAuth.'; + } + + $cm = new ClientManager(); + $client = $cm->make([ + 'host' => $object->host, + 'port' => $object->port, + 'encryption' => 'ssl', + 'validate_cert' => true, + 'protocol' => 'imap', + 'username' => $object->login, + 'password' => $token, + 'authentication' => "oauth", + ]); + } else { + // Mode login/pass with PHP-IMAP + $cm = new ClientManager(); + $client = $cm->make([ + 'host' => $object->host, + 'port' => $object->port, + 'encryption' => 'ssl', + 'validate_cert' => true, + 'protocol' => 'imap', + 'username' => $object->login, + 'password' => $object->password, + 'authentication' => "login", + ]); + } + if (!$error) { try { $client->connect(); - } catch (ConnectionFailedException $e) { - print $e->getMessage(); - } - $f = $client->getFolders(false, $object->source_directory); - $nbemail = $f[0]->examine()["exists"]; - $morehtml .= $nbemail; - } else { + $f = $client->getFolders(false, $object->source_directory); + $nbemail = $f[0]->examine()["exists"]; + $morehtml .= $nbemail; + } catch (ConnectionFailedException $e) { + $morehtml .= 'ConnectionFailedException '.$e->getMessage(); + } + } + } else { + if (function_exists('imap_open')) { try { if ($sourcedir) { //$connectstringsource = $connectstringserver.imap_utf7_encode($sourcedir); @@ -521,7 +528,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea //dol_syslog("end imap_open connection=".var_export($connection, true)); } catch (Exception $e) { - print $e->getMessage(); + $morehtml .= $e->getMessage(); } if (!$connection) { @@ -540,16 +547,16 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea dol_syslog("Imap close"); imap_close($connection); } + } else { + $morehtml .= 'IMAP functions not available on your PHP. '; } - } else { - $morehtml .= ''.img_picto('', 'refresh', 'class="paddingrightonly"').$langs->trans("Refresh").''; } - - $morehtml .= $form->textwithpicto('', 'connect string '.$connectstringserver); } else { - $morehtml .= 'IMAP functions not available on your PHP. '; + $morehtml .= ''.img_picto('', 'refresh', 'class="paddingrightonly"').$langs->trans("Refresh").''; } + $morehtml .= $form->textwithpicto('', 'connect string '.$connectstringserver); + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref.'
'.$morehtml.'
', '', 0, '', '', 0, ''); print '
'; diff --git a/htdocs/admin/oauthlogintokens.php b/htdocs/admin/oauthlogintokens.php index d6fcc9e0f7c..5c0ecdb007d 100644 --- a/htdocs/admin/oauthlogintokens.php +++ b/htdocs/admin/oauthlogintokens.php @@ -221,8 +221,11 @@ if ($mode == 'setup' && $user->admin) { $storage = new DoliStorage($db, $conf, $keyforprovider); try { // $OAUTH_SERVICENAME is for example 'Google-keyforprovider' - print $OAUTH_SERVICENAME; + print ''."\n"; $tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME); + //print $storage->token.'
'; + //print $tokenobj->getExtraParams()['id_token'].'
'; + //print $tokenobj->getAccessToken().'
'; } catch (Exception $e) { // Return an error if token not found //print $e->getMessage(); @@ -342,7 +345,6 @@ if ($mode == 'setup' && $user->admin) { print ''; if (is_object($tokenobj)) { - //var_dump($tokenobj); $tokentoshow = $tokenobj->getAccessToken(); print ''.showValueWithClipboardCPButton($tokentoshow, 1, dol_trunc($tokentoshow, 32)).'
'; //print 'Refresh: '.$tokenobj->getRefreshToken().'
'; diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index a7a87e1ce6e..f6611669556 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -908,7 +908,7 @@ class CMailFile require_once DOL_DOCUMENT_ROOT.'/includes/OAuth/bootstrap.php'; - $storage = new DoliStorage($db, $conf); + $storage = new DoliStorage($db, $conf, $keyforprovider); try { $tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME); $expire = false; @@ -1030,7 +1030,7 @@ class CMailFile require_once DOL_DOCUMENT_ROOT.'/includes/OAuth/bootstrap.php'; - $storage = new DoliStorage($db, $conf); + $storage = new DoliStorage($db, $conf, $keyforprovider); try { $tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME); diff --git a/htdocs/core/lib/oauth.lib.php b/htdocs/core/lib/oauth.lib.php index 4f504196b47..2074485cd6e 100644 --- a/htdocs/core/lib/oauth.lib.php +++ b/htdocs/core/lib/oauth.lib.php @@ -35,7 +35,7 @@ $supportedoauth2array['OAUTH_GITHUB_NAME'] = array('callbackfile' => 'github', ' if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) { $supportedoauth2array['OAUTH_OTHER_NAME'] = array('callbackfile' => 'generic', 'picto' => 'generic', 'urlforapp' => 'OAUTH_OTHER_DESC', 'name'=>'Other', 'urlforcredentials'=>'', 'availablescopes'=>'Standard', 'returnurl'=>'/core/modules/oauth/generic_oauthcallback.php'); // See https://learn.microsoft.com/fr-fr/azure/active-directory/develop/quickstart-register-app#register-an-application - $supportedoauth2array['OAUTH_MICROSOFT_NAME'] = array('callbackfile' => 'microsoft', 'picto' => 'microsoft', 'urlforapp' => 'OAUTH_MICROSOFT_DESC', 'name'=>'Microsoft', 'urlforcredentials'=>'https://portal.azure.com/', 'availablescopes'=>'openid,offline_access,profile,email,IMAP.AccessAsUser.All', 'returnurl'=>'/core/modules/oauth/microsoft_oauthcallback.php'); + $supportedoauth2array['OAUTH_MICROSOFT_NAME'] = array('callbackfile' => 'microsoft', 'picto' => 'microsoft', 'urlforapp' => 'OAUTH_MICROSOFT_DESC', 'name'=>'Microsoft', 'urlforcredentials'=>'https://portal.azure.com/', 'availablescopes'=>'openid,offline_access,profile,email,IMAP.AccessAsUser.All,SMTP.Send,Mail.Read,Mail.Send', 'returnurl'=>'/core/modules/oauth/microsoft_oauthcallback.php'); } diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php index 51c3434a456..a097ba23e3e 100644 --- a/htdocs/core/lib/security.lib.php +++ b/htdocs/core/lib/security.lib.php @@ -119,6 +119,7 @@ function dolGetRandomBytes($length) function dolEncrypt($chain, $key = '', $ciphering = "AES-256-CTR") { global $dolibarr_main_instance_unique_id; + global $dolibarr_disable_dolcrypt_for_debug; if ($chain === '' || is_null($chain)) { return ''; @@ -136,7 +137,7 @@ function dolEncrypt($chain, $key = '', $ciphering = "AES-256-CTR") $newchain = $chain; - if (function_exists('openssl_encrypt')) { + if (function_exists('openssl_encrypt') && empty($dolibarr_disable_dolcrypt_for_debug)) { $ivlen = 16; if (function_exists('openssl_cipher_iv_length')) { $ivlen = openssl_cipher_iv_length($ciphering); diff --git a/htdocs/core/modules/oauth/google_oauthcallback.php b/htdocs/core/modules/oauth/google_oauthcallback.php index c26187e4475..bd59e513ddf 100644 --- a/htdocs/core/modules/oauth/google_oauthcallback.php +++ b/htdocs/core/modules/oauth/google_oauthcallback.php @@ -217,6 +217,8 @@ if (GETPOST('code')) { // We are coming from oauth provider page. //$url .= 'hd=xxx'; } + //var_dump($url);exit; + // we go on oauth provider authorization page header('Location: '.$url); exit(); diff --git a/htdocs/core/modules/oauth/microsoft_oauthcallback.php b/htdocs/core/modules/oauth/microsoft_oauthcallback.php index ed47eec06e1..4ff573725f3 100644 --- a/htdocs/core/modules/oauth/microsoft_oauthcallback.php +++ b/htdocs/core/modules/oauth/microsoft_oauthcallback.php @@ -155,10 +155,9 @@ if (GETPOST('code') || GETPOST('error')) { // We are coming from oauth provi if (GETPOST('error')) { setEventMessages(GETPOST('error').' '.GETPOST('error_description'), null, 'errors'); } else { - $apiService->tenant = getDolGlobalString($keyforparamtenant); - //$token = $apiService->requestAccessToken(GETPOST('code'), $state); $token = $apiService->requestAccessToken(GETPOST('code')); + //print $token; // Microsoft is a service that does not need state to be stored as second paramater of requestAccessToken setEventMessages($langs->trans('NewTokenStored'), null, 'mesgs'); // Stored into object managed by class DoliStorage so into table oauth_token @@ -182,7 +181,6 @@ if (GETPOST('code') || GETPOST('error')) { // We are coming from oauth provi //if (!preg_match('/^forlogin/', $state)) { // $apiService->setApprouvalPrompt('auto'); //} - $apiService->tenant = getDolGlobalString($keyforparamtenant); // This may create record into oauth_state before the header redirect. // Creation of record with state in this tables depend on the Provider used (see its constructor). diff --git a/htdocs/core/modules/printing/printgcp.modules.php b/htdocs/core/modules/printing/printgcp.modules.php index c04d3ac9ca5..c1b6ba6c86e 100644 --- a/htdocs/core/modules/printing/printgcp.modules.php +++ b/htdocs/core/modules/printing/printgcp.modules.php @@ -116,10 +116,12 @@ class printing_printgcp extends PrintingDriver 'type'=>'info', ); } else { + $keyforprovider = ''; // @FIXME + $this->google_id = getDolGlobalString('OAUTH_GOOGLE_ID'); $this->google_secret = getDolGlobalString('OAUTH_GOOGLE_SECRET'); // Token storage - $storage = new DoliStorage($this->db, $this->conf); + $storage = new DoliStorage($this->db, $this->conf, $keyforprovider); //$storage->clearToken($this->OAUTH_SERVICENAME_GOOGLE); // Setup the credentials for the requests $credentials = new Credentials( @@ -254,8 +256,11 @@ class printing_printgcp extends PrintingDriver public function getlistAvailablePrinters() { $ret = array(); + + $keyforprovider = ''; // @FIXME + // Token storage - $storage = new DoliStorage($this->db, $this->conf); + $storage = new DoliStorage($this->db, $this->conf, $keyforprovider); // Setup the credentials for the requests $credentials = new Credentials( $this->google_id, @@ -392,8 +397,11 @@ class printing_printgcp extends PrintingDriver 'content' => base64_encode($contents), // encode file content as base64 'contentType' => $contenttype, ); + + $keyforprovider = ''; // @FIXME + // Dolibarr Token storage - $storage = new DoliStorage($this->db, $this->conf); + $storage = new DoliStorage($this->db, $this->conf, $keyforprovider); // Setup the credentials for the requests $credentials = new Credentials( $this->google_id, @@ -441,8 +449,11 @@ class printing_printgcp extends PrintingDriver $error = 0; $html = ''; + + $keyforprovider = ''; // @FIXME + // Token storage - $storage = new DoliStorage($this->db, $this->conf); + $storage = new DoliStorage($this->db, $this->conf, $keyforprovider); // Setup the credentials for the requests $credentials = new Credentials( $this->google_id, diff --git a/htdocs/emailcollector/class/emailcollector.class.php b/htdocs/emailcollector/class/emailcollector.class.php index 2c23f6e0475..2002adafd86 100644 --- a/htdocs/emailcollector/class/emailcollector.class.php +++ b/htdocs/emailcollector/class/emailcollector.class.php @@ -1082,7 +1082,7 @@ class EmailCollector extends CommonObject //$debugtext = "Host: ".$this->host."
Port: ".$this->port."
Login: ".$this->login."
Password: ".$this->password."
access type: ".$this->acces_type."
oauth service: ".$this->oauth_service."
Max email per collect: ".$this->maxemailpercollect; //dol_syslog($debugtext); - $storage = new DoliStorage($db, $conf); + $storage = new DoliStorage($db, $conf, $keyforprovider); try { $tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME); diff --git a/htdocs/includes/OAuth/Common/Storage/DoliStorage.php b/htdocs/includes/OAuth/Common/Storage/DoliStorage.php index cf280262e99..60af1f631c6 100644 --- a/htdocs/includes/OAuth/Common/Storage/DoliStorage.php +++ b/htdocs/includes/OAuth/Common/Storage/DoliStorage.php @@ -57,6 +57,8 @@ class DoliStorage implements TokenStorageInterface private $key; //private $stateKey; private $keyforprovider; + public $token; + private $tenant; public $state; public $date_creation; @@ -73,6 +75,7 @@ class DoliStorage implements TokenStorageInterface $this->db = $db; $this->conf = $conf; $this->keyforprovider = $keyforprovider; + $this->token = ''; $this->tokens = array(); $this->states = array(); //$this->key = $key; @@ -96,7 +99,7 @@ class DoliStorage implements TokenStorageInterface /** * {@inheritDoc} */ - public function storeAccessToken($service, TokenInterface $token) + public function storeAccessToken($service, TokenInterface $tokenobj) { global $conf; @@ -104,16 +107,25 @@ class DoliStorage implements TokenStorageInterface //var_dump($token); dol_syslog("storeAccessToken service=".$service); - include_once DOL_DOCUMENT_ROOT.'/core/lib/security.lib.php'; - $serializedToken = dolEncrypt(serialize($token)); + $servicepluskeyforprovider = $service; + if (!empty($this->keyforprovider)) { + // We clean the keyforprovider after the - to be sure it is not present + $servicepluskeyforprovider = preg_replace('/\-'.preg_quote($this->keyforprovider, '/').'$/', '', $servicepluskeyforprovider); + // Now we add the keyforprovider + $servicepluskeyforprovider .= '-'.$this->keyforprovider; + } - $this->tokens[$service] = $token; + include_once DOL_DOCUMENT_ROOT.'/core/lib/security.lib.php'; + $serializedToken = serialize($tokenobj); if (!is_array($this->tokens)) { $this->tokens = array(); } + + $this->tokens[$service] = $tokenobj; + $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."oauth_token"; - $sql .= " WHERE service = '".$this->db->escape($service.($this->keyforprovider?'-'.$this->keyforprovider:''))."'"; + $sql .= " WHERE service = '".$this->db->escape($servicepluskeyforprovider)."'"; $sql .= " AND entity IN (".getEntity('oauth_token').")"; $resql = $this->db->query($sql); if (! $resql) { @@ -123,7 +135,7 @@ class DoliStorage implements TokenStorageInterface if ($obj) { // update $sql = "UPDATE ".MAIN_DB_PREFIX."oauth_token"; - $sql.= " SET token = '".$this->db->escape($serializedToken)."'"; + $sql.= " SET token = '".$this->db->escape(dolEncrypt($serializedToken))."'"; $sql.= " WHERE rowid = ".((int) $obj['rowid']); $resql = $this->db->query($sql); if (!$resql) { @@ -132,7 +144,7 @@ class DoliStorage implements TokenStorageInterface } else { // save $sql = "INSERT INTO ".MAIN_DB_PREFIX."oauth_token (service, token, entity, datec)"; - $sql .= " VALUES ('".$this->db->escape($service.($this->keyforprovider?'-'.$this->keyforprovider:''))."', '".$this->db->escape($serializedToken)."', ".((int) $conf->entity).", "; + $sql .= " VALUES ('".$this->db->escape($servicepluskeyforprovider)."', '".$this->db->escape(dolEncrypt($serializedToken))."', ".((int) $conf->entity).", "; $sql .= " '".$this->db->idate(dol_now())."'"; $sql .= ")"; $resql = $this->db->query($sql); @@ -147,15 +159,26 @@ class DoliStorage implements TokenStorageInterface } /** - * {@inheritDoc} + * Load token and other data from a $service + * Note: Token load are cumulated into array ->tokens when other properties are erased by last loaded token. + * + * @return void */ public function hasAccessToken($service) { // get from db dol_syslog("hasAccessToken service=".$service); + $servicepluskeyforprovider = $service; + if (!empty($this->keyforprovider)) { + // We clean the keyforprovider after the - to be sure it is not present + $servicepluskeyforprovider = preg_replace('/\-'.preg_quote($this->keyforprovider, '/').'$/', '', $servicepluskeyforprovider); + // Now we add the keyforprovider + $servicepluskeyforprovider .= '-'.$this->keyforprovider; + } + $sql = "SELECT token, datec, tms, state FROM ".MAIN_DB_PREFIX."oauth_token"; - $sql .= " WHERE service = '".$this->db->escape($service.(empty($this->keyforprovider) ? '' : '-'.$this->keyforprovider))."'"; + $sql .= " WHERE service = '".$this->db->escape($servicepluskeyforprovider)."'"; $sql .= " AND entity IN (".getEntity('oauth_token').")"; $resql = $this->db->query($sql); if (! $resql) { @@ -164,18 +187,20 @@ class DoliStorage implements TokenStorageInterface $result = $this->db->fetch_array($resql); if ($result) { include_once DOL_DOCUMENT_ROOT.'/core/lib/security.lib.php'; - $token = unserialize(dolDecrypt($result['token'])); + $tokenobj = unserialize(dolDecrypt($result['token'])); + $this->token = dolDecrypt($result['token']); $this->date_creation = $this->db->jdate($result['datec']); $this->date_modification = $this->db->jdate($result['tms']); $this->state = $result['state']; } else { - $token = ''; + $tokenobj = ''; + $this->token = ''; $this->date_creation = null; $this->date_modification = null; $this->state = ''; } - $this->tokens[$service] = $token; + $this->tokens[$service] = $tokenobj; return is_array($this->tokens) && isset($this->tokens[$service]) @@ -331,4 +356,18 @@ class DoliStorage implements TokenStorageInterface // allow chaining return $this; } + + /** + * Return the token + * + * @return string String for the tenant used to create the token + */ + public function getTenant() + { + // Set/Reset tenant now so it will be defined for. + // TODO We must store it into the table llx_oauth_token + $this->tenant = getDolGlobalString('OAUTH_MICROSOFT'.($this->keyforprovider ? '-'.$this->keyforprovider : '').'_TENANT'); + + return $this->tenant; + } } diff --git a/htdocs/includes/OAuth/OAuth2/Service/Microsoft.php b/htdocs/includes/OAuth/OAuth2/Service/Microsoft.php index b1b6a042c01..e94799b81cf 100644 --- a/htdocs/includes/OAuth/OAuth2/Service/Microsoft.php +++ b/htdocs/includes/OAuth/OAuth2/Service/Microsoft.php @@ -38,9 +38,13 @@ class Microsoft extends AbstractService const SCOPE_APPLICATIONS = 'applications'; const SCOPE_APPLICATIONS_CREATE = 'applications_create'; const SCOPE_IMAP = 'imap'; - const SOCPE_IMAP_AccessAsUser_All='IMAP.AccessAsUser.All'; + const SOCPE_IMAP_ACCESSASUSERALL = 'IMAP.AccessAsUser.All'; + const SOCPE_SMTPSEND = 'SMTP.Send'; + const SOCPE_MAILREAD = 'Mail.Read'; + const SOCPE_MAILSEND = 'Mail.Send'; + + protected $storage; - public string $tenant; /** * MS uses some magical not officialy supported scope to get even moar info like full emailaddresses. @@ -65,6 +69,8 @@ class Microsoft extends AbstractService ) { parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri); + $this->storage = $storage; + if (null === $baseApiUri) { $this->baseApiUri = new Uri('https://apis.live.net/v5.0/'); } @@ -75,9 +81,11 @@ class Microsoft extends AbstractService */ public function getAuthorizationEndpoint() { - //return new Uri('https://login.live.com/oauth20_authorize.srf'); + $tenant = $this->storage->getTenant(); + + //return new Uri('https://login.live.com/oauth20_authorize.srf'); //return new Uri('https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize'); - return new Uri('https://login.microsoftonline.com/'.$this->tenant.'/oauth2/v2.0/authorize'); + return new Uri('https://login.microsoftonline.com/'.$tenant.'/oauth2/v2.0/authorize'); } /** @@ -85,9 +93,11 @@ class Microsoft extends AbstractService */ public function getAccessTokenEndpoint() { + $tenant = $this->storage->getTenant(); + //return new Uri('https://login.live.com/oauth20_token.srf'); //return new Uri('https://login.microsoftonline.com/organizations/oauth2/v2.0/token'); - return new Uri('https://login.microsoftonline.com/'.$this->tenant.'/oauth2/v2.0/token'); + return new Uri('https://login.microsoftonline.com/'.$tenant.'/oauth2/v2.0/token'); } /** @@ -110,6 +120,7 @@ class Microsoft extends AbstractService } elseif (isset($data['error'])) { throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); } + //print $data['access_token'];exit; $token = new StdOAuth2Token(); $token->setAccessToken($data['access_token']); diff --git a/htdocs/printing/admin/printing.php b/htdocs/printing/admin/printing.php index fb8426abc1b..ed856024d63 100644 --- a/htdocs/printing/admin/printing.php +++ b/htdocs/printing/admin/printing.php @@ -201,13 +201,15 @@ if ($mode == 'setup' && $user->admin) { $i++; if ($key['varname'] == 'PRINTGCP_TOKEN_ACCESS') { + $keyforprovider = ''; // @BUG This must be set + // Token print ''; print ''.$langs->trans("Token").''; print ''; $tokenobj = null; // Dolibarr storage - $storage = new DoliStorage($db, $conf); + $storage = new DoliStorage($db, $conf, $keyforprovider); try { $tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME_GOOGLE); } catch (Exception $e) {