O código para o manuseio de marcação de mensagens pessoais é inconsistente.
Em algumas partes da base de código, estar em pm_tags_allowed_for_groups é suficiente para poder marcar uma mensagem pessoal.
Em outras partes da base de código, é necessário estar tanto em pm_tags_allowed_for_groups quanto em tag_topic_allowed_groups.
Isso é especialmente restritivo quando há a necessidade de os usuários poderem marcar suas próprias mensagens pessoais, enquanto você não quer que eles marquem tópicos públicos (por exemplo, este Private template permissions to override allowed PM tagging groups), ou seja, quando pm_tags_allowed_for_groups não é um subconjunto adequado de tag_topic_allowed_groups.
Análise
Em TagGuardian essas são configurações distintas. Você só precisa estar em pm_tags_allowed_for_groups para poder marcar um 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
O mesmo vale para Guardian.can_tag? As configurações são distintas.
def can_tag?(topic)
return false if topic.blank?
topic.private_message? ? can_tag_pms? : can_tag_topics?
end
ListController também se contenta apenas com 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?
No entanto, TopicGuardian exige que um usuário esteja em tag_topic_allowed_groups e pm_tags_allowed_for_groups se quiser poder marcar um 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
No lado do cliente, a mesma restrição está em 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"))
);
}
Mas o modal Move to Topic não tem essa restrição:
get canTagMessages() {
return this.site.can_tag_pms;
}
e nem ChatToTopicSelector
@alias("site.can_tag_pms") canTagMessages;
e nem 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",
});
}
Resumo
| Classe | C/S | Comportamento |
|---|---|---|
| TagGuardian | servidor | apenas pm_tags_allowed_for_groups |
| Guardian | servidor | apenas pm_tags_allowed_for_groups |
| ListController | servidor | apenas pm_tags_allowed_for_groups |
| TopicGuardian | servidor | ambos pm_tags_allowed_for_groups e tag_topic_allowed_groups |
| Composer | cliente | ambos pm_tags_allowed_for_groups e tag_topic_allowed_groups |
| TopicController | cliente | ambos pm_tags_allowed_for_groups e tag_topic_allowed_groups |
| Modal Mover para Tópico | cliente | apenas pm_tags_allowed_for_groups |
| ChatToTopicSelector | cliente | apenas pm_tags_allowed_for_groups |
Questões adicionais
Encontrei mais dois impedimentos adicionais:
PostRevisor usa tc.guardian.can_tag_topics? em vez de tc.guardian.can_tag?(tc.topic)
e em DiscourseTagging
tag_topic_by_names faz a coisa certa
def self.tag_topic_by_names(topic, guardian, tag_names_arg, append: false)
if guardian.can_tag?(topic)
mas então tags_for_saving não faz
def self.tags_for_saving(tags_arg, guardian, opts = {})
return [] unless guardian.can_tag_topics? && tags_arg.present?
Este último é especialmente complicado, pois a função não sabe se está trabalhando em um PM.