Fix several security bugs on expense report

This commit is contained in:
Laurent Destailleur 2017-01-26 18:08:00 +01:00
parent 9889f0a4a2
commit c1b59b1950
8 changed files with 128 additions and 105 deletions

View File

@ -1372,7 +1372,7 @@ class Form
* @param int $show_empty 0=list with no empty value, 1=add also an empty value into list * @param int $show_empty 0=list with no empty value, 1=add also an empty value into list
* @param array $exclude Array list of users id to exclude * @param array $exclude Array list of users id to exclude
* @param int $disabled If select list must be disabled * @param int $disabled If select list must be disabled
* @param array $include Array list of users id to include or 'hierarchy' to have only supervised users * @param array|string $include Array list of users id to include or 'hierarchy' to have only supervised users or 'hierarchyme' to have supervised + me
* @param array $enableonly Array list of users id to be enabled. All other must be disabled * @param array $enableonly Array list of users id to be enabled. All other must be disabled
* @param int $force_entity 0 or Id of environment to force * @param int $force_entity 0 or Id of environment to force
* @param int $maxlength Maximum length of string into list (0=no limit) * @param int $maxlength Maximum length of string into list (0=no limit)
@ -1396,22 +1396,18 @@ class Form
$includeUsers=null; $includeUsers=null;
// Permettre l'exclusion d'utilisateurs // Permettre l'exclusion d'utilisateurs
if (is_array($exclude)) $excludeUsers = implode("','",$exclude); if (is_array($exclude)) $excludeUsers = implode(",",$exclude);
// Permettre l'inclusion d'utilisateurs // Permettre l'inclusion d'utilisateurs
if (is_array($include)) $includeUsers = implode("','",$include); if (is_array($include)) $includeUsers = implode(",",$include);
else if ($include == 'hierarchy') else if ($include == 'hierarchy')
{ {
// Build list includeUsers to have only hierarchy // Build list includeUsers to have only hierarchy
$userid=$user->id; $includeUsers = implode(",",$user->getAllChildIds(0));
$include=array(); }
if (empty($user->users) || ! is_array($user->users)) $user->get_full_tree(); else if ($include == 'hierarchyme')
foreach($user->users as $key => $val) {
{ // Build list includeUsers to have only hierarchy and current user
if (preg_match('/_'.$userid.'/',$val['fullpath'])) $include[]=$val['id']; $includeUsers = implode(",",$user->getAllChildIds(1));
}
$includeUsers = implode("','",$include);
//var_dump($includeUsers);exit;
//var_dump($user->users);exit;
} }
$out=''; $out='';
@ -1443,8 +1439,8 @@ class Form
} }
} }
if (! empty($user->societe_id)) $sql.= " AND u.fk_soc = ".$user->societe_id; if (! empty($user->societe_id)) $sql.= " AND u.fk_soc = ".$user->societe_id;
if (is_array($exclude) && $excludeUsers) $sql.= " AND u.rowid NOT IN ('".$excludeUsers."')"; if (is_array($exclude) && $excludeUsers) $sql.= " AND u.rowid NOT IN (".$excludeUsers.")";
if (is_array($include) && $includeUsers) $sql.= " AND u.rowid IN ('".$includeUsers."')"; if ($includeUsers) $sql.= " AND u.rowid IN (".$includeUsers.")";
if (! empty($conf->global->USER_HIDE_INACTIVE_IN_COMBOBOX) || $noactive) $sql.= " AND u.statut <> 0"; if (! empty($conf->global->USER_HIDE_INACTIVE_IN_COMBOBOX) || $noactive) $sql.= " AND u.statut <> 0";
if (! empty($morefilter)) $sql.=" ".$morefilter; if (! empty($morefilter)) $sql.=" ".$morefilter;
$sql.= " ORDER BY u.lastname ASC"; $sql.= " ORDER BY u.lastname ASC";

View File

@ -111,53 +111,61 @@ class modExpenseReport extends DolibarrModules
$this->rights = array(); // Permission array used by this module $this->rights = array(); // Permission array used by this module
$this->rights_class = 'expensereport'; $this->rights_class = 'expensereport';
$this->rights[1][0] = 771; $this->rights[$r][0] = 771;
$this->rights[1][1] = 'Read expense reports (yours and your subordinates)'; $this->rights[$r][1] = 'Read expense reports (yours and your subordinates)';
$this->rights[1][2] = 'r'; $this->rights[$r][2] = 'r';
$this->rights[1][3] = 0; $this->rights[$r][3] = 0;
$this->rights[1][4] = 'lire'; $this->rights[$r][4] = 'lire';
$r++;
$this->rights[3][0] = 772; $this->rights[$r][0] = 772;
$this->rights[3][1] = 'Create/modify expense reports'; $this->rights[$r][1] = 'Create/modify expense reports';
$this->rights[3][2] = 'w'; $this->rights[$r][2] = 'w';
$this->rights[3][3] = 0; $this->rights[$r][3] = 0;
$this->rights[3][4] = 'creer'; $this->rights[$r][4] = 'creer';
$r++;
$this->rights[4][0] = 773; $this->rights[$r][0] = 773;
$this->rights[4][1] = 'Delete expense reports'; $this->rights[$r][1] = 'Delete expense reports';
$this->rights[4][2] = 'd'; $this->rights[$r][2] = 'd';
$this->rights[4][3] = 0; $this->rights[$r][3] = 0;
$this->rights[4][4] = 'supprimer'; $this->rights[$r][4] = 'supprimer';
$r++;
$this->rights[6][0] = 775; $this->rights[$r][0] = 775;
$this->rights[6][1] = 'Approve expense reports'; $this->rights[$r][1] = 'Approve expense reports';
$this->rights[6][2] = 'w'; $this->rights[$r][2] = 'w';
$this->rights[6][3] = 0; $this->rights[$r][3] = 0;
$this->rights[6][4] = 'approve'; $this->rights[$r][4] = 'approve';
$r++;
$this->rights[7][0] = 776; $this->rights[$r][0] = 776;
$this->rights[7][1] = 'Pay expense reports'; $this->rights[$r][1] = 'Pay expense reports';
$this->rights[7][2] = 'w'; $this->rights[$r][2] = 'w';
$this->rights[7][3] = 0; $this->rights[$r][3] = 0;
$this->rights[7][4] = 'to_paid'; $this->rights[$r][4] = 'to_paid';
$r++;
$this->rights[2][0] = 777; $this->rights[$r][0] = 777;
$this->rights[2][1] = 'Read expense reports of everybody'; $this->rights[$r][1] = 'Read expense reports of everybody';
$this->rights[2][2] = 'r'; $this->rights[$r][2] = 'r';
$this->rights[2][3] = 1; $this->rights[$r][3] = 1;
$this->rights[2][4] = 'readall'; $this->rights[$r][4] = 'readall';
$r++;
$this->rights[2][0] = 778; $this->rights[$r][0] = 778;
$this->rights[2][1] = 'Create expense reports for everybody'; $this->rights[$r][1] = 'Create expense reports for everybody';
$this->rights[2][2] = 'w'; $this->rights[$r][2] = 'w';
$this->rights[2][3] = 0; $this->rights[$r][3] = 0;
$this->rights[2][4] = 'writeall_advance'; $this->rights[$r][4] = 'writeall_advance';
$r++;
$this->rights[5][0] = 779; $this->rights[$r][0] = 779;
$this->rights[5][1] = 'Export expense reports'; $this->rights[$r][1] = 'Export expense reports';
$this->rights[5][2] = 'r'; $this->rights[$r][2] = 'r';
$this->rights[5][3] = 0; $this->rights[$r][3] = 0;
$this->rights[5][4] = 'export'; $this->rights[$r][4] = 'export';
$r++;
// Menus // Menus
//------- //-------

View File

@ -1,6 +1,6 @@
<?php <?php
/* Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org> /* Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org>
* Copyright (C) 2004-2015 Laurent Destailleur <eldy@users.sourceforge.net> * Copyright (C) 2004-2017 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2005-2009 Regis Houssin <regis@dolibarr.fr> * Copyright (C) 2005-2009 Regis Houssin <regis@dolibarr.fr>
* Copyright (C) 2015-2016 Alexandre Spangaro <aspangaro.dolibarr@gmail.com> * Copyright (C) 2015-2016 Alexandre Spangaro <aspangaro.dolibarr@gmail.com>
* *
@ -1228,8 +1228,8 @@ if ($action == 'create')
print '<td>'; print '<td>';
$defaultselectuser=$user->id; $defaultselectuser=$user->id;
if (GETPOST('fk_user_author') > 0) $defaultselectuser=GETPOST('fk_user_author'); if (GETPOST('fk_user_author') > 0) $defaultselectuser=GETPOST('fk_user_author');
$include_users = array($user->id); $include_users = 'hierarchyme';
if (! empty($user->rights->expensereport->writeall)) $include_users=array(); if (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->expensereport->writeall_advance)) $include_users=array();
$s=$form->select_dolusers($defaultselectuser, "fk_user_author", 0, "", 0, $include_users); $s=$form->select_dolusers($defaultselectuser, "fk_user_author", 0, "", 0, $include_users);
print $s; print $s;
print '</td>'; print '</td>';
@ -1313,10 +1313,10 @@ else
if ($result > 0) if ($result > 0)
{ {
if ($object->fk_user_author != $user->id) if (! in_array($object->fk_user_author, $user->getAllChildIds(1)))
{ {
if (empty($user->rights->expensereport->readall) && empty($user->rights->expensereport->lire_tous) if (empty($user->rights->expensereport->readall) && empty($user->rights->expensereport->lire_tous)
&& empty($user->rights->expensereport->writeall_advance)) && (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || empty($user->rights->expensereport->writeall_advance)))
{ {
print load_fiche_titre($langs->trans('TripCard')); print load_fiche_titre($langs->trans('TripCard'));
@ -2090,7 +2090,7 @@ if ($action != 'create' && $action != 'edit')
*/ */
if ($user->rights->expensereport->creer && $object->fk_statut==0) if ($user->rights->expensereport->creer && $object->fk_statut==0)
{ {
if ($object->fk_user_author == $user->id) if (in_array($object->fk_user_author, $user->getAllChildIds(1)))
{ {
// Modify // Modify
print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=edit&id='.$object->id.'">'.$langs->trans('Modify').'</a></div>'; print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=edit&id='.$object->id.'">'.$langs->trans('Modify').'</a></div>';
@ -2138,7 +2138,7 @@ if ($action != 'create' && $action != 'edit')
*/ */
if ($object->fk_statut == 2) if ($object->fk_statut == 2)
{ {
if ($object->fk_user_author == $user->id) if (in_array($object->fk_user_author, $user->getAllChildIds(1)))
{ {
// Brouillonner // Brouillonner
print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=brouillonner&id='.$object->id.'">'.$langs->trans('SetToDraft').'</a></div>'; print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=brouillonner&id='.$object->id.'">'.$langs->trans('SetToDraft').'</a></div>';

View File

@ -1674,11 +1674,14 @@ class ExpenseReport extends CommonObject
$now=dol_now(); $now=dol_now();
$userchildids = $user->getAllChildIds(1);
$sql = "SELECT ex.rowid, ex.date_valid"; $sql = "SELECT ex.rowid, ex.date_valid";
$sql.= " FROM ".MAIN_DB_PREFIX."expensereport as ex"; $sql.= " FROM ".MAIN_DB_PREFIX."expensereport as ex";
if ($option == 'toapprove') $sql.= " WHERE ex.fk_statut = 2"; if ($option == 'toapprove') $sql.= " WHERE ex.fk_statut = 2";
else $sql.= " WHERE ex.fk_statut = 5"; else $sql.= " WHERE ex.fk_statut = 5";
$sql.= " AND ex.entity IN (".getEntity('expensereport', 1).")"; $sql.= " AND ex.entity IN (".getEntity('expensereport', 1).")";
$sql.= " AND ex.fk_user_author IN (".join(',',$userchildids).")";
$resql=$this->db->query($sql); $resql=$this->db->query($sql);
if ($resql) if ($resql)

View File

@ -240,7 +240,7 @@ if ($search_status != '' && $search_status >= 0)
} }
// RESTRICT RIGHTS // RESTRICT RIGHTS
if (empty($user->rights->expensereport->readall) && empty($user->rights->expensereport->lire_tous) if (empty($user->rights->expensereport->readall) && empty($user->rights->expensereport->lire_tous)
&& empty($user->rights->expensereport->writeall_advance)) && (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || empty($user->rights->expensereport->writeall_advance)))
{ {
$childids = $user->getAllChildIds(); $childids = $user->getAllChildIds();
$childids[]=$user->id; $childids[]=$user->id;

View File

@ -178,8 +178,8 @@ if (empty($user->societe_id))
! empty($conf->supplier_order->enabled) && $user->rights->fournisseur->commande->lire && empty($conf->global->SOCIETE_DISABLE_SUPPLIERS_ORDERS_STATS), ! empty($conf->supplier_order->enabled) && $user->rights->fournisseur->commande->lire && empty($conf->global->SOCIETE_DISABLE_SUPPLIERS_ORDERS_STATS),
! empty($conf->supplier_invoice->enabled) && $user->rights->fournisseur->facture->lire && empty($conf->global->SOCIETE_DISABLE_SUPPLIERS_INVOICES_STATS), ! empty($conf->supplier_invoice->enabled) && $user->rights->fournisseur->facture->lire && empty($conf->global->SOCIETE_DISABLE_SUPPLIERS_INVOICES_STATS),
! empty($conf->supplier_proposal->enabled) && $user->rights->supplier_proposal->lire && empty($conf->global->SOCIETE_DISABLE_SUPPLIERS_PROPOSAL_STATS), ! empty($conf->supplier_proposal->enabled) && $user->rights->supplier_proposal->lire && empty($conf->global->SOCIETE_DISABLE_SUPPLIERS_PROPOSAL_STATS),
! empty($conf->expensereport->enabled) && $user->rights->expensereport->lire, ! empty($conf->projet->enabled) && $user->rights->projet->lire,
! empty($conf->projet->enabled) && $user->rights->projet->lire ! empty($conf->expensereport->enabled) && $user->rights->expensereport->lire
); );
// Class file containing the method load_state_board for each line // Class file containing the method load_state_board for each line
$includes=array( $includes=array(
@ -199,8 +199,8 @@ if (empty($user->societe_id))
DOL_DOCUMENT_ROOT."/fourn/class/fournisseur.commande.class.php", DOL_DOCUMENT_ROOT."/fourn/class/fournisseur.commande.class.php",
DOL_DOCUMENT_ROOT."/fourn/class/fournisseur.facture.class.php", DOL_DOCUMENT_ROOT."/fourn/class/fournisseur.facture.class.php",
DOL_DOCUMENT_ROOT."/supplier_proposal/class/supplier_proposal.class.php", DOL_DOCUMENT_ROOT."/supplier_proposal/class/supplier_proposal.class.php",
DOL_DOCUMENT_ROOT."/expensereport/class/expensereport.class.php", DOL_DOCUMENT_ROOT."/projet/class/project.class.php",
DOL_DOCUMENT_ROOT."/projet/class/project.class.php" DOL_DOCUMENT_ROOT."/expensereport/class/expensereport.class.php"
); );
// Name class containing the method load_state_board for each line // Name class containing the method load_state_board for each line
$classes=array('User', $classes=array('User',
@ -219,8 +219,8 @@ if (empty($user->societe_id))
'CommandeFournisseur', 'CommandeFournisseur',
'FactureFournisseur', 'FactureFournisseur',
'SupplierProposal', 'SupplierProposal',
'ExpenseReport', 'Project',
'Project' 'ExpenseReport'
); );
// Cle array returned by the method load_state_board for each line // Cle array returned by the method load_state_board for each line
$keys=array('users', $keys=array('users',
@ -239,8 +239,8 @@ if (empty($user->societe_id))
'supplier_orders', 'supplier_orders',
'supplier_invoices', 'supplier_invoices',
'askprice', 'askprice',
'expensereports', 'projects',
'projects' 'expensereports'
); );
// Dashboard Icon lines // Dashboard Icon lines
$icons=array('user', $icons=array('user',
@ -259,8 +259,8 @@ if (empty($user->societe_id))
'order', 'order',
'bill', 'bill',
'propal', 'propal',
'trip', 'project',
'project' 'trip'
); );
// Translation keyword // Translation keyword
$titres=array("Users", $titres=array("Users",
@ -279,8 +279,8 @@ if (empty($user->societe_id))
"SuppliersOrders", "SuppliersOrders",
"SuppliersInvoices", "SuppliersInvoices",
"SupplierProposalShort", "SupplierProposalShort",
"ExpenseReports", "Projects",
"Projects" "ExpenseReports"
); );
// Dashboard Link lines // Dashboard Link lines
$links=array( $links=array(
@ -300,8 +300,8 @@ if (empty($user->societe_id))
DOL_URL_ROOT.'/fourn/commande/list.php', DOL_URL_ROOT.'/fourn/commande/list.php',
DOL_URL_ROOT.'/fourn/facture/list.php', DOL_URL_ROOT.'/fourn/facture/list.php',
DOL_URL_ROOT.'/supplier_proposal/list.php', DOL_URL_ROOT.'/supplier_proposal/list.php',
DOL_URL_ROOT.'/expensereport/list.php?mainmenu=hrm', DOL_URL_ROOT.'/projet/list.php?mainmenu=project',
DOL_URL_ROOT.'/projet/list.php?mainmenu=project' DOL_URL_ROOT.'/expensereport/list.php?mainmenu=hrm'
); );
// Translation lang files // Translation lang files
$langfile=array("users", $langfile=array("users",
@ -318,8 +318,8 @@ if (empty($user->societe_id))
"supplier_proposal", "supplier_proposal",
"contracts", "contracts",
"interventions", "interventions",
"trips", "projects",
"projects" "trips"
); );

View File

@ -752,9 +752,10 @@ if (($action == 'create') || ($action == 'adduserldap'))
print '</td></tr>'; print '</td></tr>';
// Employee // Employee
$defaultemployee=1;
print '<tr>'; print '<tr>';
print '<td>'.fieldLabel('Employee','employee',0).'</td><td>'; print '<td>'.$langs->trans('Employee').'</td><td>';
print $form->selectyesno("employee",(GETPOST('employee')?GETPOST('employee'):0),1); print $form->selectyesno("employee",(GETPOST('employee')!=''?GETPOST('employee'):$defaultemployee),1);
print '</td></tr>'; print '</td></tr>';
// Position/Job // Position/Job

View File

@ -127,6 +127,9 @@ class User extends CommonObject
public $dateemployment; // Define date of employment by company public $dateemployment; // Define date of employment by company
private $cache_childids;
/** /**
* Constructor de la classe * Constructor de la classe
* *
@ -2600,25 +2603,37 @@ class User extends CommonObject
} }
/** /**
* Return list of all child users id in herarchy (all sublevels). * Return list of all child users id in herarchy of current user (all sublevels).
* *
* @return int $addcurrentuser 1=Add also current user id to the list.
* @return array Array of user id lower than user. This overwrite this->users. * @return array Array of user id lower than user. This overwrite this->users.
* @see get_children * @see get_children
*/ */
function getAllChildIds() function getAllChildIds($addcurrentuser=0)
{ {
// Init this->users $childids=array();
$this->get_full_tree();
$idtoscan=$this->id; if (isset($this->cache_childids[$this->id]))
$childids=array(); {
$childids = $this->cache_childids[$this->id];
}
else
{
// Init this->users
$this->get_full_tree();
dol_syslog("Build childid for id = ".$idtoscan); $idtoscan=$this->id;
foreach($this->users as $id => $val)
{ dol_syslog("Build childid for id = ".$idtoscan);
//var_dump($val['fullpath']); foreach($this->users as $id => $val)
if (preg_match('/_'.$idtoscan.'_/', $val['fullpath'])) $childids[$val['id']]=$val['id']; {
} //var_dump($val['fullpath']);
if (preg_match('/_'.$idtoscan.'_/', $val['fullpath'])) $childids[$val['id']]=$val['id'];
}
}
$this->cache_childids[$this->id] = $childids;
if ($addcurrentuser) $childids[$this->id]=$this->id;
return $childids; return $childids;
} }