microsoft_oauthcallback.php 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. <?php
  2. /* Copyright (C) 2022 Laurent Destailleur <eldy@users.sourceforge.net>
  3. * Copyright (C) 2015 Frederic France <frederic.france@free.fr>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. */
  18. /**
  19. * \file htdocs/core/modules/oauth/microsoft_oauthcallback.php
  20. * \ingroup oauth
  21. * \brief Page to get oauth callback
  22. */
  23. // Load Dolibarr environment
  24. require '../../../main.inc.php';
  25. require_once DOL_DOCUMENT_ROOT.'/includes/OAuth/bootstrap.php';
  26. use OAuth\Common\Storage\DoliStorage;
  27. use OAuth\Common\Consumer\Credentials;
  28. use OAuth\OAuth2\Service\GitHub;
  29. // Define $urlwithroot
  30. $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
  31. $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
  32. //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current
  33. $action = GETPOST('action', 'aZ09');
  34. $backtourl = GETPOST('backtourl', 'alpha');
  35. $keyforprovider = GETPOST('keyforprovider', 'aZ09');
  36. if (empty($keyforprovider) && !empty($_SESSION["oauthkeyforproviderbeforeoauthjump"]) && (GETPOST('code') || $action == 'delete')) {
  37. $keyforprovider = $_SESSION["oauthkeyforproviderbeforeoauthjump"];
  38. }
  39. $genericstring = 'MICROSOFT';
  40. /**
  41. * Create a new instance of the URI class with the current URI, stripping the query string
  42. */
  43. $uriFactory = new \OAuth\Common\Http\Uri\UriFactory();
  44. //$currentUri = $uriFactory->createFromSuperGlobalArray($_SERVER);
  45. //$currentUri->setQuery('');
  46. $currentUri = $uriFactory->createFromAbsolute($urlwithroot.'/core/modules/oauth/microsoft_oauthcallback.php');
  47. /**
  48. * Load the credential for the service
  49. */
  50. /** @var $serviceFactory \OAuth\ServiceFactory An OAuth service factory. */
  51. $serviceFactory = new \OAuth\ServiceFactory();
  52. $httpClient = new \OAuth\Common\Http\Client\CurlClient();
  53. // TODO Set options for proxy and timeout
  54. // $params=array('CURLXXX'=>value, ...)
  55. //$httpClient->setCurlParameters($params);
  56. $serviceFactory->setHttpClient($httpClient);
  57. // Dolibarr storage
  58. $storage = new DoliStorage($db, $conf, $keyforprovider);
  59. // Setup the credentials for the requests
  60. $keyforparamid = 'OAUTH_'.$genericstring.($keyforprovider ? '-'.$keyforprovider : '').'_ID';
  61. $keyforparamsecret = 'OAUTH_'.$genericstring.($keyforprovider ? '-'.$keyforprovider : '').'_SECRET';
  62. $keyforparamtenant = 'OAUTH_'.$genericstring.($keyforprovider ? '-'.$keyforprovider : '').'_TENANT';
  63. $credentials = new Credentials(
  64. getDolGlobalString($keyforparamid),
  65. getDolGlobalString($keyforparamsecret),
  66. $currentUri->getAbsoluteUri()
  67. );
  68. $state = GETPOST('state');
  69. $requestedpermissionsarray = array();
  70. if ($state) {
  71. $requestedpermissionsarray = explode(',', $state); // Example: 'user'. 'state' parameter is standard to retrieve some parameters back
  72. }
  73. if ($action != 'delete' && empty($requestedpermissionsarray)) {
  74. print 'Error, parameter state is not defined';
  75. exit;
  76. }
  77. //var_dump($requestedpermissionsarray);exit;
  78. // Instantiate the Api service using the credentials, http client and storage mechanism for the token
  79. // ucfirst(strtolower($genericstring)) must be the name of a class into OAuth/OAuth2/Services/Xxxx
  80. // $requestedpermissionsarray contains list of scopes.
  81. // Conversion into URL is done by Reflection on constant with name SCOPE_scope_in_uppercase
  82. try {
  83. $apiService = $serviceFactory->createService(ucfirst(strtolower($genericstring)), $credentials, $storage, $requestedpermissionsarray);
  84. } catch (Exception $e) {
  85. print $e->getMessage();
  86. exit;
  87. }
  88. /*
  89. var_dump($genericstring.($keyforprovider ? '-'.$keyforprovider : ''));
  90. var_dump($credentials);
  91. var_dump($storage);
  92. var_dump($requestedpermissionsarray);
  93. */
  94. if (empty($apiService)) {
  95. print 'Error, failed to create serviceFactory';
  96. exit;
  97. }
  98. // access type needed to have oauth provider refreshing token
  99. //$apiService->setAccessType('offline');
  100. $langs->load("oauth");
  101. if (!getDolGlobalString($keyforparamid)) {
  102. accessforbidden('Setup of service is not complete. Customer ID is missing');
  103. }
  104. if (!getDolGlobalString($keyforparamsecret)) {
  105. accessforbidden('Setup of service is not complete. Secret key is missing');
  106. }
  107. /*
  108. * Actions
  109. */
  110. if ($action == 'delete') {
  111. $storage->clearToken($genericstring);
  112. setEventMessages($langs->trans('TokenDeleted'), null, 'mesgs');
  113. header('Location: '.$backtourl);
  114. exit();
  115. }
  116. //dol_syslog("GET=".join(',', $_GET));
  117. if (GETPOST('code') || GETPOST('error')) { // We are coming from oauth provider page
  118. // We should have
  119. //$_GET=array('code' => string 'aaaaaaaaaaaaaa' (length=20), 'state' => string 'user,public_repo' (length=16))
  120. dol_syslog("We are coming from the oauth provider page code=".dol_trunc(GETPOST('code'), 5)." error=".GETPOST('error'));
  121. // This was a callback request from service, get the token
  122. try {
  123. //var_dump($state);
  124. //var_dump($apiService); // OAuth\OAuth2\Service\Microsoft
  125. if (GETPOST('error')) {
  126. setEventMessages(GETPOST('error').' '.GETPOST('error_description'), null, 'errors');
  127. } else {
  128. //print GETPOST('code');exit;
  129. //$token = $apiService->requestAccessToken(GETPOST('code'), $state);
  130. $token = $apiService->requestAccessToken(GETPOST('code'));
  131. // Microsoft is a service that does not need state to be stored as second paramater of requestAccessToken
  132. //print $token->getAccessToken().'<br><br>';
  133. //print $token->getExtraParams()['id_token'].'<br>';
  134. //print $token->getRefreshToken().'<br>';exit;
  135. setEventMessages($langs->trans('NewTokenStored'), null, 'mesgs'); // Stored into object managed by class DoliStorage so into table oauth_token
  136. }
  137. $backtourl = $_SESSION["backtourlsavedbeforeoauthjump"];
  138. unset($_SESSION["backtourlsavedbeforeoauthjump"]);
  139. header('Location: '.$backtourl);
  140. exit();
  141. } catch (Exception $e) {
  142. print $e->getMessage();
  143. }
  144. } else {
  145. // If we enter this page without 'code' parameter, we arrive here. This is the case when we want to get the redirect
  146. // to the OAuth provider login page.
  147. $_SESSION["backtourlsavedbeforeoauthjump"] = $backtourl;
  148. $_SESSION["oauthkeyforproviderbeforeoauthjump"] = $keyforprovider;
  149. $_SESSION['oauthstateanticsrf'] = $state;
  150. //if (!preg_match('/^forlogin/', $state)) {
  151. // $apiService->setApprouvalPrompt('auto');
  152. //}
  153. // This may create record into oauth_state before the header redirect.
  154. // Creation of record with state in this tables depend on the Provider used (see its constructor).
  155. if ($state) {
  156. $url = $apiService->getAuthorizationUri(array('state' => $state));
  157. } else {
  158. $url = $apiService->getAuthorizationUri(); // Parameter state will be randomly generated
  159. }
  160. // Show url to get authorization
  161. //var_dump((string) $url);exit;
  162. dol_syslog("Redirect to url=".$url);
  163. // we go on oauth provider authorization page
  164. header('Location: '.$url);
  165. exit();
  166. }
  167. /*
  168. * View
  169. */
  170. // No view at all, just actions
  171. $db->close();