개인 메시지 태그 처리 관련 코드가 일관되지 않습니다.
코드베이스의 일부에서는 pm_tags_allowed_for_groups에 속해 있는 것만으로도 개인 메시지에 태그를 달 수 있습니다.
반면 코드베이스의 다른 일부에서는 pm_tags_allowed_for_groups와 tag_topic_allowed_groups 양쪽에 모두 속해 있어야 개인 메시지에 태그를 달 수 있습니다.
이는 사용자가 자신의 개인 메시지에 태그를 달 수 있도록 해야 하지만 공개 주제에는 태그를 달 수 없도록 해야 하는 경우(예: 이 Private template permissions to override allowed PM tagging groups )에 특히 제한적입니다. 즉, pm_tags_allowed_for_groups가 tag_topic_allowed_groups의 진부분집합이 아닌 경우입니다.
분석
TagGuardian에서는 이 설정들이 서로 구별됩니다. 개인 메시지에 태그를 달기 위해서는 pm_tags_allowed_for_groups에 속해 있는 것만 필요합니다.
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
Guardian.can_tag?도 마찬가지입니다. 설정들은 서로 구별됩니다.
def can_tag?(topic)
return false if topic.blank?
topic.private_message? ? can_tag_pms? : can_tag_topics?
end
ListController도 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?
그러나 TopicGuardian은 개인 메시지에 태그를 달려면 사용자가 tag_topic_allowed_groups와 pm_tags_allowed_for_groups 양쪽에 모두 속해 있어야 합니다.
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
클라이언트 측에서도 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)
);
}
그리고 TopicController에도 있습니다.
@discourseComputed("model.isPrivateMessage")
canEditTags(isPrivateMessage) {
return (
this.site.get("can_tag_topics") &&
(!isPrivateMessage || this.site.get("can_tag_pms"))
);
}
하지만 이동 대상 주제 모달에는 이 제한이 없습니다:
get canTagMessages() {
return this.site.can_tag_pms;
}
그리고 ChatToTopicSelector에도 없습니다.
@alias("site.can_tag_pms") canTagMessages;
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",
});
}
요약
| 클래스 | C/S | 동작 |
|---|---|---|
| TagGuardian | 서버 | pm_tags_allowed_for_groups만 |
| Guardian | 서버 | pm_tags_allowed_for_groups만 |
| ListController | 서버 | pm_tags_allowed_for_groups만 |
| TopicGuardian | 서버 | pm_tags_allowed_for_groups와 tag_topic_allowed_groups 모두 |
| Composer | 클라이언트 | pm_tags_allowed_for_groups와 tag_topic_allowed_groups 모두 |
| TopicController | 클라이언트 | pm_tags_allowed_for_groups와 tag_topic_allowed_groups 모두 |
| 이동 대상 주제 모달 | 클라이언트 | pm_tags_allowed_for_groups만 |
| ChatToTopicSelector | 클라이언트 | pm_tags_allowed_for_groups만 |
추가 문제
두 가지의 추가적인 장애물을 발견했습니다:
PostRevisor는 tc.guardian.can_tag?(tc.topic) 대신 tc.guardian.can_tag_topics?를 사용합니다.
그리고 DiscourseTagging에서
tag_topic_by_names는 올바르게 동작합니다.
def self.tag_topic_by_names(topic, guardian, tag_names_arg, append: false)
if guardian.can_tag?(topic)
하지만 tags_for_saving은 그렇지 않습니다.
def self.tags_for_saving(tags_arg, guardian, opts = {})
return [] unless guardian.can_tag_topics? && tags_arg.present?
마지막 항목은 해당 함수가 개인 메시지(PM)를 처리하고 있는지 여부를 인식하지 못하기 때문에 특히 까다롭습니다.