mirror of
https://github.com/Combodo/iTop.git
synced 2026-07-01 04:06:37 +02:00
Compare commits
10 Commits
feature/fa
...
issue/8542
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d2dba253d1 | ||
|
|
7791585387 | ||
|
|
3406ca79de | ||
|
|
91ad01055e | ||
|
|
804cdffe42 | ||
|
|
5f4affc896 | ||
|
|
042fee2360 | ||
|
|
7f8ec25977 | ||
|
|
41f8437c23 | ||
|
|
df8b25d4b4 |
@@ -810,6 +810,7 @@ HTML
|
||||
foreach ($aNotificationClasses as $sNotifClass) {
|
||||
$aNotifSearches[$sNotifClass] = DBObjectSearch::FromOQL("SELECT $sNotifClass AS Ev JOIN Trigger AS T ON Ev.trigger_id = T.id WHERE T.id IN (:triggers) AND Ev.object_id = :id");
|
||||
$aNotifSearches[$sNotifClass]->SetInternalParams($aParams);
|
||||
$aNotifSearches[$sNotifClass]->AllowAllData();
|
||||
$oNotifSet = new DBObjectSet($aNotifSearches[$sNotifClass], []);
|
||||
$iNotifsCount += $oNotifSet->Count();
|
||||
}
|
||||
@@ -823,6 +824,7 @@ HTML
|
||||
'menu' => false,
|
||||
'panel_title' => MetaModel::GetName($sNotifClass),
|
||||
'panel_icon' => MetaModel::GetClassIcon($sNotifClass, false),
|
||||
'display_unauthorized_objects' => true,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -724,6 +724,10 @@ class DisplayBlock
|
||||
}
|
||||
}
|
||||
|
||||
if (!$this->m_oFilter->IsAllDataAllowed() && ($aExtraParams['display_unauthorized_objects'] ?? false) === true) {
|
||||
$this->m_oFilter->AllowAllData();
|
||||
}
|
||||
|
||||
$aExtraParams['query_params'] = $this->m_oFilter->GetInternalParams();
|
||||
$this->m_oSet = new CMDBObjectSet($this->m_oFilter, $aOrderBy, $aQueryParams);
|
||||
}
|
||||
@@ -1381,7 +1385,10 @@ JS
|
||||
|
||||
// Check the classes that can be read (i.e authorized) by this user...
|
||||
foreach ($aClasses as $sAlias => $sClassName) {
|
||||
if (UserRights::IsActionAllowed($sClassName, UR_ACTION_READ, $this->m_oSet) != UR_ALLOWED_NO) {
|
||||
if (
|
||||
(UserRights::IsActionAllowed($sClassName, UR_ACTION_READ, $this->m_oSet) !== UR_ALLOWED_NO)
|
||||
|| ($aExtraParams['display_unauthorized_objects'] ?? false) === true
|
||||
) {
|
||||
$aAuthorizedClasses[$sAlias] = $sClassName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -936,11 +936,6 @@ CSS;
|
||||
public static function CloneThemeParameterAndIncludeVersion($aThemeParameters, $bSetupCompilationTimestamp, $aImportsPaths)
|
||||
{
|
||||
$aThemeParametersVariable = [];
|
||||
if (array_key_exists('variables', $aThemeParameters)) {
|
||||
if (is_array($aThemeParameters['variables'])) {
|
||||
$aThemeParametersVariable = array_merge([], $aThemeParameters['variables']);
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists('variable_imports', $aThemeParameters)) {
|
||||
if (is_array($aThemeParameters['variable_imports'])) {
|
||||
@@ -948,6 +943,14 @@ CSS;
|
||||
}
|
||||
}
|
||||
|
||||
// Variables defined in theme XML have the priority over variables defined in XML imports files
|
||||
// They're defined after so they overwrite previous parameters
|
||||
if (array_key_exists('variables', $aThemeParameters)) {
|
||||
if (is_array($aThemeParameters['variables'])) {
|
||||
$aThemeParametersVariable = array_merge($aThemeParametersVariable, $aThemeParameters['variables']);
|
||||
}
|
||||
}
|
||||
|
||||
$aThemeParametersVariable['$version'] = $bSetupCompilationTimestamp;
|
||||
return $aThemeParametersVariable;
|
||||
}
|
||||
|
||||
@@ -1455,6 +1455,12 @@ class utils
|
||||
|
||||
case iPopupMenuExtension::MENU_OBJLIST_TOOLKIT:
|
||||
/** @var \DBObjectSet $param */
|
||||
|
||||
// Check if the user has the right to read the objects of this list, otherwise do not propose any action (eg. configure this list, export, etc.)
|
||||
if (UserRights::IsActionAllowed($param->GetFilter()->GetClass(), UR_ACTION_READ, $param) !== UR_ALLOWED_YES) {
|
||||
break;
|
||||
}
|
||||
|
||||
$oAppContext = new ApplicationContext();
|
||||
$sContext = $oAppContext->GetForLink(true);
|
||||
$sDataTableId = is_null($sDataTableId) ? '' : $sDataTableId;
|
||||
|
||||
@@ -234,10 +234,11 @@ abstract class Action extends cmdbAbstractObject
|
||||
}
|
||||
|
||||
$oActionFilter = DBObjectSearch::FromOQL($sActionQueryOql, $aActionQueryParams);
|
||||
$oActionFilter->AllowAllData();
|
||||
$oSet = new DBObjectSet($oActionFilter, ['date' => false]);
|
||||
|
||||
$sPanelTitle = Dict::Format('Action:last_executions_tab_panel_title', $sActionQueryLimit);
|
||||
$oExecutionsListBlock = DataTableUIBlockFactory::MakeForResult($oPage, 'action_executions_list', $oSet, ['panel_title' => $sPanelTitle]);
|
||||
$oExecutionsListBlock = DataTableUIBlockFactory::MakeForResult($oPage, 'action_executions_list', $oSet, ['panel_title' => $sPanelTitle, 'display_unauthorized_objects' => true]);
|
||||
|
||||
$oPage->AddUiBlock($oExecutionsListBlock);
|
||||
}
|
||||
|
||||
@@ -409,7 +409,7 @@
|
||||
</php_parent>
|
||||
<parent>cmdbAbstractObject</parent>
|
||||
<properties>
|
||||
<category>core/cmdb,view_in_gui</category>
|
||||
<category>core/cmdb,grant_by_profile,silo</category>
|
||||
<abstract>false</abstract>
|
||||
<key_type>autoincrement</key_type>
|
||||
<db_table>priv_event_newsroom</db_table>
|
||||
@@ -888,7 +888,7 @@
|
||||
<!-- Generated by toolkit/export-class-to-meta.php -->
|
||||
<parent>Event</parent>
|
||||
<properties>
|
||||
<category>core/cmdb,view_in_gui</category>
|
||||
<category>core/cmdb,grant_by_profile,silo</category>
|
||||
</properties>
|
||||
<fields>
|
||||
<field id="message" xsi:type="AttributeText"/>
|
||||
|
||||
@@ -26,7 +26,7 @@ class Event extends DBObject implements iDisplay
|
||||
{
|
||||
$aParams =
|
||||
[
|
||||
"category" => "core/cmdb,view_in_gui",
|
||||
"category" => "core/cmdb,grant_by_profile,silo",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
@@ -120,7 +120,7 @@ class EventNotification extends Event
|
||||
{
|
||||
$aParams =
|
||||
[
|
||||
"category" => "core/cmdb,view_in_gui",
|
||||
"category" => "core/cmdb,grant_by_profile,silo",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
@@ -154,7 +154,7 @@ class EventNotificationEmail extends EventNotification
|
||||
{
|
||||
$aParams =
|
||||
[
|
||||
"category" => "core/cmdb,view_in_gui",
|
||||
"category" => "core/cmdb,grant_by_profile,silo",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
@@ -190,7 +190,7 @@ class EventIssue extends Event
|
||||
{
|
||||
$aParams =
|
||||
[
|
||||
"category" => "core/cmdb,view_in_gui",
|
||||
"category" => "core/cmdb,grant_by_profile,silo",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
@@ -284,7 +284,7 @@ class EventWebService extends Event
|
||||
{
|
||||
$aParams =
|
||||
[
|
||||
"category" => "core/cmdb,view_in_gui",
|
||||
"category" => "core/cmdb,grant_by_profile,silo",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
@@ -319,7 +319,7 @@ class EventRestService extends Event
|
||||
{
|
||||
$aParams =
|
||||
[
|
||||
"category" => "core/cmdb,view_in_gui",
|
||||
"category" => "core/cmdb,grant_by_profile,silo",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
@@ -354,7 +354,7 @@ class EventLoginUsage extends Event
|
||||
{
|
||||
$aParams =
|
||||
[
|
||||
"category" => "core/cmdb,view_in_gui",
|
||||
"category" => "core/cmdb,grant_by_profile,silo",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
@@ -392,7 +392,7 @@ class EventOnObject extends Event
|
||||
{
|
||||
$aParams =
|
||||
[
|
||||
"category" => "core/cmdb,view_in_gui",
|
||||
"category" => "core/cmdb,grant_by_profile,silo",
|
||||
"key_type" => "autoincrement",
|
||||
"name_attcode" => "",
|
||||
"state_attcode" => "",
|
||||
|
||||
@@ -350,15 +350,18 @@ class ormDocument
|
||||
if (!is_object($oObj)) {
|
||||
// If access to the document is not granted, check if the access to the host object is allowed
|
||||
$oObj = MetaModel::GetObject($sClass, $id, false, true);
|
||||
$bHasHostRights = false;
|
||||
if ($oObj instanceof Attachment) {
|
||||
$sItemClass = $oObj->Get('item_class');
|
||||
$sItemId = $oObj->Get('item_id');
|
||||
$oHost = MetaModel::GetObject($sItemClass, $sItemId, false, false);
|
||||
if (!is_object($oHost)) {
|
||||
$oObj = null;
|
||||
if (is_object($oHost)) {
|
||||
$bHasHostRights = true;
|
||||
}
|
||||
}
|
||||
if (!is_object($oObj)) {
|
||||
|
||||
// We could neither read the object nor get a host object matching our rights
|
||||
if ($bHasHostRights !== true) {
|
||||
throw new Exception("Invalid id ($id) for class '$sClass' - the object does not exist or you are not allowed to view it");
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -68,47 +68,47 @@ $ibo-color-information-900: #0f172a !default;
|
||||
$ibo-color-information-950: #020617 !default;
|
||||
|
||||
|
||||
$ibo-lifecycle-new-state-primary-color: $ibo-color-information-600;
|
||||
$ibo-lifecycle-new-state-secondary-color: $ibo-color-white-100;
|
||||
$ibo-lifecycle-neutral-state-primary-color: $ibo-color-information-600;
|
||||
$ibo-lifecycle-neutral-state-secondary-color: $ibo-color-white-100;
|
||||
$ibo-lifecycle-waiting-state-primary-color: $ibo-color-yellow-700;
|
||||
$ibo-lifecycle-waiting-state-secondary-color: $ibo-color-white-100;
|
||||
$ibo-lifecycle-success-state-primary-color: $ibo-color-blue-700;
|
||||
$ibo-lifecycle-success-state-secondary-color: $ibo-color-white-100;
|
||||
$ibo-lifecycle-failure-state-primary-color: $ibo-color-orange-800;
|
||||
$ibo-lifecycle-failure-state-secondary-color: $ibo-color-white-100;
|
||||
$ibo-lifecycle-frozen-state-primary-color: $ibo-color-information-200;
|
||||
$ibo-lifecycle-frozen-state-secondary-color: $ibo-color-information-700;
|
||||
$ibo-lifecycle-new-state-primary-color: $ibo-color-information-600 !default;
|
||||
$ibo-lifecycle-new-state-secondary-color: $ibo-color-white-100 !default;
|
||||
$ibo-lifecycle-neutral-state-primary-color: $ibo-color-information-600 !default;
|
||||
$ibo-lifecycle-neutral-state-secondary-color: $ibo-color-white-100 !default;
|
||||
$ibo-lifecycle-waiting-state-primary-color: $ibo-color-yellow-700 !default;
|
||||
$ibo-lifecycle-waiting-state-secondary-color: $ibo-color-white-100 !default;
|
||||
$ibo-lifecycle-success-state-primary-color: $ibo-color-blue-700 !default;
|
||||
$ibo-lifecycle-success-state-secondary-color: $ibo-color-white-100 !default;
|
||||
$ibo-lifecycle-failure-state-primary-color: $ibo-color-orange-800 !default;
|
||||
$ibo-lifecycle-failure-state-secondary-color: $ibo-color-white-100 !default;
|
||||
$ibo-lifecycle-frozen-state-primary-color: $ibo-color-information-200 !default;
|
||||
$ibo-lifecycle-frozen-state-secondary-color: $ibo-color-information-700 !default;
|
||||
|
||||
$ibo-lifecycle-active-state-primary-color: $ibo-color-blue-700;
|
||||
$ibo-lifecycle-active-state-secondary-color: $ibo-color-white-100;
|
||||
$ibo-lifecycle-inactive-state-primary-color: $ibo-color-yellow-700;
|
||||
$ibo-lifecycle-inactive-state-secondary-color: $ibo-color-white-100;
|
||||
$ibo-lifecycle-active-state-primary-color: $ibo-color-blue-700 !default;
|
||||
$ibo-lifecycle-active-state-secondary-color: $ibo-color-white-100 !default;
|
||||
$ibo-lifecycle-inactive-state-primary-color: $ibo-color-yellow-700 !default;
|
||||
$ibo-lifecycle-inactive-state-secondary-color: $ibo-color-white-100 !default;
|
||||
|
||||
$ibo-caselog-highlight-color-1: $ibo-color-blue-700;
|
||||
$ibo-caselog-highlight-color-2: $ibo-color-yellow-700;
|
||||
$ibo-caselog-highlight-color-3: $ibo-color-information-600;
|
||||
$ibo-caselog-highlight-color-4: $ibo-color-yellow-500;
|
||||
$ibo-caselog-highlight-color-5: $ibo-color-blue-500;
|
||||
$ibo-caselog-highlight-color-6: $ibo-color-yellow-300;
|
||||
$ibo-caselog-highlight-color-7: $ibo-color-blue-300;
|
||||
$ibo-caselog-highlight-color-1: $ibo-color-blue-700 !default;
|
||||
$ibo-caselog-highlight-color-2: $ibo-color-yellow-700 !default;
|
||||
$ibo-caselog-highlight-color-3: $ibo-color-information-600 !default;
|
||||
$ibo-caselog-highlight-color-4: $ibo-color-yellow-500 !default;
|
||||
$ibo-caselog-highlight-color-5: $ibo-color-blue-500 !default;
|
||||
$ibo-caselog-highlight-color-6: $ibo-color-yellow-300 !default;
|
||||
$ibo-caselog-highlight-color-7: $ibo-color-blue-300 !default;
|
||||
|
||||
$ibo-input-wrapper--is-error--border-color: $ibo-color-warning-700;
|
||||
$ibo-field-validation: $ibo-color-warning-800;
|
||||
$ibo-input-wrapper--is-error--border-color: $ibo-color-warning-700 !default;
|
||||
$ibo-field-validation: $ibo-color-warning-800 !default;
|
||||
|
||||
$ibo-navigation-menu--visual-hint--background-color: $ibo-color-blue-400;
|
||||
$ibo-navigation-menu--visual-hint--background-color: $ibo-color-blue-400 !default;
|
||||
|
||||
$ibo-wizard-container--background-color: $ibo-color-information-200;
|
||||
$ibo-wizard-container--border-color: $ibo-color-information-600;
|
||||
$ibo-wizard-container--background-color: $ibo-color-information-200 !default;
|
||||
$ibo-wizard-container--border-color: $ibo-color-information-600 !default;
|
||||
|
||||
$ibo-navigation-menu--notifications--item--new-message-indicator--background-color: $ibo-color-white-100;
|
||||
$ibo-navigation-menu--notifications--item--new-message-indicator--border: solid 2px $ibo-color-grey-500;
|
||||
$ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-1--background-color: $ibo-color-danger-100;
|
||||
$ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-1--border: solid 2px $ibo-color-danger-500;
|
||||
$ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-2--background-color: $ibo-color-warning-100;
|
||||
$ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-2--border: solid 2px $ibo-color-warning-500;
|
||||
$ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-3--background-color: $ibo-color-success-100;
|
||||
$ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-3--border: solid 2px $ibo-color-success-500;
|
||||
$ibo-navigation-menu--notifications--item--new-message-indicator--background-color: $ibo-color-white-100 !default;
|
||||
$ibo-navigation-menu--notifications--item--new-message-indicator--border: solid 2px $ibo-color-grey-500 !default;
|
||||
$ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-1--background-color: $ibo-color-danger-100 !default;
|
||||
$ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-1--border: solid 2px $ibo-color-danger-500 !default;
|
||||
$ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-2--background-color: $ibo-color-warning-100 !default;
|
||||
$ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-2--border: solid 2px $ibo-color-warning-500 !default;
|
||||
$ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-3--background-color: $ibo-color-success-100 !default;
|
||||
$ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-3--border: solid 2px $ibo-color-success-500 !default;
|
||||
|
||||
$ibo-notifications--view-all--item--unread--highlight--background-color: $ibo-color-blue-600;
|
||||
$ibo-notifications--view-all--item--unread--highlight--background-color: $ibo-color-blue-600 !default;
|
||||
@@ -32,47 +32,47 @@ $ibo-color-information-900: #0f172a !default;
|
||||
$ibo-color-information-950: #020617 !default;
|
||||
|
||||
|
||||
$ibo-lifecycle-new-state-primary-color: $ibo-color-information-600;
|
||||
$ibo-lifecycle-new-state-secondary-color: $ibo-color-white-100;
|
||||
$ibo-lifecycle-neutral-state-primary-color: $ibo-color-information-600;
|
||||
$ibo-lifecycle-neutral-state-secondary-color: $ibo-color-white-100;
|
||||
$ibo-lifecycle-waiting-state-primary-color: $ibo-color-red-200;
|
||||
$ibo-lifecycle-waiting-state-secondary-color: $ibo-color-red-800;
|
||||
$ibo-lifecycle-success-state-primary-color: $ibo-color-blue-700;
|
||||
$ibo-lifecycle-success-state-secondary-color: $ibo-color-white-100;
|
||||
$ibo-lifecycle-failure-state-primary-color: $ibo-color-red-800;
|
||||
$ibo-lifecycle-failure-state-secondary-color: $ibo-color-white-100;
|
||||
$ibo-lifecycle-frozen-state-primary-color: $ibo-color-information-200;
|
||||
$ibo-lifecycle-frozen-state-secondary-color: $ibo-color-information-700;
|
||||
$ibo-lifecycle-new-state-primary-color: $ibo-color-information-600 !default;
|
||||
$ibo-lifecycle-new-state-secondary-color: $ibo-color-white-100 !default;
|
||||
$ibo-lifecycle-neutral-state-primary-color: $ibo-color-information-600 !default;
|
||||
$ibo-lifecycle-neutral-state-secondary-color: $ibo-color-white-100 !default;
|
||||
$ibo-lifecycle-waiting-state-primary-color: $ibo-color-red-200 !default;
|
||||
$ibo-lifecycle-waiting-state-secondary-color: $ibo-color-red-800 !default;
|
||||
$ibo-lifecycle-success-state-primary-color: $ibo-color-blue-700 !default;
|
||||
$ibo-lifecycle-success-state-secondary-color: $ibo-color-white-100 !default;
|
||||
$ibo-lifecycle-failure-state-primary-color: $ibo-color-red-800 !default;
|
||||
$ibo-lifecycle-failure-state-secondary-color: $ibo-color-white-100 !default;
|
||||
$ibo-lifecycle-frozen-state-primary-color: $ibo-color-information-200 !default;
|
||||
$ibo-lifecycle-frozen-state-secondary-color: $ibo-color-information-700 !default;
|
||||
|
||||
$ibo-lifecycle-active-state-primary-color: $ibo-color-blue-700;
|
||||
$ibo-lifecycle-active-state-secondary-color: $ibo-color-white-100;
|
||||
$ibo-lifecycle-inactive-state-primary-color: $ibo-color-red-700;
|
||||
$ibo-lifecycle-inactive-state-secondary-color: $ibo-color-white-100;
|
||||
$ibo-lifecycle-active-state-primary-color: $ibo-color-blue-700 !default;
|
||||
$ibo-lifecycle-active-state-secondary-color: $ibo-color-white-100 !default;
|
||||
$ibo-lifecycle-inactive-state-primary-color: $ibo-color-red-700 !default;
|
||||
$ibo-lifecycle-inactive-state-secondary-color: $ibo-color-white-100 !default;
|
||||
|
||||
$ibo-caselog-highlight-color-1: $ibo-color-blue-700;
|
||||
$ibo-caselog-highlight-color-2: $ibo-color-red-700;
|
||||
$ibo-caselog-highlight-color-3: $ibo-color-information-600;
|
||||
$ibo-caselog-highlight-color-4: $ibo-color-red-500;
|
||||
$ibo-caselog-highlight-color-5: $ibo-color-blue-500;
|
||||
$ibo-caselog-highlight-color-6: $ibo-color-red-300;
|
||||
$ibo-caselog-highlight-color-7: $ibo-color-blue-300;
|
||||
$ibo-caselog-highlight-color-1: $ibo-color-blue-700 !default;
|
||||
$ibo-caselog-highlight-color-2: $ibo-color-red-700 !default;
|
||||
$ibo-caselog-highlight-color-3: $ibo-color-information-600 !default;
|
||||
$ibo-caselog-highlight-color-4: $ibo-color-red-500 !default;
|
||||
$ibo-caselog-highlight-color-5: $ibo-color-blue-500 !default;
|
||||
$ibo-caselog-highlight-color-6: $ibo-color-red-300 !default;
|
||||
$ibo-caselog-highlight-color-7: $ibo-color-blue-300 !default;
|
||||
|
||||
$ibo-input-wrapper--is-error--border-color: $ibo-color-pink-700;
|
||||
$ibo-field-validation: $ibo-color-pink-800;
|
||||
$ibo-input-wrapper--is-error--border-color: $ibo-color-pink-700 !default;
|
||||
$ibo-field-validation: $ibo-color-pink-800 !default;
|
||||
|
||||
$ibo-navigation-menu--visual-hint--background-color: $ibo-color-pink-600;
|
||||
$ibo-navigation-menu--visual-hint--background-color: $ibo-color-pink-600 !default;
|
||||
|
||||
$ibo-wizard-container--background-color: $ibo-color-information-200;
|
||||
$ibo-wizard-container--border-color: $ibo-color-information-600;
|
||||
$ibo-wizard-container--background-color: $ibo-color-information-200 !default;
|
||||
$ibo-wizard-container--border-color: $ibo-color-information-600 !default;
|
||||
|
||||
$ibo-navigation-menu--notifications--item--new-message-indicator--background-color: $ibo-color-white-100;
|
||||
$ibo-navigation-menu--notifications--item--new-message-indicator--border: solid 2px $ibo-color-grey-500;
|
||||
$ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-1--background-color: $ibo-color-pink-100;
|
||||
$ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-1--border: solid 2px $ibo-color-pink-600;
|
||||
$ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-2--background-color: $ibo-color-warning-100;
|
||||
$ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-2--border: solid 2px $ibo-color-warning-400;
|
||||
$ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-3--background-color: $ibo-color-success-100;
|
||||
$ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-3--border: solid 2px $ibo-color-success-500;
|
||||
$ibo-navigation-menu--notifications--item--new-message-indicator--background-color: $ibo-color-white-100 !default;
|
||||
$ibo-navigation-menu--notifications--item--new-message-indicator--border: solid 2px $ibo-color-grey-500 !default;
|
||||
$ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-1--background-color: $ibo-color-pink-100 !default;
|
||||
$ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-1--border: solid 2px $ibo-color-pink-600 !default;
|
||||
$ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-2--background-color: $ibo-color-warning-100 !default;
|
||||
$ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-2--border: solid 2px $ibo-color-warning-400 !default;
|
||||
$ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-3--background-color: $ibo-color-success-100 !default;
|
||||
$ibo-navigation-menu--notifications--item--new-message-indicator--is-priority-3--border: solid 2px $ibo-color-success-500 !default;
|
||||
|
||||
$ibo-notifications--view-all--item--unread--highlight--background-color: $ibo-color-pink-500;
|
||||
$ibo-notifications--view-all--item--unread--highlight--background-color: $ibo-color-pink-500 !default;
|
||||
@@ -279,11 +279,24 @@ try {
|
||||
$oRuntimeEnv = new RunTimeEnvironment('production', true);
|
||||
|
||||
try {
|
||||
SetupLog::Info('Move to production starts...');
|
||||
$sAuthent = utils::ReadParam('authent', '', false, 'raw_data');
|
||||
if (!file_exists(APPROOT.'data/hub/compile_authent') || $sAuthent !== file_get_contents(APPROOT.'data/hub/compile_authent')) {
|
||||
throw new SecurityException(Dict::S('iTopHub:FailAuthent'));
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
if (file_exists(APPROOT.'data/hub/compile_authent')) {
|
||||
unlink(APPROOT.'data/hub/compile_authent');
|
||||
}
|
||||
// Note: at this point, the dictionnary is not necessarily loaded
|
||||
SetupLog::Error(get_class($e).': '.Dict::S('iTopHub:ConfigurationSafelyReverted')."\n".$e->getMessage());
|
||||
SetupLog::Error('Debug trace: '.$e->getTraceAsString());
|
||||
ReportError($e->getMessage(), $e->getCode());
|
||||
break;
|
||||
}
|
||||
|
||||
try {
|
||||
SetupLog::Info('Move to production starts...');
|
||||
|
||||
unlink(APPROOT.'data/hub/compile_authent');
|
||||
// Load the "production" config file to clone & update it
|
||||
$oConfig = new Config(APPCONF.'production/'.ITOP_CONFIG_FILE);
|
||||
|
||||
@@ -1386,19 +1386,27 @@ class ObjectController extends BrickController
|
||||
if ($oField instanceof DateTimeField) {
|
||||
$oField->SetDateTimePickerWidgetParent($sDateTimePickerWidgetParent);
|
||||
}
|
||||
$sFieldRendererClass = BsLinkedSetFieldRenderer::GetFieldRendererClass($oField);
|
||||
|
||||
// View data
|
||||
$sValue = $oAttDef->GetAsHTML($oNewLink->Get($sAttCode));
|
||||
$aObjectData['attributes']['lnk__'.$sAttCode] = [
|
||||
'object_class' => $sLinkClass,
|
||||
'object_id' => $oNewLink->GetKey(),
|
||||
'prefix' => 'lnk__',
|
||||
'attribute_code' => $sAttCode,
|
||||
'attribute_type' => get_class($oAttDef),
|
||||
'value_html' => $sValue,
|
||||
];
|
||||
|
||||
// If the field has a renderer we adjust view data
|
||||
$sFieldRendererClass = BsLinkedSetFieldRenderer::GetFieldRendererClass($oField);
|
||||
if ($sFieldRendererClass !== null) {
|
||||
$oFieldRenderer = new $sFieldRendererClass($oField);
|
||||
$oFieldOutput = $oFieldRenderer->Render();
|
||||
$sValue = $oFieldOutput->GetHtml();
|
||||
$aObjectData['attributes']['lnk__'.$sAttCode]['value_html'] = $oFieldOutput->GetHtml();
|
||||
$aObjectData['attributes']['lnk__'.$sAttCode]['css_inline'] = $oFieldOutput->GetCss();
|
||||
$aObjectData['attributes']['lnk__'.$sAttCode]['js_inline'] = $oFieldOutput->GetJs();
|
||||
}
|
||||
$aObjectData['attributes']['lnk__'.$sAttCode] = [
|
||||
'att_code' => $sAttCode,
|
||||
'value' => $sValue,
|
||||
'css_inline' => $oFieldOutput->GetCss(),
|
||||
'js_inline' => $oFieldOutput->GetJs(),
|
||||
];
|
||||
}
|
||||
|
||||
$aData['items'][] = $aObjectData;
|
||||
|
||||
@@ -186,6 +186,7 @@
|
||||
<group id="AdminSysReadOnly" _delta="define">
|
||||
<classes>
|
||||
<class id="ItopFenceLogin"/>
|
||||
<class id="ModuleInstallation"/>
|
||||
</classes>
|
||||
</group>
|
||||
<group id="AdminSys" _delta="define">
|
||||
@@ -195,6 +196,11 @@
|
||||
<class id="RessourceHybridAuthMenu"/>
|
||||
</classes>
|
||||
</group>
|
||||
<group id="Event" _delta="define">
|
||||
<classes>
|
||||
<class id="Event"/>
|
||||
</classes>
|
||||
</group>
|
||||
</groups>
|
||||
<profiles>
|
||||
<profile id="117" _delta="define">
|
||||
@@ -290,6 +296,16 @@
|
||||
<action id="stimulus:ev_close">allow</action>
|
||||
</actions>
|
||||
</group>
|
||||
<group id="Event">
|
||||
<actions>
|
||||
<action id="action:read">allow</action>
|
||||
<action id="action:bulk read">allow</action>
|
||||
<action id="action:write">allow</action>
|
||||
<action id="action:bulk write">allow</action>
|
||||
<action id="action:delete">allow</action>
|
||||
<action id="action:bulk delete">allow</action>
|
||||
</actions>
|
||||
</group>
|
||||
</groups>
|
||||
</profile>
|
||||
<profile id="3" _delta="define">
|
||||
|
||||
@@ -102,6 +102,7 @@ if ($sTargetPage === false || $sModule === 'core' || $sModule === 'dictionaries'
|
||||
// force login if needed
|
||||
|
||||
$aModuleDelegatedAuthenticationEndpointsList = GetModuleDelegatedAuthenticationEndpoints($sModule);
|
||||
// If module doesn't have the delegated authentication endpoints list defined, we rely on the conf. param. to decide if we force login or not.
|
||||
if (is_null($aModuleDelegatedAuthenticationEndpointsList)) {
|
||||
$bForceLoginWhenNoDelegatedAuthenticationEndpoints = utils::GetConfig()->Get('security.force_login_when_no_delegated_authentication_endpoints_list');
|
||||
if ($bForceLoginWhenNoDelegatedAuthenticationEndpoints) {
|
||||
@@ -109,14 +110,14 @@ if (is_null($aModuleDelegatedAuthenticationEndpointsList)) {
|
||||
LoginWebPage::DoLoginEx();
|
||||
}
|
||||
}
|
||||
// If module defined a delegated authentication endpoints but not for the current page, we consider that the page is not allowed to be executed without login
|
||||
if (is_array($aModuleDelegatedAuthenticationEndpointsList) && !in_array($sPage, $aModuleDelegatedAuthenticationEndpointsList)) {
|
||||
// if module defined a delegated authentication endpoints but not for the current page, we consider that the page is not allowed to be executed without login
|
||||
require_once(APPROOT.'/application/startup.inc.php');
|
||||
LoginWebPage::DoLoginEx();
|
||||
}
|
||||
// If user is not logged in, log a warning in the log file as the page is executed without login, which is not recommended for security reason
|
||||
if (is_null($aModuleDelegatedAuthenticationEndpointsList) && !UserRights::IsLoggedIn()) {
|
||||
require_once(APPROOT.'/application/startup.inc.php');
|
||||
// check if user is not logged in, if not log a warning in the log file as the page is executed without login, which is not recommended for security reason
|
||||
IssueLog::Debug("The '$sPage' page is executed without logging in. This call will be blocked in the future and will likely cause unwanted behaviour in the '$sModule' module. Please define a delegated authentication endpoint for the module, as described at https://www.itophub.io/wiki/page?id=latest:customization:new_extension#security.");
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ class ModuleInstallation extends DBObject
|
||||
{
|
||||
$aParams =
|
||||
[
|
||||
"category" => "core,view_in_gui",
|
||||
"category" => "core,view_in_gui,grant_by_profile",
|
||||
"key_type" => "autoincrement",
|
||||
'name_attcode' => ['name', 'version'],
|
||||
"state_attcode" => "",
|
||||
|
||||
@@ -340,8 +340,10 @@ class DataTableUIBlockFactory extends AbstractUIBlockFactory
|
||||
$aClassAliases = $oSet->GetFilter()->GetSelectedClasses();
|
||||
$aAuthorizedClasses = [];
|
||||
foreach ($aClassAliases as $sAlias => $sClassName) {
|
||||
if ((UserRights::IsActionAllowed($sClassName, UR_ACTION_READ, $oSet) != UR_ALLOWED_NO) &&
|
||||
((count($aDisplayAliases) == 0) || (in_array($sAlias, $aDisplayAliases)))) {
|
||||
if (
|
||||
((UserRights::IsActionAllowed($sClassName, UR_ACTION_READ, $oSet) !== UR_ALLOWED_NO) || ($aExtraParams['display_unauthorized_objects'] ?? false) === true)
|
||||
&& ((count($aDisplayAliases) == 0) || (in_array($sAlias, $aDisplayAliases)))
|
||||
) {
|
||||
$aAuthorizedClasses[$sAlias] = $sClassName;
|
||||
}
|
||||
}
|
||||
@@ -520,6 +522,14 @@ class DataTableUIBlockFactory extends AbstractUIBlockFactory
|
||||
if ($aData['checked']) {
|
||||
if ($sAttCode == '_key_') {
|
||||
if ($bViewLink) {
|
||||
$sRenderLink = "return row['".$sClassAlias."/hyperlink'];";
|
||||
if (
|
||||
($aExtraParams['display_unauthorized_objects'] ?? false) === true
|
||||
&& UserRights::IsActionAllowed($sClassName, UR_ACTION_READ) !== UR_ALLOWED_YES
|
||||
) {
|
||||
$sRenderLink = "return row['".$sClassAlias."/friendlyname'];";
|
||||
}
|
||||
|
||||
$aColumnDefinition[] = [
|
||||
'description' => $aData['label'],
|
||||
'object_class' => $sClassName,
|
||||
@@ -527,7 +537,7 @@ class DataTableUIBlockFactory extends AbstractUIBlockFactory
|
||||
'attribute_code' => $sAttCode,
|
||||
'attribute_type' => '_key_',
|
||||
'attribute_label' => MetaModel::GetName($sClassName),
|
||||
'render' => "return row['".$sClassAlias."/hyperlink'];",
|
||||
'render' => $sRenderLink,
|
||||
];
|
||||
|
||||
}
|
||||
@@ -972,6 +982,8 @@ JS;
|
||||
/** Handler to call when trying to create a new object in modal */
|
||||
'creation_disallowed',
|
||||
/** Don't provide the standard object creation feature */
|
||||
'display_unauthorized_objects',
|
||||
/** bool Display objects for which the user has no read rights */
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,7 +74,10 @@ class AjaxRenderController
|
||||
$oSet->SetShowObsoleteData($bShowObsoleteData);
|
||||
|
||||
// N°8606 : Check user permissions on the main class
|
||||
if (UserRights::IsActionAllowed($oSet->GetClass(), UR_ACTION_READ, $oSet) !== UR_ALLOWED_YES) {
|
||||
if (
|
||||
UserRights::IsActionAllowed($oSet->GetClass(), UR_ACTION_READ, $oSet) !== UR_ALLOWED_YES
|
||||
&& ($aExtraParams['display_unauthorized_objects'] ?? false) === false
|
||||
) {
|
||||
throw new Exception(Dict::Format('UI:Error:ReadNotAllowedOn_Class', $oSet->GetClass()));
|
||||
}
|
||||
|
||||
@@ -103,7 +106,10 @@ class AjaxRenderController
|
||||
}
|
||||
|
||||
// N°8606 : Check user permissions on the current class
|
||||
if (UserRights::IsActionAllowed($sClass, UR_ACTION_READ, $oSet) !== UR_ALLOWED_YES) {
|
||||
if (
|
||||
UserRights::IsActionAllowed($sClass, UR_ACTION_READ, $oSet) !== UR_ALLOWED_YES
|
||||
&& ($aExtraParams['display_unauthorized_objects'] ?? false) === false
|
||||
) {
|
||||
throw new Exception(Dict::Format('UI:Error:ReadNotAllowedOn_Class', $sClass));
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ use CoreException;
|
||||
use DBObjectSearch;
|
||||
use DBObjectSet;
|
||||
use Dict;
|
||||
use EventNotificationNewsroom;
|
||||
use MetaModel;
|
||||
use SecurityException;
|
||||
use UserRights;
|
||||
@@ -358,6 +359,7 @@ JS
|
||||
// Search for all notifications for the current user
|
||||
$oSearch = DBObjectSearch::FromOQL('SELECT EventNotificationNewsroom');
|
||||
$oSearch->AddCondition('contact_id', UserRights::GetContactId(), '=');
|
||||
$oSearch->AllowAllData();
|
||||
$oSet = new DBObjectSet($oSearch, ['read' => true, 'date' => false], []);
|
||||
|
||||
// Add main content block
|
||||
@@ -526,6 +528,7 @@ JS
|
||||
|
||||
if (utils::IsNotNullOrEmptyString($iContactId)) {
|
||||
$oSearch = DBObjectSearch::FromOQL('SELECT EventNotificationNewsroom WHERE contact_id = :contact_id AND read = "no"');
|
||||
$oSearch->AllowAllData();
|
||||
$oSet = new DBObjectSet($oSearch, [], ['contact_id' => $iContactId]);
|
||||
|
||||
while ($oMessage = $oSet->Fetch()) {
|
||||
@@ -539,7 +542,7 @@ $sMessage
|
||||
HTML;
|
||||
|
||||
$sIcon = $oMessage->Get('icon') !== null ?
|
||||
$oMessage->Get('icon')->GetDisplayURL('EventNotificationNewsroom', $oMessage->GetKey(), 'icon') :
|
||||
$oMessage->Get('icon')->GetDisplayURL(EventNotificationNewsroom::class, $oMessage->GetKey(), 'icon') :
|
||||
Branding::GetCompactMainLogoAbsoluteUrl();
|
||||
$aMessages[] = [
|
||||
'id' => $oMessage->GetKey(),
|
||||
@@ -576,6 +579,7 @@ HTML;
|
||||
|
||||
if (utils::IsNotNullOrEmptyString($iContactId)) {
|
||||
$oSearch = DBObjectSearch::FromOQL('SELECT EventNotificationNewsroom WHERE contact_id = :contact_id AND read = "no"');
|
||||
$oSearch->AllowAllData();
|
||||
$oSet = new DBObjectSet($oSearch, [], ['contact_id' => $iContactId]);
|
||||
|
||||
while ($oEvent = $oSet->Fetch()) {
|
||||
@@ -605,7 +609,7 @@ HTML;
|
||||
$sEventId = utils::ReadParam('event_id', 0);
|
||||
if ($sEventId > 0) {
|
||||
try {
|
||||
$oEvent = MetaModel::GetObject('EventNotificationNewsroom', $sEventId);
|
||||
$oEvent = MetaModel::GetObject(EventNotificationNewsroom::class, $sEventId, true, true);
|
||||
if ($oEvent !== null && $oEvent->Get('contact_id') === UserRights::GetContactId()) {
|
||||
$oEvent->Set('read', 'yes');
|
||||
$oEvent->SetCurrentDate('read_date');
|
||||
|
||||
@@ -117,6 +117,7 @@ class NotificationsRepository
|
||||
protected function PrepareSearchForNotificationsByContact(int $iContactId, array $aNotificationIds = []): DBSearch
|
||||
{
|
||||
$oSearch = DBObjectSearch::FromOQL("SELECT EventNotificationNewsroom WHERE contact_id = :contact_id");
|
||||
$oSearch->AllowAllData();
|
||||
$aParams = [
|
||||
"contact_id" => $iContactId,
|
||||
];
|
||||
|
||||
@@ -645,4 +645,54 @@ SCSS;
|
||||
[ '/var/www/html/iTop/css/ui-lightness/images/ui-icons_222222_256x240.png', '/var/www/html/iTop/env-production//branding/themes/light-grey//../../../../css/ui-lightness/images/ui-icons_222222_256x240.png' ],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $aThemeParameters
|
||||
* @param $bSetupCompilationTimestamp
|
||||
* @param $aExpectedClonedParameters
|
||||
* @dataProvider CloneParameterParameterOverloadProvider
|
||||
*/
|
||||
public function testCloneParameterParameterOverload($aThemeParameters, $bSetupCompilationTimestamp, $aExpectedClonedParameters)
|
||||
{
|
||||
$aClonedParameters = ThemeHandler::CloneThemeParameterAndIncludeVersion($aThemeParameters, $bSetupCompilationTimestamp, [APPROOT.'tests/php-unit-tests/unitary-tests/application/theme-handler/imports/']);
|
||||
$this->assertEquals($aExpectedClonedParameters, $aClonedParameters);
|
||||
}
|
||||
|
||||
public function CloneParameterParameterOverloadProvider()
|
||||
{
|
||||
return [
|
||||
"empty parameters" => [
|
||||
'parameters' => [],
|
||||
'timestamp' => '1',
|
||||
'expected' => [
|
||||
'$version' => '1',
|
||||
],
|
||||
],
|
||||
"parameters without variables" => [
|
||||
'parameters' => [
|
||||
'variable_imports' => ['file1' => 'variable_imports.scss'],
|
||||
'utility_imports' => ['util1' => 'path2'],
|
||||
'stylesheets' => ['style1' => 'path3'],
|
||||
],
|
||||
'timestamp' => '2',
|
||||
'expected' => [
|
||||
'var1' => 'value1',
|
||||
'var2' => 'value2',
|
||||
'$version' => '2',
|
||||
],
|
||||
],
|
||||
"parameters with variables overload" => [
|
||||
'parameters' => [
|
||||
'variables' => ['var1' => 'value2'],
|
||||
'variable_imports' => ['file1' => 'variable_imports.scss'],
|
||||
],
|
||||
'timestamp' => '3',
|
||||
'expected' => [
|
||||
'var1' => 'value2',
|
||||
'var2' => 'value2',
|
||||
'$version' => '3',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
$var1: value1;
|
||||
$var2: value2;
|
||||
@@ -214,14 +214,14 @@ class UserRightsTest extends ItopDataTestCase
|
||||
'User Portal UserRequest read' => [2, ['class' => 'UserRequest', 'action' => 1, 'res' => true]],
|
||||
'User Portal URP_UserProfile read' => [2, ['class' => 'URP_UserProfile', 'action' => 1, 'res' => false]],
|
||||
'User Portal UserLocal read' => [2, ['class' => 'UserLocal', 'action' => 1, 'res' => false]],
|
||||
'User Portal ModuleInstallation read' => [2, ['class' => 'ModuleInstallation', 'action' => 1, 'res' => true]],
|
||||
'User Portal ModuleInstallation read' => [2, ['class' => 'ModuleInstallation', 'action' => 1, 'res' => false]],
|
||||
|
||||
/* Configuration manager (1 = UR_ACTION_READ) */
|
||||
'Configuration manager FunctionalCI read' => [3, ['class' => 'FunctionalCI', 'action' => 1, 'res' => true]],
|
||||
'Configuration manager UserRequest read' => [3, ['class' => 'UserRequest', 'action' => 1, 'res' => true]],
|
||||
'Configuration manager URP_UserProfile read' => [3, ['class' => 'URP_UserProfile', 'action' => 1, 'res' => false]],
|
||||
'Configuration manager UserLocal read' => [3, ['class' => 'UserLocal', 'action' => 1, 'res' => false]],
|
||||
'Configuration manager ModuleInstallation read' => [3, ['class' => 'ModuleInstallation', 'action' => 1, 'res' => true]],
|
||||
'Configuration manager ModuleInstallation read' => [3, ['class' => 'ModuleInstallation', 'action' => 1, 'res' => false]],
|
||||
];
|
||||
}
|
||||
|
||||
@@ -267,14 +267,14 @@ class UserRightsTest extends ItopDataTestCase
|
||||
'User Portal UserRequest' => [2, ['class' => 'UserRequest', 'action' => 2, 'res' => true]],
|
||||
'User Portal URP_UserProfile' => [2, ['class' => 'URP_UserProfile', 'action' => 2, 'res' => false]],
|
||||
'User Portal UserLocal' => [2, ['class' => 'UserLocal', 'action' => 2, 'res' => false]],
|
||||
'User Portal ModuleInstallation' => [2, ['class' => 'ModuleInstallation', 'action' => 2, 'res' => true]],
|
||||
'User Portal ModuleInstallation' => [2, ['class' => 'ModuleInstallation', 'action' => 2, 'res' => false]],
|
||||
|
||||
/* Configuration manager (2 = UR_ACTION_MODIFY) */
|
||||
'Configuration manager FunctionalCI' => [3, ['class' => 'FunctionalCI', 'action' => 2, 'res' => true]],
|
||||
'Configuration manager UserRequest' => [3, ['class' => 'UserRequest', 'action' => 2, 'res' => false]],
|
||||
'Configuration manager URP_UserProfile' => [3, ['class' => 'URP_UserProfile', 'action' => 2, 'res' => false]],
|
||||
'Configuration manager UserLocal' => [3, ['class' => 'UserLocal', 'action' => 2, 'res' => false]],
|
||||
'Configuration manager ModuleInstallation' => [3, ['class' => 'ModuleInstallation', 'action' => 2, 'res' => true]],
|
||||
'Configuration manager ModuleInstallation' => [3, ['class' => 'ModuleInstallation', 'action' => 2, 'res' => false]],
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -7,14 +7,36 @@
|
||||
|
||||
namespace Combodo\iTop\Test\UnitTest\Core;
|
||||
|
||||
use Combodo\iTop\Application\WebPage\CaptureWebPage;
|
||||
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
|
||||
use ormDocument;
|
||||
use UserRights;
|
||||
|
||||
/**
|
||||
* Tests of the ormDocument class
|
||||
*/
|
||||
class ormDocumentTest extends ItopDataTestCase
|
||||
{
|
||||
private const RESTRICTED_PROFILE = 'Configuration Manager';
|
||||
private int $iUserOrg;
|
||||
private int $iOrgDifferentFromUser;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->iUserOrg = $this->GivenObjectInDB('Organization', [
|
||||
'name' => 'UserOrg',
|
||||
]);
|
||||
|
||||
$this->iOrgDifferentFromUser = $this->GivenObjectInDB('Organization', [
|
||||
'name' => 'OrgDifferentFromUser',
|
||||
]);
|
||||
|
||||
$this->LoginRestrictedUser($this->iUserOrg, self::RESTRICTED_PROFILE);
|
||||
$this->ResetMetaModelQueyCacheGetObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@@ -139,4 +161,107 @@ class ormDocumentTest extends ItopDataTestCase
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that DownloadDocument enforces rights for documents
|
||||
*
|
||||
* @dataProvider DownloadDocumentRightsProvider
|
||||
*/
|
||||
public function testDownloadDocumentDifferentOrg(string $sTargetClass, string $sAttCode, string $sData, string $sFileName, ?string $sHostClass)
|
||||
{
|
||||
$iDeniedDocumentId = $this->CreateDownloadTargetInOrg($sTargetClass, $sAttCode, $this->iOrgDifferentFromUser, $sData, $sFileName, $sHostClass);
|
||||
|
||||
$oPageDenied = new CaptureWebPage();
|
||||
ormDocument::DownloadDocument($oPageDenied, $sTargetClass, $iDeniedDocumentId, $sAttCode);
|
||||
$sDeniedHtml = (string) $oPageDenied->GetHtml();
|
||||
$this->assertStringContainsString(
|
||||
'the object does not exist or you are not allowed to view it',
|
||||
$sDeniedHtml,
|
||||
'Expected error message when rights are missing.'
|
||||
);
|
||||
$this->assertStringNotContainsString($sData, $sDeniedHtml, 'Unexpected file data present when rights are missing.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that DownloadDocument allows to retrieve document with the same org (or host object org)
|
||||
*
|
||||
* @dataProvider DownloadDocumentRightsProvider
|
||||
*/
|
||||
public function testDownloadDocumentSameOrg(string $sTargetClass, string $sAttCode, string $sData, string $sFileName, ?string $sHostClass)
|
||||
{
|
||||
$iAllowedDocumentId = $this->CreateDownloadTargetInOrg($sTargetClass, $sAttCode, $this->iUserOrg, $sData, $sFileName, $sHostClass);
|
||||
|
||||
$oPageAllowed = new CaptureWebPage();
|
||||
ormDocument::DownloadDocument($oPageAllowed, $sTargetClass, $iAllowedDocumentId, $sAttCode);
|
||||
$sAllowedHtml = (string) $oPageAllowed->GetHtml();
|
||||
$this->assertStringContainsString($sData, $sAllowedHtml, 'Expected file data present when rights are sufficient.');
|
||||
$this->assertStringNotContainsString('the object does not exist or you are not allowed to view it', $sAllowedHtml, 'Unexpected error message when rights are sufficient.');
|
||||
}
|
||||
|
||||
public function DownloadDocumentRightsProvider(): array
|
||||
{
|
||||
return [
|
||||
'DocumentFile' => [
|
||||
'class' => 'DocumentFile',
|
||||
'data_attribute_id' => 'file',
|
||||
'data' => 'document_data',
|
||||
'file_name' => 'document.txt',
|
||||
'host_class' => null],
|
||||
'Attachment' => [
|
||||
'class' => 'Attachment',
|
||||
'data_attribute_id' => 'contents',
|
||||
'data' => 'attachment_data',
|
||||
'file_name' => 'attachment.txt',
|
||||
'host_class' => 'UserRequest'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to avoid duplicating object creation in tests
|
||||
* Created objects and host objects depending on the Document class
|
||||
* @param string $sTargetClass
|
||||
* @param string $sAttCode
|
||||
* @param int $iOrgId
|
||||
* @param string $sData
|
||||
* @param string $sFileName
|
||||
* @param string|null $sHostClass
|
||||
* @return int
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function CreateDownloadTargetInOrg(string $sTargetClass, string $sAttCode, int $iOrgId, string $sData, string $sFileName, ?string $sHostClass): int
|
||||
{
|
||||
|
||||
if ($sTargetClass === 'DocumentFile') {
|
||||
return $this->GivenObjectInDB($sTargetClass, [
|
||||
'name' => 'UnitTestDocFile_'.uniqid(),
|
||||
'org_id' => $iOrgId,
|
||||
$sAttCode => new ormDocument($sData, 'text/plain', $sFileName),
|
||||
]);
|
||||
}
|
||||
|
||||
if ($sTargetClass === 'Attachment') {
|
||||
$iHostId = $this->GivenObjectInDB($sHostClass, [
|
||||
'title' => 'UnitTestUserRequest_'.uniqid(),
|
||||
'org_id' => $iOrgId,
|
||||
'description' => 'A user request for testing attachment download rights',
|
||||
]);
|
||||
|
||||
return $this->GivenObjectInDB('Attachment', [
|
||||
'item_class' => $sHostClass,
|
||||
'item_id' => $iHostId,
|
||||
$sAttCode => new ormDocument($sData, 'text/plain', $sFileName),
|
||||
]);
|
||||
}
|
||||
|
||||
throw new \Exception("Unsupported target class: $sTargetClass");
|
||||
}
|
||||
|
||||
private function LoginRestrictedUser(int $iAllowedOrgId, string $sProfileName): void
|
||||
{
|
||||
if (UserRights::IsLoggedIn()) {
|
||||
UserRights::Logoff();
|
||||
}
|
||||
$sLogin = $this->GivenUserRestrictedToAnOrganizationInDB($iAllowedOrgId, self::$aURP_Profiles[$sProfileName]);
|
||||
UserRights::Login($sLogin);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user