Skip to content
代码片段 群组 项目
content_blocked_state.rb 2.15 KiB
# frozen_string_literal: true

module ContentValidation
  class ContentBlockedState < ApplicationRecord
    self.table_name = 'content_blocked_states'

    include Gitlab::Utils::StrongMemoize
    include ShaAttribute

    validates :container_identifier, presence: true
    validates :commit_sha, presence: true
    validates :blob_sha, presence: true
    validates :path, exclusion: { in: [nil] }

    sha_attribute :commit_sha
    sha_attribute :blob_sha

    delegate :full_path, to: :project, prefix: true, allow_nil: true

    def identifier
      strong_memoize(:identifier) { ::Gitlab::GlRepository::Identifier.parse(container_identifier) }
    end

    def container
      strong_memoize(:container) { identifier.container }
    end

    def repo_type
      strong_memoize(:repo_type) { identifier.repo_type }
    end

    def project
      strong_memoize(:project) { repo_type.project_for(container) }
    end

    def self.blocked?(container_identifier:, commit_sha:, path:)
      where(container_identifier: container_identifier, commit_sha: commit_sha, path: path).exists?
    end

    # Find by container
    def self.find_by_container_commit_path(container, commit_sha, path)
      path = path&.gsub(%r/^\//, "")
      container_identifier = container.repository.repo_type.identifier_for_container(container)
      where(container_identifier: container_identifier, commit_sha: commit_sha, path: path).first
    end

    def self.find_by_wiki_page(page)
      container_identifier = page.wiki.repository.repo_type.identifier_for_container(page.wiki)
      commit = page.last_version
      where(container_identifier: container_identifier, commit_sha: commit.id, path: page.path).first
    end

    def self.find_by_snippet_path(snippet, path)
      last_commit = Gitlab::Git::Commit.last_for_path(snippet.repository, snippet.default_branch, path)
      container_identifier = snippet.repository.repo_type.identifier_for_container(snippet)
      where(container_identifier: container_identifier, commit_sha: last_commit&.id, path: path).first
    end

    def self.find_by_snippet(snippet)
      snippet.list_files.map { |file| find_by_snippet_path(snippet, file) }.compact
    end
  end
end