Compare commits

...

18 Commits

Author SHA1 Message Date
odain
163276a6c2 N°5620-merge fix 2022-11-23 09:24:21 +01:00
odain
9b0c2f7324 Merge branch 'feature/5620-hide-org-filter-menu' into saas/3.0 2022-11-22 13:47:33 +01:00
odain
e1807f598f N°5620-fix ci 2022-11-22 13:46:33 +01:00
Molkobain
02e63fff64 Add PHPDoc 2022-11-22 13:28:02 +01:00
odain
0864f05d9f N°5620 - conf param renaming + backward compatibility test 2022-11-22 08:25:43 +01:00
denis.flaven@combodo.com
1bbcd9656a N°5619 - fixed crash when no provider at all! 2022-11-22 08:25:43 +01:00
odain
34d8e52c22 N°5620 - remove debug log 2022-11-22 08:25:27 +01:00
odain
ac7309e48c N°5620 - Hide the organization filter with a conf parameter 2022-11-22 08:25:27 +01:00
odain
c8fade6013 5620-simplify test to avoid regression in other test sections linked to MetaModel use 2022-11-22 07:42:03 +01:00
odain
ad052dd861 N°5620-renaming IsOrgMenuFilterAllowed<-IsSiloSelectionEnabled and made public 2022-11-22 07:31:12 +01:00
odain
a5ea868609 fix test 2022-11-21 10:41:03 +01:00
odain
0b03b3ef4d N°5620 - conf param renaming + backward compatibility test 2022-11-21 09:56:56 +01:00
odain
174cace20a N°5620 - remove debug log 2022-11-15 09:55:12 +01:00
odain
e3f5dbfc80 N°5620 - Hide the organization filter with a conf parameter 2022-11-15 09:49:36 +01:00
denis.flaven@combodo.com
40e24c25a2 N°5619 - hide newsroom menu when no provider 2022-11-15 09:17:27 +01:00
odain
c6e4466c53 ci: fix ItopDataTestCase CreateUser contactid unset 2022-10-26 14:03:11 +02:00
odain
6638eb4adc ci: adapt impersonate test to any friendlyname output 2022-10-26 09:50:56 +02:00
odain
eb40968e34 ci: add CreateContactlessUser method in test framework 2022-10-25 09:26:57 +02:00
7 changed files with 143 additions and 21 deletions

View File

@@ -1238,6 +1238,14 @@ class Config
'source_of_value' => '', 'source_of_value' => '',
'show_in_conf_sample' => false, 'show_in_conf_sample' => false,
], ],
'navigation_menu.show_organization_filter' => [
'type' => 'bool',
'description' => 'Display organization filter in menu',
'default' => true,
'value' => true,
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'quick_create.enabled' => [ 'quick_create.enabled' => [
'type' => 'bool', 'type' => 'bool',
'description' => 'Whether or not the quick create is enabled', 'description' => 'Whether or not the quick create is enabled',
@@ -1861,7 +1869,7 @@ class Config
} }
if (strlen($sNoise) > 0) if (strlen($sNoise) > 0)
{ {
// Note: sNoise is an html output, but so far it was ok for me (e.g. showing the entire call stack) // Note: sNoise is an html output, but so far it was ok for me (e.g. showing the entire call stack)
throw new ConfigException('Syntax error in configuration file', throw new ConfigException('Syntax error in configuration file',
array('file' => $sConfigFile, 'error' => '<tt>'.htmlentities($sNoise, ENT_QUOTES, 'UTF-8').'</tt>')); array('file' => $sConfigFile, 'error' => '<tt>'.htmlentities($sNoise, ENT_QUOTES, 'UTF-8').'</tt>'));
} }
@@ -2671,7 +2679,7 @@ class ConfigPlaceholdersResolver
} }
$sPattern = '/\%(env|server)\((\w+)\)(?:\?:(\w*))?\%/'; //3 capturing groups, ie `%env(HTTP_PORT)?:8080%` produce: `env` `HTTP_PORT` and `8080`. $sPattern = '/\%(env|server)\((\w+)\)(?:\?:(\w*))?\%/'; //3 capturing groups, ie `%env(HTTP_PORT)?:8080%` produce: `env` `HTTP_PORT` and `8080`.
if (! preg_match_all($sPattern, $rawValue, $aMatchesCollection, PREG_SET_ORDER)) if (! preg_match_all($sPattern, $rawValue, $aMatchesCollection, PREG_SET_ORDER))
{ {
return $rawValue; return $rawValue;

View File

@@ -49,6 +49,16 @@ class NewsroomMenuFactory
return $oMenu; return $oMenu;
} }
/**
* Check if there is any Newsroom provider configured
* @return boolean
*/
public static function HasProviders()
{
$aProviders = MetaModel::EnumPlugins('iNewsroomProvider');
return count($aProviders) > 0;
}
/** /**
* Prepare parameters for the newsroom JS widget * Prepare parameters for the newsroom JS widget
* *

View File

@@ -19,7 +19,6 @@
namespace Combodo\iTop\Application\UI\Base\Layout\NavigationMenu; namespace Combodo\iTop\Application\UI\Base\Layout\NavigationMenu;
use ApplicationContext; use ApplicationContext;
use ApplicationMenu; use ApplicationMenu;
use appUserPreferences; use appUserPreferences;
@@ -35,6 +34,7 @@ use MetaModel;
use UIExtKeyWidget; use UIExtKeyWidget;
use UserRights; use UserRights;
use utils; use utils;
use Combodo\iTop\Application\UI\Base\Component\PopoverMenu\NewsroomMenu\NewsroomMenuFactory;
/** /**
* Class NavigationMenu * Class NavigationMenu
@@ -196,7 +196,7 @@ class NavigationMenu extends UIBlock implements iKeyboardShortcut
} }
return ''; return '';
} }
/** /**
* @return array * @return array
*/ */
@@ -269,7 +269,7 @@ class NavigationMenu extends UIBlock implements iKeyboardShortcut
*/ */
public function IsNewsroomEnabled(): bool public function IsNewsroomEnabled(): bool
{ {
return MetaModel::GetConfig()->Get('newsroom_enabled'); return (MetaModel::GetConfig()->Get('newsroom_enabled') && NewsroomMenuFactory::HasProviders());
} }
/** /**
@@ -290,6 +290,14 @@ class NavigationMenu extends UIBlock implements iKeyboardShortcut
} }
} }
/**
* @return True if the silo selection is enabled, false otherwise
* @since 3.1.0
*/
public function IsSiloSelectionEnabled() : bool {
return MetaModel::GetConfig()->Get('navigation_menu.show_organization_filter');
}
/** /**
* @return void * @return void
* @throws \CoreException * @throws \CoreException
@@ -301,6 +309,10 @@ class NavigationMenu extends UIBlock implements iKeyboardShortcut
$this->bHasSiloSelected = false; $this->bHasSiloSelected = false;
$this->sSiloLabel = null; $this->sSiloLabel = null;
if (! $this->IsSiloSelectionEnabled()){
return;
}
//TODO 3.0 Use components if we have the time to build select/autocomplete components before release //TODO 3.0 Use components if we have the time to build select/autocomplete components before release
// List of visible Organizations // List of visible Organizations
$iCount = 0; $iCount = 0;
@@ -343,7 +355,7 @@ class NavigationMenu extends UIBlock implements iKeyboardShortcut
$this->aSiloSelection['html'] = '<form data-role="ibo-navigation-menu--silo-selection--form" action="'.utils::GetAbsoluteUrlAppRoot().'pages/UI.php">'; //<select class="org_combo" name="c[org_id]" title="Pick an organization" onChange="this.form.submit();">'; $this->aSiloSelection['html'] = '<form data-role="ibo-navigation-menu--silo-selection--form" action="'.utils::GetAbsoluteUrlAppRoot().'pages/UI.php">'; //<select class="org_combo" name="c[org_id]" title="Pick an organization" onChange="this.form.submit();">';
$oPage = new \CaptureWebPage(); $oPage = new \CaptureWebPage();
$oWidget = new UIExtKeyWidget('Organization', 'org_id', '', true /* search mode */); $oWidget = new UIExtKeyWidget('Organization', 'org_id', '', true /* search mode */);
$iMaxComboLength = MetaModel::GetConfig()->Get('max_combo_length'); $iMaxComboLength = MetaModel::GetConfig()->Get('max_combo_length');
$this->aSiloSelection['html'] .= $oWidget->DisplaySelect($oPage, $iMaxComboLength, false, Dict::S('UI:Layout:NavigationMenu:Silo:Label'), $oSet, $iCurrentOrganization, false, 'c[org_id]', '', $this->aSiloSelection['html'] .= $oWidget->DisplaySelect($oPage, $iMaxComboLength, false, Dict::S('UI:Layout:NavigationMenu:Silo:Label'), $oSet, $iCurrentOrganization, false, 'c[org_id]', '',
@@ -376,7 +388,7 @@ $sAddClearButton
JS; JS;
} }
} }
/** /**
* Compute if the menu is expanded or collapsed * Compute if the menu is expanded or collapsed
* *
@@ -479,4 +491,4 @@ JS;
{ {
return "[data-role='".static::BLOCK_CODE."']"; return "[data-role='".static::BLOCK_CODE."']";
} }
} }

View File

@@ -48,7 +48,7 @@ class NavigationMenuFactory
{ {
$oNewsroomMenu = null; $oNewsroomMenu = null;
if (MetaModel::GetConfig()->Get('newsroom_enabled')) if (MetaModel::GetConfig()->Get('newsroom_enabled') && NewsroomMenuFactory::HasProviders())
{ {
$oNewsroomMenu = NewsroomMenuFactory::MakeNewsroomMenuForNavigationMenu(); $oNewsroomMenu = NewsroomMenuFactory::MakeNewsroomMenuForNavigationMenu();
} }

View File

@@ -410,10 +410,25 @@ class ItopDataTestCase extends ItopTestCase
* @param string $sLogin * @param string $sLogin
* @param int $iProfileId * @param int $iProfileId
* *
* @return \DBObject * @return \UserLocal
* @throws Exception * @throws Exception
*/ */
protected function CreateUser($sLogin, $iProfileId, $sPassword=null, $iContactid=2) protected function CreateUser($sLogin, $iProfileId, $sPassword=null, $iContactid=2)
{
$oUser = $this->CreateContactlessUser($sLogin, $iProfileId, $sPassword);
$oUser->Set('contactid', $iContactid);
$oUser->DBWrite();
return $oUser;
}
/**
* @param string $sLogin
* @param int $iProfileId
*
* @return \UserLocal
* @throws Exception
*/
protected function CreateContactlessUser($sLogin, $iProfileId, $sPassword=null)
{ {
if (empty($sPassword)){ if (empty($sPassword)){
$sPassword = $sLogin; $sPassword = $sLogin;
@@ -423,8 +438,8 @@ class ItopDataTestCase extends ItopTestCase
$oUserProfile->Set('profileid', $iProfileId); $oUserProfile->Set('profileid', $iProfileId);
$oUserProfile->Set('reason', 'UNIT Tests'); $oUserProfile->Set('reason', 'UNIT Tests');
$oSet = DBObjectSet::FromObject($oUserProfile); $oSet = DBObjectSet::FromObject($oUserProfile);
/** @var \UserLocal $oUser */
$oUser = $this->createObject('UserLocal', array( $oUser = $this->createObject('UserLocal', array(
'contactid' => $iContactid,
'login' => $sLogin, 'login' => $sLogin,
'password' => $sPassword, 'password' => $sPassword,
'language' => 'EN US', 'language' => 'EN US',

View File

@@ -0,0 +1,67 @@
<?php
namespace UI\Base\Layout;
use ApplicationContext;
use Combodo\iTop\Application\UI\Base\Component\PopoverMenu\PopoverMenu;
use Combodo\iTop\Application\UI\Base\Layout\NavigationMenu\NavigationMenu;
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
/**
*
* @runTestsInSeparateProcesses
* @preserveGlobalState disabled
* @backupGlobals disabled
* Class NavigationMenuTest
*
* @package UI\Base\Layout
*/
class NavigationMenuTest extends ItopDataTestCase {
public function IsAllowedProvider(){
return [
'show menu' => [ true ],
'hide menu' => [ false ],
];
}
/**
* @dataProvider IsAllowedProvider
* test used to make sure backward compatibility is ensured
*/
public function testIsAllowed($bExpectedIsAllowed=true){
\MetaModel::GetConfig()->Set('navigation_menu.show_organization_filter', $bExpectedIsAllowed);
$oNavigationMenu = new NavigationMenu(
$this->createMock(ApplicationContext::class),
$this->createMock(PopoverMenu::class));
$isAllowed = $oNavigationMenu->IsSiloSelectionEnabled();
$this->assertEquals($bExpectedIsAllowed, $isAllowed);
}
public function testIsAllowed_BackwardCompatibility_NoVariableInConfFile(){
\MetaModel::GetConfig()->Set('navigation_menu.show_organization_filter', false);
$sTmpFilePath = tempnam(sys_get_temp_dir(), 'test_');
$oInitConfig = \MetaModel::GetConfig();
$oInitConfig->WriteToFile($sTmpFilePath);
//remove variable for the test
$aLines = file($sTmpFilePath);
$aRows = array();
foreach ($aLines as $key => $sLine) {
if (!preg_match('/navigation_menu.show_organization_filter/', $sLine)) {
$aRows[] = $sLine;
}
}
file_put_contents($sTmpFilePath, implode("\n", $aRows));
$oTempConfig = new \Config($sTmpFilePath);
$isAllowed = $oTempConfig->Get('navigation_menu.show_organization_filter');
$this->assertEquals(true, $isAllowed);
unlink($sTmpFilePath);
}
}

View File

@@ -108,8 +108,8 @@ class CMDBObjectTest extends ItopDataTestCase
$sAdminLogin = "admin-user-".$sUid; $sAdminLogin = "admin-user-".$sUid;
$sImpersonatedLogin = "impersonated-user-".$sUid; $sImpersonatedLogin = "impersonated-user-".$sUid;
$iAdminUserId = $this->CreateUserForImpersonation($sAdminLogin, 'Administrator', 'AdminName', 'AdminSurName'); $oAdminUser = $this->CreateUserForImpersonation($sAdminLogin, 'Administrator', 'AdminName', 'AdminSurName');
$this->CreateUserForImpersonation($sImpersonatedLogin, 'Configuration Manager', 'ImpersonatedName', 'ImpersonatedSurName'); $oImpersonatedUser = $this->CreateUserForImpersonation($sImpersonatedLogin, 'Configuration Manager', 'ImpersonatedName', 'ImpersonatedSurName');
$_SESSION = []; $_SESSION = [];
\UserRights::Login($sAdminLogin); \UserRights::Login($sAdminLogin);
@@ -124,28 +124,31 @@ class CMDBObjectTest extends ItopDataTestCase
if (is_null($sTrackInfo)){ if (is_null($sTrackInfo)){
CMDBObject::SetTrackInfo(null); CMDBObject::SetTrackInfo(null);
} else { } else {
$sTrackInfo = $this->ReplaceByFriendlyNames($sTrackInfo, $oAdminUser, $oImpersonatedUser);
CMDBObject::SetTrackInfo($sTrackInfo); CMDBObject::SetTrackInfo($sTrackInfo);
} }
$this->CreateSimpleObject(); $this->CreateSimpleObject();
if (is_null($sTrackInfo)){ if (is_null($sTrackInfo)){
self::assertEquals("AdminSurName AdminName", CMDBObject::GetCurrentChange()->Get('userinfo'), self::assertEquals($oAdminUser->GetFriendlyName(), CMDBObject::GetCurrentChange()->Get('userinfo'),
'TrackInfo : no impersonation'); 'TrackInfo : no impersonation');
} else { } else {
self::assertEquals($sTrackInfo, CMDBObject::GetCurrentChange()->Get('userinfo'), self::assertEquals($sTrackInfo, CMDBObject::GetCurrentChange()->Get('userinfo'),
'TrackInfo : no impersonation'); 'TrackInfo : no impersonation');
} }
self::assertEquals($iAdminUserId, CMDBObject::GetCurrentChange()->Get('user_id'), self::assertEquals($oAdminUser->GetKey(), CMDBObject::GetCurrentChange()->Get('user_id'),
'TrackInfo : admin userid'); 'TrackInfo : admin userid');
\UserRights::Impersonate($sImpersonatedLogin); \UserRights::Impersonate($sImpersonatedLogin);
$this->CreateSimpleObject(); $this->CreateSimpleObject();
if (is_null($sExpectedChangeLogWhenImpersonation)){ if (is_null($sExpectedChangeLogWhenImpersonation)){
self::assertEquals("AdminSurName AdminName on behalf of ImpersonatedSurName ImpersonatedName", CMDBObject::GetCurrentChange()->Get('userinfo'), $sExpectedMsg = $this->ReplaceByFriendlyNames("AdminSurName AdminName on behalf of ImpersonatedSurName ImpersonatedName", $oAdminUser, $oImpersonatedUser);
self::assertEquals($sExpectedMsg, CMDBObject::GetCurrentChange()->Get('userinfo'),
'TrackInfo : impersonation'); 'TrackInfo : impersonation');
} else { } else {
self::assertEquals($sExpectedChangeLogWhenImpersonation, CMDBObject::GetCurrentChange()->Get('userinfo'), $sExpectedMsg = $this->ReplaceByFriendlyNames($sExpectedChangeLogWhenImpersonation, $oAdminUser, $oImpersonatedUser);
self::assertEquals($sExpectedMsg, CMDBObject::GetCurrentChange()->Get('userinfo'),
'TrackInfo : impersonation'); 'TrackInfo : impersonation');
} }
@@ -155,13 +158,13 @@ class CMDBObjectTest extends ItopDataTestCase
\UserRights::Deimpersonate(); \UserRights::Deimpersonate();
$this->CreateSimpleObject(); $this->CreateSimpleObject();
if (is_null($sTrackInfo)){ if (is_null($sTrackInfo)){
self::assertEquals("AdminSurName AdminName", CMDBObject::GetCurrentChange()->Get('userinfo'), self::assertEquals($oAdminUser->GetFriendlyName(), CMDBObject::GetCurrentChange()->Get('userinfo'),
'TrackInfo : no impersonation'); 'TrackInfo : no impersonation');
} else { } else {
self::assertEquals($sTrackInfo, CMDBObject::GetCurrentChange()->Get('userinfo'), self::assertEquals($sTrackInfo, CMDBObject::GetCurrentChange()->Get('userinfo'),
'TrackInfo : no impersonation'); 'TrackInfo : no impersonation');
} }
self::assertEquals($iAdminUserId, CMDBObject::GetCurrentChange()->Get('user_id'), self::assertEquals($oAdminUser->GetKey(), CMDBObject::GetCurrentChange()->Get('user_id'),
'TrackInfo : admin userid'); 'TrackInfo : admin userid');
// restore initial conditions // restore initial conditions
@@ -169,6 +172,12 @@ class CMDBObjectTest extends ItopDataTestCase
CMDBObject::SetTrackInfo($sInitialTrackInfo); CMDBObject::SetTrackInfo($sInitialTrackInfo);
} }
private function ReplaceByFriendlyNames($sMessage, $oAdminUser, $oImpersonatedUser) : string {
$sNewMessage = str_replace('AdminSurName AdminName', $oAdminUser->GetFriendlyName(), $sMessage);
$sNewMessage = str_replace('ImpersonatedSurName ImpersonatedName', $oImpersonatedUser->GetFriendlyName(), $sNewMessage);
return $sNewMessage;
}
private function CreateSimpleObject(){ private function CreateSimpleObject(){
/** @var \DocumentWeb $oTestObject */ /** @var \DocumentWeb $oTestObject */
$oTestObject = MetaModel::NewObject('DocumentWeb'); $oTestObject = MetaModel::NewObject('DocumentWeb');
@@ -178,7 +187,7 @@ class CMDBObjectTest extends ItopDataTestCase
$oTestObject->DBWrite(); $oTestObject->DBWrite();
} }
private function CreateUserForImpersonation($sLogin, $sProfileName, $sName, $sSurname): int { private function CreateUserForImpersonation($sLogin, $sProfileName, $sName, $sSurname): \UserLocal {
/** @var \Person $oPerson */ /** @var \Person $oPerson */
$oPerson = $this->createObject('Person', array( $oPerson = $this->createObject('Person', array(
'name' => $sName, 'name' => $sName,
@@ -187,8 +196,9 @@ class CMDBObjectTest extends ItopDataTestCase
)); ));
$oProfile = \MetaModel::GetObjectFromOQL("SELECT URP_Profiles WHERE name = :name", array('name' => $sProfileName), true); $oProfile = \MetaModel::GetObjectFromOQL("SELECT URP_Profiles WHERE name = :name", array('name' => $sProfileName), true);
/** @var \UserLocal $oUser */
$oUser = $this->CreateUser($sLogin, $oProfile->GetKey(), "1234567Azert@", $oPerson->GetKey()); $oUser = $this->CreateUser($sLogin, $oProfile->GetKey(), "1234567Azert@", $oPerson->GetKey());
return $oUser->GetKey(); return $oUser;
} }
} }