diff --git a/htdocs/blockedlog/admin/blockedlog.php b/htdocs/blockedlog/admin/blockedlog.php index f77c6e9edd8..b3822a9acb7 100644 --- a/htdocs/blockedlog/admin/blockedlog.php +++ b/htdocs/blockedlog/admin/blockedlog.php @@ -17,7 +17,7 @@ /** * \file htdocs/blockedlog/admin/blockedlog.php - * \ingroup system + * \ingroup blockedlog * \brief Page setup for blockedlog module */ @@ -31,12 +31,13 @@ $langs->load("other"); $langs->load("blockedlog"); if (! $user->admin) accessforbidden(); - + $action = GETPOST('action','alpha'); /* * Actions */ + if (preg_match('/set_(.*)/',$action,$reg)) { $code=$reg[1]; @@ -77,7 +78,7 @@ $form=new Form($db); llxHeader('',$langs->trans("BlockedLogSetup")); $linkback=''.$langs->trans("BackToModuleList").''; -print load_fiche_titre($langs->trans("ModuleSetup").' BlockedLog',$linkback); +print load_fiche_titre($langs->trans("ModuleSetup").' '.$langs->trans('BlockedLog'),$linkback); $head=blockedlogadmin_prepare_head(); @@ -95,13 +96,11 @@ print "\n"; print ''; print ''; -print $langs->trans("EntityKey").''; - +print $langs->trans("CompanyInitialKey").''; print $block_static->getSignature(); - print ''; -if(!empty($conf->global->BLOCKEDLOG_USE_REMOTE_AUTHORITY)) { +if (!empty($conf->global->BLOCKEDLOG_USE_REMOTE_AUTHORITY)) { // Example with a yes / no select $var=!$var; print ''; diff --git a/htdocs/blockedlog/admin/fingerprints.php b/htdocs/blockedlog/admin/fingerprints.php index f585b883c65..da149d4340d 100644 --- a/htdocs/blockedlog/admin/fingerprints.php +++ b/htdocs/blockedlog/admin/fingerprints.php @@ -16,8 +16,8 @@ */ /** - * \file htdocs/blockedlog/admin/blockedlog.php - * \ingroup system + * \file htdocs/blockedlog/admin/fingerprints.php + * \ingroup blockedlog * \brief Page setup for blockedlog module */ @@ -32,39 +32,39 @@ $langs->load("other"); $langs->load("blockedlog"); if (! $user->admin) accessforbidden(); - + $action = GETPOST('action','alpha'); $showonlyerrors = GETPOST('showonlyerrors','int'); $block_static = new BlockedLog($db); if($action === 'downloadblockchain') { - + $auth = new BlockedLogAuthority($db); - + $bc = $auth->getLocalBlockChain(); - + header('Content-Type: application/octet-stream'); header("Content-Transfer-Encoding: Binary"); - header("Content-disposition: attachment; filename=\"" .$auth->signature. ".certif\""); - + header("Content-disposition: attachment; filename=\"" .$auth->signature. ".certif\""); + echo $bc; - + exit; } else if($action === 'downloadcsv') { - + $res = $db->query("SELECT rowid,tms,action,amounts,element,fk_object,date_object,ref_object,signature,fk_user FROM ".MAIN_DB_PREFIX."blockedlog ORDER BY rowid ASC"); - + if($res) { - + $signature = $block_static->getSignature(); - + header('Content-Type: application/octet-stream'); header("Content-Transfer-Encoding: Binary"); header("Content-disposition: attachment; filename=\"" .$signature. ".csv\""); - + print $langs->transnoentities('Id') .';'.$langs->transnoentities('Timestamp') .';'.$langs->transnoentities('Action') @@ -75,9 +75,9 @@ else if($action === 'downloadcsv') { .';'.$langs->transnoentities('Ref') .';'.$langs->transnoentities('Fingerprint') .';'.$langs->transnoentities('User')."\n"; - + while($obj = $db->fetch_object($res)) { - + print $obj->rowid .';'.$obj->tms .';'.$obj->action @@ -88,15 +88,15 @@ else if($action === 'downloadcsv') { .';'.$obj->ref_object .';'.$obj->signature .';'.$obj->fk_user."\n"; - + } - + exit; } else{ setEventMessage($db->lasterror, 'errors'); } - + } /* @@ -110,7 +110,7 @@ $form=new Form($db); llxHeader('',$langs->trans("BlockedLogSetup")); $linkback=''.$langs->trans("BackToModuleList").''; -print load_fiche_titre($langs->trans("ModuleSetup").' BlockedLog',$linkback); +print load_fiche_titre($langs->trans("ModuleSetup").' '.$langs->trans('BlockedLog'),$linkback); $head=blockedlogadmin_prepare_head(); @@ -131,52 +131,63 @@ print ' '; print ''; print ''; -print ''; -print ''; +print ''; +print ''; +print ''; print ''; +print ''; print ''; print ''; -print ''; +print ''; print ''; print ''; - + print ''; foreach($blocks as &$block) { $checksignature = $block->checkSignature(); $object_link = $block->getObjectLink(); - + if(!$showonlyerrors || $block->error>0) { - + print ''; + print ''; print ''; - print ''; - print ''; - print ''; - print ''; print ''; - print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + + print ''; + print ''; - + } } print '
'.$langs->trans('Date').''.$langs->trans('Ref').''.$langs->trans('#').''.$langs->trans('Date').''.$langs->trans('Author').''.$langs->trans('Action').''.$langs->trans('Ref').''.$langs->trans('Element').''.$langs->trans('Amount').''.$langs->trans('Author').''.$langs->trans('DataOfArchivedEvent').''.$langs->trans('Fingerprint').'
'.$block->id.''.dol_print_date($block->tms,'dayhour').''.$block->ref_object.''.$langs->trans('log'.$block->action).''.$object_link.''.img_info($langs->trans('ShowDetails')).''.price($block->amounts).''.$block->getUser().''.$block->signature.''.$langs->trans('log'.$block->action).''.$block->ref_object.''.$object_link.''.price($block->amounts).''.img_info($langs->trans('ShowDetails')).''; - - print $block->error == 0 ? img_picto($langs->trans('OkCheckFingerprintValidity'), 'on') : img_picto($langs->trans('KoCheckFingerprintValidity'), 'off'); + print $form->textwithpicto(dol_trunc($block->signature, '12'), $block->signature); + print ''; + print $block->error == 0 ? img_picto($langs->trans('OkCheckFingerprintValidity'), 'tick') : img_picto($langs->trans('KoCheckFingerprintValidity'), 'statut8'); + if(!empty($conf->global->BLOCKEDLOG_USE_REMOTE_AUTHORITY) && !empty($conf->global->BLOCKEDLOG_AUTHORITY_URL)) { print ' '.($block->certified ? img_picto($langs->trans('AddedByAuthority'), 'info') : img_picto($langs->trans('NotAddedByAuthorityYet'), 'info_black') ); } print '
'; + + ?> -global->BLOCKEDLOG_USE_REMOTE_AUTHORITY) && !empty($conf->global->BLOCKEDLOG_AUTHORITY_URL)) { ?> - + + * Copyright (C) 2017 ATM Consulting + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ - $user=new User($db); - $user->fetch(1); //TODO conf user authority - - $auth = new BlockedLogAuthority($db); - - $signature = GETPOST('s'); - $newblock = GETPOST('b'); - $hash = GETPOST('h'); - - if($auth->fetch(0, $signature)<=0) { - $auth->signature = $signature; - $auth->create($user); - } - - - if(!empty($hash)) { - - echo $auth->checkBlockchain($hash) ? 'hashisok' : 'hashisjunk'; - - } - elseif(!empty($newblock)){ - if($auth->checkBlock($newblock)) { - $auth->addBlock($newblock); - $auth->update($user); - - echo 'blockadded'; - } - else{ - - echo 'blockalreadyadded'; - - } +/** + * \file htdocs/blockedlog/ajax/authority.php + * \ingroup blockedlog + * \brief authority + */ + + +// This script is called with a POST method. +// Directory to scan (full path) is inside POST['dir']. + +if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL',1); // Disables token renewal +//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); +if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); +if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); +//if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); + +$res=require '../../master.inc.php'; + +require_once DOL_DOCUMENT_ROOT.'/blockedlog/class/blockedlog.class.php'; +require_once DOL_DOCUMENT_ROOT.'/blockedlog/class/authority.class.php'; + +$user=new User($db); +$user->fetch(1); //TODO conf user authority + +$auth = new BlockedLogAuthority($db); + +$signature = GETPOST('s'); +$newblock = GETPOST('b'); +$hash = GETPOST('h'); + +if($auth->fetch(0, $signature)<=0) { + $auth->signature = $signature; + $auth->create($user); +} + + +if(!empty($hash)) { + + echo $auth->checkBlockchain($hash) ? 'hashisok' : 'hashisjunk'; + +} +elseif(!empty($newblock)){ + if($auth->checkBlock($newblock)) { + $auth->addBlock($newblock); + $auth->update($user); + + echo 'blockadded'; } else{ - echo 'idontunderstandwhatihavetodo'; + + echo 'blockalreadyadded'; + } - - +} +else{ + echo 'idontunderstandwhatihavetodo'; +} + + diff --git a/htdocs/blockedlog/ajax/block-add.php b/htdocs/blockedlog/ajax/block-add.php index 247b01186fe..c82eac81e7b 100644 --- a/htdocs/blockedlog/ajax/block-add.php +++ b/htdocs/blockedlog/ajax/block-add.php @@ -1,19 +1,49 @@ - + * Copyright (C) 2017 ATM Consulting + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ - require '../../main.inc.php'; - require_once DOL_DOCUMENT_ROOT.'/blockedlog/class/blockedlog.class.php'; - - $id = GETPOST('id','int'); - $element = GETPOST('element','alpha'); - $action = GETPOST('action','alpha'); - - if($element === 'facture') { - dol_include_once('/compta/facture/class/facture.class.php'); - - $facture = new Facture($db); - if($facture->fetch($id)>0) { - $facture->call_trigger($action, $user); - } - +/** + * \file htdocs/blockedlog/ajax/block-add.php + * \ingroup blockedlog + * \brief Block-add + */ + + +// This script is called with a POST method. +// Directory to scan (full path) is inside POST['dir']. + +if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL',1); // Disables token renewal +//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); +if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); +if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); +//if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); + +$res=require '../../main.inc.php'; + +$id = GETPOST('id','int'); +$element = GETPOST('element','alpha'); +$action = GETPOST('action','alpha'); + +if ($element === 'facture') { + require_once DOL_DOCUMENT_ROOT.'/blockedlog/class/blockedlog.class.php'; + require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; + + $facture = new Facture($db); + if($facture->fetch($id)>0) { + $facture->call_trigger($action, $user); } - \ No newline at end of file +} diff --git a/htdocs/blockedlog/ajax/block-info.php b/htdocs/blockedlog/ajax/block-info.php index 7a5f531e8f1..83317f33d57 100644 --- a/htdocs/blockedlog/ajax/block-info.php +++ b/htdocs/blockedlog/ajax/block-info.php @@ -1,15 +1,47 @@ + * Copyright (C) 2017 ATM Consulting + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ - require '../../main.inc.php'; - require_once DOL_DOCUMENT_ROOT.'/blockedlog/class/blockedlog.class.php'; - - $id = GETPOST('id'); - - $block = new BlockedLog($db); - if($block->fetch($id)>0) { - echo json_encode($block->object_data); - } - else { - echo json_encode(false); - } - \ No newline at end of file +/** + * \file htdocs/blockedlog/ajax/block-info.php + * \ingroup blockedlog + * \brief block-info + */ + + +// This script is called with a POST method. +// Directory to scan (full path) is inside POST['dir']. + +if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL',1); // Disables token renewal +//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); +if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); +if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); +//if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); + + +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/blockedlog/class/blockedlog.class.php'; + +$id = GETPOST('id'); + +$block = new BlockedLog($db); +if($block->fetch($id)>0) { + echo json_encode($block->object_data); +} +else { + echo json_encode(false); +} diff --git a/htdocs/blockedlog/ajax/check_signature.php b/htdocs/blockedlog/ajax/check_signature.php index bb018508a31..170693a2ece 100644 --- a/htdocs/blockedlog/ajax/check_signature.php +++ b/htdocs/blockedlog/ajax/check_signature.php @@ -1,30 +1,63 @@ + * Copyright (C) 2017 ATM Consulting + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ - require '../../main.inc.php'; +/** + * \file htdocs/blockedlog/ajax/block-info.php + * \ingroup blockedlog + * \brief block-info + */ - if(empty($conf->global->BLOCKEDLOG_AUTHORITY_URL)) exit('BLOCKEDLOG_AUTHORITY_URL not set'); - - require_once DOL_DOCUMENT_ROOT.'/blockedlog/class/blockedlog.class.php'; - require_once DOL_DOCUMENT_ROOT.'/blockedlog/class/authority.class.php'; - - $auth=new BlockedLogAuthority($db); - $auth->syncSignatureWithAuthority(); - - $block_static = new BlockedLog($db); - - $blocks = $block_static->getLog('just_certified', 0, 0, 1) ; - $auth->signature = $block_static->getSignature(); - - foreach($blocks as &$b) { - $auth->blockchain.=$b->signature; - - } - - $hash = $auth->getBlockchainHash(); - - $url = $conf->global->BLOCKEDLOG_AUTHORITY_URL.'/blockedlog/ajax/authority.php?s='.$auth->signature.'&h='.$hash; +// This script is called with a POST method. +// Directory to scan (full path) is inside POST['dir']. - $res = file_get_contents($url); - //echo $url; - echo $res; \ No newline at end of file +if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL',1); // Disables token renewal +//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); +if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); +if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); +//if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); + + +require '../../main.inc.php'; + +if(empty($conf->global->BLOCKEDLOG_AUTHORITY_URL)) exit('BLOCKEDLOG_AUTHORITY_URL not set'); + +require_once DOL_DOCUMENT_ROOT.'/blockedlog/class/blockedlog.class.php'; +require_once DOL_DOCUMENT_ROOT.'/blockedlog/class/authority.class.php'; + +$auth=new BlockedLogAuthority($db); +$auth->syncSignatureWithAuthority(); + +$block_static = new BlockedLog($db); + +$blocks = $block_static->getLog('just_certified', 0, 0, 1) ; + +$auth->signature = $block_static->getSignature(); + +foreach($blocks as &$b) { + $auth->blockchain.=$b->signature; + +} + +$hash = $auth->getBlockchainHash(); + +$url = $conf->global->BLOCKEDLOG_AUTHORITY_URL.'/blockedlog/ajax/authority.php?s='.$auth->signature.'&h='.$hash; + +$res = file_get_contents($url); +//echo $url; +echo $res; \ No newline at end of file diff --git a/htdocs/blockedlog/class/blockedlog.class.php b/htdocs/blockedlog/class/blockedlog.class.php index b0cddd66f75..8a1508b7a04 100644 --- a/htdocs/blockedlog/class/blockedlog.class.php +++ b/htdocs/blockedlog/class/blockedlog.class.php @@ -21,65 +21,65 @@ class BlockedLog { - + /** * Id of the log * @var int */ public $id; - + /** * Unique fingerprint of the log * @var string */ public $signature = ''; - + /** * Unique fingerprint of the line log content * @var string */ public $signature_line = ''; - + public $amounts = null; - + /** * trigger action * @var string */ public $action = ''; - + /** * Object element * @var string */ public $element = ''; - + /** * Object id * @var int */ public $fk_object = 0; - + /** * Log certified by remote authority or not * @var boolean */ public $certified = false; - + /** * Author * @var int */ public $fk_user = 0; - + public $date_object = 0; - + public $ref_object = ''; - + public $object_data = null; - + public $error = 0; - + /** * Constructor * @@ -88,7 +88,7 @@ class BlockedLog public function __construct(DoliDB $db) { $this->db = $db; - + } /** @@ -96,10 +96,10 @@ class BlockedLog */ public function getObjectLink() { global $langs; - + if($this->element === 'facture') { require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; - + $object = new Facture($this->db); if($object->fetch($this->fk_object)>0) { return $object->getNomUrl(1); @@ -110,7 +110,7 @@ class BlockedLog } else if($this->element === 'payment') { require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php'; - + $object = new Paiement($this->db); if($object->fetch($this->fk_object)>0) { return $object->getNomUrl(1); @@ -119,61 +119,61 @@ class BlockedLog $this->error++; } } - + return $langs->trans('ImpossibleToReloadObject', $this->element, $this->fk_object); - + } - + /** * try to retrieve user author */ public function getUser() { global $langs, $cachedUser; - + if(empty($cachedUser))$cachedUser=array(); - + if(empty($cachedUser[$this->fk_user])) { $u=new User($this->db); if($u->fetch($this->fk_user)>0) { $cachedUser[$this->fk_user] = $u; } } - + if(!empty($cachedUser[$this->fk_user])) { return $cachedUser[$this->fk_user]->getNomUrl(1); } - + return $langs->trans('ImpossibleToRetrieveUser', $this->fk_user); } - + /** * populate log by object * * @param payment|facture $object object to store */ public function setObjectData(&$object) { - + if($object->element=='payment') { $this->date_object = $object->datepaye; } else{ $this->date_object = $object->date; } - + $this->ref_object = $object->ref; $this->element = $object->element; $this->fk_object = $object->id; - + $this->object_data=new stdClass(); - + if($this->element === 'facture') { if(empty($object->thirdparty))$object->fetch_thirdparty(); $this->object_data->thirdparty = new stdClass(); - + foreach($object->thirdparty as $key=>$value) { if(!is_object($value)) $this->object_data->thirdparty->{$key} = $value; } - + $this->object_data->total_ht = (double) $object->total_ht; $this->object_data->total_tva = (double) $object->total_tva; $this->object_data->total_ttc = (double) $object->total_ttc; @@ -181,17 +181,17 @@ class BlockedLog $this->object_data->total_localtax2= (double) $object->total_localtax2; $this->object_data->note_public = (double) $object->note_public; $this->object_data->note_private= (double) $object->note_private; - + } elseif($this->element==='payment'){ - + $this->object_data->amounts = $object->amounts; - + } - - + + } - + /** * Get object from database * @@ -199,50 +199,50 @@ class BlockedLog * @return int >0 if OK, <0 if KO, 0 if not found */ public function fetch($id) { - + global $langs; - + dol_syslog(get_class($this)."::fetch id=".$id, LOG_DEBUG); - + if (empty($id)) { $this->error='BadParameter'; return -1; } - + $langs->load("blockedlog"); - + $sql = "SELECT b.rowid, b.signature, b.amounts, b.action, b.element, b.fk_object, b.certified, b.tms, b.fk_user, b.date_object, b.ref_object, b.object_data"; $sql.= " FROM ".MAIN_DB_PREFIX."blockedlog as b"; if ($id) $sql.= " WHERE b.rowid = ". $id; - + $resql=$this->db->query($sql); if ($resql) { if ($this->db->num_rows($resql)) { $obj = $this->db->fetch_object($resql); - + $this->id = $obj->rowid; $this->ref = $obj->rowid; - + $this->signature = $obj->signature; $this->amounts = (double) $obj->amounts; $this->action = $obj->action; $this->element = $obj->element; - + $this->fk_object = trim($obj->fk_object); $this->date_object = $this->db->jdate($obj->date_object); $this->ref_object = $obj->ref_object; - + $this->certified = ($obj->certified == 1); - + $this->fk_user = $obj->fk_user; - + $this->tms = $this->db->jdate($obj->tms); - + $this->object_data = unserialize($obj->object_data); - + return 1; } else @@ -256,24 +256,24 @@ class BlockedLog $this->error=$this->db->error(); return -1; } - + } - + /** * Set block certified by authority * * @return boolean */ public function setCertified() { - + $res = $this->db->query("UPDATE ".MAIN_DB_PREFIX."blockedlog SET certified=1 WHERE rowid=".$this->id); if($res===false) return false; - + return true; - - + + } - + /** * Create blocked log in database. * @@ -281,31 +281,31 @@ class BlockedLog * @return int <0 if KO, >0 if OK */ public function create($user) { - + global $conf,$langs,$hookmanager; - + $langs->load('blockedlog'); - + $error=0; - + dol_syslog(get_class($this).'::create', LOG_DEBUG); - + $this->getSignatureRecursive(); - - + + if (is_null($this->amounts)) { $this->error=$langs->trans("BlockLogNeedAmountsValue"); dol_syslog($this->error, LOG_WARNING); return -1; } - + if(empty($this->element)) { $this->error=$langs->trans("BlockLogNeedElement"); dol_syslog($this->error, LOG_WARNING); return -2; } - + if(empty($this->action)) { $this->error=$langs->trans("BlockLogNeedAction"); dol_syslog($this->error, LOG_WARNING); @@ -313,9 +313,9 @@ class BlockedLog } $this->fk_user = $user->id; - + $this->db->begin(); - + $sql = "INSERT INTO ".MAIN_DB_PREFIX."blockedlog ("; $sql.= "action,"; $sql.= " amounts,"; @@ -343,18 +343,18 @@ class BlockedLog $sql.= "".$user->id.","; $sql.= $conf->entity; $sql.= ")"; - + $res = $this->db->query($sql); if ($res) { $id = $this->db->last_insert_id(MAIN_DB_PREFIX."blockedlog"); - + if ($id > 0) { $this->id = $id; - + $this->db->commit(); - + return $this->id; } else @@ -369,9 +369,9 @@ class BlockedLog $this->db->rollback(); return -1; } - + } - + /** * return crypted value. * @@ -379,56 +379,56 @@ class BlockedLog * @return string crypted string */ private function crypt($value) { - + return hash('sha256',$value); - + } - + /** * check if current signature still correct compare to the chain * - * @return boolean + * @return boolean */ public function checkSignature() { - + $signature_to_test = $this->signature; - + $this->getSignatureRecursive(); - + $res = ($signature_to_test === $this->signature); - + if(!$res) { $this->error++; } - + return $res; } - + /** - * set current signatures + * set current signatures */ private function getSignatureRecursive(){ - + $this->signature_line = $this->crypt( $this->action . $this->getSignature() . $this->amounts . print_r($this->object_data, true) ); /*if($this->signature=='d6320580a02c1ab67fcc0a6d49d453c7d96dda0148901736f7f55725bfe1b900' || $this->signature=='ea65d435ff12ca929936a406aa9d707d99fb334c127878d256b602a5541bbbc9') { var_dump($this->signature_line,$this->action ,$this->getSignature() , $this->amounts , $this->object_data); }*/ $this->signature = $this->signature_line; - + $logs = $this->getLog('all', 0, 0, 1) ; if($logs!==false) { foreach($logs as &$b) { - + if($this->id>0 && $b->id == $this->id) break; // on arrête sur un enregistrement précis pour recalculer une signature - + $b->getCurrentValue(); // on récupère la valeur actuelle en base de l'élément enregistré - + $this->signature = $this->crypt($this->signature. $this->action . $b->signature . $b->amounts); } } - + } - + /** * return log object for a element. * @@ -439,110 +439,110 @@ class BlockedLog * @return array array of object log */ public function getLog($element, $fk_object, $limit = 0, $order = -1) { - global $conf,$cachedlogs ; - + global $conf,$cachedlogs ; + /* $cachedlogs allow fastest search */ if(empty($cachedlogs)) $cachedlogs=array(); - - + + if($element=='all') { - + $sql="SELECT rowid FROM ".MAIN_DB_PREFIX."blockedlog WHERE entity=".$conf->entity; - + } else if($element=='not_certified') { $sql="SELECT rowid FROM ".MAIN_DB_PREFIX."blockedlog WHERE entity=".$conf->entity." AND certified = 0"; - + } else if($element=='just_certified') { $sql="SELECT rowid FROM ".MAIN_DB_PREFIX."blockedlog WHERE entity=".$conf->entity." AND certified = 1"; - + } else{ $sql="SELECT rowid FROM ".MAIN_DB_PREFIX."blockedlog WHERE element='".$element."' AND fk_object=".(int) $fk_object; - + } - + $sql.=($order<0 ? ' ORDER BY rowid DESC ' : ' ORDER BY rowid ASC '); - + if($limit > 0 )$sql.=' LIMIT '.$limit; - + $res = $this->db->query($sql); - + if($res) { - + $results=array(); - + while($obj = $this->db->fetch_object($res)) { - + if(!isset($cachedlogs[$obj->rowid])) { $b=new BlockedLog($this->db); $b->fetch($obj->rowid); - + $cachedlogs[$obj->rowid] = $b; } - + $results[] = $cachedlogs[$obj->rowid]; - + } - + return $results; } else{ return false; } } - + /** * set amounts of log from current element value in order to compare signature. */ private function getCurrentValue() { - + if($this->element === 'payment') { $sql="SELECT amount FROM ".MAIN_DB_PREFIX."paiement WHERE rowid=".$this->fk_object; - + $res = $this->db->query($sql); - + if($res && $obj = $this->db->fetch_object($res)) { $this->amounts = (double) $obj->amount; } } elseif($this->element === 'facture') { $sql="SELECT total_ttc FROM ".MAIN_DB_PREFIX."facture WHERE rowid=".$this->fk_object; - + $res = $this->db->query($sql); if($res && $obj = $this->db->fetch_object($res)) { $this->amounts = (double) $obj->total_ttc; } } - + } - + /** - * return and set the entity signature included into line signature + * Return and set the entity signature included into line signature * * @return string current entity signature */ public function getSignature() { global $db,$conf,$mysoc; - - if(empty($conf->global->BLOCKEDLOG_ENTITY_FINGERPRINT)) { // creation of a unique fingerprint - + + if (empty($conf->global->BLOCKEDLOG_ENTITY_FINGERPRINT)) { // creation of a unique fingerprint + require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; - + $fingerprint = $this->crypt(print_r($mysoc,true).time().rand(0,1000)); - + dolibarr_set_const($db, 'BLOCKEDLOG_ENTITY_FINGERPRINT', $fingerprint, 'chaine',0,'Numeric Unique Fingerprint', $conf->entity); - - $conf->global->BLOCKEDLOG_ENTITY_FINGERPRINT= $fingerprint; + + $conf->global->BLOCKEDLOG_ENTITY_FINGERPRINT=$fingerprint; } - + return $conf->global->BLOCKEDLOG_ENTITY_FINGERPRINT; } - + } diff --git a/htdocs/blockedlog/lib/blockedlog.lib.php b/htdocs/blockedlog/lib/blockedlog.lib.php index a7fca40d116..cffac7cbff9 100644 --- a/htdocs/blockedlog/lib/blockedlog.lib.php +++ b/htdocs/blockedlog/lib/blockedlog.lib.php @@ -32,17 +32,17 @@ function blockedlogadmin_prepare_head() $h = 0; $head = array(); - + $head[$h][0] = DOL_URL_ROOT."/blockedlog/admin/blockedlog.php"; - $head[$h][1] = $langs->trans("BlockedLog"); + $head[$h][1] = $langs->trans("Setup"); $head[$h][2] = 'blockedlog'; $h++; - + $head[$h][0] = DOL_URL_ROOT."/blockedlog/admin/fingerprints.php"; $head[$h][1] = $langs->trans("Fingerprints"); $head[$h][2] = 'fingerprints'; $h++; - + $object=new stdClass(); // Show more tabs from modules diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index ce16d6b9931..223acb91fb3 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -4247,37 +4247,6 @@ else if ($id > 0 || ! empty($ref)) $delallowed = $user->rights->facture->supprimer; print $formfile->showdocuments('facture', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->modelpdf, 1, 0, 0, 28, 0, '', '', '', $soc->default_lang); - - if(!empty($conf->blockedlog->enabled) && $object->statut>0) { - ?> - - numoffiles; // Show links to link elements diff --git a/htdocs/core/modules/modBlockedLog.class.php b/htdocs/core/modules/modBlockedLog.class.php index b149471cd20..f3f3be971b5 100644 --- a/htdocs/core/modules/modBlockedLog.class.php +++ b/htdocs/core/modules/modBlockedLog.class.php @@ -43,15 +43,15 @@ class modBlockedLog extends DolibarrModules // Family can be 'crm','financial','hr','projects','products','ecm','technic','other' // It is used to group modules in module setup page - $this->family = "technic"; + $this->family = "base"; // Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module) $this->name = preg_replace('/^mod/i','',get_class($this)); - $this->description = "Enable a log on some business events into a reserved log. This module may be mandatory for some countries."; + $this->description = "Enable a log on some business events into a non reversible log. This module may be mandatory for some countries."; $this->version = 'development'; // 'development', 'experimental' or 'dolibarr' or version // Key used in llx_const table to save module status enabled/disabled (where MYMODULE is value of property name of module in uppercase) $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name); // Where to store the module in setup page (0=common,1=interface,2=others,3=very specific) - $this->special = 1; + $this->special = 2; // Name of image file used for this module. $this->picto='technic'; diff --git a/htdocs/core/triggers/interface_50_modBlockedlog_ActionsBlockedLog.class.php b/htdocs/core/triggers/interface_50_modBlockedlog_ActionsBlockedLog.class.php index 004c4eecd78..6759d18ba5d 100644 --- a/htdocs/core/triggers/interface_50_modBlockedlog_ActionsBlockedLog.class.php +++ b/htdocs/core/triggers/interface_50_modBlockedlog_ActionsBlockedLog.class.php @@ -50,9 +50,9 @@ class InterfaceActionsBlockedLog extends DolibarrTriggers if (empty($conf->blockedlog->enabled)) { return 0; } - - if($action==='BILL_VALIDATE' || $action === 'BILL_PAYED' || $action==='BILL_UNPAYED' - || $action === 'BILL_SENTBYMAIL' || $action === 'DOWNLOAD_BILL' || $action === 'PREVIEW_BILL') { + + if($action==='BILL_VALIDATE' || $action === 'BILL_PAYED' || $action==='BILL_UNPAYED' + || $action === 'BILL_SENTBYMAIL' || $action === 'DOC_DOWNLOAD' || $action === 'DOC_PREVIEW') { $amounts= (double) $object->total_ttc; } else if($action === 'PAYMENT_CUSTOMER_CREATE' || $action === 'PAYMENT_ADD_TO_BANK') { @@ -62,8 +62,8 @@ class InterfaceActionsBlockedLog extends DolibarrTriggers $amounts+= price2num($amount); } } - - + + } else if(strpos($action,'PAYMENT')!==false) { $amounts= (double) $object->amount; @@ -71,25 +71,25 @@ class InterfaceActionsBlockedLog extends DolibarrTriggers else { return 0; // not implemented action log } - + $b=new BlockedLog($this->db); $b->action = $action; $b->amounts= $amounts; $b->setObjectData($object); - + $res = $b->create($user); - + if($res<0) { setEventMessage($b->error,'errors'); - + return -1; } else { - + return 1; } - - + + } } diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 695373e22b5..1aa79c2dced 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -467,7 +467,7 @@ Module30Desc=Invoice and credit note management for customers. Invoice managemen Module40Name=Suppliers Module40Desc=Supplier management and buying (orders and invoices) Module42Name=Logs -Module42Desc=Logging facilities (file, syslog, ...) +Module42Desc=Logging facilities (file, syslog, ...). Such logs are for technical/debug purposes. For legal purpose, see instead module 'Non Reversible Logs'. Module49Name=Editors Module49Desc=Editor management Module50Name=Products @@ -565,6 +565,8 @@ Module2900Name=GeoIPMaxmind Module2900Desc=GeoIP Maxmind conversions capabilities Module3100Name=Skype Module3100Desc=Add a Skype button into users / third parties / contacts / members cards +Module3200Name=Non Reversible Logs +Module3200Desc=Activate log of some business events into a non reversible log. Events are archived in real-time. The log is a table that can be then exported. This module may be mandatory for some countries. Module4000Name=HRM Module4000Desc=Human resources management (mangement of department, employee contracts and feelings) Module5000Name=Multi-company diff --git a/htdocs/langs/en_US/blockedlog.lang b/htdocs/langs/en_US/blockedlog.lang index fcad52508bd..7129b65257d 100644 --- a/htdocs/langs/en_US/blockedlog.lang +++ b/htdocs/langs/en_US/blockedlog.lang @@ -1,12 +1,14 @@ +BlockedLog=Non Reversible Logs Field=Field -BlockedLogDesc=This module store event for invoice and payments as block chain -FingerprintsDesc=All fingerprints stored -EntityKey=Entity Key -ShowAllFingerPrintsMightBeTooLong=Show all fingerprints (might be long) -ShowAllFingerPrintsErrorsMightBeTooLong=Show all fingerprints with error (might be long) +BlockedLogDesc=This module store event for invoice and payments into a block chain +Fingerprints=Archived events and fingerprints +FingerprintsDesc=Archived business events and fingerprints +CompanyInitialKey=Company initial key +ShowAllFingerPrintsMightBeTooLong=Show all archived logs (might be long) +ShowAllFingerPrintsErrorsMightBeTooLong=Show all archive logs with error (might be long) DownloadBlockChain=Download fingerprints -KoCheckFingerprintValidity=Fingerprint is not valid -OkCheckFingerprintValidity=Fingerprint is valid +KoCheckFingerprintValidity=Archived log is not valid. It means someone (a hacker ?) has modified some datas of this archived log after it was recorded, or has erased the previous archived record (check that line with previous # exists). +OkCheckFingerprintValidity=Archived log is valid. It means all data on this line were not modified and record follow the previous one. AddedByAuthority=Stored into remote authority NotAddedByAuthorityYet=Not yet stored into remote authority ShowDetails=Show stored details @@ -18,6 +20,7 @@ logBILL_VALIDATE=Customer bill set valid from draft logBILL_SENTBYMAIL=Customer bill send by mail BlockedlogInfoDialog=Log Details Fingerprint=Fingerprint -DownloadLogCSV=Download fingerprints CSV -logPREVIEW_BILL=Preview of a validated customer bill in order to print or download -logDOWNLOAD_BILL=Download of a validated customer bill in order to print or send \ No newline at end of file +DownloadLogCSV=Download archive logs (CSV) +logDOC_PREVIEW=Preview of a validated document in order to print or download +logDOC_DOWNLOAD=Download of a validated document in order to print or send +DataOfArchivedEvent=Full datas of archived event \ No newline at end of file diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 6b75b957590..33b155bb64c 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -1891,7 +1891,7 @@ if (! function_exists("llxFooter")) */ function llxFooter($comment='',$zone='private') { - global $conf, $langs, $user; + global $conf, $langs, $user, $object; global $delayedhtmlcontent; // Global html output events ($mesgs, $errors, $warnings) @@ -2026,6 +2026,40 @@ if (! function_exists("llxFooter")) '; } + // Wrapper to add log when clicking on download or preview + if (! empty($conf->blockedlog->enabled) && is_object($object) && $object->id > 0 && $object->statut > 0) + { + if (in_array($object->element, array('facture'))) // Restrict for the moment to element 'facture' + { + print "\n\n"; + ?> + + \n"; print ''."\n";