diff --git a/htdocs/compta/paiement/card.php b/htdocs/compta/paiement/card.php
index 374ab19e358..a7fd5476d7f 100644
--- a/htdocs/compta/paiement/card.php
+++ b/htdocs/compta/paiement/card.php
@@ -43,12 +43,20 @@ $action = GETPOST('action', 'aZ09');
$confirm = GETPOST('confirm', 'alpha');
$backtopage = GETPOST('backtopage', 'alpha');
+$object = new Paiement($db);
+
+// Load object
+include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once.
+
+$result = restrictedArea($user, $object->element, $object->id, 'paiement', '');
+
// Security check
if ($user->socid) $socid = $user->socid;
-// TODO ajouter regle pour restreindre acces paiement
-//$result = restrictedArea($user, 'facture', $id,'');
-
-$object = new Paiement($db);
+// Now check also permission on thirdparty of invoices of payments. Thirdparty were loaded by the fetch_object before based on first invoice.
+// It should be enough because all payments are done on invoices of the same thirdparty.
+if ($socid && $socid != $object->thirdparty->id) {
+ accessforbidden();
+}
/*
@@ -59,7 +67,6 @@ if ($action == 'setnote' && $user->rights->facture->paiement)
{
$db->begin();
- $object->fetch($id);
$result = $object->update_note(GETPOST('note', 'restricthtml'));
if ($result > 0)
{
@@ -75,7 +82,6 @@ if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->facture->
{
$db->begin();
- $object->fetch($id);
$result = $object->delete();
if ($result > 0)
{
@@ -100,7 +106,6 @@ if ($action == 'confirm_validate' && $confirm == 'yes' && $user->rights->facture
{
$db->begin();
- $object->fetch($id);
if ($object->validate($user) > 0)
{
$db->commit();
@@ -134,7 +139,6 @@ if ($action == 'confirm_validate' && $confirm == 'yes' && $user->rights->facture
if ($action == 'setnum_paiement' && !empty($_POST['num_paiement']))
{
- $object->fetch($id);
$res = $object->update_num($_POST['num_paiement']);
if ($res === 0)
{
@@ -146,7 +150,6 @@ if ($action == 'setnum_paiement' && !empty($_POST['num_paiement']))
if ($action == 'setdatep' && !empty($_POST['datepday']))
{
- $object->fetch($id);
$datepaye = dol_mktime(GETPOST('datephour', 'int'), GETPOST('datepmin', 'int'), GETPOST('datepsec', 'int'), GETPOST('datepmonth', 'int'), GETPOST('datepday', 'int'), GETPOST('datepyear', 'int'));
$res = $object->update_date($datepaye);
if ($res === 0)
diff --git a/htdocs/compta/paiement/class/paiement.class.php b/htdocs/compta/paiement/class/paiement.class.php
index e308c61b41e..bf25485dc14 100644
--- a/htdocs/compta/paiement/class/paiement.class.php
+++ b/htdocs/compta/paiement/class/paiement.class.php
@@ -1293,7 +1293,8 @@ class Paiement extends CommonObject
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
/**
- * Load the third party of object, from id into this->thirdparty
+ * Load the third party of object, from id into this->thirdparty.
+ * For payments, take the thirdparty linked to the first invoice found. This is enough because payments are done on invoices of the same thirdparty.
*
* @param int $force_thirdparty_id Force thirdparty id
* @return int <0 if KO, >0 if OK
diff --git a/htdocs/compta/paiement/info.php b/htdocs/compta/paiement/info.php
index 208d74a316f..ace21e40f95 100644
--- a/htdocs/compta/paiement/info.php
+++ b/htdocs/compta/paiement/info.php
@@ -36,6 +36,23 @@ $ref = GETPOST('ref', 'alpha');
$action = GETPOST('action', 'aZ09');
$confirm = GETPOST('confirm', 'alpha');
+$object = new Paiement($db);
+
+// Load object
+include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once.
+
+$result = restrictedArea($user, $object->element, $object->id, 'paiement', '');
+
+// Security check
+if ($user->socid) $socid = $user->socid;
+// Now check also permission on thirdparty of invoices of payments. Thirdparty were loaded by the fetch_object before based on first invoice.
+// It should be enough because all payments are done on invoices of the same thirdparty.
+if ($socid && $socid != $object->thirdparty->id) {
+ accessforbidden();
+}
+
+
+
/*
* Actions
*/
@@ -49,8 +66,6 @@ $confirm = GETPOST('confirm', 'alpha');
llxHeader('', $langs->trans("Payment"));
-$object = new Paiement($db);
-$object->fetch($id, $ref);
$object->info($object->id);
$head = payment_prepare_head($object);
diff --git a/htdocs/compta/paiement/rapport.php b/htdocs/compta/paiement/rapport.php
index 47bb2ad2582..0af202016df 100644
--- a/htdocs/compta/paiement/rapport.php
+++ b/htdocs/compta/paiement/rapport.php
@@ -30,9 +30,6 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
-// Security check
-if (!$user->rights->facture->lire) accessforbidden();
-
$action = GETPOST('action', 'aZ09');
$socid = 0;
@@ -48,6 +45,9 @@ if (!$user->rights->societe->client->voir || $socid) $dir .= '/private/'.$user->
$year = GETPOST('year', 'int');
if (!$year) { $year = date("Y"); }
+// Security check
+if (empty($user->rights->facture->lire)) accessforbidden();
+
/*
* Actions
diff --git a/htdocs/compta/paiement/tovalidate.php b/htdocs/compta/paiement/tovalidate.php
index f6582a4ffb4..4cf14ad8a5c 100644
--- a/htdocs/compta/paiement/tovalidate.php
+++ b/htdocs/compta/paiement/tovalidate.php
@@ -27,10 +27,6 @@ require '../../main.inc.php';
// Load translation files required by the page
$langs->load("bills");
-// Security check
-if (!$user->rights->facture->lire)
- accessforbidden();
-
$socid = 0;
if ($user->socid > 0)
{
@@ -50,6 +46,9 @@ $pagenext = $page + 1;
if (!$sortorder) $sortorder = "DESC";
if (!$sortfield) $sortfield = "p.rowid";
+// Security check
+if (empty($user->rights->facture->lire)) accessforbidden();
+
/*
* Actions
diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php
index 4602e877bd1..9d18dd1dd85 100644
--- a/htdocs/core/lib/security.lib.php
+++ b/htdocs/core/lib/security.lib.php
@@ -165,6 +165,7 @@ function dol_verifyHash($chain, $hash, $type = '0')
/**
* Check permissions of a user to show a page and an object. Check read permission.
* If GETPOST('action','aZ09') defined, we also check write and delete permission.
+ * This method check permission on module then call checkUserAccessToObject() for permission on object (according to entity and socid of user).
*
* @param User $user User to check
* @param string $features Features to check (it must be module $object->element. Examples: 'societe', 'contact', 'produit&service', 'produit|service', ...)
@@ -175,20 +176,22 @@ function dol_verifyHash($chain, $hash, $type = '0')
* @param string $dbt_select Field name for select if not rowid. Not used if objectid is null (optional)
* @param int $isdraft 1=The object with id=$objectid is a draft
* @return int Always 1, die process if not allowed
- * @see dol_check_secure_access_document()
+ * @see dol_check_secure_access_document(), checkUserAccessToObject()
*/
function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $feature2 = '', $dbt_keyfield = 'fk_soc', $dbt_select = 'rowid', $isdraft = 0)
{
global $db, $conf;
global $hookmanager;
- //dol_syslog("functions.lib:restrictedArea $feature, $objectid, $dbtablename,$feature2,$dbt_socfield,$dbt_select");
+ //dol_syslog("functions.lib:restrictedArea $feature, $objectid, $dbtablename, $feature2, $dbt_socfield, $dbt_select, $isdraft");
//print "user_id=".$user->id.", features=".$features.", feature2=".$feature2.", objectid=".$objectid;
//print ", dbtablename=".$dbtablename.", dbt_socfield=".$dbt_keyfield.", dbt_select=".$dbt_select;
//print ", perm: ".$features."->".$feature2."=".($user->rights->$features->$feature2->lire)."
";
$parentfortableentity = '';
+ // Fix syntax of $features param
+ $originalfeatures = $features;
if ($features == 'facturerec') $features = 'facture';
if ($features == 'mo') $features = 'mrp';
if ($features == 'member') $features = 'adherent';
@@ -198,7 +201,7 @@ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $f
if ($features == 'product') $features = 'produit';
// Get more permissions checks from hooks
- $parameters = array('features'=>$features, 'objectid'=>$objectid, 'idtype'=>$dbt_select);
+ $parameters = array('features'=>$features, 'originalfeatures'=>$originalfeatures, 'objectid'=>$objectid, 'dbt_select'=>$dbt_select, 'idtype'=>$dbt_select, 'isdraft'=>$isdraft);
$reshook = $hookmanager->executeHooks('restrictedArea', $parameters);
if (isset($hookmanager->resArray['result'])) {
@@ -218,11 +221,6 @@ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $f
// More subfeatures to check
if (!empty($feature2)) $feature2 = explode("|", $feature2);
- // More parameters
- $params = explode('&', $tableandshare);
- $dbtablename = (!empty($params[0]) ? $params[0] : '');
- $sharedelement = (!empty($params[1]) ? $params[1] : $dbtablename);
-
$listofmodules = explode(',', $conf->global->MAIN_MODULES_FOR_EXTERNAL);
// Check read permission from module
@@ -247,6 +245,10 @@ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $f
if (!$user->rights->banque->cheque) { $readok = 0; $nbko++; }
} elseif ($feature == 'projet') {
if (!$user->rights->projet->lire && !$user->rights->projet->all->lire) { $readok = 0; $nbko++; }
+ } elseif ($feature == 'payment') {
+ if (!$user->rights->facture->lire) { $readok = 0; $nbko++; }
+ } elseif ($feature == 'payment_supplier') {
+ if (!$user->rights->fournisseur->facture->lire) { $readok = 0; $nbko++; }
} elseif (!empty($feature2)) { // This is for permissions on 2 levels
$tmpreadok = 1;
foreach ($feature2 as $subfeature) {
@@ -426,6 +428,10 @@ function checkUserAccessToObject($user, $featuresarray, $objectid = 0, $tableand
{
global $db, $conf;
+ //dol_syslog("functions.lib:restrictedArea $feature, $objectid, $dbtablename, $feature2, $dbt_socfield, $dbt_select, $isdraft");
+ //print "user_id=".$user->id.", features=".join(',', $featuresarray).", feature2=".$feature2.", objectid=".$objectid;
+ //print ", tableandshare=".$tableandshare.", dbt_socfield=".$dbt_keyfield.", dbt_select=".$dbt_select."
";
+
// More parameters
$params = explode('&', $tableandshare);
$dbtablename = (!empty($params[0]) ? $params[0] : '');
@@ -440,13 +446,13 @@ function checkUserAccessToObject($user, $featuresarray, $objectid = 0, $tableand
if ($feature == 'project') $feature = 'projet';
if ($feature == 'task') $feature = 'projet_task';
- $check = array('adherent', 'banque', 'bom', 'don', 'mrp', 'user', 'usergroup', 'product', 'produit', 'service', 'produit|service', 'categorie', 'resource', 'expensereport', 'holiday', 'website'); // Test on entity only (Objects with no link to company)
+ $check = array('adherent', 'banque', 'bom', 'don', 'mrp', 'user', 'usergroup', 'payment', 'payment_supplier', 'product', 'produit', 'service', 'produit|service', 'categorie', 'resource', 'expensereport', 'holiday', 'website'); // Test on entity only (Objects with no link to company)
$checksoc = array('societe'); // Test for societe object
- $checkother = array('contact', 'agenda'); // Test on entity and link to third party. Allowed if link is empty (Ex: contacts...).
+ $checkother = array('contact', 'agenda'); // Test on entity + link to third party on field $dbt_keyfield. Allowed if link is empty (Ex: contacts...).
$checkproject = array('projet', 'project'); // Test for project object
$checktask = array('projet_task'); // Test for task object
$nocheck = array('barcode', 'stock'); // No test
- //$checkdefault = 'all other not already defined'; // Test on entity and link to third party. Not allowed if link is empty (Ex: invoice, orders...).
+ //$checkdefault = 'all other not already defined'; // Test on entity + link to third party on field $dbt_keyfield. Not allowed if link is empty (Ex: invoice, orders...).
// If dbtablename not defined, we use same name for table than module name
if (empty($dbtablename))
@@ -455,17 +461,14 @@ function checkUserAccessToObject($user, $featuresarray, $objectid = 0, $tableand
$sharedelement = (!empty($params[1]) ? $params[1] : $dbtablename); // We change dbtablename, so we set sharedelement too.
}
- // Check permission for object with entity
+ // Check permission for object on entity only
if (in_array($feature, $check))
{
$sql = "SELECT COUNT(dbt.".$dbt_select.") as nb";
$sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt";
- if (($feature == 'user' || $feature == 'usergroup') && !empty($conf->multicompany->enabled))
- {
- if (!empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE))
- {
- if ($conf->entity == 1 && $user->admin && !$user->entity)
- {
+ if (($feature == 'user' || $feature == 'usergroup') && !empty($conf->multicompany->enabled)) { // Special for multicompany
+ if (!empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
+ if ($conf->entity == 1 && $user->admin && !$user->entity) {
$sql .= " WHERE dbt.".$dbt_select." IN (".$objectid.")";
$sql .= " AND dbt.entity IS NOT NULL";
} else {
@@ -490,15 +493,12 @@ function checkUserAccessToObject($user, $featuresarray, $objectid = 0, $tableand
$sql .= " AND dbt.entity IN (".getEntity($sharedelement, 1).")";
}
}
- } elseif (in_array($feature, $checksoc)) // We check feature = checksoc
- {
- // If external user: Check permission for external users
- if ($user->socid > 0)
- {
+ } elseif (in_array($feature, $checksoc)) { // We check feature = checksoc
+ if ($user->socid > 0) {
+ // If external user: Check permission for external users
if ($user->socid <> $objectid) return false;
- } // If internal user: Check permission for internal users that are restricted on their objects
- elseif (!empty($conf->societe->enabled) && ($user->rights->societe->lire && !$user->rights->societe->client->voir))
- {
+ } elseif (!empty($conf->societe->enabled) && ($user->rights->societe->lire && !$user->rights->societe->client->voir)) {
+ // If internal user: Check permission for internal users that are restricted on their objects
$sql = "SELECT COUNT(sc.fk_soc) as nb";
$sql .= " FROM (".MAIN_DB_PREFIX."societe_commerciaux as sc";
$sql .= ", ".MAIN_DB_PREFIX."societe as s)";
@@ -506,15 +506,14 @@ function checkUserAccessToObject($user, $featuresarray, $objectid = 0, $tableand
$sql .= " AND sc.fk_user = ".$user->id;
$sql .= " AND sc.fk_soc = s.rowid";
$sql .= " AND s.entity IN (".getEntity($sharedelement, 1).")";
- } // If multicompany and internal users with all permissions, check user is in correct entity
- elseif (!empty($conf->multicompany->enabled))
- {
+ } elseif (!empty($conf->multicompany->enabled)) {
+ // If multicompany and internal users with all permissions, check user is in correct entity
$sql = "SELECT COUNT(s.rowid) as nb";
$sql .= " FROM ".MAIN_DB_PREFIX."societe as s";
$sql .= " WHERE s.rowid IN (".$objectid.")";
$sql .= " AND s.entity IN (".getEntity($sharedelement, 1).")";
}
- } elseif (in_array($feature, $checkother)) // Test on entity and link to societe. Allowed if link is empty (Ex: contacts...).
+ } elseif (in_array($feature, $checkother)) // Test on entity + link to thirdparty. Allowed if link is empty (Ex: contacts...).
{
// If external user: Check permission for external users
if ($user->socid > 0)
diff --git a/htdocs/fourn/paiement/card.php b/htdocs/fourn/paiement/card.php
index 355b84796f2..a69b450fa84 100644
--- a/htdocs/fourn/paiement/card.php
+++ b/htdocs/fourn/paiement/card.php
@@ -40,10 +40,19 @@ $confirm = GETPOST('confirm', 'alpha');
$object = new PaiementFourn($db);
-// PDF
-$hidedetails = (GETPOST('hidedetails', 'int') ? GETPOST('hidedetails', 'int') : (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 1 : 0));
-$hidedesc = (GETPOST('hidedesc', 'int') ? GETPOST('hidedesc', 'int') : (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC) ? 1 : 0));
-$hideref = (GETPOST('hideref', 'int') ? GETPOST('hideref', 'int') : (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_REF) ? 1 : 0));
+// Load object
+include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once.
+
+$result = restrictedArea($user, $object->element, $object->id, 'paiementfourn', '');
+
+// Security check
+if ($user->socid) $socid = $user->socid;
+// Now check also permission on thirdparty of invoices of payments. Thirdparty were loaded by the fetch_object before based on first invoice.
+// It should be enough because all payments are done on invoices of the same thirdparty.
+if ($socid && $socid != $object->thirdparty->id) {
+ accessforbidden();
+}
+
/*
* Actions
@@ -177,41 +186,46 @@ if ($result > 0)
print '
| '.$langs->trans('Ref').' | '; + print ' | '.$langs->trans('Ref').' | '; print $form->showrefnav($object,'id','',1,'rowid','ref'); print ' | |||
| '.$form->editfieldkey("Date", 'datep', $object->date, $object, $object->statut == 0 && $user->rights->fournisseur->facture->creer).' | '; + print ' | |||||
| '.$form->editfieldkey("Date", 'datep', $object->date, $object, $object->statut == 0 && $user->rights->fournisseur->facture->creer).' | '; + print ''; print $form->editfieldval("Date", 'datep', $object->date, $object, $object->statut == 0 && $user->rights->fournisseur->facture->creer, 'datehourpicker', '', null, $langs->trans('PaymentDateUpdateSucceeded')); print ' | |||||
| '.$langs->trans('PaymentMode').' | '.$labeltype; + print ' | |||||
| '.$langs->trans('PaymentMode').' | '; + print ''.$labeltype; print $object->num_payment ? ' - '.$object->num_payment : ''; print ' | |||||
| '.$form->editfieldkey("Numero",'num_paiement',$object->num_paiement,$object,$object->statut == 0 && $user->rights->fournisseur->facture->creer).' | '; + print ' | |||||
| '.$form->editfieldkey("Numero",'num_paiement',$object->num_paiement,$object,$object->statut == 0 && $user->rights->fournisseur->facture->creer).' | '; + print ''; print $form->editfieldval("Numero",'num_paiement',$object->num_paiement,$object,$object->statut == 0 && $user->rights->fournisseur->facture->creer,'string','',null,$langs->trans('PaymentNumberUpdateSucceeded')); print ' | |||||
| '.$langs->trans('Amount').' | '.price($object->amount, '', $langs, 0, 0, -1, $conf->currency).' | |||||
| '.$langs->trans('Amount').' | '; + print ''.price($object->amount, '', $langs, 0, 0, -1, $conf->currency).' | |||||
| '.$langs->trans('Status').' | '.$object->getLibStatut(4).' | |||||
| '.$langs->trans('Status').' | '; + print ''.$object->getLibStatut(4).' | |||||
| '.$langs->trans('BankAccount').' | '; - print ''; + print ' | '.$langs->trans('BankAccount').' | '; + print ''; $accountstatic = new Account($db); $accountstatic->fetch($bankline->fk_account); print $accountstatic->getNomUrl(1); @@ -231,8 +245,8 @@ if ($result > 0) print ' | |||
| '.$langs->trans('BankTransactionLine').' | '; - print ''; + print ' | '.$langs->trans('BankTransactionLine').' | '; + print ''; print $bankline->getNomUrl(1, 0, 'showconciliated'); print ' | '; print '|||
| '.$form->editfieldkey("Note", 'note', $object->note, $object, $user->rights->fournisseur->facture->creer).' | '; + print ' | |||||
| '.$form->editfieldkey("Comments", 'note', $object->note, $object, $user->rights->fournisseur->facture->creer).' | '; + print ''; print $form->editfieldval("Note", 'note', $object->note, $object, $user->rights->fournisseur->facture->creer, 'textarea'); print ' | |||||