Skip to content
Snippets Groups Projects
Verified Commit 62b941fa authored by Omar Qunsul's avatar Omar Qunsul 2️⃣
Browse files

Identifying all cross joins between namespaces and users

Addressing Issue #415196

Changelog: other
parent 161a2055
No related branches found
No related tags found
1 merge request!124319Identifying all cross joins between namespaces and users
Showing
with 49 additions and 23 deletions
......@@ -768,6 +768,7 @@ def billed_project_users(exclude_guests: false)
members = members.not_banned_in(root_ancestor)
users_without_bots(members).with_state(:active)
.allow_cross_joins_across_databases(url: "https://gitlab.com/gitlab-org/gitlab/-/issues/417455")
end
# Members belonging to Groups invited to collaborate with Groups and Subgroups
......
......@@ -704,7 +704,9 @@ def approvals_before_merge
def applicable_approval_rules_for_user(user_id, target_branch = nil)
visible_approval_rules(target_branch: target_branch).select do |rule|
rule.approvers.pluck(:id).include?(user_id)
rule.approvers
.allow_cross_joins_across_databases(url: "https://gitlab.com/gitlab-org/gitlab/-/issues/417461")
.pluck(:id).include?(user_id)
end
end
......
......@@ -11,14 +11,18 @@ def initialize(merge_request)
def execute
return unless merge_request.merged?
ApplicationRecord.transaction do
if merge_request.approval_rules.regular.exists?
merge_group_members_into_users
else
copy_project_approval_rules
end
# fails ee/spec/services/approval_rules/finalize_service_spec.rb
cross_join_issue = "https://gitlab.com/gitlab-org/gitlab/-/issues/417459"
::Gitlab::Database.allow_cross_joins_across_databases(url: cross_join_issue) do
ApplicationRecord.transaction do
if merge_request.approval_rules.regular.exists?
merge_group_members_into_users
else
copy_project_approval_rules
end
merge_request.approval_rules.each(&:sync_approved_approvers)
merge_request.approval_rules.each(&:sync_approved_approvers)
end
end
end
......
......@@ -89,7 +89,9 @@ def find_iteration(board)
# rubocop: disable CodeReuse/ActiveRecord
def find_user(board)
user_ids = user_finder(board).execute.reselect(:user_id)
::User.id_in(user_ids).find_by(id: params['assignee_id'])
::User.id_in(user_ids)
.allow_cross_joins_across_databases(url: "https://gitlab.com/gitlab-org/gitlab/-/issues/417465")
.find_by(id: params['assignee_id'])
end
# rubocop: enable CodeReuse/ActiveRecord
......
......@@ -57,6 +57,7 @@ def authorizable_users_in_group_hierarchy_by_ids_or_usernames(user_ids, user_nam
.arel
.exists
)
.allow_cross_joins_across_databases(url: "https://gitlab.com/gitlab-org/gitlab/-/issues/417460")
end
# rubocop: enable CodeReuse/ActiveRecord
......
......@@ -32,8 +32,11 @@ def enqueue_consecutive
end
def enqueue_consecutive_groups
find_groups_in_batches do |group|
enqueue_group(group)
cross_join_issue = "https://gitlab.com/gitlab-org/gitlab/-/issues/417467"
::Gitlab::Database.allow_cross_joins_across_databases(url: cross_join_issue) do
find_groups_in_batches do |group|
enqueue_group(group)
end
end
end
end
......
......@@ -162,6 +162,7 @@ def inherit_higher_access_levels(group, access_levels)
.where(users: { identities: ::Identity.iwhere(extern_uid: access_levels.keys) })
.select(:id, 'identities.extern_uid AS distinguished_name', :access_level, :source_id)
.references(:identities)
.allow_cross_joins_across_databases(url: "https://gitlab.com/gitlab-org/gitlab/-/issues/417455")
permissions_in_ancestry.each do |member|
access_levels.set([member.distinguished_name], to: member.access_level)
......
......@@ -29,6 +29,7 @@ def authorize_admin_source!(source_type, source)
# rubocop: disable CodeReuse/ActiveRecord
def retrieve_members(source, params:, deep: false)
members = deep ? find_all_members(source) : source_members(source).connected_to_user
members = members.allow_cross_joins_across_databases(url: "https://gitlab.com/gitlab-org/gitlab/-/issues/417456")
members = members.includes(:user)
members = members.references(:user).merge(User.search(params[:query], use_minimum_char_limit: false)) if params[:query].present?
members = members.where(user_id: params[:user_ids]) if params[:user_ids].present?
......
......@@ -58,8 +58,11 @@ def enqueue_consecutive
end
def enqueue_consecutive_projects
project_relation.find_each(batch_size: 1000) do |project|
enqueue_project(project)
cross_join_issue = "https://gitlab.com/gitlab-org/gitlab/-/issues/417467"
::Gitlab::Database.allow_cross_joins_across_databases(url: cross_join_issue) do
project_relation.find_each(batch_size: 1000) do |project|
enqueue_project(project)
end
end
end
......
......@@ -65,10 +65,13 @@ def object_link_filter(text, pattern, link_content: nil, link_reference: false)
# The keys of this Hash are the namespace paths, the values the
# corresponding Namespace objects.
def namespaces
@namespaces ||= Namespace.eager_load(:owner, :route)
.where_full_path_in(usernames)
.index_by(&:full_path)
.transform_keys(&:downcase)
cross_join_issue = "https://gitlab.com/gitlab-org/gitlab/-/issues/417466"
Gitlab::Database.allow_cross_joins_across_databases(url: cross_join_issue) do
@namespaces ||= Namespace.eager_load(:owner, :route)
.where_full_path_in(usernames)
.index_by(&:full_path)
.transform_keys(&:downcase)
end
end
# Returns all usernames referenced in the current document.
......
......@@ -97,9 +97,12 @@ def find_users(ids)
def find_users_for_groups(ids)
return [] if ids.empty?
User.joins(:group_members).where(members: {
source_id: Namespace.where(id: ids).where('mentions_disabled IS NOT TRUE').select(:id)
}).to_a
cross_join_issue = "https://gitlab.com/gitlab-org/gitlab/-/issues/417466"
::Gitlab::Database.allow_cross_joins_across_databases(url: cross_join_issue) do
User.joins(:group_members).where(members: {
source_id: Namespace.where(id: ids).where('mentions_disabled IS NOT TRUE').select(:id)
}).to_a
end
end
def find_users_for_projects(ids)
......
......@@ -13,6 +13,7 @@ def initialize(current_user, query, limit_projects = nil, group:, default_projec
# rubocop:disable CodeReuse/ActiveRecord
def users
groups = group.self_and_hierarchy_intersecting_with_user_groups(current_user)
groups = groups.allow_cross_joins_across_databases(url: "https://gitlab.com/gitlab-org/gitlab/-/issues/417455")
members = GroupMember.where(group: groups).non_invite
users = super
......
......@@ -2,7 +2,8 @@
require 'spec_helper'
RSpec.describe Gitlab::BackgroundMigration::BatchingStrategies::PrimaryKeyBatchingStrategy, '#next_batch' do
RSpec.describe Gitlab::BackgroundMigration::BatchingStrategies::PrimaryKeyBatchingStrategy,
'#next_batch', feature_category: :database do
let(:batching_strategy) { described_class.new(connection: ActiveRecord::Base.connection) }
let(:namespaces) { table(:namespaces) }
......@@ -64,7 +65,7 @@
context 'when scope has a join which makes the column name ambiguous' do
let(:job_class) do
Class.new(Gitlab::BackgroundMigration::BatchedMigrationJob) do
scope_to ->(r) { r.joins('LEFT JOIN users ON users.id = namespaces.owner_id') }
scope_to ->(r) { r.joins('LEFT JOIN namespaces as parents ON parents.id = namespaces.parent_id') }
end
end
......
# frozen_string_literal: true
# This module tries to discover and prevent cross-joins across tables
# This will forbid usage of tables between CI and main database
# This will forbid usage of tables of different gitlab_schemas
# on a same query unless explicitly allowed by. This will change execution
# from a given point to allow cross-joins. The state will be cleared
# on a next test run.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment