From e561594a4766d80040b697d56fed2e193f1c7440 Mon Sep 17 00:00:00 2001 From: Alex Kriuchykhin Date: Tue, 20 Aug 2024 14:47:32 +0200 Subject: [PATCH] Fix permissions checking user assignments scopes [SCI-10991] (#7805) --- app/models/concerns/assignable.rb | 30 +++++++++++++++++++++--------- app/models/repository.rb | 4 +++- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/app/models/concerns/assignable.rb b/app/models/concerns/assignable.rb index afcea0ae8..d09db4d95 100644 --- a/app/models/concerns/assignable.rb +++ b/app/models/concerns/assignable.rb @@ -15,21 +15,33 @@ module Assignable inverse_of: :assignable scope :readable_by_user, lambda { |user| - joins(user_assignments: :user_role) - .where(user_assignments: { user: user }) - .where('? = ANY(user_roles.permissions)', "::#{self.class.to_s.split('::').first}Permissions".constantize::READ) + joins("INNER JOIN user_assignments reading_user_assignments " \ + "ON reading_user_assignments.assignable_type = '#{base_class.name}' " \ + "AND reading_user_assignments.assignable_id = #{table_name}.id " \ + "INNER JOIN user_roles reading_user_roles " \ + "ON reading_user_assignments.user_role_id = reading_user_roles.id") + .where(reading_user_assignments: { user_id: user.id }) + .where('? = ANY(reading_user_roles.permissions)', "::#{self.class.to_s.split('::').first}Permissions".constantize::READ) } scope :managable_by_user, lambda { |user| - joins(user_assignments: :user_role) - .where(user_assignments: { user: user }) - .where('? = ANY(user_roles.permissions)', "::#{self.class.to_s.split('::').first}Permissions".constantize::MANAGE) + joins("INNER JOIN user_assignments managing_user_assignments " \ + "ON managing_user_assignments.assignable_type = '#{base_class.name}' " \ + "AND managing_user_assignments.assignable_id = #{table_name}.id " \ + "INNER JOIN user_roles managing_user_roles " \ + "ON managing_user_assignments.user_role_id = managing_user_roles.id") + .where(managing_user_assignments: { user_id: user.id }) + .where('? = ANY(managing_user_roles.permissions)', "::#{self.class.to_s.split('::').first}Permissions".constantize::MANAGE) } scope :with_user_permission, lambda { |user, permission| - joins(user_assignments: :user_role) - .where(user_assignments: { user: user }) - .where('? = ANY(user_roles.permissions)', permission) + joins("INNER JOIN user_assignments permission_checking_user_assignments " \ + "ON permission_checking_user_assignments.assignable_type = '#{base_class.name}' " \ + "AND permission_checking_user_assignments.assignable_id = #{table_name}.id " \ + "INNER JOIN user_roles permission_checking_user_roles " \ + "ON permission_checking_user_assignments.user_role_id = permission_checking_user_roles.id") + .where(permission_checking_user_assignments: { user_id: user.id }) + .where('? = ANY(permission_checking_user_roles.permissions)', permission) } after_create :create_users_assignments diff --git a/app/models/repository.rb b/app/models/repository.rb index 9fb86d8de..052b4c346 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -49,12 +49,14 @@ class Repository < RepositoryBase scope :globally_shared, -> { where(permission_level: %i(shared_read shared_write)) } scope :viewable_by_user, lambda { |user, teams = user.current_team| - readable_repositories = readable_by_user(user) + readable_repositories = readable_by_user(user).left_outer_joins(:team_shared_objects) readable_repositories .where(team: teams) + .or(readable_repositories.where(team_shared_objects: { team: teams })) .or(readable_repositories .where(permission_level: [Extends::SHARED_OBJECTS_PERMISSION_LEVELS[:shared_read], Extends::SHARED_OBJECTS_PERMISSION_LEVELS[:shared_write]]) .where.not(team: teams)) + .distinct } scope :assigned_to_project, lambda { |project|