Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add possibility to disable or restrict users mentions in RichText #18849

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions install/empty_data.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@

use Glpi\Form\Form;
use Glpi\Inventory\Conf;
use Glpi\RichText\UserMention;
use Glpi\Socket;

// Use anonymous class so we can have constants that define special values without polluting the global table
Expand Down Expand Up @@ -8899,6 +8900,7 @@ public function getEmptyData(): array
'is_default' => '1',
'helpdesk_hardware' => '1',
'helpdesk_item_type' => '["Computer","Monitor","NetworkEquipment","Peripheral","Phone","Printer","Software", "DCRoom", "Rack", "Enclosure", "Database"]',
'use_mentions' => UserMention::USER_MENTION_FULL,
'ticket_status' => '{"1":{"2":0,"3":0,"4":0,"5":0,"6":0},"2":{"1":0,"3":0,"4":0,"5":0,"6":0},"3":{"1":0,"2":0,"4":0,"5":0,"6":0},"4":{"1":0,"2":0,"3":0,"5":0,"6":0},"5":{"1":0,"2":0,"3":0,"4":0},"6":{"1":0,"2":0,"3":0,"4":0,"5":0}}',
'comment' => '',
'problem_status' => '[]',
Expand All @@ -8913,6 +8915,7 @@ public function getEmptyData(): array
'is_default' => '0',
'helpdesk_hardware' => '1',
'helpdesk_item_type' => '["Computer","Monitor","NetworkEquipment","Peripheral","Phone","Printer","Software", "DCRoom", "Rack", "Enclosure", "Database"]',
'use_mentions' => UserMention::USER_MENTION_FULL,
'ticket_status' => '[]',
'comment' => '',
'problem_status' => '[]',
Expand All @@ -8927,6 +8930,7 @@ public function getEmptyData(): array
'is_default' => '0',
'helpdesk_hardware' => '3',
'helpdesk_item_type' => '["Computer","Monitor","NetworkEquipment","Peripheral","Phone","Printer","Software", "DCRoom", "Rack", "Enclosure", "Database"]',
'use_mentions' => UserMention::USER_MENTION_FULL,
'ticket_status' => '[]',
'comment' => '',
'problem_status' => '[]',
Expand All @@ -8941,6 +8945,7 @@ public function getEmptyData(): array
'is_default' => '0',
'helpdesk_hardware' => '3',
'helpdesk_item_type' => '["Computer","Monitor","NetworkEquipment","Peripheral","Phone","Printer","Software", "DCRoom", "Rack", "Enclosure", "Database"]',
'use_mentions' => UserMention::USER_MENTION_FULL,
'ticket_status' => '[]',
'comment' => '',
'problem_status' => '[]',
Expand All @@ -8955,6 +8960,7 @@ public function getEmptyData(): array
'is_default' => '0',
'helpdesk_hardware' => '3',
'helpdesk_item_type' => '["Computer","Monitor","NetworkEquipment","Peripheral","Phone","Printer","Software", "DCRoom", "Rack", "Enclosure", "Database"]',
'use_mentions' => UserMention::USER_MENTION_FULL,
'ticket_status' => '[]',
'comment' => '',
'problem_status' => '[]',
Expand All @@ -8969,6 +8975,7 @@ public function getEmptyData(): array
'is_default' => '0',
'helpdesk_hardware' => '3',
'helpdesk_item_type' => '["Computer","Monitor","NetworkEquipment","Peripheral","Phone","Printer","Software", "DCRoom", "Rack", "Enclosure", "Database"]',
'use_mentions' => UserMention::USER_MENTION_FULL,
'ticket_status' => '[]',
'comment' => '',
'problem_status' => '[]',
Expand All @@ -8983,6 +8990,7 @@ public function getEmptyData(): array
'is_default' => '0',
'helpdesk_hardware' => '3',
'helpdesk_item_type' => '["Computer","Monitor","NetworkEquipment","Peripheral","Phone","Printer","Software", "DCRoom", "Rack", "Enclosure", "Database"]',
'use_mentions' => UserMention::USER_MENTION_FULL,
'ticket_status' => '[]',
'comment' => '',
'problem_status' => '[]',
Expand All @@ -8997,6 +9005,7 @@ public function getEmptyData(): array
'is_default' => '0',
'helpdesk_hardware' => '0',
'helpdesk_item_type' => '[]',
'use_mentions' => UserMention::USER_MENTION_FULL,
'ticket_status' => '{"1":{"2":0,"3":0,"4":0,"5":0,"6":0},"2":{"1":0,"3":0,"4":0,"5":0,"6":0},"3":{"1":0,"2":0,"4":0,"5":0,"6":0},"4":{"1":0,"2":0,"3":0,"5":0,"6":0},"5":{"1":0,"2":0,"3":0,"4":0,"6":0},"6":{"1":0,"2":0,"3":0,"4":0,"5":0}}',
'comment' => 'This profile defines read-only access. It is used when objects are locked. It can also be used to give to users rights to unlock objects.',
'problem_status' => '{"1":{"7":0,"2":0,"3":0,"4":0,"5":0,"8":0,"6":0},"7":{"1":0,"2":0,"3":0,"4":0,"5":0,"8":0,"6":0},"2":{"1":0,"7":0,"3":0,"4":0,"5":0,"8":0,"6":0},"3":{"1":0,"7":0,"2":0,"4":0,"5":0,"8":0,"6":0},"4":{"1":0,"7":0,"2":0,"3":0,"5":0,"8":0,"6":0},"5":{"1":0,"7":0,"2":0,"3":0,"4":0,"8":0,"6":0},"8":{"1":0,"7":0,"2":0,"3":0,"4":0,"5":0,"6":0},"6":{"1":0,"7":0,"2":0,"3":0,"4":0,"5":0,"8":0}}',
Expand Down
13 changes: 13 additions & 0 deletions install/migrations/update_10.0.x_to_11.0.0/profiles.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
* ---------------------------------------------------------------------
*/

use Glpi\RichText\UserMention;

/**
* @var \Migration $migration
*/
Expand All @@ -47,3 +49,14 @@
]
);
$migration->addKey('glpi_profiles', 'last_rights_update');

$migration->addField(
'glpi_profiles',
'use_mentions',
'int',
[
'null' => false,
'value' => UserMention::USER_MENTION_FULL,
'after' => 'helpdesk_item_type'
]
);
1 change: 1 addition & 0 deletions install/mysql/glpi-empty.sql
Original file line number Diff line number Diff line change
Expand Up @@ -5824,6 +5824,7 @@ CREATE TABLE `glpi_profiles` (
`is_default` tinyint NOT NULL DEFAULT '0',
`helpdesk_hardware` int NOT NULL DEFAULT '0',
`helpdesk_item_type` text,
`use_mentions` int NOT NULL DEFAULT '1',
`ticket_status` text COMMENT 'json encoded array of from/dest allowed status change',
`date_mod` timestamp NULL DEFAULT NULL,
`comment` text,
Expand Down
13 changes: 11 additions & 2 deletions js/RichText/UserMention.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,13 @@ window.GLPI.RichText.UserMention = class {
* @param {Editor} editor
* @param {number} activeEntity
* @param {string} idorToken
* @param {Array} mentions_options
*/
constructor(editor, activeEntity, idorToken) {
constructor(editor, activeEntity, idorToken, mentions_options) {
this.editor = editor;
this.activeEntity = activeEntity;
this.idorToken = idorToken;
this.mentionsOptions = mentions_options;
}

/**
Expand Down Expand Up @@ -99,7 +101,14 @@ window.GLPI.RichText.UserMention = class {
}
).done(
(data) => {
const items = data.results.map(
let results = data.results;

if (!this.mentionsOptions.full) {
const allowedIds = this.mentionsOptions.users;
results = results.filter(user => allowedIds.includes(user.id));
}

const items = results.map(
(user) => {
return {
type: 'autocompleteitem',
Expand Down
18 changes: 13 additions & 5 deletions src/CommonITILObject.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
use Glpi\Form\Destination\AnswersSet_FormDestinationItem;
use Glpi\Plugin\Hooks;
use Glpi\RichText\RichText;
use Glpi\RichText\UserMention;
use Glpi\Team\Team;

/**
Expand Down Expand Up @@ -7358,6 +7359,8 @@ public function getTimelineItemtypes(): array

$itemtypes = [];

$use_mentions = UserMention::getRestrictedUsers($this);

$itemtypes['answer'] = [
'type' => 'ITILFollowup',
'class' => 'ITILFollowup',
Expand All @@ -7366,7 +7369,8 @@ public function getTimelineItemtypes(): array
'short_label' => _x('button', 'Answer'),
'template' => 'components/itilobject/timeline/form_followup.html.twig',
'item' => $fup,
'hide_in_menu' => !$canadd_fup
'hide_in_menu' => !$canadd_fup,
'use_mentions' => $use_mentions,
];
$itemtypes['task'] = [
'type' => 'ITILTask',
Expand All @@ -7376,7 +7380,8 @@ public function getTimelineItemtypes(): array
'short_label' => _x('button', 'Task'),
'template' => 'components/itilobject/timeline/form_task.html.twig',
'item' => $task,
'hide_in_menu' => !$canadd_task
'hide_in_menu' => !$canadd_task,
'use_mentions' => $use_mentions,
];
$itemtypes['solution'] = [
'type' => 'ITILSolution',
Expand All @@ -7386,7 +7391,8 @@ public function getTimelineItemtypes(): array
'short_label' => _x('button', 'Solution'),
'template' => 'components/itilobject/timeline/form_solution.html.twig',
'item' => new ITILSolution(),
'hide_in_menu' => !$canadd_solution
'hide_in_menu' => !$canadd_solution,
'use_mentions' => $use_mentions,
];
$itemtypes['document'] = [
'type' => 'Document_Item',
Expand All @@ -7396,7 +7402,8 @@ public function getTimelineItemtypes(): array
'short_label' => _x('button', 'Document'),
'template' => 'components/itilobject/timeline/form_document_item.html.twig',
'item' => new Document_Item(),
'hide_in_menu' => !$canadd_document
'hide_in_menu' => !$canadd_document,
'use_mentions' => $use_mentions,
];
if ($validation !== null) {
$itemtypes['validation'] = [
Expand All @@ -7407,7 +7414,8 @@ public function getTimelineItemtypes(): array
'short_label' => _x('button', 'Validation'),
'template' => 'components/itilobject/timeline/form_validation.html.twig',
'item' => $validation,
'hide_in_menu' => !$canadd_validation
'hide_in_menu' => !$canadd_validation,
'use_mentions' => $use_mentions,
];
}

Expand Down
47 changes: 47 additions & 0 deletions src/Glpi/RichText/UserMention.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,15 @@
use ITILFollowup;
use ITILSolution;
use NotificationEvent;
use Profile;
use User;

final class UserMention
{
const USER_MENTION_DISABLED = 0;
const USER_MENTION_FULL = 1;
const USER_MENTION_RESTRICTED = 2;

/**
* Handle user mentions.
* Add newly mention users to observers and send them a notification.
Expand Down Expand Up @@ -261,4 +266,46 @@ public static function refreshUserMentionsHtmlToDisplay(string $content): string

return $content;
}

public static function isEnabled(): bool
{
$pro = Profile::getById($_SESSION['glpiactiveprofile']['id']);
return $pro->fields['use_mentions'] !== self::USER_MENTION_DISABLED;
}

public static function isMentionsRestricted(): bool
{
$pro = Profile::getById($_SESSION['glpiactiveprofile']['id']);
return $pro->fields['use_mentions'] === self::USER_MENTION_RESTRICTED;
}

public static function getRestrictedUsers(CommonITILObject $item): array
{
$data = [
'enabled' => self::isEnabled(),
];

if (!self::isMentionsRestricted()) {
$data['full'] = true;
return $data;
} else {
$data['full'] = false;
}

$items_id = $item->getID();

//get actors from item
$userlink = new $item->userlinkclass();
$actors = $userlink->getActors($items_id);

$data['users'] = [];

foreach ($actors as $actor) {
foreach ($actor as $a) {
$data['users'][] = $a['users_id'];
}
}

return $data;
}
}
64 changes: 64 additions & 0 deletions src/Profile.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
use Glpi\Form\Form;
use Glpi\Helpdesk\DefaultDataManager;
use Glpi\Helpdesk\Tile\TilesManager;
use Glpi\RichText\UserMention;
use Glpi\Session\SessionInfo;
use Glpi\Toolbox\ArrayNormalizer;

Expand Down Expand Up @@ -68,6 +69,7 @@ class Profile extends CommonDBTM
'reservation',
'rssfeed_public',
'show_group_hardware',
'use_mentions',
'task',
'ticket',
'ticket_cost',
Expand Down Expand Up @@ -1597,6 +1599,47 @@ public function showFormTracking($openform = true, $closeform = true)
$matrix_options['title'] = _n('Followup', 'Followups', Session::getPluralNumber()) . " / " . _n('Task', 'Tasks', Session::getPluralNumber());
$this->displayRightsChoiceMatrix(self::getRightsForForm('central', 'tracking', 'followups_tasks'), $matrix_options);

echo "<div class='mt-n2 mx-n2 mb-4'>";
echo "<table class='table table-hover card-table'>";
echo "<thead>";
echo "<tr><th colspan='2'><h4>" . __s('Users mentions') . "<h4></th></tr>";

echo "</thead>";

echo "<tbody>";

$description = __s('Enables or disables the ability to mention users within the application.') . "<br><br>";
$description .= "<b>" . __s('Disabled') . "</b> : " . __('User mentions are disabled for this profile.') . "<br><br>";
$description .= "<b>" . __s('Full') . "</b> : " . __('Displays all users.') . "<br><br>";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps specify that the user will be added as an observer if they are not already a ticket actor?

$description .= "<b>" . __s('Restricted') . "</b> : " . __('Limits the display to actors directly involved in the ticket.') . "<br><br><br>";
$description .= "<i><b>" . __s('Warning') . "</b> : " . __('Notifications must be enabled to activate mentions.') . "</i>";
RomainLvr marked this conversation as resolved.
Show resolved Hide resolved

echo "<tr>";
echo "<td>" . __s('Mentions configuration');
echo "<span class='ms-2 form-help'
data-bs-toggle='popover'
data-bs-placement='top'
data-bs-html='true'
data-bs-content='" . htmlspecialchars($description) . "'>
?
</span>";
echo "</td><td>";

echo Dropdown::showFromArray(
'use_mentions',
self::getMentionsLists(),
[
'value' => $this->fields['use_mentions'],
'display' => false
]
);

echo "</td></tr>";

echo "</tbody>";
echo "</table>";
echo "</div>";

$matrix_options['title'] = _n('Validation', 'Validations', Session::getPluralNumber());
$this->displayRightsChoiceMatrix(self::getRightsForForm('central', 'tracking', 'validations'), $matrix_options);

Expand Down Expand Up @@ -4015,6 +4058,27 @@ public static function dropdownHelpdeskItemtypes($options)
return Dropdown::showFromArray($p['name'], $values, $p);
}

/**
* @return array<int, string>
**/
public static function getMentionsLists(): array
{
return [
UserMention::USER_MENTION_DISABLED => __('Disabled'),
UserMention::USER_MENTION_FULL => __('Full'),
UserMention::USER_MENTION_RESTRICTED => __('Restricted'),
];
}

/**
* @param $value
* @return string
*/
public static function getMentionsListName($value): string
{
return self::getMentionsLists()[$value] ?? NOT_AVAILABLE;
}

/**
* Check if user has given right.
*
Expand Down
10 changes: 8 additions & 2 deletions templates/components/form/basic_inputs_macros.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,12 @@
'content_style': "",
}|merge(options) %}

{% if options.use_mentions.enabled %}
{% set options = options|merge({
'enable_mentions': true,
}) %}
{% endif %}

{% if options.fields_template.isMandatoryField(name) %}
{% set options = {'required': true}|merge(options) %}
{% endif %}
Expand Down Expand Up @@ -354,7 +360,6 @@
options.content_style,
]) %}
{% endif %}

{% if options.enable_form_tags %}
<script>
$(function() {
Expand All @@ -373,7 +378,8 @@
const user_mention = new GLPI.RichText.UserMention(
tinymce.get('{{ options.id }}'),
{{ options.entities_id }},
'{{ idor_token('User', {'right': 'all', 'entity_restrict': options.entities_id}) }}'
'{{ idor_token('User', {'right': 'all', 'entity_restrict': options.entities_id}) }}',
{{ options.use_mentions|json_encode|raw }}
);
user_mention.register();
});
Expand Down
3 changes: 2 additions & 1 deletion templates/components/itilobject/answer.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@
{% if timeline_itemtype.template is defined %}
{{ include(timeline_itemtype.template, {
'item': item,
'subitem': timeline_itemtype.item
'subitem': timeline_itemtype.item,
'use_mentions': timeline_itemtype.use_mentions,
}) }}
{% else %}
{% set sf_options = {'parent': item} %}
Expand Down
Loading
Loading