28if (!empty($_GET[
'state']) && preg_match(
'/^forlogin-/', $_GET[
'state'])) {
30 $_GET[
'keyforprovider'] =
'Login';
33if (!defined(
'NOLOGIN') && $forlogin) {
38require
'../../../main.inc.php';
47require_once DOL_DOCUMENT_ROOT.
'/includes/OAuth/bootstrap.php';
49use OAuth\Common\Storage\DoliStorage;
50use OAuth\Common\Consumer\Credentials;
51use OAuth\Common\Http\Uri\Uri;
55$urlwithouturlroot = preg_replace(
'/'.preg_quote(DOL_URL_ROOT,
'/').
'$/i',
'', trim($dolibarr_main_url_root));
56$urlwithroot = $urlwithouturlroot.DOL_URL_ROOT;
61$action =
GETPOST(
'action',
'aZ09');
62$backtourl =
GETPOST(
'backtourl',
'alpha');
63$keyforprovider =
GETPOST(
'keyforprovider',
'aZ09');
64if (!GETPOSTISSET(
'keyforprovider') && !empty($_SESSION[
"oauthkeyforproviderbeforeoauthjump"]) && (
GETPOST(
'code') || $action ==
'delete')) {
66 $keyforprovider = $_SESSION[
"oauthkeyforproviderbeforeoauthjump"];
68$genericstring =
'GENERIC';
77$currentUri =
$uriFactory->createFromAbsolute($urlwithroot.
'/core/modules/oauth/generic_oauthcallback.php');
85$serviceFactory = new \OAuth\ServiceFactory();
86$httpClient = new \OAuth\Common\Http\Client\CurlClient();
90$serviceFactory->setHttpClient($httpClient);
93$keyforparamid =
'OAUTH_'.$genericstring.($keyforprovider ?
'-'.$keyforprovider :
'').
'_ID';
94$keyforparamsecret =
'OAUTH_'.$genericstring.($keyforprovider ?
'-'.$keyforprovider :
'').
'_SECRET';
95$credentials =
new Credentials(
98 $currentUri->getAbsoluteUri()
102$statewithscopeonly =
'';
103$statewithanticsrfonly =
'';
105$requestedpermissionsarray = array();
108 $statewithscopeonly = preg_replace(
'/\-.*$/',
'', preg_replace(
'/^forlogin-/',
'', $state));
109 if ($statewithscopeonly !=
'none') {
110 $requestedpermissionsarray = explode(
',', $statewithscopeonly);
111 $statewithanticsrfonly = preg_replace(
'/^.*\-/',
'', $state);
113 $statewithscopeonly =
'';
119if ($action !=
'delete' && !
GETPOST(
'afteroauthloginreturn') && (empty($statewithscopeonly) || empty($requestedpermissionsarray)) && !preg_match(
'/^none/', $state)) {
123 dol_syslog(
"state or statewithscopeonly and/or requestedpermissionsarray are empty");
125 if (empty($backtourl)) {
126 $backtourl = DOL_URL_ROOT.
'/';
128 header(
'Location: '.$backtourl);
136$storage =
new DoliStorage($db, $conf, $keyforprovider);
138$keyforurl =
'OAUTH_'.$genericstring.($keyforprovider ?
'-'.$keyforprovider :
'').
'_URL';
142 print
'Error, failed to get value for constant '.$keyforurl;
147$nameofservice = ucfirst(strtolower($genericstring));
151 $apiService = $serviceFactory->createService($nameofservice, $credentials, $storage, $requestedpermissionsarray, $baseApiUriInt);
152 '@phan-var-force OAuth\OAuth2\Service\AbstractService|OAuth\OAuth1\Service\AbstractService $apiService';
154 print
'Error, failed to create service for provider '.$nameofservice.($keyforprovider ?
'-'.$keyforprovider :
'').
'. Message was: '.$e->getMessage();
165if (empty($apiService) || !$apiService instanceof OAuth\OAuth2\Service\Generic) {
166 print
'Error, failed to create Generic serviceFactory';
169if (!$apiService->getBaseApiUri()) {
170 print
'Error, setup of OAuth entry is not complete (missing base url)';
176if (method_exists($apiService,
'setAccessType')) {
177 $apiService->setAccessType(
'offline');
181 accessforbidden(
'Setup of service '.$keyforparamid.
' is not complete. Customer ID is missing');
184 accessforbidden(
'Setup of service '.$keyforparamid.
' is not complete. Secret key is missing');
192if ($action ==
'delete' && (!empty($user->admin) || $user->id ==
GETPOSTINT(
'userid'))) {
194 $storage->clearToken($genericstring);
198 if (empty($backtourl)) {
199 $backtourl = DOL_URL_ROOT.
'/';
202 header(
'Location: '.$backtourl);
207 dol_syslog(
"Page is called without the 'code' parameter defined");
209 if (empty($state) || $state ==
'none') {
211 $state =
'none-'.bin2hex(random_bytes(16));
216 $_SESSION[
"backtourlsavedbeforeoauthjump"] = $backtourl;
217 $_SESSION[
"oauthkeyforproviderbeforeoauthjump"] = $keyforprovider;
218 $_SESSION[
'oauthstateanticsrf'] = $state;
226 $approval_prompt =
getDolGlobalString(
'OAUTH_'.$genericstring.
'_FORCE_PROMPT_ON_LOGIN',
'auto');
227 if (method_exists($apiService,
'setApprouvalPrompt')) {
228 $apiService->setApprouvalPrompt($approval_prompt);
231 if (method_exists($apiService,
'setApprouvalPrompt')) {
232 $apiService->setApprouvalPrompt(
'force');
239 $url = $apiService->getAuthorizationUri(array(
'client_id' =>
getDolGlobalString($keyforparamid),
'response_type' =>
'code',
'state' => $state));
246 if ($statewithscopeonly) {
247 $url .=
'&scope='.str_replace(
',',
'+', $statewithscopeonly);
251 $url .=
'&nonce='.bin2hex(random_bytes(64 / 8));
258 $url .=
'&login_hint='.urlencode(
GETPOST(
'username'));
265 $urlwithouturlroot = preg_replace(
'/'.preg_quote(DOL_URL_ROOT,
'/').
'$/i',
'', trim($dolibarr_main_url_root));
266 $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT;
269 include DOL_DOCUMENT_ROOT.
'/core/lib/geturl.lib.php';
273 if ($currentrooturl != $externalrooturl) {
274 $langs->load(
"errors");
275 setEventMessages($langs->trans(
"ErrorTheUrlOfYourDolInstanceDoesNotMatchURLIntoOAuthSetup", $currentrooturl, $externalrooturl),
null,
'errors');
283 header(
'Location: '.$url);
287 dol_syslog(basename(__FILE__).
" We are coming from the oauth provider page keyforprovider=".$keyforprovider.
" code=".
dol_trunc(
GETPOST(
'code'), 5));
290 if (isset($_SESSION[
'oauthstateanticsrf']) && $state != $_SESSION[
'oauthstateanticsrf']) {
292 print
'Value for state='.dol_escape_htmltag($state).
' differs from value in $_SESSION["oauthstateanticsrf"]. Code is refused.';
293 unset($_SESSION[
'oauthstateanticsrf']);
309 $token = $apiService->requestAccessToken(
GETPOST(
'code'), $state);
310 '@phan-var-force OAuth\Common\Token\AbstractToken $token';
312 $storage = $apiService->getStorage();
313 if (property_exists($storage,
'last_insert_id')) {
314 $last_insert_id = $storage->last_insert_id;
317 dol_syslog(
"Failed to get token with requestAccessToken: ".$e->getMessage(), LOG_ERR);
318 setEventMessages(
"Failed to get token with requestAccessToken: ".$e->getMessage(),
null,
'errors');
333 $extraparams = $token->getExtraParams();
335 $scope = empty($extraparams[
'scope']) ?
'' : $extraparams[
'scope'];
336 $tokenstring = $token->getAccessToken();
340 $refreshtoken = empty($extraparams[
'refresh_token']) ?
'' : $extraparams[
'refresh_token'];
341 if (empty($refreshtoken)) {
342 $refreshtoken = $token->getRefreshToken();
345 if ($last_insert_id) {
346 $sqlupdate =
"UPDATE ".MAIN_DB_PREFIX.
"oauth_token";
347 $sqlupdate .=
" SET state = '".(empty($scope) ?
'' : $db->escape($scope)).
"', tokenstring = '".$db->escape($tokenstring).
"', tokenstring_refresh = '".$db->escape($refreshtoken).
"'";
348 $sqlupdate .=
" WHERE rowid = ".((int) $last_insert_id);
350 $db->query($sqlupdate);
402 if (!$errorincheck) {
405 dol_syslog(
"we received the login/email to log to, it is ".$useremail);
407 $tmparray = (empty($_SESSION[
'datafromloginform']) ? array() : $_SESSION[
'datafromloginform']);
408 $entitytosearchuser = ((isset($tmparray[
'entity']) && $tmparray[
'entity'] !=
'') ? $tmparray[
'entity'] : -1);
411 $storage->clearToken($genericstring);
413 $tmpuser =
new User($db);
414 $res = $tmpuser->fetch(0,
'',
'', 0, $entitytosearchuser, $useremail, 0, 1);
417 $username = $tmpuser->login;
419 $_SESSION[
'genericoauth_receivedlogin'] =
dol_hash($conf->file->instance_unique_id.$username,
'0');
420 dol_syslog(
'We set $_SESSION[\'genericoauth_receivedlogin\']='.$_SESSION[
'genericoauth_receivedlogin']);
422 $errormessage =
"Failed to login using '.$genericstring.'. User with the Email '".$useremail.
"' was not found";
423 if ($entitytosearchuser > 0) {
424 $errormessage .=
' ('.$langs->trans(
"Entity").
' '.$entitytosearchuser.
')';
426 $_SESSION[
"dol_loginmesg"] = $errormessage;
435 $_SESSION[
"dol_loginmesg"] =
"Failed to login using '.$genericstring.'. OAuth callback URL retrieves a token with non valid data";
440 if (!$errorincheck) {
446 $backtourl = $_SESSION[
"backtourlsavedbeforeoauthjump"];
447 unset($_SESSION[
"backtourlsavedbeforeoauthjump"]);
449 if (empty($backtourl)) {
450 $backtourl = DOL_URL_ROOT.
'/';
456 $backtourl .=
'?actionlogin=login&afteroauthloginreturn=generic&mainmenu=home'.($username ?
'&username='.urlencode($username) :
'').
'&token='.
newToken();
457 if (!empty($tmparray[
'entity'])) {
458 $backtourl .=
'&entity='.$tmparray[
'entity'];
462 dol_syslog(
"Redirect now on backtourl=".$backtourl);
464 header(
'Location: '.$backtourl);
467 print $e->getMessage();
global $dolibarr_main_url_root
Class to manage Dolibarr users.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
newToken()
Return the value of token currently saved into session with name 'newtoken'.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '…' if string larger than length.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
$uriFactory
Create a new instance of the URI class with the current URI, stripping the query string.
getRootURLFromURL($url)
Function root url from a long url For example: https://www.abc.mydomain.com/dir/page....
dol_hash($chain, $type='0', $nosalt=0, $mode=0)
Returns a hash (non reversible encryption) of a string.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.