PM 태그 관련 코드/요구사항 불일치

개인 메시지 태그 처리 관련 코드가 일관되지 않습니다.

코드베이스의 일부에서는 pm_tags_allowed_for_groups에 속해 있는 것만으로도 개인 메시지에 태그를 달 수 있습니다.

반면 코드베이스의 다른 일부에서는 pm_tags_allowed_for_groupstag_topic_allowed_groups 양쪽에 모두 속해 있어야 개인 메시지에 태그를 달 수 있습니다.

이는 사용자가 자신의 개인 메시지에 태그를 달 수 있도록 해야 하지만 공개 주제에는 태그를 달 수 없도록 해야 하는 경우(예: 이 Private template permissions to override allowed PM tagging groups )에 특히 제한적입니다. 즉, pm_tags_allowed_for_groupstag_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

ListControllercan_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_groupspm_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만

추가 문제

두 가지의 추가적인 장애물을 발견했습니다:

PostRevisortc.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)를 처리하고 있는지 여부를 인식하지 못하기 때문에 특히 까다롭습니다.

6개의 좋아요