Il codice per la gestione del tagging dei messaggi personali è incoerente.
In alcune parti della codebase, essere in pm_tags_allowed_for_groups è sufficiente per poter taggare un messaggio personale.
In altre parti della codebase, è necessario essere sia in pm_tags_allowed_for_groups che in tag_topic_allowed_groups.
Questo è particolarmente restrittivo quando c’è la necessità che gli utenti possano taggare i propri messaggi personali mentre non si desidera che tagghino argomenti pubblici (ad esempio, questo Private template permissions to override allowed PM tagging groups), cioè quando pm_tags_allowed_for_groups non è un sottoinsieme proprio di tag_topic_allowed_groups.
Analisi
In TagGuardian queste sono impostazioni distinte. È sufficiente essere in pm_tags_allowed_for_groups per poter taggare un PM.
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
Lo stesso vale per Guardian.can_tag? Le impostazioni sono distinte.
def can_tag?(topic)
return false if topic.blank?
topic.private_message? ? can_tag_pms? : can_tag_topics?
end
Anche ListController si accontenta solo di 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?
Tuttavia, TopicGuardian richiede che un utente sia sia in tag_topic_allowed_groups che in pm_tags_allowed_for_groups se desidera poter taggare un PM.
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
Sul lato client, la stessa restrizione si trova in 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"))
);
}
Ma la modale Move to Topic non ha questa restrizione:
get canTagMessages() {
return this.site.can_tag_pms;
}
e nemmeno ChatToTopicSelector
@alias("site.can_tag_pms") canTagMessages;
e nemmeno UserPrivateMessagesController
@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",
});
}
Riepilogo
| Classe | C/S | Comportamento |
|---|---|---|
| TagGuardian | server | solo pm_tags_allowed_for_groups |
| Guardian | server | solo pm_tags_allowed_for_groups |
| ListController | server | solo pm_tags_allowed_for_groups |
| TopicGuardian | server | sia pm_tags_allowed_for_groups che tag_topic_allowed_groups |
| Composer | client | sia pm_tags_allowed_for_groups che tag_topic_allowed_groups |
| TopicController | client | sia pm_tags_allowed_for_groups che tag_topic_allowed_groups |
| Modale Move to Topic | client | solo pm_tags_allowed_for_groups |
| ChatToTopicSelector | client | solo pm_tags_allowed_for_groups |
Problemi aggiuntivi
Ho trovato altri due impedimenti:
PostRevisor utilizza tc.guardian.can_tag_topics? invece di tc.guardian.can_tag?(tc.topic)
e in DiscourseTagging
tag_topic_by_names fa la cosa giusta
def self.tag_topic_by_names(topic, guardian, tag_names_arg, append: false)
if guardian.can_tag?(topic)
ma poi tags_for_saving no
def self.tags_for_saving(tags_arg, guardian, opts = {})
return [] unless guardian.can_tag_topics? && tags_arg.present?
Quest’ultimo è particolarmente insidioso poiché la funzione non è consapevole se sta lavorando su un PM.