NEW Can test signature of a version from API

This commit is contained in:
Laurent Destailleur
2017-12-16 17:24:23 +01:00
parent fcf50c01b9
commit 2163db446b
3 changed files with 405 additions and 48 deletions

View File

@@ -329,7 +329,7 @@ class Setup extends DolibarrApi
*
* @throws RestException
*/
function getListOfEvents($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $type = '', $module = '', $sqlfilters = '')
function getListOfEventTypes($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $type = '', $module = '', $sqlfilters = '')
{
$list = array();
@@ -577,4 +577,345 @@ class Setup extends DolibarrApi
return $list;
}
/**
* Do a test of integrity for files and setup.
*
* @param string $target Can be 'local' or 'default' or Url of the signatures file to use for the test. Must be reachable by the tested Dolibarr.
* @return Result of file and setup integrity check
*
* @url GET checkintegrity
*
* @throws RestException
*/
function getCheckIntegrity($target)
{
global $langs, $conf;
if (! DolibarrApiAccess::$user->admin
&& (empty($conf->global->API_LOGIN_ALLOWED_FOR_INTEGRITY_CHECK) || DolibarrApiAccess::$user->login != $conf->global->API_LOGIN_ALLOWED_FOR_INTEGRITY_CHECK))
{
throw new RestException(503, 'Error API open to admin users only or to login user defined with constant API_LOGIN_ALLOWED_FOR_INTEGRITY_CHECK');
}
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php';
$langs->load("admin");
$outexpectedchecksum = '';
$outcurrentchecksum = '';
// Modified or missing files
$file_list = array('missing' => array(), 'updated' => array());
// Local file to compare to
$xmlshortfile = GETPOST('xmlshortfile')?GETPOST('xmlshortfile'):'/install/filelist-'.DOL_VERSION.'.xml';
$xmlfile = DOL_DOCUMENT_ROOT.$xmlshortfile;
// Remote file to compare to
$xmlremote = ($target == 'default' ? '' : $target);
if (empty($xmlremote) && ! empty($conf->global->MAIN_FILECHECK_URL)) $xmlremote = $conf->global->MAIN_FILECHECK_URL;
$param='MAIN_FILECHECK_URL_'.DOL_VERSION;
if (empty($xmlremote) && ! empty($conf->global->$param)) $xmlremote = $conf->global->$param;
if (empty($xmlremote)) $xmlremote = 'https://www.dolibarr.org/files/stable/signatures/filelist-'.DOL_VERSION.'.xml';
if ($target == 'local')
{
if (dol_is_file($xmlfile))
{
$xml = simplexml_load_file($xmlfile);
}
else
{
throw new RestException(500, $langs->trans('XmlNotFound') . ': ' . $xmlfile);
$error++;
}
}
else
{
$xmlarray = getURLContent($xmlremote);
// Return array('content'=>response,'curl_error_no'=>errno,'curl_error_msg'=>errmsg...)
if (! $xmlarray['curl_error_no'] && $xmlarray['http_code'] != '404')
{
$xmlfile = $xmlarray['content'];
//print "eee".$xmlfile."eee";
$xml = simplexml_load_string($xmlfile);
}
else
{
$errormsg=$langs->trans('XmlNotFound') . ': ' . $xmlremote.' - '.$xmlarray['http_code'].' '.$xmlarray['curl_error_no'].' '.$xmlarray['curl_error_msg'];
throw new RestException(500, $errormsg);
$error++;
}
}
if (! $error && $xml)
{
$checksumconcat = array();
$file_list = array();
$out = '';
// Forced constants
if (is_object($xml->dolibarr_constants[0]))
{
$out.=load_fiche_titre($langs->trans("ForcedConstants"));
$out.='<div class="div-table-responsive-no-min">';
$out.='<table class="noborder">';
$out.='<tr class="liste_titre">';
$out.='<td>#</td>';
$out.='<td>' . $langs->trans("Constant") . '</td>';
$out.='<td align="center">' . $langs->trans("ExpectedValue") . '</td>';
$out.='<td align="center">' . $langs->trans("Value") . '</td>';
$out.='</tr>'."\n";
$i = 0;
foreach ($xml->dolibarr_constants[0]->constant as $constant) // $constant is a simpleXMLElement
{
$constname=$constant['name'];
$constvalue=(string) $constant;
$constvalue = (empty($constvalue)?'0':$constvalue);
// Value found
$value='';
if ($constname && $conf->global->$constname != '') $value=$conf->global->$constname;
$valueforchecksum=(empty($value)?'0':$value);
$checksumconcat[]=$valueforchecksum;
$i++;
$out.='<tr class="oddeven">';
$out.='<td>'.$i.'</td>' . "\n";
$out.='<td>'.$constname.'</td>' . "\n";
$out.='<td align="center">'.$constvalue.'</td>' . "\n";
$out.='<td align="center">'.$valueforchecksum.'</td>' . "\n";
$out.="</tr>\n";
}
if ($i==0)
{
$out.='<tr class="oddeven"><td colspan="4" class="opacitymedium">'.$langs->trans("None").'</td></tr>';
}
$out.='</table>';
$out.='</div>';
$out.='<br>';
}
// Scan htdocs
if (is_object($xml->dolibarr_htdocs_dir[0]))
{
//var_dump($xml->dolibarr_htdocs_dir[0]['includecustom']);exit;
$includecustom=(empty($xml->dolibarr_htdocs_dir[0]['includecustom'])?0:$xml->dolibarr_htdocs_dir[0]['includecustom']);
// Defined qualified files (must be same than into generate_filelist_xml.php)
$regextoinclude='\.(php|css|html|js|json|tpl|jpg|png|gif|sql|lang)$';
$regextoexclude='('.($includecustom?'':'custom|').'documents|conf|install|public\/test|Shared\/PCLZip|nusoap\/lib\/Mail|php\/example|php\/test|geoip\/sample.*\.php|ckeditor\/samples|ckeditor\/adapters)$'; // Exclude dirs
$scanfiles = dol_dir_list(DOL_DOCUMENT_ROOT, 'files', 1, $regextoinclude, $regextoexclude);
// Fill file_list with files in signature, new files, modified files
$ret = getFilesUpdated($file_list, $xml->dolibarr_htdocs_dir[0], '', DOL_DOCUMENT_ROOT, $checksumconcat, $scanfiles); // Fill array $file_list
// Complete with list of new files
foreach ($scanfiles as $keyfile => $valfile)
{
$tmprelativefilename=preg_replace('/^'.preg_quote(DOL_DOCUMENT_ROOT,'/').'/','', $valfile['fullname']);
if (! in_array($tmprelativefilename, $file_list['insignature']))
{
$md5newfile=@md5_file($valfile['fullname']); // Can fails if we don't have permission to open/read file
$file_list['added'][]=array('filename'=>$tmprelativefilename, 'md5'=>$md5newfile);
}
}
// Files missings
$out.=load_fiche_titre($langs->trans("FilesMissing"));
$out.='<div class="div-table-responsive-no-min">';
$out.='<table class="noborder">';
$out.='<tr class="liste_titre">';
$out.='<td>#</td>';
$out.='<td>' . $langs->trans("Filename") . '</td>';
$out.='<td align="center">' . $langs->trans("ExpectedChecksum") . '</td>';
$out.='</tr>'."\n";
$tmpfilelist = dol_sort_array($file_list['missing'], 'filename');
if (is_array($tmpfilelist) && count($tmpfilelist))
{
$i = 0;
foreach ($tmpfilelist as $file)
{
$i++;
$out.='<tr class="oddeven">';
$out.='<td>'.$i.'</td>' . "\n";
$out.='<td>'.$file['filename'].'</td>' . "\n";
$out.='<td align="center">'.$file['expectedmd5'].'</td>' . "\n";
$out.="</tr>\n";
}
}
else
{
$out.='<tr class="oddeven"><td colspan="3" class="opacitymedium">'.$langs->trans("None").'</td></tr>';
}
$out.='</table>';
$out.='</div>';
$out.='<br>';
// Files modified
$out.=load_fiche_titre($langs->trans("FilesModified"));
$totalsize=0;
$out.='<div class="div-table-responsive-no-min">';
$out.='<table class="noborder">';
$out.='<tr class="liste_titre">';
$out.='<td>#</td>';
$out.='<td>' . $langs->trans("Filename") . '</td>';
$out.='<td align="center">' . $langs->trans("ExpectedChecksum") . '</td>';
$out.='<td align="center">' . $langs->trans("CurrentChecksum") . '</td>';
$out.='<td align="right">' . $langs->trans("Size") . '</td>';
$out.='<td align="right">' . $langs->trans("DateModification") . '</td>';
$out.='</tr>'."\n";
$tmpfilelist2 = dol_sort_array($file_list['updated'], 'filename');
if (is_array($tmpfilelist2) && count($tmpfilelist2))
{
$i = 0;
foreach ($tmpfilelist2 as $file)
{
$i++;
$out.='<tr class="oddeven">';
$out.='<td>'.$i.'</td>' . "\n";
$out.='<td>'.$file['filename'].'</td>' . "\n";
$out.='<td align="center">'.$file['expectedmd5'].'</td>' . "\n";
$out.='<td align="center">'.$file['md5'].'</td>' . "\n";
$size = dol_filesize(DOL_DOCUMENT_ROOT.'/'.$file['filename']);
$totalsize += $size;
$out.='<td align="right">'.dol_print_size($size).'</td>' . "\n";
$out.='<td align="right">'.dol_print_date(dol_filemtime(DOL_DOCUMENT_ROOT.'/'.$file['filename']),'dayhour').'</td>' . "\n";
$out.="</tr>\n";
}
$out.='<tr class="liste_total">';
$out.='<td></td>' . "\n";
$out.='<td>'.$langs->trans("Total").'</td>' . "\n";
$out.='<td align="center"></td>' . "\n";
$out.='<td align="center"></td>' . "\n";
$out.='<td align="right">'.dol_print_size($totalsize).'</td>' . "\n";
$out.='<td align="right"></td>' . "\n";
$out.="</tr>\n";
}
else
{
$out.='<tr class="oddeven"><td colspan="5" class="opacitymedium">'.$langs->trans("None").'</td></tr>';
}
$out.='</table>';
$out.='</div>';
$out.='<br>';
// Files added
$out.=load_fiche_titre($langs->trans("FilesAdded"));
$totalsize = 0;
$out.='<div class="div-table-responsive-no-min">';
$out.='<table class="noborder">';
$out.='<tr class="liste_titre">';
$out.='<td>#</td>';
$out.='<td>' . $langs->trans("Filename") . '</td>';
$out.='<td align="center">' . $langs->trans("ExpectedChecksum") . '</td>';
$out.='<td align="center">' . $langs->trans("CurrentChecksum") . '</td>';
$out.='<td align="right">' . $langs->trans("Size") . '</td>';
$out.='<td align="right">' . $langs->trans("DateModification") . '</td>';
$out.='</tr>'."\n";
$tmpfilelist3 = dol_sort_array($file_list['added'], 'filename');
if (is_array($tmpfilelist3) && count($tmpfilelist3))
{
$i = 0;
foreach ($tmpfilelist3 as $file)
{
$i++;
$out.='<tr class="oddeven">';
$out.='<td>'.$i.'</td>' . "\n";
$out.='<td>'.$file['filename'].'</td>' . "\n";
$out.='<td align="center">'.$file['expectedmd5'].'</td>' . "\n";
$out.='<td align="center">'.$file['md5'].'</td>' . "\n";
$size = dol_filesize(DOL_DOCUMENT_ROOT.'/'.$file['filename']);
$totalsize += $size;
$out.='<td align="right">'.dol_print_size($size).'</td>' . "\n";
$out.='<td align="right">'.dol_print_date(dol_filemtime(DOL_DOCUMENT_ROOT.'/'.$file['filename']),'dayhour').'</td>' . "\n";
$out.="</tr>\n";
}
$out.='<tr class="liste_total">';
$out.='<td></td>' . "\n";
$out.='<td>'.$langs->trans("Total").'</td>' . "\n";
$out.='<td align="center"></td>' . "\n";
$out.='<td align="center"></td>' . "\n";
$out.='<td align="right">'.dol_print_size($totalsize).'</td>' . "\n";
$out.='<td align="right"></td>' . "\n";
$out.="</tr>\n";
}
else
{
$out.='<tr class="oddeven"><td colspan="5" class="opacitymedium">'.$langs->trans("None").'</td></tr>';
}
$out.='</table>';
$out.='</div>';
// Show warning
if (empty($tmpfilelist) && empty($tmpfilelist2) && empty($tmpfilelist3))
{
//setEventMessage($langs->trans("FileIntegrityIsStrictlyConformedWithReference"));
}
else
{
//setEventMessage($langs->trans("FileIntegritySomeFilesWereRemovedOrModified"), 'warnings');
}
}
else
{
throw new RestException(500, 'Error: Failed to found dolibarr_htdocs_dir into XML file '.$xmlfile);
$error++;
}
// Scan scripts
asort($checksumconcat); // Sort list of checksum
//var_dump($checksumconcat);
$checksumget = md5(join(',',$checksumconcat));
$checksumtoget = trim((string) $xml->dolibarr_htdocs_dir_checksum);
$outexpectedchecksum = ($checksumtoget ? $checksumtoget : $langs->trans("Unknown"));
if ($checksumget == $checksumtoget)
{
if (count($file_list['added']))
{
$resultcode = 'warning';
$resultcomment='FileIntegrityIsOkButFilesWereAdded';
//$outcurrentchecksum = $checksumget.' - <span class="'.$resultcode.'">'.$langs->trans("FileIntegrityIsOkButFilesWereAdded").'</span>';
$outcurrentchecksum = $checksumget;
}
else
{
$resultcode = 'ok';
$resultcomment='Success';
//$outcurrentchecksum = '<span class="'.$resultcode.'">'.$checksumget.'</span>';
$outcurrentchecksum = $checksumget;
}
}
else
{
$resultcode = 'error';
$resultcomment='Error';
//$outcurrentchecksum = '<span class="'.$resultcode.'">'.$checksumget.'</span>';
$outcurrentchecksum = $checksumget;
}
}
else {
throw new RestException(404, 'No signature file known');
}
return array('resultcode'=>$resultcode, 'resultcomment'=>$resultcomment, 'expectedchecksum'=> $outexpectedchecksum, 'currentchecksum'=> $outcurrentchecksum, 'out'=>$out);
}
}