Merge remote-tracking branch 'origin/support/3.1' into support/3.2

This commit is contained in:
Molkobain
2024-01-24 15:19:20 +01:00
8 changed files with 121 additions and 10 deletions

View File

@@ -92,6 +92,8 @@ const OAuthConnect = function(sClass, sId, sAjaxUri) {
function (oData) { function (oData) {
if (oData.status === 'success') { if (oData.status === 'success') {
oOpenSignInWindow(oData.data.authorization_url, 'OAuth authorization') oOpenSignInWindow(oData.data.authorization_url, 'OAuth authorization')
} else {
CombodoModal.OpenErrorModal(oData.error_description);
} }
} }
); );

View File

@@ -380,6 +380,11 @@ HTML
<default_value>no</default_value> <default_value>no</default_value>
<is_null_allowed>true</is_null_allowed> <is_null_allowed>true</is_null_allowed>
</field> </field>
<field id="tenant" xsi:type="AttributeString">
<sql>tenant</sql>
<default_value>common</default_value>
<is_null_allowed>false</is_null_allowed>
</field>
</fields> </fields>
<presentation> <presentation>
<details> <details>
@@ -405,15 +410,18 @@ HTML
<item id="redirect_url"> <item id="redirect_url">
<rank>50</rank> <rank>50</rank>
</item> </item>
<item id="client_id"> <item id="tenant">
<rank>60</rank> <rank>60</rank>
</item> </item>
<item id="client_secret"> <item id="client_id">
<rank>70</rank> <rank>70</rank>
</item> </item>
<item id="mailbox_list"> <item id="client_secret">
<rank>80</rank> <rank>80</rank>
</item> </item>
<item id="mailbox_list">
<rank>90</rank>
</item>
</items> </items>
</item> </item>
</items> </items>

View File

@@ -93,6 +93,8 @@ Dict::Add('EN US', 'English', 'English', array(
'Class:OAuthClientAzure/Attribute:used_for_smtp+' => 'At least one OAuth client must have this flag to “Yes”, if you want iTop to use it for sending mails', 'Class:OAuthClientAzure/Attribute:used_for_smtp+' => 'At least one OAuth client must have this flag to “Yes”, if you want iTop to use it for sending mails',
'Class:OAuthClientAzure/Attribute:used_for_smtp/Value:yes' => 'Yes', 'Class:OAuthClientAzure/Attribute:used_for_smtp/Value:yes' => 'Yes',
'Class:OAuthClientAzure/Attribute:used_for_smtp/Value:no' => 'No', 'Class:OAuthClientAzure/Attribute:used_for_smtp/Value:no' => 'No',
'Class:OAuthClientAzure/Attribute:tenant' => 'Tenant',
'Class:OAuthClientAzure/Attribute:tenant+' => 'Tenant ID of the configured application. For multi-tenant application, use "common".',
)); ));
// //

View File

@@ -10,6 +10,7 @@ use cmdbAbstractObject;
use Combodo\iTop\Application\TwigBase\Controller\Controller; use Combodo\iTop\Application\TwigBase\Controller\Controller;
use Combodo\iTop\Core\Authentication\Client\OAuth\OAuthClientProviderFactory; use Combodo\iTop\Core\Authentication\Client\OAuth\OAuthClientProviderFactory;
use Dict; use Dict;
use Exception;
use IssueLog; use IssueLog;
use League\OAuth2\Client\Provider\Exception\IdentityProviderException; use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
use MetaModel; use MetaModel;
@@ -32,8 +33,13 @@ class AjaxOauthClientController extends Controller
$aResult = ['status' => 'success', 'data' => []]; $aResult = ['status' => 'success', 'data' => []];
try {
$sAuthorizationUrl = OAuthClientProviderFactory::GetAuthorizationUrl($oOAuthClient); $sAuthorizationUrl = OAuthClientProviderFactory::GetAuthorizationUrl($oOAuthClient);
$aResult['data']['authorization_url'] = $sAuthorizationUrl; $aResult['data']['authorization_url'] = $sAuthorizationUrl;
} catch (Exception $oException) {
$aResult['status'] = 'error';
$aResult['error_description'] = $oException->getMessage();
}
$this->DisplayJSONPage($aResult); $this->DisplayJSONPage($aResult);
} }

View File

@@ -256,6 +256,7 @@ abstract class Controller extends AbstractController
} }
/** /**
* @since 3.0.0 N°3606 - Adapt TwigBase Controller for combodo-monitoring extension
* @throws \Exception * @throws \Exception
*/ */
protected function CheckAccess() protected function CheckAccess()
@@ -273,10 +274,21 @@ abstract class Controller extends AbstractController
LoginWebPage::DoLogin($this->m_bMustBeAdmin); LoginWebPage::DoLogin($this->m_bMustBeAdmin);
} else { } else {
//token mode without login required //token mode without login required
$sPassedToken = utils::ReadParam($this->m_sAccessTokenConfigParamId, null); //N°7147 - Error HTTP 500 due to access_token not URL decoded
if ($sPassedToken !== $sConfiguredAccessTokenValue){ $sPassedToken = utils::ReadPostedParam($this->m_sAccessTokenConfigParamId, null, false, 'raw_data');
if (is_null($sPassedToken)){
$sPassedToken = utils::ReadParam($this->m_sAccessTokenConfigParamId, null, false, 'raw_data');
}
$sDecodedPassedToken = urldecode($sPassedToken);
if ($sDecodedPassedToken !== $sConfiguredAccessTokenValue){
$sMsg = "Invalid token passed under '$this->m_sAccessTokenConfigParamId' http param to reach '$sExecModule' page."; $sMsg = "Invalid token passed under '$this->m_sAccessTokenConfigParamId' http param to reach '$sExecModule' page.";
IssueLog::Error($sMsg); IssueLog::Error($sMsg, null,
[
'sHtmlDecodedToken' => $sDecodedPassedToken,
'conf param ID' => $this->m_sAccessTokenConfigParamId
]
);
throw new Exception("Invalid token"); throw new Exception("Invalid token");
} }
} }

View File

@@ -20,6 +20,7 @@ class OAuthClientProviderAzure extends OAuthClientProviderAbstract
'clientId' => $oOAuthClient->Get('client_id'), 'clientId' => $oOAuthClient->Get('client_id'),
'clientSecret' => $oOAuthClient->Get('client_secret'), 'clientSecret' => $oOAuthClient->Get('client_secret'),
'redirectUri' => $oOAuthClient->Get('redirect_url'), 'redirectUri' => $oOAuthClient->Get('redirect_url'),
'tenant' => $oOAuthClient->Get('tenant'),
]; ];
$this->oVendorProvider = new Azure($aOptions, $collaborators); $this->oVendorProvider = new Azure($aOptions, $collaborators);

View File

@@ -0,0 +1,75 @@
<?php
namespace Combodo\iTop\Application\TwigBase\Controller;
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
use MetaModel;
class ControllerTest extends ItopDataTestCase {
protected function setUp(): void
{
parent::setUp();
$this->RequireOnceUnitTestFile('FakeController.php');
}
public function CheckAccessProvider() {
return [
'simple token access OK' => [
'access_token' => 'toto123',
'http_access_token' => 'toto123',
'bSuccess' => true,
],
'simple token access OK sent by POST' => [
'access_token' => 'toto123',
'http_access_token' => 'toto123',
'bSuccess' => true,
'bPost' => true,
],
'simple token access FAILED' => [
'access_token' => 'toto123',
'http_access_token' => 'toto124',
'bSuccess' => false,
],
'url encoded token access OK' => [
'access_token' => 'rfb4j"E?7}-ZJq4T^B*26pk8{;zxem',
'http_access_token' => 'rfb4j%22E%3F7%7D-ZJq4T%5EB%2A26pk8%7B%3Bzxem',
'bSuccess' => true,
],
];
}
/**
* Fix N°7147
* @dataProvider CheckAccessProvider
*/
public function testCheckAccess($sConfiguredAccessToken, $sHttpAccessToken, $bSuccess, $bPost=false){
$sModuleName = "MyModule";
$sTokenParamName = "access_token_conf_param";
$_SESSION = [];
$_POST = [];
$_REQUEST = [];
$_REQUEST['exec_module'] = $sModuleName;
if ($bPost){
$_POST[$sTokenParamName] = $sHttpAccessToken;
} else {
$_REQUEST[$sTokenParamName] = $sHttpAccessToken;
}
$oController = new FakeController();
$oController->SetAccessTokenConfigParamId($sTokenParamName);
MetaModel::GetConfig()->SetModuleSetting($sModuleName, $sTokenParamName, $sConfiguredAccessToken);
if (! $bSuccess){
$this->expectExceptionMessage("Invalid token");
}
$this->InvokeNonPublicMethod(FakeController::class, "CheckAccess", $oController);
if ($bSuccess){
$this->assertTrue(true, "no issue encountered");
}
}
}

View File

@@ -0,0 +1,5 @@
<?php
namespace Combodo\iTop\Application\TwigBase\Controller;
class FakeController extends Controller {
}