El código para el etiquetado de mensajes personales es inconsistente.
En algunas partes de la base de código, estar en pm_tags_allowed_for_groups es suficiente para poder etiquetar un mensaje personal.
En otras partes de la base de código, se necesita estar tanto en pm_tags_allowed_for_groups como en tag_topic_allowed_groups.
Esto es especialmente restrictivo cuando existe la necesidad de que los usuarios puedan etiquetar sus propios mensajes personales, mientras que no se desea que etiqueten temas públicos (por ejemplo, esto Private template permissions to override allowed PM tagging groups), es decir, cuando pm_tags_allowed_for_groups no es un subconjunto propio de tag_topic_allowed_groups.
Análisis
En TagGuardian estas son configuraciones distintas. Solo necesitas estar en pm_tags_allowed_for_groups para poder etiquetar 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 mismo ocurre con Guardian.can_tag? Las configuraciones son distintas.
def can_tag?(topic)
return false if topic.blank?
topic.private_message? ? can_tag_pms? : can_tag_topics?
end
ListController también se conforma con solo 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?
Sin embargo, TopicGuardian requiere que un usuario esté tanto en tag_topic_allowed_groups como en pm_tags_allowed_for_groups si desea poder etiquetar 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
En el lado del cliente, la misma restricción se encuentra en 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"))
);
}
Pero el modal Move to Topic no tiene esta restricción:
get canTagMessages() {
return this.site.can_tag_pms;
}
y tampoco ChatToTopicSelector
@alias("site.can_tag_pms") canTagMessages;
y tampoco 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",
});
}
Resumen
| Clase | C/S | Comportamiento |
|---|---|---|
| TagGuardian | servidor | solo pm_tags_allowed_for_groups |
| Guardian | servidor | solo pm_tags_allowed_for_groups |
| ListController | servidor | solo pm_tags_allowed_for_groups |
| TopicGuardian | servidor | tanto pm_tags_allowed_for_groups como tag_topic_allowed_groups |
| Composer | cliente | tanto pm_tags_allowed_for_groups como tag_topic_allowed_groups |
| TopicController | cliente | tanto pm_tags_allowed_for_groups como tag_topic_allowed_groups |
| Modal “Move to Topic” | cliente | solo pm_tags_allowed_for_groups |
| ChatToTopicSelector | cliente | solo pm_tags_allowed_for_groups |
Problemas adicionales
Encontré dos impedimentos adicionales:
PostRevisor utiliza tc.guardian.can_tag_topics? en lugar de tc.guardian.can_tag?(tc.topic)
y en DiscourseTagging
tag_topic_by_names hace lo correcto
def self.tag_topic_by_names(topic, guardian, tag_names_arg, append: false)
if guardian.can_tag?(topic)
pero luego tags_for_saving no lo hace
def self.tags_for_saving(tags_arg, guardian, opts = {})
return [] unless guardian.can_tag_topics? && tags_arg.present?
Este último es especialmente desagradable ya que la función no es consciente de si está trabajando en un PM.