NEW Can define date range of validity of a login during creation

This commit is contained in:
Laurent Destailleur 2020-09-22 14:45:19 +02:00
parent 5f4547bf7c
commit d21ee07afc
8 changed files with 117 additions and 17 deletions

View File

@ -466,8 +466,8 @@ function dol_get_next_week($day, $week, $month, $year)
* @param int $year Year
* @param int $month Month
* @param mixed $gm False or 0 or 'server' = Return date to compare with server TZ, True or 1 to compare with GM date.
* Exemple: dol_get_first_day(1970,1,false) will return -3600 with TZ+1, after a dol_print_date will return 1970-01-01 00:00:00
* Exemple: dol_get_first_day(1970,1,true) will return 0 whatever is TZ, after a dol_print_date will return 1970-01-01 00:00:00
* Exemple: dol_get_first_day(1970,1,false) will return -3600 with TZ+1, a dol_print_date on it will return 1970-01-01 00:00:00
* Exemple: dol_get_first_day(1970,1,true) will return 0 whatever is TZ, a dol_print_date on it will return 1970-01-01 00:00:00
* @return int Date for first day, '' if error
*/
function dol_get_first_day($year, $month = 1, $gm = false)
@ -502,6 +502,28 @@ function dol_get_last_day($year, $month = 12, $gm = false)
return $datelim;
}
/** Return GMT time for last hour of a given GMT date (it removes hours, min and second part)
*
* @param int $dat
* @return int Date for last hour of a given date
*/
function dol_get_last_hour($date)
{
$tmparray = dol_getdate($date);
return dol_mktime(23, 59, 59, $tmparray['mon'], $tmparray['mday'], $tmparray['year'], false);
}
/** Return GMT time for first hour of a given GMT date (it removes hours, min and second part)
*
* @param int $dat
* @return int Date for last hour of a given date
*/
function dol_get_first_hour($date)
{
$tmparray = dol_getdate($date);
return dol_mktime(0, 0, 0, $tmparray['mon'], $tmparray['mday'], $tmparray['year'], false);
}
/** Return first day of week for a date. First day of week may be monday if option MAIN_START_WEEK is 1.
*
* @param int $day Day

View File

@ -92,7 +92,7 @@ function checkLoginPassEntity($usertotest, $passwordtotest, $entitytotest, $auth
// Call function to check user/password
$function = 'check_user_password_'.$mode;
$login = call_user_func($function, $usertotest, $passwordtotest, $entitytotest, $context);
if ($login) // Login is successfull
if ($login && $login != '--bad-login-validity--') // Login is successfull
{
$test = false; // To stop once at first login success
$conf->authmode = $mode; // This properties is defined only when logged to say what mode was successfully used

View File

@ -45,6 +45,7 @@ function check_user_password_dolibarr($usertotest, $passwordtotest, $entitytotes
if (!empty($usertotest))
{
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
dol_syslog("functions_dolibarr::check_user_password_dolibarr usertotest=".$usertotest." passwordtotest=".preg_replace('/./', '*', $passwordtotest)." entitytotest=".$entitytotest);
// If test username/password asked, we define $test=false if ko and $login var to login if ok, set also $_SESSION["dol_loginmesg"] if ko
@ -53,14 +54,15 @@ function check_user_password_dolibarr($usertotest, $passwordtotest, $entitytotes
$usernamecol2 = 'email';
$entitycol = 'entity';
$sql = 'SELECT rowid, login, entity, pass, pass_crypted';
$sql = 'SELECT rowid, login, entity, pass, pass_crypted, datestartvalidity, dateendvalidity';
$sql .= ' FROM '.$table;
$sql .= ' WHERE ('.$usernamecol1." = '".$db->escape($usertotest)."'";
if (preg_match('/@/', $usertotest)) $sql .= ' OR '.$usernamecol2." = '".$db->escape($usertotest)."'";
$sql .= ') AND '.$entitycol." IN (0,".($entity ? $entity : 1).")";
$sql .= ' AND statut = 1';
// Required to first found the user into entity, then the superadmin.
// For the case (TODO and that we must avoid) a user has renamed its login with same value than a user in entity 0.
// Note: Test on validity is done later
// Required to firstly found the user into entity, then the superadmin.
// For the case (TODO we must avoid that) a user has renamed its login with same value than a user in entity 0.
$sql .= ' ORDER BY entity DESC';
$resql = $db->query($sql);
@ -69,6 +71,20 @@ function check_user_password_dolibarr($usertotest, $passwordtotest, $entitytotes
$obj = $db->fetch_object($resql);
if ($obj)
{
$now = dol_now();
if ($obj->datestartvalidity && $db->jdate($obj->datestartvalidity) > $now) {
// Load translation files required by the page
$langs->loadLangs(array('main', 'errors'));
$_SESSION["dol_loginmesg"] = $langs->trans("ErrorLoginDateValidity");
return '--bad-login-validity--';
}
if ($obj->dateendvalidity && $db->jdate($obj->dateendvalidity) < dol_get_first_hour($now)) {
// Load translation files required by the page
$langs->loadLangs(array('main', 'errors'));
$_SESSION["dol_loginmesg"] = $langs->trans("ErrorLoginDateValidity");
return '--bad-login-validity--';
}
$passclear = $obj->pass;
$passcrypted = $obj->pass_crypted;
$passtyped = $passwordtotest;
@ -79,19 +95,19 @@ function check_user_password_dolibarr($usertotest, $passwordtotest, $entitytotes
$cryptType = '';
if (!empty($conf->global->DATABASE_PWD_ENCRYPTED)) $cryptType = $conf->global->DATABASE_PWD_ENCRYPTED;
// By default, we used MD5
if (!in_array($cryptType, array('md5'))) $cryptType = 'md5';
// By default, we use default setup for encryption rule
if (!in_array($cryptType, array('auto'))) $cryptType = 'auto';
// Check crypted password according to crypt algorithm
if ($cryptType == 'md5')
if ($cryptType == 'auto')
{
if (dol_verifyHash($passtyped, $passcrypted))
if (dol_verifyHash($passtyped, $passcrypted, '0'))
{
$passok = true;
dol_syslog("functions_dolibarr::check_user_password_dolibarr Authentification ok - ".$cryptType." of pass is ok");
}
}
// For compatibility with old versions
// For compatibility with very old versions
if (!$passok)
{
if ((!$passcrypted || $passtyped)

View File

@ -33,6 +33,8 @@
*/
function check_user_password_http($usertotest, $passwordtotest, $entitytotest)
{
global $db, $langs;
dol_syslog("functions_http::check_user_password_http _SERVER[REMOTE_USER]=".(empty($_SERVER["REMOTE_USER"]) ? '' : $_SERVER["REMOTE_USER"]));
$login = '';
@ -41,5 +43,24 @@ function check_user_password_http($usertotest, $passwordtotest, $entitytotest)
$login = $_SERVER["REMOTE_USER"];
}
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
$tmpuser = new User($db);
$tmpuser->fetch('', $login, '', 1, ($entitytotest > 0 ? $entitytotest : -1));
$now = dol_now();
if ($tmpuser->datestartvalidity && $db->jdate($tmpuser->datestartvalidity) >= $now) {
// Load translation files required by the page
$langs->loadLangs(array('main', 'errors'));
$_SESSION["dol_loginmesg"] = $langs->trans("ErrorLoginDateValidity");
return '--bad-login-validity--';
}
if ($tmpuser->dateendvalidity && $db->jdate($tmpuser->dateendvalidity) <= dol_get_first_hour($now)) {
// Load translation files required by the page
$langs->loadLangs(array('main', 'errors'));
$_SESSION["dol_loginmesg"] = $langs->trans("ErrorLoginDateValidity");
return '--bad-login-validity--';
}
return $login;
}

View File

@ -151,6 +151,27 @@ function check_user_password_ldap($usertotest, $passwordtotest, $entitytotest)
dol_syslog("functions_ldap::check_user_password_ldap Authentification ok");
$login = $usertotest;
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
$tmpuser = new User($db);
$tmpuser->fetch('', $login, '', 1, ($entitytotest > 0 ? $entitytotest : -1));
$now = dol_now();
if ($tmpuser->datestartvalidity && $db->jdate($tmpuser->datestartvalidity) >= $now) {
$ldap->close();
// Load translation files required by the page
$langs->loadLangs(array('main', 'errors'));
$_SESSION["dol_loginmesg"] = $langs->trans("ErrorLoginDateValidity");
return '--bad-login-validity--';
}
if ($tmpuser->dateendvalidity && $db->jdate($tmpuser->dateendvalidity) <= dol_get_first_hour($now)) {
$ldap->close();
// Load translation files required by the page
$langs->loadLangs(array('main', 'errors'));
$_SESSION["dol_loginmesg"] = $langs->trans("ErrorLoginDateValidity");
return '--bad-login-validity--';
}
// ldap2dolibarr synchronisation
if ($login && !empty($conf->ldap->enabled) && $conf->global->LDAP_SYNCHRO_ACTIVE == 'ldap2dolibarr') // ldap2dolibarr synchronisation
{
@ -188,6 +209,7 @@ function check_user_password_ldap($usertotest, $passwordtotest, $entitytotest)
//$resultUpdate = $usertmp->update_ldap2dolibarr($ldap);
}
unset($usertmp);
}

View File

@ -36,7 +36,7 @@ include_once DOL_DOCUMENT_ROOT.'/core/class/openid.class.php';
*/
function check_user_password_openid($usertotest, $passwordtotest, $entitytotest)
{
global $_POST, $db, $conf, $langs;
global $db, $conf, $langs;
dol_syslog("functions_openid::check_user_password_openid usertotest=".$usertotest);
@ -57,7 +57,7 @@ function check_user_password_openid($usertotest, $passwordtotest, $entitytotest)
$openid->SetApprovedURL($protocol.$_SERVER["HTTP_HOST"].$_SERVER["SCRIPT_NAME"]); // Send Response from OpenID server to this script
$openid->Redirect(); // This will redirect user to OpenID Server
} else {
$error = $openid->GetError();
$_SESSION["dol_loginmesg"] = $openid->GetError();
return false;
}
return false;
@ -72,7 +72,7 @@ function check_user_password_openid($usertotest, $passwordtotest, $entitytotest)
{
// OK HERE KEY IS VALID
$sql = "SELECT login";
$sql = "SELECT login, entity, datestartvalidity, dateendvalidity";
$sql .= " FROM ".MAIN_DB_PREFIX."user";
$sql .= " WHERE openid = '".$db->escape($_GET['openid_identity'])."'";
$sql .= " AND entity IN (0,".($_SESSION["dol_entity"] ? $_SESSION["dol_entity"] : 1).")";
@ -84,13 +84,27 @@ function check_user_password_openid($usertotest, $passwordtotest, $entitytotest)
$obj = $db->fetch_object($resql);
if ($obj)
{
$now = dol_now();
if ($obj->datestartvalidity && $db->jdate($obj->datestartvalidity) > $now) {
// Load translation files required by the page
$langs->loadLangs(array('main', 'errors'));
$_SESSION["dol_loginmesg"] = $langs->trans("ErrorLoginDateValidity");
return '--bad-login-validity--';
}
if ($obj->dateendvalidity && $db->jdate($obj->dateendvalidity) < dol_get_first_hour($now)) {
// Load translation files required by the page
$langs->loadLangs(array('main', 'errors'));
$_SESSION["dol_loginmesg"] = $langs->trans("ErrorLoginDateValidity");
return '--bad-login-validity--';
}
$login = $obj->login;
}
}
} elseif ($openid->IsError() === true)
{
// ON THE WAY, WE GOT SOME ERROR
$error = $openid->GetError();
$_SESSION["dol_loginmesg"] = $openid->GetError();
return false;
} else {
// Signature Verification Failed

View File

@ -244,6 +244,7 @@ ErrorProductNeedBatchNumber=Error, product '<b>%s</b>' need a lot/serial number
ErrorProductDoesNotNeedBatchNumber=Error, product '<b>%s</b>' does not accept a lot/serial number
ErrorFailedToReadObject=Error, failed to read object of type <b>%s</b>
ErrorParameterMustBeEnabledToAllwoThisFeature=Error, parameter <b>%s</b> must be enabled into <b>conf/conf.php<b> to allow use of Command Line Interface by the internal job scheduler
ErrorLoginDateValidity=Error, this login is outside the validity date range
# Warnings
WarningParamUploadMaxFileSizeHigherThanPostMaxSize=Your PHP parameter upload_max_filesize (%s) is higher than PHP parameter post_max_size (%s). This is not a consistent setup.
WarningPasswordSetWithNoAccount=A password was set for this member. However, no user account was created. So this password is stored but can't be used to login to Dolibarr. It may be used by an external module/interface but if you don't need to define any login nor password for a member, you can disable option "Manage a login for each member" from Member module setup. If you need to manage a login but don't need any password, you can keep this field empty to avoid this warning. Note: Email can also be used as a login if the member is linked to a user.

View File

@ -357,7 +357,7 @@ if (!defined('NOTOKENRENEWAL'))
$_SESSION['newtoken'] = $token;
}
dol_syslog("aaaa - ".defined('NOCSRFCHECK')." - ".$dolibarr_nocsrfcheck." - ".$conf->global->MAIN_SECURITY_CSRF_WITH_TOKEN." - ".$_SERVER['REQUEST_METHOD']." - ".GETPOST('token', 'alpha').' '.$_SESSION['token']);
//dol_syslog("aaaa - ".defined('NOCSRFCHECK')." - ".$dolibarr_nocsrfcheck." - ".$conf->global->MAIN_SECURITY_CSRF_WITH_TOKEN." - ".$_SERVER['REQUEST_METHOD']." - ".GETPOST('token', 'alpha').' '.$_SESSION['token']);
//$dolibarr_nocsrfcheck=1;
// Check token
if ((!defined('NOCSRFCHECK') && empty($dolibarr_nocsrfcheck) && !empty($conf->global->MAIN_SECURITY_CSRF_WITH_TOKEN))
@ -563,6 +563,10 @@ if (!defined('NOLOGIN'))
if ($test && $goontestloop && (GETPOST('actionlogin', 'aZ09') == 'login' || $dolibarr_main_authentication != 'dolibarr'))
{
$login = checkLoginPassEntity($usertotest, $passwordtotest, $entitytotest, $authmode);
if ($login === '--bad-login-validity--') {
$login = '';
}
if ($login)
{
$dol_authmode = $conf->authmode; // This properties is defined only when logged, to say what mode was successfully used
@ -623,7 +627,7 @@ if (!defined('NOLOGIN'))
exit;
}
$resultFetchUser = $user->fetch('', $login, '', 1, ($entitytotest > 0 ? $entitytotest : -1));
$resultFetchUser = $user->fetch('', $login, '', 1, ($entitytotest > 0 ? $entitytotest : -1)); // login was retreived previously when checking password.
if ($resultFetchUser <= 0)
{
dol_syslog('User not found, connexion refused');