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 $nameofservice = ucfirst(strtolower(empty($supportedoauth2array[$keyforsupportedoauth2array]['callbackfile']) ? 'Unknown' : $supportedoauth2array[$keyforsupportedoauth2array]['callbackfile']));
183 $nameofservice .= ($keyforprovider ? '-'.$keyforprovider : '');
184 $OAUTH_SERVICENAME = $nameofservice;
185
186 $keyforparamtenant = 'OAUTH_'.strtoupper(empty($supportedoauth2array[$keyforsupportedoauth2array]['callbackfile']) ? 'Unknown' : $supportedoauth2array[$keyforsupportedoauth2array]['callbackfile']).($keyforprovider ? '-'.$keyforprovider : '').'_TENANT';
187
188 $shortscope = '';
189 if (getDolGlobalString($key[4])) {
190 $shortscope = getDolGlobalString($key[4]);
191 }
192 $state = $shortscope; // TODO USe a better state
193
194 // Define $urltorenew, $urltodelete, $urltocheckperms
195 if ($keyforsupportedoauth2array == 'OAUTH_GITHUB_NAME') {
196 // List of keys that will be converted into scopes (from constants 'SCOPE_state_in_uppercase' in file of service).
197 // We pass this param list in to 'state' because we need it before and after the redirect.
198
199 // Note: github does not accept csrf key inside the state parameter (only known values)
200 $urltorenew = $urlwithroot.'/core/modules/oauth/github_oauthcallback.php?shortscope='.urlencode($shortscope).'&state='.urlencode($shortscope).'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
201 $urltodelete = $urlwithroot.'/core/modules/oauth/github_oauthcallback.php?action=delete&token='.newToken().'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
202 $urltocheckperms = 'https://github.com/settings/applications/';
203 } elseif ($keyforsupportedoauth2array == 'OAUTH_GOOGLE_NAME') {
204 // List of keys that will be converted into scopes (from constants 'SCOPE_state_in_uppercase' in file of service).
205 // List of scopes for Google are here: https://developers.google.com/identity/protocols/oauth2/scopes
206 // We pass this key list into the param 'state' because we need it before and after the redirect.
207 $urltorenew = $urlwithroot.'/core/modules/oauth/google_oauthcallback.php?shortscope='.urlencode($shortscope).'&state='.urlencode($state).'-'.$oauthstateanticsrf.'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
208 $urltodelete = $urlwithroot.'/core/modules/oauth/google_oauthcallback.php?action=delete&token='.newToken().'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
209 $urltocheckperms = 'https://security.google.com/settings/security/permissions';
210 } elseif (!empty($supportedoauth2array[$keyforsupportedoauth2array]['returnurl'])) {
211 $urltorenew = $urlwithroot.$supportedoauth2array[$keyforsupportedoauth2array]['returnurl'].'?shortscope='.urlencode($shortscope).'&state='.urlencode($state).'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
212 $urltodelete = $urlwithroot.$supportedoauth2array[$keyforsupportedoauth2array]['returnurl'].'?action=delete&token='.newToken().'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
213 $urltocheckperms = '';
214 } else {
215 $urltorenew = '';
216 $urltodelete = '';
217 $urltocheckperms = '';
218 }
219
220 if ($urltorenew) {
221 $urltorenew .= '&keyforprovider='.urlencode($keyforprovider);
222 }
223 if ($urltodelete) {
224 $urltodelete .= '&keyforprovider='.urlencode($keyforprovider);
225 }
226
227 // Show value of token
228 $tokenobj = null;
229 // Token
230 require_once DOL_DOCUMENT_ROOT.'/includes/OAuth/bootstrap.php';
231 // Dolibarr storage
232 $storage = new DoliStorage($db, $conf, $keyforprovider, getDolGlobalString($keyforparamtenant));
233 try {
234 // $OAUTH_SERVICENAME is for example 'Google-keyforprovider'
235 print '<!-- '.$OAUTH_SERVICENAME.' -->'."\n";
236 $tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME);
237 //print $storage->token.'<br>';
238 //print $tokenobj->getExtraParams()['id_token'].'<br>';
239 //print $tokenobj->getAccessToken().'<br>';
240 } catch (Exception $e) {
241 // Return an error if token not found
242 //print $e->getMessage();
243 }
244
245 // Set other properties
246 $refreshtoken = false;
247 $expiredat = '';
248
249 $expire = false;
250 // Is token expired or will token expire in the next 30 seconds
251 if (is_object($tokenobj)) {
252 $expire = ($tokenobj->getEndOfLife() !== $tokenobj::EOL_NEVER_EXPIRES && $tokenobj->getEndOfLife() !== $tokenobj::EOL_UNKNOWN && time() > ($tokenobj->getEndOfLife() - 30));
253 }
254 if ($key[1] != '' && $key[2] != '') {
255 if (is_object($tokenobj)) {
256 $refreshtoken = $tokenobj->getRefreshToken();
257
258 $endoflife = $tokenobj->getEndOfLife();
259 if ($endoflife == $tokenobj::EOL_NEVER_EXPIRES) {
260 $expiredat = $langs->trans("Never");
261 } elseif ($endoflife == $tokenobj::EOL_UNKNOWN) {
262 $expiredat = $langs->trans("Unknown");
263 } else {
264 $expiredat = dol_print_date($endoflife, "dayhour", 'tzuserrel');
265 }
266 }
267 }
268
269 $submit_enabled = 0;
270
271 print '<form method="post" action="'.$_SERVER["PHP_SELF"].'?mode=setup&amp;driver='.$driver.'" autocomplete="off">';
272 print '<input type="hidden" name="token" value="'.newToken().'">';
273 print '<input type="hidden" name="action" value="setconst">';
274 print '<input type="hidden" name="page_y" value="">';
275
276 print '<div class="div-table-responsive-no-min">';
277 print '<table class="noborder centpercent">'."\n";
278
279 // Api Name
280 $label = $langs->trans($keyforsupportedoauth2array);
281 print '<tr class="liste_titre">';
282 print '<th class="titlefieldcreate">';
283 print img_picto('', $supportedoauth2array[$keyforsupportedoauth2array]['picto'], 'class="pictofixedwidth"');
284 if ($label == $keyforsupportedoauth2array) {
285 print $supportedoauth2array[$keyforsupportedoauth2array]['name'];
286 } else {
287 print $label;
288 }
289 if ($keyforprovider) {
290 print ' (<b>'.$keyforprovider.'</b>)';
291 } else {
292 print ' (<b>'.$langs->trans("NoName").'</b>)';
293 }
294 print '</th>';
295 print '<th></th>';
296 print '<th></th>';
297 print "</tr>\n";
298
299 print '<tr class="oddeven">';
300 print '<td>';
301 //var_dump($key);
302 print $langs->trans("OAuthIDSecret").'</td>';
303 print '<td>';
304 print '<span class="opacitymedium">'.$langs->trans("SeePreviousTab").'</span>';
305 print '</td>';
306 print '<td>';
307 print '</td>';
308 print '</tr>'."\n";
309
310 // Scopes
311 print '<tr class="oddeven">';
312 print '<td>'.$langs->trans("Scopes").'</td>';
313 print '<td colspan="2">';
314 $currentscopes = getDolGlobalString($key[4]);
315 print $currentscopes;
316 print '</td></tr>';
317
318 print '<tr class="oddeven">';
319 print '<td>';
320 //var_dump($key);
321 print $langs->trans("IsTokenGenerated");
322 print '</td>';
323 print '<td>';
324 if ($keyforprovider != 'Login') {
325 if (is_object($tokenobj)) {
326 print $form->textwithpicto(yn(1), $langs->trans("HasAccessToken").' : '.dol_print_date($storage->date_modification, 'dayhour').' state='.dol_escape_htmltag($storage->state));
327 } else {
328 print '<span class="opacitymedium">'.$langs->trans("NoAccessToken").'</span>';
329 }
330 } else {
331 print '<span class="opacitymedium">'.$langs->trans("TokenNotRequiredForOAuthLogin").'</span>';
332 }
333 print '</td>';
334 print '<td width="50%">';
335 if ($keyforprovider != 'Login') {
336 // Links to delete/checks token
337 if (is_object($tokenobj)) {
338 //test on $storage->hasAccessToken($OAUTH_SERVICENAME) ?
339 if ($urltodelete) {
340 print '<a class="button smallpaddingimp reposition" href="'.$urltodelete.'">'.$langs->trans('DeleteAccess').'</a><br>';
341 } else {
342 print '<span class="opacitymedium">'.$langs->trans('GoOnTokenProviderToDeleteToken').'</span><br>';
343 }
344 }
345 // Request remote token
346 if ($urltorenew) {
347 print '<a class="button smallpaddingimp reposition" href="'.$urltorenew.'">'.$langs->trans('GetAccess').'</a>';
348 print $form->textwithpicto('', $langs->trans('RequestAccess'));
349 print '<br>';
350 }
351 // Check remote access
352 if ($urltocheckperms) {
353 print '<br>'.$langs->trans("ToCheckDeleteTokenOnProvider", $OAUTH_SERVICENAME).': <a href="'.$urltocheckperms.'" target="_'.strtolower($OAUTH_SERVICENAME).'">'.$urltocheckperms.'</a>';
354 }
355 }
356 print '</td>';
357 print '</tr>';
358
359 print '<tr class="oddeven">';
360 print '<td>';
361 //var_dump($key);
362 print $langs->trans("Token").'</td>';
363 print '<td colspan="2">';
364
365 if (is_object($tokenobj)) {
366 $tokentoshow = $tokenobj->getAccessToken();
367 print '<span class="" title="'.dol_escape_htmltag($tokentoshow).'">'.showValueWithClipboardCPButton($tokentoshow, 1, dol_trunc($tokentoshow, 32)).'</span><br>';
368 //print 'Refresh: '.$tokenobj->getRefreshToken().'<br>';
369 //print 'EndOfLife: '.$tokenobj->getEndOfLife().'<br>';
370 //var_dump($tokenobj->getExtraParams());
371 /*print '<br>Extra: <br><textarea class="quatrevingtpercent">';
372 print ''.join(',',$tokenobj->getExtraParams());
373 print '</textarea>';*/
374 }
375 print '</td>';
376 print '</tr>'."\n";
377
378 if (is_object($tokenobj)) {
379 // Token refresh
380 print '<tr class="oddeven">';
381 print '<td>';
382 //var_dump($key);
383 print $langs->trans("TOKEN_REFRESH");
384 print '</td>';
385 print '<td colspan="2">';
386 print '<span class="" title="'.dol_escape_htmltag($refreshtoken).'">'.showValueWithClipboardCPButton($refreshtoken, 1, dol_trunc($refreshtoken, 32)).'</span>';
387 print '</td>';
388 print '</tr>';
389
390 // Token expired
391 print '<tr class="oddeven">';
392 print '<td>';
393 //var_dump($key);
394 print $langs->trans("TOKEN_EXPIRED");
395 print '</td>';
396 print '<td colspan="2">';
397 print yn($expire);
398 print '</td>';
399 print '</tr>';
400
401 // Token expired at
402 print '<tr class="oddeven">';
403 print '<td>';
404 //var_dump($key);
405 print $langs->trans("TOKEN_EXPIRE_AT");
406 print '</td>';
407 print '<td colspan="2">';
408 print $expiredat;
409 print '</td>';
410 print '</tr>';
411 }
412
413 print '</table>';
414 print '</div>';
415
416 if (!empty($driver)) {
417 if ($submit_enabled) {
418 print $form->buttonsSaveCancel("Modify", '');
419 }
420 }
421
422 print '</form>';
423 print '<br>';
424 }
425 }
426}
427
428if ($mode == 'test' && $user->admin) {
429 print $langs->trans('PrintTestDesc'.$driver)."<br><br>\n";
430
431 print '<div class="div-table-responsive-no-min">';
432 print '<table class="noborder centpercent">';
433 if (!empty($driver)) {
434 require_once DOL_DOCUMENT_ROOT.'/core/modules/printing/'.$driver.'.modules.php';
435 $classname = 'printing_'.$driver;
436 $langs->load($driver);
437 $printer = new $classname($db);
438 //print '<pre>'.print_r($printer, true).'</pre>';
439 if (count($printer->getlistAvailablePrinters())) {
440 if ($printer->listAvailablePrinters() == 0) {
441 print $printer->resprint;
442 } else {
443 setEventMessages($printer->error, $printer->errors, 'errors');
444 }
445 } else {
446 print $langs->trans('PleaseConfigureDriverfromList');
447 }
448 }
449
450 print '</table>';
451 print '</div>';
452}
453
454if ($mode == 'userconf' && $user->admin) {
455 print $langs->trans('PrintUserConfDesc'.$driver)."<br><br>\n";
456
457 print '<div class="div-table-responsive">';
458 print '<table class="noborder centpercent">';
459 print '<tr class="liste_titre">';
460 print '<th>'.$langs->trans("User").'</th>';
461 print '<th>'.$langs->trans("PrintModule").'</th>';
462 print '<th>'.$langs->trans("PrintDriver").'</th>';
463 print '<th>'.$langs->trans("Printer").'</th>';
464 print '<th>'.$langs->trans("PrinterLocation").'</th>';
465 print '<th>'.$langs->trans("PrinterId").'</th>';
466 print '<th>'.$langs->trans("NumberOfCopy").'</th>';
467 print '<th class="center">'.$langs->trans("Delete").'</th>';
468 print "</tr>\n";
469 $sql = "SELECT p.rowid, p.printer_name, p.printer_location, p.printer_id, p.copy, p.module, p.driver, p.userid, u.login";
470 $sql .= " FROM ".MAIN_DB_PREFIX."printing as p, ".MAIN_DB_PREFIX."user as u WHERE p.userid = u.rowid";
471 $resql = $db->query($sql);
472 while ($obj = $db->fetch_object($resql)) {
473 print '<tr class="oddeven">';
474 print '<td>'.$obj->login.'</td>';
475 print '<td>'.$obj->module.'</td>';
476 print '<td>'.$obj->driver.'</td>';
477 print '<td>'.$obj->printer_name.'</td>';
478 print '<td>'.$obj->printer_location.'</td>';
479 print '<td>'.$obj->printer_id.'</td>';
480 print '<td>'.$obj->copy.'</td>';
481 print '<td class="center">'.img_picto($langs->trans("Delete"), 'delete').'</td>';
482 print "</tr>\n";
483 }
484 print '</table>';
485 print '</div>';
486}
487
488print dol_get_fiche_end();
489
490// End of page
491llxFooter();
492$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.