N°6358 - Login API REST

This commit is contained in:
Eric Espie
2023-06-07 09:13:13 +02:00
parent a45177410e
commit c596fa2967
12 changed files with 165 additions and 41 deletions

View File

@@ -51,7 +51,7 @@ class LoginBasic extends AbstractLoginFSMExtension
protected function OnCheckCredentials(&$iErrorCode)
{
if ($_SESSION['login_mode'] == 'basic')
if (isset($_SESSION['login_mode']) && $_SESSION['login_mode'] == 'basic')
{
list($sAuthUser, $sAuthPwd) = $this->GetAuthUserAndPassword();
if (!UserRights::CheckCredentials($sAuthUser, $sAuthPwd, $_SESSION['login_mode'], 'internal'))
@@ -67,7 +67,7 @@ class LoginBasic extends AbstractLoginFSMExtension
protected function OnCredentialsOK(&$iErrorCode)
{
if ($_SESSION['login_mode'] == 'basic')
if (isset($_SESSION['login_mode']) && $_SESSION['login_mode'] == 'basic')
{
$sAuthUser = $_SESSION['auth_user'];
LoginWebPage::OnLoginSuccess($sAuthUser, 'internal', $_SESSION['login_mode']);
@@ -77,8 +77,13 @@ class LoginBasic extends AbstractLoginFSMExtension
protected function OnError(&$iErrorCode)
{
if ($_SESSION['login_mode'] == 'basic')
if (isset($_SESSION['login_mode']) && $_SESSION['login_mode'] == 'basic')
{
$iOnExit = LoginWebPage::getIOnExit();
if ($iOnExit === LoginWebPage::EXIT_RETURN)
{
return LoginWebPage::LOGIN_FSM_RETURN; // Error, exit FSM
}
LoginWebPage::HTTP401Error();
}
return LoginWebPage::LOGIN_FSM_CONTINUE;
@@ -86,7 +91,7 @@ class LoginBasic extends AbstractLoginFSMExtension
protected function OnConnected(&$iErrorCode)
{
if ($_SESSION['login_mode'] == 'basic')
if (isset($_SESSION['login_mode']) && $_SESSION['login_mode'] == 'basic')
{
$_SESSION['can_logoff'] = true;
return LoginWebPage::CheckLoggedUser($iErrorCode);

View File

@@ -77,7 +77,7 @@ class LoginDefaultAfter extends AbstractLoginFSMExtension implements iLogoutExte
{
self::ResetLoginSession();
$iOnExit = LoginWebPage::getIOnExit();
if ($iOnExit == LoginWebPage::EXIT_RETURN)
if ($iOnExit === LoginWebPage::EXIT_RETURN)
{
return LoginWebPage::LOGIN_FSM_RETURN; // Error, exit FSM
}
@@ -93,6 +93,12 @@ class LoginDefaultAfter extends AbstractLoginFSMExtension implements iLogoutExte
{
if (!isset($_SESSION['login_mode']))
{
// N°6358 - if EXIT_RETURN was asked, send an error
if (LoginWebPage::getIOnExit() === LoginWebPage::EXIT_RETURN) {
$iErrorCode = LoginWebPage::EXIT_CODE_WRONGCREDENTIALS;
return LoginWebPage::LOGIN_FSM_ERROR;
}
// If no plugin validated the user, exit
self::ResetLoginSession();
exit();

View File

@@ -35,7 +35,7 @@ class LoginExternal extends AbstractLoginFSMExtension
protected function OnCheckCredentials(&$iErrorCode)
{
if ($_SESSION['login_mode'] == 'external')
if (isset($_SESSION['login_mode']) && $_SESSION['login_mode'] == 'external')
{
$sAuthUser = $this->GetAuthUser();
if (!UserRights::CheckCredentials($sAuthUser, '', $_SESSION['login_mode'], 'external'))
@@ -51,7 +51,7 @@ class LoginExternal extends AbstractLoginFSMExtension
protected function OnCredentialsOK(&$iErrorCode)
{
if ($_SESSION['login_mode'] == 'external')
if (isset($_SESSION['login_mode']) && $_SESSION['login_mode'] == 'external')
{
$sAuthUser = $_SESSION['auth_user'];
LoginWebPage::OnLoginSuccess($sAuthUser, 'external', $_SESSION['login_mode']);
@@ -61,7 +61,7 @@ class LoginExternal extends AbstractLoginFSMExtension
protected function OnConnected(&$iErrorCode)
{
if ($_SESSION['login_mode'] == 'external')
if (isset($_SESSION['login_mode']) && $_SESSION['login_mode'] == 'external')
{
$_SESSION['can_logoff'] = false;
return LoginWebPage::CheckLoggedUser($iErrorCode);
@@ -71,8 +71,13 @@ class LoginExternal extends AbstractLoginFSMExtension
protected function OnError(&$iErrorCode)
{
if ($_SESSION['login_mode'] == 'external')
if (isset($_SESSION['login_mode']) && $_SESSION['login_mode'] == 'external')
{
$iOnExit = LoginWebPage::getIOnExit();
if ($iOnExit === LoginWebPage::EXIT_RETURN)
{
return LoginWebPage::LOGIN_FSM_RETURN; // Error, exit FSM
}
LoginWebPage::HTTP401Error();
}
return LoginWebPage::LOGIN_FSM_CONTINUE;

View File

@@ -43,6 +43,10 @@ class LoginForm extends AbstractLoginFSMExtension implements iLoginUIExtension
exit;
}
if (LoginWebPage::getIOnExit() === LoginWebPage::EXIT_RETURN) {
return LoginWebPage::LOGIN_FSM_CONTINUE;
}
// No credentials yet, display the form
$oPage = LoginWebPage::NewLoginWebPage();
$oPage->DisplayLoginForm($this->bForceFormOnError);
@@ -62,7 +66,7 @@ class LoginForm extends AbstractLoginFSMExtension implements iLoginUIExtension
*/
protected function OnCheckCredentials(&$iErrorCode)
{
if ($_SESSION['login_mode'] == 'form')
if (isset($_SESSION['login_mode']) && $_SESSION['login_mode'] == 'form')
{
$sAuthUser = utils::ReadPostedParam('auth_user', '', 'raw_data');
$sAuthPwd = utils::ReadPostedParam('auth_pwd', null, 'raw_data');
@@ -82,7 +86,7 @@ class LoginForm extends AbstractLoginFSMExtension implements iLoginUIExtension
*/
protected function OnCredentialsOK(&$iErrorCode)
{
if ($_SESSION['login_mode'] == 'form')
if (isset($_SESSION['login_mode']) && $_SESSION['login_mode'] == 'form')
{
$sAuthUser = $_SESSION['auth_user'];
// Store 'auth_user' in session for further use
@@ -96,7 +100,7 @@ class LoginForm extends AbstractLoginFSMExtension implements iLoginUIExtension
*/
protected function OnError(&$iErrorCode)
{
if ($_SESSION['login_mode'] == 'form')
if (isset($_SESSION['login_mode']) && $_SESSION['login_mode'] == 'form')
{
$this->bForceFormOnError = true;
}
@@ -108,7 +112,7 @@ class LoginForm extends AbstractLoginFSMExtension implements iLoginUIExtension
*/
protected function OnConnected(&$iErrorCode)
{
if ($_SESSION['login_mode'] == 'form')
if (isset($_SESSION['login_mode']) && $_SESSION['login_mode'] == 'form')
{
$_SESSION['can_logoff'] = true;
return LoginWebPage::CheckLoggedUser($iErrorCode);

View File

@@ -32,7 +32,7 @@ class LoginWebPage extends NiceWebPage
{
const EXIT_PROMPT = 0;
const EXIT_HTTP_401 = 1;
const EXIT_RETURN = 2;
const EXIT_RETURN = 2; // Non interactive mode (ajax, rest, ...)
const EXIT_CODE_OK = 0;
const EXIT_CODE_MISSINGLOGIN = 1;
@@ -352,14 +352,20 @@ class LoginWebPage extends NiceWebPage
$this->output();
}
public static function ResetSession()
public static function ResetSession($bFullCleanup = false)
{
// Unset all of the session variables.
unset($_SESSION['auth_user']);
unset($_SESSION['login_state']);
unset($_SESSION['can_logoff']);
unset($_SESSION['archive_mode']);
unset($_SESSION['impersonate_user']);
if ($bFullCleanup) {
// Unset all of the session variables.
foreach (array_keys($_SESSION) as $sKey) {
unset($_SESSION[$sKey]);
}
} else {
unset($_SESSION['auth_user']);
unset($_SESSION['login_state']);
unset($_SESSION['can_logoff']);
unset($_SESSION['archive_mode']);
unset($_SESSION['impersonate_user']);
}
UserRights::_ResetSessionCache();
// If it's desired to kill the session, also delete the session cookie.
// Note: This will destroy the session, and not just the session data!
@@ -931,7 +937,7 @@ class LoginWebPage extends NiceWebPage
}
else
{
if ($iOnExit == self::EXIT_RETURN)
if ($iOnExit === self::EXIT_RETURN)
{
return self::EXIT_CODE_PORTALUSERNOTAUTHORIZED;
}
@@ -987,7 +993,7 @@ class LoginWebPage extends NiceWebPage
{
if ($bMustBeAdmin && !UserRights::IsAdministrator())
{
if ($iOnExit == self::EXIT_RETURN)
if ($iOnExit === self::EXIT_RETURN)
{
return self::EXIT_CODE_MUSTBEADMIN;
}
@@ -1003,7 +1009,7 @@ class LoginWebPage extends NiceWebPage
}
$iRet = call_user_func(array(self::$sHandlerClass, 'ChangeLocation'), $sRequestedPortalId, $iOnExit);
}
if ($iOnExit == self::EXIT_RETURN)
if ($iOnExit === self::EXIT_RETURN)
{
return $iRet;
}

View File

@@ -47,6 +47,11 @@ class CASLoginExtension extends AbstractLoginFSMExtension implements iLogoutExte
protected function OnReadCredentials(&$iErrorCode)
{
if (LoginWebPage::getIOnExit() === LoginWebPage::EXIT_RETURN) {
// Not allowed if not already connected
return LoginWebPage::LOGIN_FSM_CONTINUE;
}
if (!isset($_SESSION['login_mode']) || ($_SESSION['login_mode'] == 'cas'))
{
static::InitCASClient();
@@ -71,7 +76,8 @@ class CASLoginExtension extends AbstractLoginFSMExtension implements iLogoutExte
return LoginWebPage::LOGIN_FSM_ERROR;
}
}
$_SESSION['login_mode'] = 'cas';
$_SESSION['login_mode'] = 'cas';
phpCAS::forceAuthentication(); // Redirect to CAS and exit
}
}
@@ -80,7 +86,7 @@ class CASLoginExtension extends AbstractLoginFSMExtension implements iLogoutExte
protected function OnCheckCredentials(&$iErrorCode)
{
if ($_SESSION['login_mode'] == 'cas')
if (isset($_SESSION['login_mode']) && $_SESSION['login_mode'] == 'cas')
{
if (!isset($_SESSION['auth_user']))
{
@@ -97,7 +103,7 @@ class CASLoginExtension extends AbstractLoginFSMExtension implements iLogoutExte
protected function OnCredentialsOK(&$iErrorCode)
{
if ($_SESSION['login_mode'] == 'cas')
if (isset($_SESSION['login_mode']) && $_SESSION['login_mode'] == 'cas')
{
$sAuthUser = $_SESSION['auth_user'];
if (!LoginWebPage::CheckUser($sAuthUser))
@@ -112,7 +118,7 @@ class CASLoginExtension extends AbstractLoginFSMExtension implements iLogoutExte
protected function OnError(&$iErrorCode)
{
if ($_SESSION['login_mode'] == 'cas')
if (isset($_SESSION['login_mode']) && $_SESSION['login_mode'] == 'cas')
{
unset($_SESSION['phpCAS']);
if ($iErrorCode != LoginWebPage::EXIT_CODE_MISSINGLOGIN)
@@ -127,7 +133,7 @@ class CASLoginExtension extends AbstractLoginFSMExtension implements iLogoutExte
protected function OnConnected(&$iErrorCode)
{
if ($_SESSION['login_mode'] == 'cas')
if (isset($_SESSION['login_mode']) && $_SESSION['login_mode'] == 'cas')
{
$_SESSION['can_logoff'] = true;
return LoginWebPage::CheckLoggedUser($iErrorCode);

View File

@@ -37,10 +37,7 @@ try
$oKPI->ComputeAndReport('Data model loaded');
$oKPI = new ExecutionKPI();
if (LoginWebPage::EXIT_CODE_OK != LoginWebPage::DoLoginEx('backoffice', false, LoginWebPage::EXIT_RETURN))
{
throw new SecurityException('You must be logged in');
}
LoginWebPage::DoLogin();
$sParams = utils::ReadParam('params', '', false, 'raw_data');
if (!$sParams)

View File

@@ -96,5 +96,11 @@ if ($bLoginDebug)
IssueLog::Info("--> Display logout page");
}
LoginWebPage::ResetSession(true);
if ($bLoginDebug) {
$sSessionLog = session_id().' '.utils::GetSessionLog();
IssueLog::Info("SESSION: $sSessionLog");
}
$oPage = LoginWebPage::NewLoginWebPage();
$oPage->DisplayLogoutPage($bPortal);

View File

@@ -111,7 +111,36 @@ if (utils::IsModeCLI())
else
{
require_once(APPROOT.'/application/loginwebpage.class.inc.php');
LoginWebPage::DoLogin(); // Check user rights and prompt if needed
LoginWebPage::ResetSession(true);
$iRet = LoginWebPage::DoLogin(false, false, LoginWebPage::EXIT_RETURN);
if ($iRet !== LoginWebPage::EXIT_CODE_OK) {
switch ($iRet) {
case LoginWebPage::EXIT_CODE_MISSINGLOGIN:
$oP->p("Missing parameter 'auth_user'");
break;
case LoginWebPage::EXIT_CODE_MISSINGPASSWORD:
$oP->p("Missing parameter 'auth_pwd'");
break;
case LoginWebPage::EXIT_CODE_WRONGCREDENTIALS:
$oP->p('Invalid login');
break;
case LoginWebPage::EXIT_CODE_PORTALUSERNOTAUTHORIZED:
$oP->p('Portal user is not allowed');
break;
case LoginWebPage::EXIT_CODE_NOTAUTHORIZED:
$oP->p('This user is not authorized to use the web services. (The profile REST Services User is required to access the REST web services)');
break;
default:
$oP->p("Unknown authentication error (retCode=$iRet)");
}
$oP->output();
exit -1;
}
$sDataSourcesList = utils::ReadParam('data_sources', null, true, 'raw_data');

View File

@@ -303,7 +303,36 @@ if (utils::IsModeCLI())
else
{
require_once APPROOT.'/application/loginwebpage.class.inc.php';
LoginWebPage::DoLogin(); // Check user rights and prompt if needed
LoginWebPage::ResetSession(true);
$iRet = LoginWebPage::DoLogin(false, false, LoginWebPage::EXIT_RETURN);
if ($iRet !== LoginWebPage::EXIT_CODE_OK) {
switch ($iRet) {
case LoginWebPage::EXIT_CODE_MISSINGLOGIN:
$oP->p("Missing parameter 'auth_user'");
break;
case LoginWebPage::EXIT_CODE_MISSINGPASSWORD:
$oP->p("Missing parameter 'auth_pwd'");
break;
case LoginWebPage::EXIT_CODE_WRONGCREDENTIALS:
$oP->p('Invalid login');
break;
case LoginWebPage::EXIT_CODE_PORTALUSERNOTAUTHORIZED:
$oP->p('Portal user is not allowed');
break;
case LoginWebPage::EXIT_CODE_NOTAUTHORIZED:
$oP->p('This user is not authorized to use the web services. (The profile REST Services User is required to access the REST web services)');
break;
default:
$oP->p("Unknown authentication error (retCode=$iRet)");
}
$oP->output();
exit -1;
}
$sCSVData = utils::ReadPostedParam('csvdata', '', 'raw_data');
}

View File

@@ -260,7 +260,36 @@ if (utils::IsModeCLI())
else
{
require_once(APPROOT.'/application/loginwebpage.class.inc.php');
LoginWebPage::DoLogin(); // Check user rights and prompt if needed
LoginWebPage::ResetSession(true);
$iRet = LoginWebPage::DoLogin(false, false, LoginWebPage::EXIT_RETURN);
if ($iRet !== LoginWebPage::EXIT_CODE_OK) {
switch ($iRet) {
case LoginWebPage::EXIT_CODE_MISSINGLOGIN:
$oP->p("Missing parameter 'auth_user'");
break;
case LoginWebPage::EXIT_CODE_MISSINGPASSWORD:
$oP->p("Missing parameter 'auth_pwd'");
break;
case LoginWebPage::EXIT_CODE_WRONGCREDENTIALS:
$oP->p('Invalid login');
break;
case LoginWebPage::EXIT_CODE_PORTALUSERNOTAUTHORIZED:
$oP->p('Portal user is not allowed');
break;
case LoginWebPage::EXIT_CODE_NOTAUTHORIZED:
$oP->p('This user is not authorized to use the web services. (The profile REST Services User is required to access the REST web services)');
break;
default:
$oP->p("Unknown authentication error (retCode=$iRet)");
}
$oP->output();
exit -1;
}
$sCSVData = utils::ReadPostedParam('csvdata', '', 'raw_data');
}

View File

@@ -80,10 +80,12 @@ try
$oKPI->ComputeAndReport('Data model loaded');
$iRet = LoginWebPage::DoLogin(false, false, LoginWebPage::EXIT_RETURN); // Starting with iTop 2.2.0 portal users are no longer allowed to access the REST/JSON API
$oKPI->ComputeAndReport('User login');
if ($iRet == LoginWebPage::EXIT_CODE_OK)
// N°6358 - force credentials for REST calls
LoginWebPage::ResetSession(true);
$iRet = LoginWebPage::DoLogin(false, false, LoginWebPage::EXIT_RETURN);
$oKPI->ComputeAndReport('User login');
if ($iRet == LoginWebPage::EXIT_CODE_OK)
{
// Extra validation of the profile
if ((MetaModel::GetConfig()->Get('secure_rest_services') == true) && !UserRights::HasProfile('REST Services User'))
@@ -94,7 +96,7 @@ try
}
if ($iRet != LoginWebPage::EXIT_CODE_OK)
{
switch($iRet)
switch($iRet)
{
case LoginWebPage::EXIT_CODE_MISSINGLOGIN:
throw new Exception("Missing parameter 'auth_user'", RestResult::MISSING_AUTH_USER);