Merge branch '14.0' of git@github.com:Dolibarr/dolibarr.git into develop

This commit is contained in:
Laurent Destailleur 2021-07-05 17:04:38 +02:00
commit fe5c4f4a0e
9 changed files with 77 additions and 44 deletions

View File

@ -778,12 +778,16 @@ function checkVal($out = '', $check = 'alphanohtml', $filter = null, $options =
do {
$oldstringtoclean = $out;
// Ckeditor use the numeric entitic for apostrophe so we force it to text entity (all other special chars are correctly
// encoded using text entities). This is a fix for CKeditor (CKeditor still encode in HTML4 instead of HTML5).
$out = preg_replace('/'/i', ''', $out);
// We replace chars from a/A to z/Z encoded with numeric HTML entities with the real char so we won't loose the chars at the next step.
// No need to use a loop here, this step is not to sanitize (this is done at next step, this is to try to save chars, even if they are
// using a non coventionnel way to be encoded, to not have them sanitized just after)
$out = preg_replace_callback('/&#(x?[0-9][0-9a-f]+;?)/i', 'realCharForNumericEntities', $out);
// Now we remove all remaining HTML entities staring with a number. We don't want such entities.
// Now we remove all remaining HTML entities starting with a number. We don't want such entities.
$out = preg_replace('/&#x?[0-9]+/i', '', $out); // For example if we have j&#x61vascript with an entities without the ; to hide the 'a' of 'javascript'.
$out = dol_string_onlythesehtmltags($out, 0, 1, 1);

View File

@ -29,7 +29,7 @@
*
* @param string $usertotest Login
* @param string $passwordtotest Password
* @param int $entitytotest Number of instance (always 1 if module multicompany not enabled)
* @param int $entitytotest Numero of instance (always 1 if module multicompany not enabled)
* @return string Login if OK, '' if KO
*/
function check_user_password_ldap($usertotest, $passwordtotest, $entitytotest)
@ -151,10 +151,13 @@ function check_user_password_ldap($usertotest, $passwordtotest, $entitytotest)
if ($result > 0) {
if ($result == 2) { // Connection is ok for user/pass into LDAP
$login = $usertotest;
if (!empty($conf->global->LDAP_FIELD_LOGIN)) {
$login = $ldap->login;
}
dol_syslog("functions_ldap::check_user_password_ldap $login authentication ok");
// For the case, we search the user id using a search key without the login (but using other fields like id),
// we need to get the real login to use in the ldap answer.
if (!empty($conf->global->LDAP_FIELD_LOGIN) && !empty($ldap->login)) {
$login = $ldap->login;
dol_syslog("functions_ldap::check_user_password_ldap login is now $login (LDAP_FIELD_LOGIN=".$conf->global->LDAP_FIELD_LOGIN.")");
}
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
@ -207,7 +210,7 @@ function check_user_password_ldap($usertotest, $passwordtotest, $entitytotest)
}
$usertmp = new User($db);
$resultFetchUser = $usertmp->fetch('', $login, $sid);
$resultFetchUser = $usertmp->fetch('', $login, $sid, 1, ($entitytotest > 0 ? $entitytotest : -1));
if ($resultFetchUser > 0) {
dol_syslog("functions_ldap::check_user_password_ldap Sync user found user id=".$usertmp->id);
// On verifie si le login a change et on met a jour les attributs dolibarr
@ -215,7 +218,7 @@ function check_user_password_ldap($usertotest, $passwordtotest, $entitytotest)
if ($usertmp->login != $ldap->login && $ldap->login) {
$usertmp->login = $ldap->login;
$usertmp->update($usertmp);
// TODO Que faire si update echoue car on update avec un login deja existant.
// TODO Que faire si update echoue car on update avec un login deja existant pour un autre compte.
}
//$resultUpdate = $usertmp->update_ldap2dolibarr($ldap);
@ -231,7 +234,7 @@ function check_user_password_ldap($usertotest, $passwordtotest, $entitytotest)
$usertmp->fetch('', $login);
$ret = $mc->checkRight($usertmp->id, $entitytotest);
if ($ret < 0) {
dol_syslog("functions_ldap::check_user_password_ldap Authentication KO entity '".$entitytotest."' not allowed for user '".$usertmp->id."'", LOG_NOTICE);
dol_syslog("functions_ldap::check_user_password_ldap Authentication KO entity '".$entitytotest."' not allowed for user id '".$usertmp->id."'", LOG_NOTICE);
$login = ''; // force authentication failure
}
unset($usertmp);

View File

@ -55,7 +55,7 @@ create table llx_actioncomm
durationp real, -- planed duration
label varchar(255) NOT NULL, -- label/title of event or topic of email
note text, -- note of event or content of email
note text, -- private note of event or content of email
calling_duration integer, -- when event is a phone call, duration of phone call

View File

@ -53,6 +53,7 @@ InternalUser=Internal user
ExternalUser=External user
InternalUsers=Internal users
ExternalUsers=External users
UserInterface=User interface
GUISetup=Display
SetupArea=Setup
UploadNewTemplate=Upload new template(s)

View File

@ -507,14 +507,16 @@ print "<br>";
print "<br>";
print load_fiche_titre($langs->trans("ProductOtherConf"), '', '');
print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="other">';
print '<input type="hidden" name="page_y" value="">';
print load_fiche_titre($langs->trans("ProductOtherConf"), '', '');
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<td>'.$langs->trans("Parameters").'</td>'."\n";
@ -592,6 +594,38 @@ print $form->selectPriceBaseType($conf->global->PRODUCT_PRICE_BASE_TYPE, "price_
print '</td>';
print '</tr>';
if ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_order->enabled) || !empty($conf->supplier_invoice->enabled)) {
print '<tr class="oddeven">';
print '<td>'.$langs->trans("UseProductFournDesc").'</td>';
print '<td class="right">';
print $form->selectyesno("activate_useProdFournDesc", (!empty($conf->global->PRODUIT_FOURN_TEXTS) ? $conf->global->PRODUIT_FOURN_TEXTS : 0), 1);
print '</td>';
print '</tr>';
print '<tr class="oddeven">';
print '<td>'.$langs->trans("UseProductSupplierPackaging").'</td>';
print '<td align="right">';
print $form->selectyesno("activate_useProdSupplierPackaging", (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING) ? $conf->global->PRODUCT_USE_SUPPLIER_PACKAGING : 0), 1);
print '</td>';
print '</tr>';
}
print '</table>';
print '<div class="center">';
print '<input type="submit" class="button reposition" value="'.$langs->trans("Modify").'">';
print '</div>';
print load_fiche_titre($langs->trans("UserInterface"), '', '');
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<td>'.$langs->trans("Parameters").'</td>'."\n";
print '<td class="right" width="60">'.$langs->trans("Value").'</td>'."\n";
print '</tr>'."\n";
// Use Ajax form to select a product
print '<tr class="oddeven">';
@ -624,9 +658,10 @@ if (empty($conf->global->PRODUIT_USE_SEARCH_TO_SELECT)) {
print '<tr class="oddeven">';
print '<td>'.$langs->trans("OnProductSelectAddProductDesc").'</td>';
print '<td class="right">';
print '<!-- PRODUIT_AUTOFILL_DESC -->';
print $form->selectarray(
"activate_FillProductDescAuto",
array(1=>'AutoFillFormFieldBeforeSubmit', 0=>'DoNotAutofillButAutoConcat', -1=>'DoNotUseDescriptionOfProdut'),
array(0=>'DoNotAutofillButAutoConcat', 1=>'AutoFillFormFieldBeforeSubmit', 2=>'DoNotUseDescriptionOfProdut'),
empty($conf->global->PRODUIT_AUTOFILL_DESC) ? 0 : $conf->global->PRODUIT_AUTOFILL_DESC,
0,
0,
@ -682,22 +717,6 @@ if (!empty($conf->global->MAIN_MULTILANGS)) {
print '</tr>';
}
if ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_order->enabled) || !empty($conf->supplier_invoice->enabled)) {
print '<tr class="oddeven">';
print '<td>'.$langs->trans("UseProductFournDesc").'</td>';
print '<td class="right">';
print $form->selectyesno("activate_useProdFournDesc", (!empty($conf->global->PRODUIT_FOURN_TEXTS) ? $conf->global->PRODUIT_FOURN_TEXTS : 0), 1);
print '</td>';
print '</tr>';
print '<tr class="oddeven">';
print '<td>'.$langs->trans("UseProductSupplierPackaging").'</td>';
print '<td align="right">';
print $form->selectyesno("activate_useProdSupplierPackaging", (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING) ? $conf->global->PRODUCT_USE_SUPPLIER_PACKAGING : 0), 1);
print '</td>';
print '</tr>';
}
if (!empty($conf->global->PRODUCT_CANVAS_ABILITY)) {
// Add canvas feature

View File

@ -2236,7 +2236,7 @@ class Product extends CommonObject
// Check parameters
if (!$id && !$ref && !$ref_ext && !$barcode) {
$this->error = 'ErrorWrongParameters';
dol_syslog(get_class($this)."::fetch ".$this->error);
dol_syslog(get_class($this)."::fetch ".$this->error, LOG_ERR);
return -1;
}
@ -2286,7 +2286,7 @@ class Product extends CommonObject
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product_perentity as ppe ON ppe.fk_product = p.rowid AND ppe.entity = " . ((int) $conf->entity);
}
if ($separatedStock) {
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product_stock as sp ON sp.fk_product = p.rowid";
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product_stock as sp ON sp.fk_product = p.rowid AND sp.fk_entrepot IN (SELECT rowid FROM ".MAIN_DB_PREFIX."entrepot WHERE entity IN (".$this->db->sanitize($visibleWarehousesEntities)."))";
}
if ($id) {
$sql .= " WHERE p.rowid = ".((int) $id);
@ -2300,9 +2300,6 @@ class Product extends CommonObject
$sql .= " AND p.barcode = '".$this->db->escape($barcode)."'";
}
}
if ($separatedStock) {
$sql .= " AND sp.fk_entrepot IN (SELECT rowid FROM ".MAIN_DB_PREFIX."entrepot WHERE entity IN (".$this->db->sanitize($visibleWarehousesEntities)."))";
}
if ($separatedStock) {
$sql .= " GROUP BY p.rowid, p.ref, p.ref_ext, p.label, p.description, p.url, p.note_public, p.note, p.customcode, p.fk_country, p.fk_state, p.lifetime, p.qc_frequency, p.price, p.price_ttc,";
$sql .= " p.price_min, p.price_min_ttc, p.price_base_type, p.cost_price, p.default_vat_code, p.tva_tx, p.recuperableonly, p.localtax1_tx, p.localtax2_tx, p.localtax1_type, p.localtax2_type, p.tosell,";

View File

@ -3091,8 +3091,8 @@ div.tabsElem a {
div.tabBar {
color: #<?php echo $colortextbacktab; ?>;
padding-top: 21px;
padding-left: 18px;
padding-right: 18px;
padding-left: 24px;
padding-right: 24px;
padding-bottom: 18px;
margin: 0px 0px 18px 0px;
-webkit-border-radius: 3px;
@ -3439,9 +3439,9 @@ tr.liste_titre_filter td.liste_titre {
}
.liste_titre_create td, .liste_titre_create th, .liste_titre_create .tagtd
{
/*border-top-width: 1px;
border-top-width: 1px;
border-top-color: rgb(<?php echo $colortopbordertitle1 ?>);
border-top-style: solid;*/
border-top-style: solid;
}
.liste_titre_add td, .liste_titre_add th, .liste_titre_add .tagtd
{
@ -3830,7 +3830,7 @@ div.liste_titre_bydiv, .liste_titre div.tagtr, tr.liste_titre, tr.liste_titre_se
{
background: rgb(<?php echo $colorbacktitle1; ?>);
font-weight: <?php echo $useboldtitle ? 'bold' : 'normal'; ?>;
border-bottom: 1px solid #FDFFFF;
/* border-bottom: 1px solid #FDFFFF; */
color: rgb(<?php echo $colortexttitle; ?>);
font-family: <?php print $fontlist ?>;

View File

@ -442,7 +442,7 @@ class User extends CommonObject
if ($entity < 0) {
if ((empty($conf->multicompany->enabled) || empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) && (!empty($user->entity))) {
$sql .= " WHERE u.entity IN (0, ".$this->db->sanitize($conf->entity).")";
$sql .= " WHERE u.entity IN (0, ".((int) $conf->entity).")";
} else {
$sql .= " WHERE u.entity IS NOT NULL"; // multicompany is on in transverse mode or user making fetch is on entity 0, so user is allowed to fetch anywhere into database
}
@ -451,7 +451,7 @@ class User extends CommonObject
if (!empty($conf->multicompany->enabled) && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
$sql .= " WHERE u.entity IS NOT NULL"; // multicompany is on in transverse mode or user making fetch is on entity 0, so user is allowed to fetch anywhere into database
} else {
$sql .= " WHERE u.entity IN (0, ".$this->db->sanitize(($entity != '' && $entity >= 0) ? $entity : $conf->entity).")"; // search in entity provided in parameter
$sql .= " WHERE u.entity IN (0, ".((int) (($entity != '' && $entity >= 0) ? $entity : $conf->entity)).")"; // search in entity provided in parameter
}
}
@ -2109,8 +2109,8 @@ class User extends CommonObject
$outputlangs = new Translate("", $conf);
if (isset($this->conf->MAIN_LANG_DEFAULT)
&& $this->conf->MAIN_LANG_DEFAULT != 'auto') { // If user has defined its own language (rare because in most cases, auto is used)
$outputlangs->getDefaultLang($this->conf->MAIN_LANG_DEFAULT);
&& $this->conf->MAIN_LANG_DEFAULT != 'auto') { // If user has defined its own language (rare because in most cases, auto is used)
$outputlangs->getDefaultLang($this->conf->MAIN_LANG_DEFAULT);
}
if ($this->conf->MAIN_LANG_DEFAULT) {
@ -2184,7 +2184,7 @@ class User extends CommonObject
'',
'',
$trackid
);
);
if ($mailfile->sendfile()) {
return 1;
@ -3222,7 +3222,7 @@ class User extends CommonObject
foreach ($this->users as $key => $val) {
if (preg_match('/'.$keyfilter1.'/', $val['fullpath']) || preg_match('/'.$keyfilter2.'/', $val['fullpath'])
|| preg_match('/'.$keyfilter3.'/', $val['fullpath']) || preg_match('/'.$keyfilter4.'/', $val['fullpath'])) {
unset($this->users[$key]);
unset($this->users[$key]);
}
}
}

View File

@ -321,6 +321,10 @@ class SecurityTest extends PHPUnit\Framework\TestCase
$test="<a onpointerdown=alert(document.domain)>XSS</a>";
$result=testSqlAndScriptInject($test, 0);
$this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject lll');
$test="Text with ' encoded with the numeric html entity converted into text entity &#39; (like when submited by CKEditor)";
$result=testSqlAndScriptInject($test, 0);
$this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject mmm');
}
/**
@ -358,6 +362,7 @@ class SecurityTest extends PHPUnit\Framework\TestCase
$_POST["param12"]='<!DOCTYPE html><html>aaa</html>';
$_POST["param13"]='&#110; &#x6E; &gt; &lt; &quot; <a href=\"j&#x61;vascript:alert(document.domain)\">XSS</a>';
$_POST["param13b"]='&#110; &#x6E; &gt; &lt; &quot; <a href=\"j&#x61vascript:alert(document.domain)\">XSS</a>';
$_POST["param14"]="Text with ' encoded with the numeric html entity converted into text entity &#39; (like when submited by CKEditor)";
//$_POST["param13"]='javascript%26colon%26%23x3B%3Balert(1)';
//$_POST["param14"]='javascripT&javascript#x3a alert(1)';
@ -494,6 +499,10 @@ class SecurityTest extends PHPUnit\Framework\TestCase
print __METHOD__." result=".$result."\n";
$this->assertEquals('n n &gt; &lt; &quot; <a href=\"alert(document.domain)\">XSS</a>', $result, 'Test 13b that HTML entities are decoded with restricthtml, but only for common alpha chars');
$result=GETPOST("param14", 'restricthtml');
print __METHOD__." result=".$result."\n";
$this->assertEquals("Text with ' encoded with the numeric html entity converted into text entity &apos; (like when submited by CKEditor)", $result, 'Test 14');
// Special test for GETPOST of backtopage, backtolist or backtourl parameter
$_POST["backtopage"]='//www.google.com';