Le code de gestion des étiquettes de messages privés est incohérent.
Dans certaines parties de la base de code, le fait d’être dans pm_tags_allowed_for_groups est suffisant pour pouvoir étiqueter un message privé.
Dans d’autres parties de la base de code, il faut être à la fois dans pm_tags_allowed_for_groups et tag_topic_allowed_groups.
Ceci est particulièrement restrictif lorsqu’il est nécessaire que les utilisateurs puissent étiqueter leurs propres messages privés, alors que vous ne voulez pas qu’ils étiquettent des sujets publics (par exemple, ceci Private template permissions to override allowed PM tagging groups), c’est-à-dire lorsque pm_tags_allowed_for_groups n’est pas un sous-ensemble propre de tag_topic_allowed_groups.
Analyse
Dans TagGuardian, ces paramètres sont distincts. Il suffit d’être dans pm_tags_allowed_for_groups pour pouvoir étiqueter un MP.
def can_tag_topics?
SiteSetting.tagging_enabled && @user.in_any_groups?(SiteSetting.tag_topic_allowed_groups_map)
end
def can_tag_pms?
return false if !SiteSetting.tagging_enabled
return false if @user.blank?
return true if @user == Discourse.system_user
group_ids = SiteSetting.pm_tags_allowed_for_groups_map
group_ids.include?(Group::AUTO_GROUPS[:everyone]) ||
@user.group_users.exists?(group_id: group_ids)
end
Il en va de même pour Guardian.can_tag?. Les paramètres sont distincts.
def can_tag?(topic)
return false if topic.blank?
topic.private_message? ? can_tag_pms? : can_tag_topics?
end
ListController se contente également de can_tag_pms?
when :private_messages_tag
raise Discourse::NotFound if target_user.id != current_user.id
raise Discourse::NotFound if !guardian.can_tag_pms?
Cependant, TopicGuardian exige qu’un utilisateur soit à la fois dans tag_topic_allowed_groups et pm_tags_allowed_for_groups s’il souhaite pouvoir étiqueter un MP.
def can_edit_tags?(topic)
return false unless can_tag_topics?
return false if topic.private_message? && !can_tag_pms?
return true if can_edit_topic?(topic)
if topic&.first_post&.wiki &&
@user.in_any_groups?(SiteSetting.edit_wiki_post_allowed_groups_map)
return can_create_post?(topic)
end
false
end
Côté client, la même restriction se trouve dans Composer
@discourseComputed("model.canEditTitle", "model.creatingPrivateMessage")
canEditTags(canEditTitle, creatingPrivateMessage) {
const isPrivateMessage =
creatingPrivateMessage || this.get("model.topic.isPrivateMessage");
return (
canEditTitle &&
this.site.can_tag_topics &&
(!isPrivateMessage || this.site.can_tag_pms)
);
}
@discourseComputed("model.isPrivateMessage")
canEditTags(isPrivateMessage) {
return (
this.site.get("can_tag_topics") &&
(!isPrivateMessage || this.site.get("can_tag_pms"))
);
}
Mais la modale Move to Topic n’a pas cette restriction :
get canTagMessages() {
return this.site.can_tag_pms;
}
et ChatToTopicSelector non plus
@alias("site.can_tag_pms") canTagMessages;
et UserPrivateMessagesController non plus
@readOnly("site.can_tag_pms") pmTaggingEnabled;
if (this.pmTaggingEnabled) {
content.push({
id: this.router.urlFor("userPrivateMessages.tags", usernameLower),
name: i18n("user.messages.tags"),
icon: "tags",
});
}
Résumé
| Classe | C/S | Comportement |
|---|---|---|
| TagGuardian | serveur | pm_tags_allowed_for_groups uniquement |
| Guardian | serveur | pm_tags_allowed_for_groups uniquement |
| ListController | serveur | pm_tags_allowed_for_groups uniquement |
| TopicGuardian | serveur | pm_tags_allowed_for_groups et tag_topic_allowed_groups |
| Composer | client | pm_tags_allowed_for_groups et tag_topic_allowed_groups |
| TopicController | client | pm_tags_allowed_for_groups et tag_topic_allowed_groups |
| Modale Move to Topic | client | pm_tags_allowed_for_groups uniquement |
| ChatToTopicSelector | client | pm_tags_allowed_for_groups uniquement |
Problèmes supplémentaires
J’ai trouvé deux autres obstacles :
PostRevisor utilise tc.guardian.can_tag_topics? au lieu de tc.guardian.can_tag?(tc.topic)
et dans DiscourseTagging
tag_topic_by_names fait la bonne chose
def self.tag_topic_by_names(topic, guardian, tag_names_arg, append: false)
if guardian.can_tag?(topic)
mais ensuite tags_for_saving ne le fait pas
def self.tags_for_saving(tags_arg, guardian, opts = {})
return [] unless guardian.can_tag_topics? && tags_arg.present?
Ce dernier est particulièrement vicieux car la fonction n’est pas consciente si elle travaille sur un MP.