Commit da9b896c authored by Mayra Cabrera's avatar Mayra Cabrera

Merge branch 'isolate-mentions-migration' into 'master'

Isolate User and Project models for mentions migrations RUN AS-IF-FOSS

See merge request gitlab-org/gitlab!43307
parents 861db903 70600969
# frozen_string_literal: true
module Gitlab
module BackgroundMigration
module UserMentions
module Lib
module Banzai
module ReferenceParser
# isolated Banzai::ReferenceParser::MentionedGroupParser
class IsolatedMentionedProjectParser < ::Banzai::ReferenceParser::MentionedProjectParser
extend ::Gitlab::Utils::Override
self.reference_type = :user
override :references_relation
def references_relation
::Gitlab::BackgroundMigration::UserMentions::Models::Project
end
end
end
end
end
end
end
end
# frozen_string_literal: true
module Gitlab
module BackgroundMigration
module UserMentions
module Lib
module Banzai
module ReferenceParser
# isolated Banzai::ReferenceParser::MentionedGroupParser
class IsolatedMentionedUserParser < ::Banzai::ReferenceParser::MentionedUserParser
extend ::Gitlab::Utils::Override
self.reference_type = :user
override :references_relation
def references_relation
::Gitlab::BackgroundMigration::UserMentions::Models::User
end
end
end
end
end
end
end
end
......@@ -7,7 +7,7 @@ module Gitlab
module Gitlab
# Extract possible GFM references from an arbitrary String for further processing.
class IsolatedReferenceExtractor < ::Gitlab::ReferenceExtractor
REFERABLES = %i(isolated_mentioned_group).freeze
REFERABLES = %i(isolated_mentioned_group isolated_mentioned_user isolated_mentioned_project).freeze
REFERABLES.each do |type|
define_method("#{type}s") do
......
# frozen_string_literal: true
module Gitlab
module BackgroundMigration
module UserMentions
module Lib
module Gitlab
# Gitlab::IsolatedVisibilityLevel module
#
# Define allowed public modes that can be used for
# GitLab projects to determine project public mode
#
module IsolatedVisibilityLevel
extend ::ActiveSupport::Concern
included do
scope :public_to_user, -> (user = nil) do
where(visibility_level: IsolatedVisibilityLevel.levels_for_user(user))
end
end
PRIVATE = 0 unless const_defined?(:PRIVATE)
INTERNAL = 10 unless const_defined?(:INTERNAL)
PUBLIC = 20 unless const_defined?(:PUBLIC)
class << self
def levels_for_user(user = nil)
return [PUBLIC] unless user
if user.can_read_all_resources?
[PRIVATE, INTERNAL, PUBLIC]
elsif user.external?
[PUBLIC]
else
[INTERNAL, PUBLIC]
end
end
end
def private?
visibility_level_value == PRIVATE
end
def internal?
visibility_level_value == INTERNAL
end
def public?
visibility_level_value == PUBLIC
end
def visibility_level_value
self[visibility_level_field]
end
end
end
end
end
end
end
......@@ -7,6 +7,7 @@ module Gitlab
module Models
class CommitUserMention < ActiveRecord::Base
self.table_name = 'commit_user_mentions'
self.inheritance_column = :_type_disabled
def self.resource_foreign_key
:commit_id
......
# frozen_string_literal: true
module Gitlab
module BackgroundMigration
module UserMentions
module Models
module Concerns
# isolated FeatureGate module
module IsolatedFeatureGate
def flipper_id
return if new_record?
"#{self.class.name}:#{id}"
end
end
end
end
end
end
end
......@@ -70,8 +70,8 @@ module Gitlab
def build_mention_values(resource_foreign_key)
refs = all_references(author)
mentioned_users_ids = array_to_sql(refs.mentioned_users.pluck(:id))
mentioned_projects_ids = array_to_sql(refs.mentioned_projects.pluck(:id))
mentioned_users_ids = array_to_sql(refs.isolated_mentioned_users.pluck(:id))
mentioned_projects_ids = array_to_sql(refs.isolated_mentioned_projects.pluck(:id))
mentioned_groups_ids = array_to_sql(refs.isolated_mentioned_groups.pluck(:id))
return if mentioned_users_ids.blank? && mentioned_projects_ids.blank? && mentioned_groups_ids.blank?
......
......@@ -6,7 +6,7 @@ module Gitlab
module Models
module Concerns
module Namespace
# extracted methods for recursive traversing of namespace hierarchy
# isolate recursive traversal code for namespace hierarchy
module RecursiveTraversal
extend ActiveSupport::Concern
......
......@@ -10,6 +10,9 @@ module Gitlab
include EachBatch
include Concerns::MentionableMigrationMethods
self.table_name = 'design_management_designs'
self.inheritance_column = :_type_disabled
def self.user_mention_model
Gitlab::BackgroundMigration::UserMentions::Models::DesignUserMention
end
......
......@@ -7,6 +7,7 @@ module Gitlab
module Models
class DesignUserMention < ActiveRecord::Base
self.table_name = 'design_user_mentions'
self.inheritance_column = :_type_disabled
def self.resource_foreign_key
:design_id
......
......@@ -17,10 +17,10 @@ module Gitlab
cache_markdown_field :description, issuable_state_filter_enabled: true
self.table_name = 'epics'
self.inheritance_column = :_type_disabled
belongs_to :author, class_name: "User"
belongs_to :project
belongs_to :group
belongs_to :author, class_name: "::Gitlab::BackgroundMigration::UserMentions::Models::User"
belongs_to :group, class_name: "::Gitlab::BackgroundMigration::UserMentions::Models::Group"
def self.user_mention_model
Gitlab::BackgroundMigration::UserMentions::Models::EpicUserMention
......
......@@ -7,6 +7,7 @@ module Gitlab
module Models
class EpicUserMention < ActiveRecord::Base
self.table_name = 'epic_user_mentions'
self.inheritance_column = :_type_disabled
def self.resource_foreign_key
:epic_id
......
......@@ -7,6 +7,8 @@ module Gitlab
# isolated Group model
class Group < ::Gitlab::BackgroundMigration::UserMentions::Models::Namespace
self.store_full_sti_class = false
self.inheritance_column = :_type_disabled
has_one :saml_provider
def self.declarative_policy_class
......
......@@ -17,10 +17,11 @@ module Gitlab
cache_markdown_field :description, issuable_state_filter_enabled: true
self.table_name = 'merge_requests'
self.inheritance_column = :_type_disabled
belongs_to :author, class_name: "User"
belongs_to :target_project, class_name: "Project"
belongs_to :source_project, class_name: "Project"
belongs_to :author, class_name: "::Gitlab::BackgroundMigration::UserMentions::Models::User"
belongs_to :target_project, class_name: "::Gitlab::BackgroundMigration::UserMentions::Models::Project"
belongs_to :source_project, class_name: "::Gitlab::BackgroundMigration::UserMentions::Models::Project"
alias_attribute :project, :target_project
......
......@@ -7,6 +7,7 @@ module Gitlab
module Models
class MergeRequestUserMention < ActiveRecord::Base
self.table_name = 'merge_request_user_mentions'
self.inheritance_column = :_type_disabled
def self.resource_foreign_key
:merge_request_id
......
......@@ -5,9 +5,11 @@ module Gitlab
module UserMentions
module Models
# isolated Namespace model
class Namespace < ApplicationRecord
include FeatureGate
include ::Gitlab::VisibilityLevel
class Namespace < ActiveRecord::Base
self.inheritance_column = :_type_disabled
include Concerns::IsolatedFeatureGate
include Gitlab::BackgroundMigration::UserMentions::Lib::Gitlab::IsolatedVisibilityLevel
include ::Gitlab::Utils::StrongMemoize
include Gitlab::BackgroundMigration::UserMentions::Models::Concerns::Namespace::RecursiveTraversal
......
......@@ -16,9 +16,9 @@ module Gitlab
attr_mentionable :note, pipeline: :note
cache_markdown_field :note, pipeline: :note, issuable_state_filter_enabled: true
belongs_to :author, class_name: "User"
belongs_to :author, class_name: "::Gitlab::BackgroundMigration::UserMentions::Models::User"
belongs_to :noteable, polymorphic: true
belongs_to :project
belongs_to :project, class_name: "::Gitlab::BackgroundMigration::UserMentions::Models::Project"
def for_personal_snippet?
noteable && noteable.class.name == 'PersonalSnippet'
......
# frozen_string_literal: true
module Gitlab
module BackgroundMigration
module UserMentions
module Models
# isolated Namespace model
class Project < ActiveRecord::Base
include Concerns::IsolatedFeatureGate
include Gitlab::BackgroundMigration::UserMentions::Lib::Gitlab::IsolatedVisibilityLevel
self.table_name = 'projects'
self.inheritance_column = :_type_disabled
belongs_to :group, -> { where(type: 'Group') }, foreign_key: 'namespace_id', class_name: "::Gitlab::BackgroundMigration::UserMentions::Models::Group"
belongs_to :namespace, class_name: "::Gitlab::BackgroundMigration::UserMentions::Models::Namespace"
alias_method :parent, :namespace
# Returns a collection of projects that is either public or visible to the
# logged in user.
def self.public_or_visible_to_user(user = nil, min_access_level = nil)
min_access_level = nil if user&.can_read_all_resources?
return public_to_user unless user
if user.is_a?(::Gitlab::BackgroundMigration::UserMentions::Models::User)
where('EXISTS (?) OR projects.visibility_level IN (?)',
user.authorizations_for_projects(min_access_level: min_access_level),
levels_for_user(user))
end
end
def grafana_integration
nil
end
def default_issues_tracker?
true # we do not care of the issue tracker type(internal or external) when parsing mentions
end
def visibility_level_field
:visibility_level
end
end
end
end
end
end
# frozen_string_literal: true
module Gitlab
module BackgroundMigration
module UserMentions
module Models
# isolated Namespace model
class User < ActiveRecord::Base
include Concerns::IsolatedFeatureGate
self.table_name = 'users'
self.inheritance_column = :_type_disabled
has_many :project_authorizations, dependent: :delete_all # rubocop:disable Cop/ActiveRecordDependent
def authorizations_for_projects(min_access_level: nil, related_project_column: 'projects.id')
authorizations = project_authorizations
.select(1)
.where("project_authorizations.project_id = #{related_project_column}")
return authorizations unless min_access_level.present?
authorizations.where('project_authorizations.access_level >= ?', min_access_level)
end
def can_read_all_resources?
can?(:read_all_resources)
end
def can?(action, subject = :global)
Ability.allowed?(self, action, subject)
end
end
end
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment