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
20/**
21 * \file        htdocs/admin/oauthlogintokens.php
22 * \ingroup     oauth
23 * \brief       Setup page to configure oauth access to login information
24 */
25
26require '../main.inc.php';
27require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
28require_once DOL_DOCUMENT_ROOT.'/core/lib/oauth.lib.php'; // This define $list
29require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
30use OAuth\Common\Storage\DoliStorage;
31
32// Load translation files required by the page
33$langs->loadLangs(array('admin', 'printing', 'oauth'));
34
35if (!$user->admin) accessforbidden();
36
37$action = GETPOST('action', 'aZ09');
38$mode = GETPOST('mode', 'alpha');
39$value = GETPOST('value', 'alpha');
40$varname = GETPOST('varname', 'alpha');
41$driver = GETPOST('driver', 'alpha');
42
43if (!empty($driver)) $langs->load($driver);
44
45if (!$mode) $mode = 'setup';
46
47
48/*
49 * Action
50 */
51
52/*if (($mode == 'test' || $mode == 'setup') && empty($driver))
53{
54    setEventMessages($langs->trans('PleaseSelectaDriverfromList'), null);
55    header("Location: ".$_SERVER['PHP_SELF'].'?mode=config');
56    exit;
57}*/
58
59if ($action == 'setconst' && $user->admin)
60{
61	$error = 0;
62	$db->begin();
63
64	$setupconstarray = GETPOST('setupdriver', 'array');
65
66	foreach ($setupconstarray as $setupconst) {
67		//print '<pre>'.print_r($setupconst, true).'</pre>';
68
69		$constname = dol_escape_htmltag($setupconst['varname']);
70		$constvalue = dol_escape_htmltag($setupconst['value']);
71		$consttype = dol_escape_htmltag($setupconst['type']);
72		$constnote = dol_escape_htmltag($setupconst['note']);
73
74		$result = dolibarr_set_const($db, $constname, $constvalue, $consttype, 0, $constnote, $conf->entity);
75		if (!$result > 0) $error++;
76	}
77
78	if (!$error)
79	{
80		$db->commit();
81		setEventMessages($langs->trans("SetupSaved"), null);
82	} else {
83		$db->rollback();
84		dol_print_error($db);
85	}
86	$action = '';
87}
88
89if ($action == 'setvalue' && $user->admin)
90{
91	$db->begin();
92
93	$result = dolibarr_set_const($db, $varname, $value, 'chaine', 0, '', $conf->entity);
94	if (!$result > 0) $error++;
95
96	if (!$error)
97	{
98		$db->commit();
99		setEventMessages($langs->trans("SetupSaved"), null);
100	} else {
101		$db->rollback();
102		dol_print_error($db);
103	}
104	$action = '';
105}
106
107
108/*
109 * View
110 */
111
112// Define $urlwithroot
113$urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
114$urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
115//$urlwithroot=DOL_MAIN_URL_ROOT;					// This is to use same domain name than current
116
117$form = new Form($db);
118
119llxHeader('', $langs->trans("PrintingSetup"));
120
121$linkback = '<a href="'.DOL_URL_ROOT.'/admin/modules.php?restore_lastsearch_values=1">'.$langs->trans("BackToModuleList").'</a>';
122print load_fiche_titre($langs->trans('ConfigOAuth'), $linkback, 'title_setup');
123
124$head = oauthadmin_prepare_head();
125
126print dol_get_fiche_head($head, 'tokengeneration', '', -1, 'technic');
127
128if (GETPOST('error')) {
129	setEventMessages(GETPOST('error'), null, 'errors');
130}
131
132if ($mode == 'setup' && $user->admin)
133{
134	print '<span class="opacitymedium">'.$langs->trans("OAuthSetupForLogin")."</span><br><br>\n";
135
136	foreach ($list as $key)
137	{
138		$supported = 0;
139		if (in_array($key[0], array_keys($supportedoauth2array))) $supported = 1;
140		if (!$supported) continue; // show only supported
141
142
143		$OAUTH_SERVICENAME = 'Unknown';
144		if ($key[0] == 'OAUTH_GITHUB_NAME')
145		{
146			$OAUTH_SERVICENAME = 'GitHub';
147			// List of keys that will be converted into scopes (from constants 'SCOPE_state_in_uppercase' in file of service).
148			// We pass this param list in to 'state' because we need it before and after the redirect.
149			$shortscope = 'user,public_repo';
150			$urltorenew = $urlwithroot.'/core/modules/oauth/github_oauthcallback.php?shortscope='.$shortscope.'&state='.$shortscope.'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
151			$urltodelete = $urlwithroot.'/core/modules/oauth/github_oauthcallback.php?action=delete&token='.newToken().'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
152			$urltocheckperms = 'https://github.com/settings/applications/';
153		} elseif ($key[0] == 'OAUTH_GOOGLE_NAME')
154		{
155			$OAUTH_SERVICENAME = 'Google';
156			// List of keys that will be converted into scopes (from constants 'SCOPE_state_in_uppercase' in file of service).
157			// We pass this param list in to 'state' because we need it before and after the redirect.
158			$shortscope = 'userinfo_email,userinfo_profile,cloud_print';
159			if (!empty($conf->global->OAUTH_GSUITE)) {
160				$shortscope .= ',admin_directory_user';
161			}
162			//$scope.=',gmail_full';
163			$urltorenew = $urlwithroot.'/core/modules/oauth/google_oauthcallback.php?shortscope='.$shortscope.'&state='.$shortscope.'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
164			$urltodelete = $urlwithroot.'/core/modules/oauth/google_oauthcallback.php?action=delete&token='.newToken().'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
165			$urltocheckperms = 'https://security.google.com/settings/security/permissions';
166		} elseif ($key[0] == 'OAUTH_STRIPE_TEST_NAME')
167		{
168			$OAUTH_SERVICENAME = 'StripeTest';
169			$urltorenew = $urlwithroot.'/core/modules/oauth/stripetest_oauthcallback.php?backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
170			$urltodelete = '';
171			$urltocheckperms = '';
172		} elseif ($key[0] == 'OAUTH_STRIPE_LIVE_NAME')
173		{
174			$OAUTH_SERVICENAME = 'StripeLive';
175			$urltorenew = $urlwithroot.'/core/modules/oauth/stripelive_oauthcallback.php?backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
176			$urltodelete = '';
177			$urltocheckperms = '';
178		} else {
179			$urltorenew = '';
180			$urltodelete = '';
181			$urltocheckperms = '';
182		}
183
184
185		// Show value of token
186		$tokenobj = null;
187		// Token
188		require_once DOL_DOCUMENT_ROOT.'/includes/OAuth/bootstrap.php';
189		require_once DOL_DOCUMENT_ROOT.'/includes/OAuth/bootstrap.php';
190		// Dolibarr storage
191		$storage = new DoliStorage($db, $conf);
192		try {
193			$tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME);
194		} catch (Exception $e)
195		{
196			// Return an error if token not found
197		}
198
199		// Set other properties
200		$refreshtoken = false;
201		$expiredat = '';
202
203		$expire = false;
204		// Is token expired or will token expire in the next 30 seconds
205		if (is_object($tokenobj)) {
206			$expire = ($tokenobj->getEndOfLife() !== $tokenobj::EOL_NEVER_EXPIRES && $tokenobj->getEndOfLife() !== $tokenobj::EOL_UNKNOWN && time() > ($tokenobj->getEndOfLife() - 30));
207		}
208
209		if ($key[1] != '' && $key[2] != '') {
210			if (is_object($tokenobj)) {
211				$refreshtoken = $tokenobj->getRefreshToken();
212
213				$endoflife = $tokenobj->getEndOfLife();
214				if ($endoflife == $tokenobj::EOL_NEVER_EXPIRES)
215				{
216					$expiredat = $langs->trans("Never");
217				} elseif ($endoflife == $tokenobj::EOL_UNKNOWN)
218				{
219					$expiredat = $langs->trans("Unknown");
220				} else {
221					$expiredat = dol_print_date($endoflife, "dayhour");
222				}
223			}
224		}
225
226		$submit_enabled = 0;
227
228		print '<form method="post" action="'.$_SERVER["PHP_SELF"].'?mode=setup&amp;driver='.$driver.'" autocomplete="off">';
229		print '<input type="hidden" name="token" value="'.newToken().'">';
230		print '<input type="hidden" name="action" value="setconst">';
231
232
233		print '<table class="noborder centpercent">'."\n";
234
235		print '<tr class="liste_titre">';
236		print '<th class="titlefieldcreate">'.$langs->trans($key[0]).'</th>';
237		print '<th></th>';
238		print '<th></th>';
239		print "</tr>\n";
240
241		print '<tr class="oddeven">';
242		print '<td'.($key['required'] ? ' class="required"' : '').'>';
243		//var_dump($key);
244		print $langs->trans("OAuthIDSecret").'</td>';
245		print '<td>';
246		print $langs->trans("SeePreviousTab");
247		print '</td>';
248		print '<td>';
249		print '</td>';
250		print '</tr>'."\n";
251
252		print '<tr class="oddeven">';
253		print '<td'.($key['required'] ? ' class="required"' : '').'>';
254		//var_dump($key);
255		print $langs->trans("IsTokenGenerated");
256		print '</td>';
257		print '<td>';
258		if (is_object($tokenobj)) print $langs->trans("HasAccessToken");
259		else print $langs->trans("NoAccessToken");
260		print '</td>';
261		print '<td>';
262		// Links to delete/checks token
263		if (is_object($tokenobj))
264		{
265			//test on $storage->hasAccessToken($OAUTH_SERVICENAME) ?
266			print '<a class="button" href="'.$urltodelete.'">'.$langs->trans('DeleteAccess').'</a><br>';
267		}
268		// Request remote token
269		if ($urltorenew)
270		{
271			print '<a class="button" href="'.$urltorenew.'">'.$langs->trans('RequestAccess').'</a><br>';
272		}
273		// Check remote access
274		if ($urltocheckperms)
275		{
276			print '<br>'.$langs->trans("ToCheckDeleteTokenOnProvider", $OAUTH_SERVICENAME).': <a href="'.$urltocheckperms.'" target="_'.strtolower($OAUTH_SERVICENAME).'">'.$urltocheckperms.'</a>';
277		}
278		print '</td>';
279		print '</tr>';
280
281		print '<tr class="oddeven">';
282		print '<td'.($key['required'] ? ' class="required"' : '').'>';
283		//var_dump($key);
284		print $langs->trans("Token").'</td>';
285		print '<td colspan="2">';
286		if (is_object($tokenobj))
287		{
288			//var_dump($tokenobj);
289			print $tokenobj->getAccessToken().'<br>';
290			//print 'Refresh: '.$tokenobj->getRefreshToken().'<br>';
291			//print 'EndOfLife: '.$tokenobj->getEndOfLife().'<br>';
292			//var_dump($tokenobj->getExtraParams());
293			/*print '<br>Extra: <br><textarea class="quatrevingtpercent">';
294            print ''.join(',',$tokenobj->getExtraParams());
295            print '</textarea>';*/
296		}
297		print '</td>';
298		print '</tr>'."\n";
299
300		if (is_object($tokenobj))
301		{
302			// Token refresh
303			print '<tr class="oddeven">';
304			print '<td'.($key['required'] ? ' class="required"' : '').'>';
305			//var_dump($key);
306			print $langs->trans("TOKEN_REFRESH").'</td>';
307			print '<td colspan="2">';
308			print yn($refreshtoken);
309			print '</td>';
310			print '</tr>';
311
312			// Token expired
313			print '<tr class="oddeven">';
314			print '<td'.($key['required'] ? ' class="required"' : '').'>';
315			//var_dump($key);
316			print $langs->trans("TOKEN_EXPIRED").'</td>';
317			print '<td colspan="2">';
318			print yn($expire);
319			print '</td>';
320			print '</tr>';
321
322			// Token expired at
323			print '<tr class="oddeven">';
324			print '<td'.($key['required'] ? ' class="required"' : '').'>';
325			//var_dump($key);
326			print $langs->trans("TOKEN_EXPIRE_AT").'</td>';
327			print '<td colspan="2">';
328			print $expiredat;
329			print '</td>';
330			print '</tr>';
331		}
332
333		print '</table>';
334
335		if (!empty($driver))
336		{
337			if ($submit_enabled) {
338				print '<div class="center"><input type="submit" class="button" value="'.dol_escape_htmltag($langs->trans("Modify")).'"></div>';
339			}
340		}
341
342
343		print '</form>';
344	}
345}
346
347if ($mode == 'test' && $user->admin)
348{
349	print $langs->trans('PrintTestDesc'.$driver)."<br><br>\n";
350
351	print '<table class="noborder centpercent">';
352	if (!empty($driver))
353	{
354		require_once DOL_DOCUMENT_ROOT.'/core/modules/printing/'.$driver.'.modules.php';
355		$classname = 'printing_'.$driver;
356		$langs->load($driver);
357		$printer = new $classname($db);
358		//print '<pre>'.print_r($printer, true).'</pre>';
359		if (count($printer->getlistAvailablePrinters())) {
360			if ($printer->listAvailablePrinters() == 0) {
361				print $printer->resprint;
362			} else {
363				setEventMessages($printer->error, $printer->errors, 'errors');
364			}
365		} else {
366			print $langs->trans('PleaseConfigureDriverfromList');
367		}
368	}
369
370	print '</table>';
371}
372
373if ($mode == 'userconf' && $user->admin)
374{
375	print $langs->trans('PrintUserConfDesc'.$driver)."<br><br>\n";
376
377	print '<table class="noborder centpercent">';
378	print '<tr class="liste_titre">';
379	print '<th>'.$langs->trans("User").'</th>';
380	print '<th>'.$langs->trans("PrintModule").'</th>';
381	print '<th>'.$langs->trans("PrintDriver").'</th>';
382	print '<th>'.$langs->trans("Printer").'</th>';
383	print '<th>'.$langs->trans("PrinterLocation").'</th>';
384	print '<th>'.$langs->trans("PrinterId").'</th>';
385	print '<th>'.$langs->trans("NumberOfCopy").'</th>';
386	print '<th class="center">'.$langs->trans("Delete").'</th>';
387	print "</tr>\n";
388	$sql = 'SELECT p.rowid, p.printer_name, p.printer_location, p.printer_id, p.copy, p.module, p.driver, p.userid, u.login FROM '.MAIN_DB_PREFIX.'printing as p, '.MAIN_DB_PREFIX.'user as u WHERE p.userid=u.rowid';
389	$resql = $db->query($sql);
390	while ($row = $db->fetch_array($resql)) {
391		print '<tr class="oddeven">';
392		print '<td>'.$row['login'].'</td>';
393		print '<td>'.$row['module'].'</td>';
394		print '<td>'.$row['driver'].'</td>';
395		print '<td>'.$row['printer_name'].'</td>';
396		print '<td>'.$row['printer_location'].'</td>';
397		print '<td>'.$row['printer_id'].'</td>';
398		print '<td>'.$row['copy'].'</td>';
399		print '<td class="center">'.img_picto($langs->trans("Delete"), 'delete').'</td>';
400		print "</tr>\n";
401	}
402	print '</table>';
403}
404
405print dol_get_fiche_end();
406
407// End of page
408llxFooter();
409$db->close();
410