dolibarr 20.0.0
oauthlogintokens.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2013-2016 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2014-2018 Frederic France <frederic.france@netlogic.fr>
4 * Copyright (C) 2020 Nicolas ZABOURI <info@inovea-conseil.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
26// Load Dolibarr environment
27require '../main.inc.php';
28require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
29require_once DOL_DOCUMENT_ROOT.'/core/lib/oauth.lib.php';
30require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
31
32use OAuth\Common\Storage\DoliStorage;
33
34$supportedoauth2array = getSupportedOauth2Array();
35
36// Load translation files required by the page
37$langs->loadLangs(array('admin', 'printing', 'oauth'));
38
39$action = GETPOST('action', 'aZ09');
40$mode = GETPOST('mode', 'alpha');
41$value = GETPOST('value', 'alpha');
42$varname = GETPOST('varname', 'alpha');
43$driver = GETPOST('driver', 'alpha');
44
45if (!empty($driver)) {
46 $langs->load($driver);
47}
48
49if (!$mode) {
50 $mode = 'setup';
51}
52
53if (!$user->admin) {
55}
56
57
58/*
59 * Action
60 */
61
62/*if (($mode == 'test' || $mode == 'setup') && empty($driver))
63{
64 setEventMessages($langs->trans('PleaseSelectaDriverfromList'), null);
65 header("Location: ".$_SERVER['PHP_SELF'].'?mode=config');
66 exit;
67}*/
68
69if ($action == 'setconst' && $user->admin) {
70 $error = 0;
71 $db->begin();
72
73 $setupconstarray = GETPOST('setupdriver', 'array');
74
75 foreach ($setupconstarray as $setupconst) {
76 //print '<pre>'.print_r($setupconst, true).'</pre>';
77
78 $constname = dol_escape_htmltag($setupconst['varname']);
79 $constvalue = dol_escape_htmltag($setupconst['value']);
80 $consttype = dol_escape_htmltag($setupconst['type']);
81 $constnote = dol_escape_htmltag($setupconst['note']);
82
83 $result = dolibarr_set_const($db, $constname, $constvalue, $consttype, 0, $constnote, $conf->entity);
84 if (!($result > 0)) {
85 $error++;
86 }
87 }
88
89 if (!$error) {
90 $db->commit();
91 setEventMessages($langs->trans("SetupSaved"), null);
92 } else {
93 $db->rollback();
94 dol_print_error($db);
95 }
96 $action = '';
97}
98
99if ($action == 'setvalue' && $user->admin) {
100 $db->begin();
101
102 $result = dolibarr_set_const($db, $varname, $value, 'chaine', 0, '', $conf->entity);
103 if (!($result > 0)) {
104 $error++;
105 }
106
107 if (!$error) {
108 $db->commit();
109 setEventMessages($langs->trans("SetupSaved"), null);
110 } else {
111 $db->rollback();
112 dol_print_error($db);
113 }
114 $action = '';
115}
116
117
118/*
119 * View
120 */
121
122// Define $urlwithroot
123$urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
124$urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
125//$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current
126
127$form = new Form($db);
128
129$title = $langs->trans("TokenManager");
130$help_url = 'EN:Module_OAuth|FR:Module_OAuth_FR|ES:Módulo_OAuth_ES';
131
132llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'mod-admin page-oauthlogintokens');
133
134$linkback = '<a href="'.DOL_URL_ROOT.'/admin/modules.php?restore_lastsearch_values=1">'.$langs->trans("BackToModuleList").'</a>';
135print load_fiche_titre($langs->trans('ConfigOAuth'), $linkback, 'title_setup');
136
138
139print dol_get_fiche_head($head, 'tokengeneration', '', -1, '');
140
141if (GETPOST('error')) {
142 setEventMessages(GETPOST('error'), null, 'errors');
143}
144
145if ($mode == 'setup' && $user->admin) {
146 print '<span class="opacitymedium">'.$langs->trans("OAuthSetupForLogin")."</span><br><br>\n";
147
148 // Define $listinsetup
149 $listinsetup = array();
150 foreach ($conf->global as $key => $val) {
151 if (!empty($val) && preg_match('/^OAUTH_.*_ID$/', $key)) {
152 $provider = preg_replace('/_ID$/', '', $key);
153 $listinsetup[] = array(
154 $provider.'_NAME',
155 $provider.'_ID',
156 $provider.'_SECRET',
157 $provider.'_URLAUTHORIZE', // For custom oauth links
158 $provider.'_SCOPE' // For custom oauth links
159 );
160 }
161 }
162
163 $oauthstateanticsrf = bin2hex(random_bytes(128 / 8));
164
165 // $list is defined into oauth.lib.php to the list of supported OAuth providers.
166 if (!empty($listinsetup)) {
167 foreach ($listinsetup as $key) {
168 $supported = 0;
169 $keyforsupportedoauth2array = $key[0]; // May be OAUTH_GOOGLE_NAME or OAUTH_GOOGLE_xxx_NAME
170 $keyforsupportedoauth2array = preg_replace('/^OAUTH_/', '', $keyforsupportedoauth2array);
171 $keyforsupportedoauth2array = preg_replace('/_NAME$/', '', $keyforsupportedoauth2array);
172 if (preg_match('/^.*-/', $keyforsupportedoauth2array)) {
173 $keybeforeprovider = preg_replace('/-.*$/', '', $keyforsupportedoauth2array);
174 $keyforprovider = preg_replace('/^.*-/', '', $keyforsupportedoauth2array);
175 } else {
176 $keybeforeprovider = $keyforsupportedoauth2array;
177 $keyforprovider = '';
178 }
179 $keyforsupportedoauth2array = preg_replace('/-.*$/', '', $keyforsupportedoauth2array);
180 $keyforsupportedoauth2array = 'OAUTH_'.$keyforsupportedoauth2array.'_NAME';
181
182
183 $OAUTH_SERVICENAME = (empty($supportedoauth2array[$keyforsupportedoauth2array]['name']) ? 'Unknown' : $supportedoauth2array[$keyforsupportedoauth2array]['name'].($keyforprovider ? '-'.$keyforprovider : ''));
184
185 $shortscope = '';
186 if (getDolGlobalString($key[4])) {
187 $shortscope = getDolGlobalString($key[4]);
188 }
189 $state = $shortscope; // TODO USe a better state
190
191 // Define $urltorenew, $urltodelete, $urltocheckperms
192 if ($keyforsupportedoauth2array == 'OAUTH_GITHUB_NAME') {
193 // List of keys that will be converted into scopes (from constants 'SCOPE_state_in_uppercase' in file of service).
194 // We pass this param list in to 'state' because we need it before and after the redirect.
195
196 // Note: github does not accept csrf key inside the state parameter (only known values)
197 $urltorenew = $urlwithroot.'/core/modules/oauth/github_oauthcallback.php?shortscope='.urlencode($shortscope).'&state='.urlencode($shortscope).'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
198 $urltodelete = $urlwithroot.'/core/modules/oauth/github_oauthcallback.php?action=delete&token='.newToken().'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
199 $urltocheckperms = 'https://github.com/settings/applications/';
200 } elseif ($keyforsupportedoauth2array == 'OAUTH_GOOGLE_NAME') {
201 // List of keys that will be converted into scopes (from constants 'SCOPE_state_in_uppercase' in file of service).
202 // List of scopes for Google are here: https://developers.google.com/identity/protocols/oauth2/scopes
203 // We pass this key list into the param 'state' because we need it before and after the redirect.
204 $urltorenew = $urlwithroot.'/core/modules/oauth/google_oauthcallback.php?shortscope='.urlencode($shortscope).'&state='.urlencode($state).'-'.$oauthstateanticsrf.'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
205 $urltodelete = $urlwithroot.'/core/modules/oauth/google_oauthcallback.php?action=delete&token='.newToken().'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
206 $urltocheckperms = 'https://security.google.com/settings/security/permissions';
207 } elseif (!empty($supportedoauth2array[$keyforsupportedoauth2array]['returnurl'])) {
208 $urltorenew = $urlwithroot.$supportedoauth2array[$keyforsupportedoauth2array]['returnurl'].'?shortscope='.urlencode($shortscope).'&state='.urlencode($state).'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
209 $urltodelete = $urlwithroot.$supportedoauth2array[$keyforsupportedoauth2array]['returnurl'].'?action=delete&token='.newToken().'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
210 $urltocheckperms = '';
211 } else {
212 $urltorenew = '';
213 $urltodelete = '';
214 $urltocheckperms = '';
215 }
216
217 if ($urltorenew) {
218 $urltorenew .= '&keyforprovider='.urlencode($keyforprovider);
219 }
220 if ($urltodelete) {
221 $urltodelete .= '&keyforprovider='.urlencode($keyforprovider);
222 }
223
224 // Show value of token
225 $tokenobj = null;
226 // Token
227 require_once DOL_DOCUMENT_ROOT.'/includes/OAuth/bootstrap.php';
228 // Dolibarr storage
229 $storage = new DoliStorage($db, $conf, $keyforprovider);
230 try {
231 // $OAUTH_SERVICENAME is for example 'Google-keyforprovider'
232 print '<!-- '.$OAUTH_SERVICENAME.' -->'."\n";
233 $tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME);
234 //print $storage->token.'<br>';
235 //print $tokenobj->getExtraParams()['id_token'].'<br>';
236 //print $tokenobj->getAccessToken().'<br>';
237 } catch (Exception $e) {
238 // Return an error if token not found
239 //print $e->getMessage();
240 }
241
242 // Set other properties
243 $refreshtoken = false;
244 $expiredat = '';
245
246 $expire = false;
247 // Is token expired or will token expire in the next 30 seconds
248 if (is_object($tokenobj)) {
249 $expire = ($tokenobj->getEndOfLife() !== $tokenobj::EOL_NEVER_EXPIRES && $tokenobj->getEndOfLife() !== $tokenobj::EOL_UNKNOWN && time() > ($tokenobj->getEndOfLife() - 30));
250 }
251 if ($key[1] != '' && $key[2] != '') {
252 if (is_object($tokenobj)) {
253 $refreshtoken = $tokenobj->getRefreshToken();
254
255 $endoflife = $tokenobj->getEndOfLife();
256 if ($endoflife == $tokenobj::EOL_NEVER_EXPIRES) {
257 $expiredat = $langs->trans("Never");
258 } elseif ($endoflife == $tokenobj::EOL_UNKNOWN) {
259 $expiredat = $langs->trans("Unknown");
260 } else {
261 $expiredat = dol_print_date($endoflife, "dayhour", 'tzuserrel');
262 }
263 }
264 }
265
266 $submit_enabled = 0;
267
268 print '<form method="post" action="'.$_SERVER["PHP_SELF"].'?mode=setup&amp;driver='.$driver.'" autocomplete="off">';
269 print '<input type="hidden" name="token" value="'.newToken().'">';
270 print '<input type="hidden" name="action" value="setconst">';
271 print '<input type="hidden" name="page_y" value="">';
272
273 print '<div class="div-table-responsive-no-min">';
274 print '<table class="noborder centpercent">'."\n";
275
276 // Api Name
277 $label = $langs->trans($keyforsupportedoauth2array);
278 print '<tr class="liste_titre">';
279 print '<th class="titlefieldcreate">';
280 print img_picto('', $supportedoauth2array[$keyforsupportedoauth2array]['picto'], 'class="pictofixedwidth"');
281 if ($label == $keyforsupportedoauth2array) {
282 print $supportedoauth2array[$keyforsupportedoauth2array]['name'];
283 } else {
284 print $label;
285 }
286 if ($keyforprovider) {
287 print ' (<b>'.$keyforprovider.'</b>)';
288 } else {
289 print ' (<b>'.$langs->trans("NoName").'</b>)';
290 }
291 print '</th>';
292 print '<th></th>';
293 print '<th></th>';
294 print "</tr>\n";
295
296 print '<tr class="oddeven">';
297 print '<td>';
298 //var_dump($key);
299 print $langs->trans("OAuthIDSecret").'</td>';
300 print '<td>';
301 print '<span class="opacitymedium">'.$langs->trans("SeePreviousTab").'</span>';
302 print '</td>';
303 print '<td>';
304 print '</td>';
305 print '</tr>'."\n";
306
307 // Scopes
308 print '<tr class="oddeven">';
309 print '<td>'.$langs->trans("Scopes").'</td>';
310 print '<td colspan="2">';
311 $currentscopes = getDolGlobalString($key[4]);
312 print $currentscopes;
313 print '</td></tr>';
314
315 print '<tr class="oddeven">';
316 print '<td>';
317 //var_dump($key);
318 print $langs->trans("IsTokenGenerated");
319 print '</td>';
320 print '<td>';
321 if ($keyforprovider != 'Login') {
322 if (is_object($tokenobj)) {
323 print $form->textwithpicto(yn(1), $langs->trans("HasAccessToken").' : '.dol_print_date($storage->date_modification, 'dayhour').' state='.dol_escape_htmltag($storage->state));
324 } else {
325 print '<span class="opacitymedium">'.$langs->trans("NoAccessToken").'</span>';
326 }
327 } else {
328 print '<span class="opacitymedium">'.$langs->trans("TokenNotRequiredForOAuthLogin").'</span>';
329 }
330 print '</td>';
331 print '<td width="50%">';
332 if ($keyforprovider != 'Login') {
333 // Links to delete/checks token
334 if (is_object($tokenobj)) {
335 //test on $storage->hasAccessToken($OAUTH_SERVICENAME) ?
336 if ($urltodelete) {
337 print '<a class="button smallpaddingimp reposition" href="'.$urltodelete.'">'.$langs->trans('DeleteAccess').'</a><br>';
338 } else {
339 print '<span class="opacitymedium">'.$langs->trans('GoOnTokenProviderToDeleteToken').'</span><br>';
340 }
341 }
342 // Request remote token
343 if ($urltorenew) {
344 print '<a class="button smallpaddingimp reposition" href="'.$urltorenew.'">'.$langs->trans('GetAccess').'</a>';
345 print $form->textwithpicto('', $langs->trans('RequestAccess'));
346 print '<br>';
347 }
348 // Check remote access
349 if ($urltocheckperms) {
350 print '<br>'.$langs->trans("ToCheckDeleteTokenOnProvider", $OAUTH_SERVICENAME).': <a href="'.$urltocheckperms.'" target="_'.strtolower($OAUTH_SERVICENAME).'">'.$urltocheckperms.'</a>';
351 }
352 }
353 print '</td>';
354 print '</tr>';
355
356 print '<tr class="oddeven">';
357 print '<td>';
358 //var_dump($key);
359 print $langs->trans("Token").'</td>';
360 print '<td colspan="2">';
361
362 if (is_object($tokenobj)) {
363 $tokentoshow = $tokenobj->getAccessToken();
364 print '<span class="" title="'.dol_escape_htmltag($tokentoshow).'">'.showValueWithClipboardCPButton($tokentoshow, 1, dol_trunc($tokentoshow, 32)).'</span><br>';
365 //print 'Refresh: '.$tokenobj->getRefreshToken().'<br>';
366 //print 'EndOfLife: '.$tokenobj->getEndOfLife().'<br>';
367 //var_dump($tokenobj->getExtraParams());
368 /*print '<br>Extra: <br><textarea class="quatrevingtpercent">';
369 print ''.join(',',$tokenobj->getExtraParams());
370 print '</textarea>';*/
371 }
372 print '</td>';
373 print '</tr>'."\n";
374
375 if (is_object($tokenobj)) {
376 // Token refresh
377 print '<tr class="oddeven">';
378 print '<td>';
379 //var_dump($key);
380 print $langs->trans("TOKEN_REFRESH");
381 print '</td>';
382 print '<td colspan="2">';
383 print '<span class="" title="'.dol_escape_htmltag($refreshtoken).'">'.showValueWithClipboardCPButton($refreshtoken, 1, dol_trunc($refreshtoken, 32)).'</span>';
384 print '</td>';
385 print '</tr>';
386
387 // Token expired
388 print '<tr class="oddeven">';
389 print '<td>';
390 //var_dump($key);
391 print $langs->trans("TOKEN_EXPIRED");
392 print '</td>';
393 print '<td colspan="2">';
394 print yn($expire);
395 print '</td>';
396 print '</tr>';
397
398 // Token expired at
399 print '<tr class="oddeven">';
400 print '<td>';
401 //var_dump($key);
402 print $langs->trans("TOKEN_EXPIRE_AT");
403 print '</td>';
404 print '<td colspan="2">';
405 print $expiredat;
406 print '</td>';
407 print '</tr>';
408 }
409
410 print '</table>';
411 print '</div>';
412
413 if (!empty($driver)) {
414 if ($submit_enabled) {
415 print $form->buttonsSaveCancel("Modify", '');
416 }
417 }
418
419 print '</form>';
420 print '<br>';
421 }
422 }
423}
424
425if ($mode == 'test' && $user->admin) {
426 print $langs->trans('PrintTestDesc'.$driver)."<br><br>\n";
427
428 print '<div class="div-table-responsive-no-min">';
429 print '<table class="noborder centpercent">';
430 if (!empty($driver)) {
431 require_once DOL_DOCUMENT_ROOT.'/core/modules/printing/'.$driver.'.modules.php';
432 $classname = 'printing_'.$driver;
433 $langs->load($driver);
434 $printer = new $classname($db);
435 //print '<pre>'.print_r($printer, true).'</pre>';
436 if (count($printer->getlistAvailablePrinters())) {
437 if ($printer->listAvailablePrinters() == 0) {
438 print $printer->resprint;
439 } else {
440 setEventMessages($printer->error, $printer->errors, 'errors');
441 }
442 } else {
443 print $langs->trans('PleaseConfigureDriverfromList');
444 }
445 }
446
447 print '</table>';
448 print '</div>';
449}
450
451if ($mode == 'userconf' && $user->admin) {
452 print $langs->trans('PrintUserConfDesc'.$driver)."<br><br>\n";
453
454 print '<div class="div-table-responsive">';
455 print '<table class="noborder centpercent">';
456 print '<tr class="liste_titre">';
457 print '<th>'.$langs->trans("User").'</th>';
458 print '<th>'.$langs->trans("PrintModule").'</th>';
459 print '<th>'.$langs->trans("PrintDriver").'</th>';
460 print '<th>'.$langs->trans("Printer").'</th>';
461 print '<th>'.$langs->trans("PrinterLocation").'</th>';
462 print '<th>'.$langs->trans("PrinterId").'</th>';
463 print '<th>'.$langs->trans("NumberOfCopy").'</th>';
464 print '<th class="center">'.$langs->trans("Delete").'</th>';
465 print "</tr>\n";
466 $sql = "SELECT p.rowid, p.printer_name, p.printer_location, p.printer_id, p.copy, p.module, p.driver, p.userid, u.login";
467 $sql .= " FROM ".MAIN_DB_PREFIX."printing as p, ".MAIN_DB_PREFIX."user as u WHERE p.userid = u.rowid";
468 $resql = $db->query($sql);
469 while ($obj = $db->fetch_object($resql)) {
470 print '<tr class="oddeven">';
471 print '<td>'.$obj->login.'</td>';
472 print '<td>'.$obj->module.'</td>';
473 print '<td>'.$obj->driver.'</td>';
474 print '<td>'.$obj->printer_name.'</td>';
475 print '<td>'.$obj->printer_location.'</td>';
476 print '<td>'.$obj->printer_id.'</td>';
477 print '<td>'.$obj->copy.'</td>';
478 print '<td class="center">'.img_picto($langs->trans("Delete"), 'delete').'</td>';
479 print "</tr>\n";
480 }
481 print '</table>';
482 print '</div>';
483}
484
485print dol_get_fiche_end();
486
487// End of page
488llxFooter();
489$db->close();
dolibarr_set_const($db, $name, $value, $type='chaine', $visible=0, $note='', $entity=1)
Insert a parameter (key,value) into database (delete old key then insert it again).
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader()
Empty header.
Definition wrapper.php:55
llxFooter()
Empty footer.
Definition wrapper.php:69
Class to manage generation of HTML components Only common components must be here.
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
showValueWithClipboardCPButton($valuetocopy, $showonlyonhover=1, $texttoshow='')
Create a button to copy $valuetocopy in the clipboard (for copy and paste feature).
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
yn($yesno, $case=1, $color=0)
Return yes or no in current language.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0)
Show tabs of a record.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
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.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
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 dolibarr global constant string value.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
getSupportedOauth2Array()
Return array of tabs to used on pages to setup cron module.
oauthadmin_prepare_head()
Return array of tabs to used on pages to setup cron module.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.