Merge pull request #3605 from okriuchykhin/ok_SCI_6151

Update the search to abide the permissions [SCI-6151]
This commit is contained in:
Alex Kriuchykhin 2021-10-28 14:32:22 +02:00 committed by GitHub
commit 333f2eb18e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 118 additions and 292 deletions

View file

@ -36,27 +36,19 @@ class Checklist < ApplicationRecord
page = 1,
_current_team = nil,
options = {})
step_ids =
Step
.search(user, include_archived, nil, Constants::SEARCH_NO_LIMIT)
.pluck(:id)
step_ids = Step.search(user, include_archived, nil, Constants::SEARCH_NO_LIMIT)
.pluck(:id)
new_query =
Checklist
.distinct
.where('checklists.step_id IN (?)', step_ids)
.joins('LEFT JOIN checklist_items ON ' \
'checklists.id = checklist_items.checklist_id')
.where_attributes_like(['checklists.name', 'checklist_items.text'],
query, options)
new_query = Checklist.distinct
.where(checklists: { step_id: step_ids })
.left_outer_joins(:checklist_items)
.where_attributes_like(['checklists.name', 'checklist_items.text'], query, options)
# Show all results if needed
if page == Constants::SEARCH_NO_LIMIT
new_query
else
new_query
.limit(Constants::SEARCH_LIMIT)
.offset((page - 1) * Constants::SEARCH_LIMIT)
new_query.limit(Constants::SEARCH_LIMIT).offset((page - 1) * Constants::SEARCH_LIMIT)
end
end
end

View file

@ -18,46 +18,34 @@ class Comment < ApplicationRecord
_current_team = nil,
options = {}
)
project_ids =
Project
.search(user, include_archived, nil, Constants::SEARCH_NO_LIMIT)
.pluck(:id)
my_module_ids =
MyModule
.search(user, include_archived, nil, Constants::SEARCH_NO_LIMIT)
.pluck(:id)
step_ids =
Step
.search(user, include_archived, nil, Constants::SEARCH_NO_LIMIT)
.pluck(:id)
result_ids =
Result
.search(user, include_archived, nil, Constants::SEARCH_NO_LIMIT)
.pluck(:id)
project_ids = Project.search(user, include_archived, nil, Constants::SEARCH_NO_LIMIT)
.pluck(:id)
my_module_ids = MyModule.search(user, include_archived, nil, Constants::SEARCH_NO_LIMIT)
.pluck(:id)
step_ids = Step.search(user, include_archived, nil, Constants::SEARCH_NO_LIMIT)
.pluck(:id)
result_ids = Result.search(user, include_archived, nil, Constants::SEARCH_NO_LIMIT)
.pluck(:id)
new_query =
Comment.distinct
.joins(:user)
.where(
'(comments.associated_id IN (?) AND comments.type = ?) OR ' \
'(comments.associated_id IN (?) AND comments.type = ?) OR ' \
'(comments.associated_id IN (?) AND comments.type = ?) OR ' \
'(comments.associated_id IN (?) AND comments.type = ?)',
project_ids, 'ProjectComment',
my_module_ids, 'TaskComment',
step_ids, 'StepComment',
result_ids, 'ResultComment'
)
.where_attributes_like(['message', 'users.full_name'],
query, options)
new_query = Comment.distinct
.joins(:user)
.where(
'(comments.associated_id IN (?) AND comments.type = ?) OR ' \
'(comments.associated_id IN (?) AND comments.type = ?) OR ' \
'(comments.associated_id IN (?) AND comments.type = ?) OR ' \
'(comments.associated_id IN (?) AND comments.type = ?)',
project_ids, 'ProjectComment',
my_module_ids, 'TaskComment',
step_ids, 'StepComment',
result_ids, 'ResultComment'
)
.where_attributes_like(['message', 'users.full_name'], query, options)
# Show all results if needed
if page == Constants::SEARCH_NO_LIMIT
new_query
else
new_query
.limit(Constants::SEARCH_LIMIT)
.offset((page - 1) * Constants::SEARCH_LIMIT)
new_query.limit(Constants::SEARCH_LIMIT).offset((page - 1) * Constants::SEARCH_LIMIT)
end
end

View file

@ -3,6 +3,16 @@
module PermissionCheckableModel
extend ActiveSupport::Concern
included do
include PermissionExtends
scope :with_granted_permissions, lambda { |user, permissions|
left_outer_joins(user_assignments: :user_role)
.where(user_assignments: { user: user })
.where('user_roles.permissions @> ARRAY[?]::varchar[]', permissions)
}
end
def permission_granted?(user, permission)
user_role_permissions = load_user_role_permissions(user)
return false if user_role_permissions.blank?
@ -13,13 +23,10 @@ module PermissionCheckableModel
private
def load_user_role_permissions(user)
user_role_permissions =
if user_assignments.loaded?
user_assignments.detect { |user_assignment| user_assignment.user == user }&.user_role&.permissions
else
user_assignments.find_by(user: user)&.user_role&.permissions
end
user_role_permissions
if user_assignments.loaded?
user_assignments.detect { |user_assignment| user_assignment.user == user }&.user_role&.permissions
else
user_assignments.find_by(user: user)&.user_role&.permissions
end
end
end

View file

@ -69,47 +69,25 @@ class Experiment < ApplicationRecord
current_team = nil,
options = {}
)
experiment_scope = experiment_search_scope(
Project
.search(user, include_archived, nil, Constants::SEARCH_NO_LIMIT)
.pluck(:id),
user
)
viewable_projects = Project.search(user, include_archived, nil, Constants::SEARCH_NO_LIMIT, current_team)
.pluck(:id)
new_query = Experiment.with_granted_permissions(user, ExperimentPermissions::READ)
.where(project: viewable_projects)
.where_attributes_like(SEARCHABLE_ATTRIBUTES, query, options)
if current_team
new_query = experiment_search_scope(
Project.search(
user,
include_archived,
nil,
1,
current_team
).select('id'),
user
).where_attributes_like(SEARCHABLE_ATTRIBUTES, query, options)
return include_archived ? new_query : new_query.active
elsif include_archived
new_query = experiment_scope.where_attributes_like(SEARCHABLE_ATTRIBUTES, query, options)
else
new_query = experiment_scope.active
.where_attributes_like(SEARCHABLE_ATTRIBUTES, query, options)
end
new_query = new_query.active unless include_archived
# Show all results if needed
if page == Constants::SEARCH_NO_LIMIT
new_query
else
new_query
.limit(Constants::SEARCH_LIMIT)
.offset((page - 1) * Constants::SEARCH_LIMIT)
new_query.limit(Constants::SEARCH_LIMIT).offset((page - 1) * Constants::SEARCH_LIMIT)
end
end
def self.viewable_by_user(user, teams)
left_outer_joins(user_assignments: :user_role)
with_granted_permissions(user, ExperimentPermissions::READ)
.where(project: Project.viewable_by_user(user, teams))
.where(user_assignments: { user: user })
.where('user_roles.permissions @> ARRAY[?]::varchar[]', %w[experiment_read])
end
def archived_branch?

View file

@ -1,7 +1,7 @@
# frozen_string_literal: true
class MyModule < ApplicationRecord
SEARCHABLE_ATTRIBUTES = %i(name description).freeze
SEARCHABLE_ATTRIBUTES = ['my_modules.name', 'my_modules.description']
include ArchivableModel
include SearchableModel
@ -92,52 +92,26 @@ class MyModule < ApplicationRecord
current_team = nil,
options = {}
)
my_module_scope = my_module_search_scope(
Experiment
.search(user, include_archived, nil, Constants::SEARCH_NO_LIMIT)
.pluck(:id),
user
)
viewable_experiments = Experiment.search(user, include_archived, nil, Constants::SEARCH_NO_LIMIT, current_team)
.pluck(:id)
if current_team
new_query = my_module_search_scope(
Experiment
.search(user,
include_archived,
nil,
1,
current_team)
.select('id'),
user
).where_attributes_like(SEARCHABLE_ATTRIBUTES, query, options)
new_query = MyModule.with_granted_permissions(user, MyModulePermissions::READ)
.where(experiment: viewable_experiments)
.where_attributes_like(SEARCHABLE_ATTRIBUTES, query, options)
if include_archived
return new_query
else
return new_query.where('my_modules.archived = ?', false)
end
elsif include_archived
new_query = my_module_scope.where_attributes_like(SEARCHABLE_ATTRIBUTES, query, options)
else
new_query = my_module_scope.where('my_modules.archived = ?', false)
.where_attributes_like(SEARCHABLE_ATTRIBUTES, query, options)
end
new_query = new_query.active unless include_archived
# Show all results if needed
if page == Constants::SEARCH_NO_LIMIT
new_query
else
new_query
.limit(Constants::SEARCH_LIMIT)
.offset((page - 1) * Constants::SEARCH_LIMIT)
new_query.limit(Constants::SEARCH_LIMIT).offset((page - 1) * Constants::SEARCH_LIMIT)
end
end
def self.viewable_by_user(user, teams)
left_outer_joins(user_assignments: :user_role)
with_granted_permissions(user, MyModulePermissions::READ)
.where(experiment: Experiment.viewable_by_user(user, teams))
.where(user_assignments: { user: user })
.where('user_roles.permissions @> ARRAY[?]::varchar[]', %w[task_read])
end
def navigable?

View file

@ -82,64 +82,15 @@ class Project < ApplicationRecord
options = {}
)
if current_team
new_query =
Project
.distinct
.joins(:user_assignments)
.where('projects.team_id = ?', current_team.id)
unless user.user_teams.find_by(team: current_team).try(:admin?)
# Admins see all projects in the team
new_query = new_query.where(
'projects.visibility = 1 OR user_assignments.user_id = ?',
user.id
)
end
new_query = new_query.where_attributes_like('projects.name', query, options)
if include_archived
return new_query
else
return new_query.where('projects.archived = ?', false)
end
else
new_query = Project
.distinct
.joins(team: :user_teams)
.where('user_teams.user_id = ?', user.id)
if include_archived
new_query =
new_query
.joins(:user_assignments)
.where(
'user_teams.role = 2 OR projects.visibility = 1 OR ' \
'user_assignments.user_id = ?',
user.id
)
.where_attributes_like('projects.name', query, options)
else
new_query =
new_query
.joins(:user_assignments)
.where(
'user_teams.role = 2 OR projects.visibility = 1 OR ' \
'user_assignments.user_id = ?',
user.id
)
.where_attributes_like('projects.name', query, options)
.where('projects.archived = ?', false)
end
end
new_query = Project.viewable_by_user(user, current_team || user.teams)
.where_attributes_like('projects.name', query, options)
new_query = new_query.active unless include_archived
# Show all results if needed
if page == Constants::SEARCH_NO_LIMIT
new_query
else
new_query
.limit(Constants::SEARCH_LIMIT)
.offset((page - 1) * Constants::SEARCH_LIMIT)
new_query.limit(Constants::SEARCH_LIMIT).offset((page - 1) * Constants::SEARCH_LIMIT)
end
end
@ -147,15 +98,12 @@ class Project < ApplicationRecord
# Admins see all projects in the team
# Member of the projects can view
# If project is visible everyone from the team can view it
Project.where(team: teams)
.left_outer_joins(team: :user_teams)
.left_outer_joins(user_assignments: :user_role)
.where('projects.visibility = 1 OR '\
'user_assignments.user_id = :user_id OR '\
'(user_teams.user_id = :user_id AND user_teams.role = 2)',
user_id: user.id)
.where('user_roles.permissions @> ARRAY[?]::varchar[]', [ProjectPermissions::READ])
.distinct
projects = Project.where(team: teams)
.left_outer_joins(team: :user_teams)
.left_outer_joins(user_assignments: :user_role)
projects.where('projects.visibility = 1 OR (user_teams.user_id = ? AND user_teams.role = 2)', user)
.or(projects.with_granted_permissions(user, ProjectPermissions::READ))
.distinct
end
def permission_parent

View file

@ -123,14 +123,11 @@ class Protocol < ApplicationRecord
_current_team = nil,
options = {})
team_ids = Team.joins(:user_teams)
.where('user_teams.user_id = ?', user.id)
.where(user_teams: { user_id: user.id })
.distinct
.pluck(:id)
module_ids = MyModule.search(user,
include_archived,
nil,
Constants::SEARCH_NO_LIMIT)
module_ids = MyModule.search(user, include_archived, nil, Constants::SEARCH_NO_LIMIT)
.pluck(:id)
where_str =
@ -193,9 +190,7 @@ class Protocol < ApplicationRecord
if page == Constants::SEARCH_NO_LIMIT
new_query
else
new_query
.limit(Constants::SEARCH_LIMIT)
.offset((page - 1) * Constants::SEARCH_LIMIT)
new_query.limit(Constants::SEARCH_LIMIT).offset((page - 1) * Constants::SEARCH_LIMIT)
end
end

View file

@ -65,24 +65,18 @@ class Report < ApplicationRecord
options = {}
)
project_ids =
Project
.search(user, include_archived, nil, Constants::SEARCH_NO_LIMIT)
.pluck(:id)
project_ids = Project.search(user, include_archived, nil, Constants::SEARCH_NO_LIMIT)
.pluck(:id)
new_query =
Report
.distinct
.where('reports.project_id IN (?)', project_ids)
.where_attributes_like(%i(name description), query, options)
new_query = Report.distinct
.where(reports: { project_id: project_ids })
.where_attributes_like(%i(name description), query, options)
# Show all results if needed
if page == Constants::SEARCH_NO_LIMIT
new_query
else
new_query
.limit(Constants::SEARCH_LIMIT)
.offset((page - 1) * Constants::SEARCH_LIMIT)
new_query.limit(Constants::SEARCH_LIMIT).offset((page - 1) * Constants::SEARCH_LIMIT)
end
end

View file

@ -74,27 +74,17 @@ class Repository < RepositoryBase
repository = nil,
options = {}
)
serchable_row_fields = [RepositoryRow::PREFIXED_ID_SQL, 'repository_rows.name', 'users.full_name']
repositories = repository&.id || Repository.accessible_by_teams(user.teams).pluck(:id)
readable_rows = RepositoryRow.joins(:repository).where(repository_id: repositories)
readable_rows = RepositoryRow.joins(:repository, :created_by).where(repository_id: repositories)
matched_by_user = readable_rows.joins(:created_by).where_attributes_like('users.full_name', query, options)
prefixed_repository_row_ids = RepositoryRow.where(repository_id: repositories)
.where_attributes_like([RepositoryRow::PREFIXED_ID_SQL], query, options)
.select(:id)
repository_row_matches =
readable_rows.where_attributes_like(['repository_rows.name'], query, options).or(
readable_rows.where('repository_rows.id' => prefixed_repository_row_ids)
)
repository_rows = readable_rows.where(id: repository_row_matches)
repository_rows = repository_rows.or(readable_rows.where(id: matched_by_user))
repository_rows = readable_rows.where_attributes_like(serchable_row_fields, query, options)
Extends::REPOSITORY_EXTRA_SEARCH_ATTR.each do |_data_type, config|
custom_cell_matches = repository_rows.joins(config[:includes])
.where_attributes_like(config[:field], query, options)
custom_cell_matches = readable_rows.joins(config[:includes])
.where_attributes_like(config[:field], query, options)
repository_rows = repository_rows.or(readable_rows.where(id: custom_cell_matches))
end
@ -103,8 +93,7 @@ class Repository < RepositoryBase
repository_rows.select('repositories.id AS id, COUNT(DISTINCT repository_rows.id) AS counter')
.group('repositories.id')
else
repository_rows.limit(Constants::SEARCH_LIMIT)
.offset((page - 1) * Constants::SEARCH_LIMIT)
repository_rows.limit(Constants::SEARCH_LIMIT).offset((page - 1) * Constants::SEARCH_LIMIT)
end
end

View file

@ -32,28 +32,22 @@ class Result < ApplicationRecord
page = 1,
_current_team = nil,
options = {})
module_ids =
MyModule
.search(user, include_archived, nil, Constants::SEARCH_NO_LIMIT)
.pluck(:id)
module_ids = MyModule.search(user, include_archived, nil, Constants::SEARCH_NO_LIMIT).pluck(:id)
new_query =
Result
.distinct
.joins('LEFT JOIN result_texts ON results.id = result_texts.result_id')
.where('results.my_module_id IN (?)', module_ids)
.where_attributes_like(['results.name', 'result_texts.text'],
query, options)
.where(results: { my_module_id: module_ids })
.where_attributes_like(['results.name', 'result_texts.text'], query, options)
new_query = new_query.where('results.archived = ?', false) unless include_archived
new_query = new_query.active unless include_archived
# Show all results if needed
if page == Constants::SEARCH_NO_LIMIT
new_query
else
new_query
.limit(Constants::SEARCH_LIMIT)
.offset((page - 1) * Constants::SEARCH_LIMIT)
new_query.limit(Constants::SEARCH_LIMIT).offset((page - 1) * Constants::SEARCH_LIMIT)
end
end

View file

@ -51,23 +51,18 @@ class Step < ApplicationRecord
page = 1,
_current_team = nil,
options = {})
protocol_ids =
Protocol
.search(user, include_archived, nil, Constants::SEARCH_NO_LIMIT)
.pluck(:id)
protocol_ids = Protocol.search(user, include_archived, nil, Constants::SEARCH_NO_LIMIT)
.pluck(:id)
new_query = Step
.distinct
.where('steps.protocol_id IN (?)', protocol_ids)
.where_attributes_like([:name, :description], query, options)
new_query = Step.distinct
.where(steps: { protocol_id: protocol_ids })
.where_attributes_like(%i(name description), query, options)
# Show all results if needed
if page == Constants::SEARCH_NO_LIMIT
new_query
else
new_query
.limit(Constants::SEARCH_LIMIT)
.offset((page - 1) * Constants::SEARCH_LIMIT)
new_query.limit(Constants::SEARCH_LIMIT).offset((page - 1) * Constants::SEARCH_LIMIT)
end
end

View file

@ -35,29 +35,19 @@ class Table < ApplicationRecord
page = 1,
_current_team = nil,
options = {})
step_ids =
Step
.search(user, include_archived, nil, Constants::SEARCH_NO_LIMIT)
.joins(:step_tables)
.distinct
.pluck('step_tables.id')
step_ids = Step.search(user, include_archived, nil, Constants::SEARCH_NO_LIMIT)
.joins(:step_tables)
.distinct
.pluck('step_tables.id')
result_ids =
Result
.search(user, include_archived, nil, Constants::SEARCH_NO_LIMIT)
.joins(:result_table)
.distinct
.pluck('result_tables.id')
result_ids = Result.search(user, include_archived, nil, Constants::SEARCH_NO_LIMIT)
.joins(:result_table)
.distinct
.pluck('result_tables.id')
table_query =
Table
.distinct
.joins('LEFT OUTER JOIN step_tables ON step_tables.table_id = tables.id')
.joins('LEFT OUTER JOIN result_tables ON ' \
'result_tables.table_id = tables.id')
.joins('LEFT OUTER JOIN results ON result_tables.result_id = results.id')
.where('step_tables.id IN (?) OR result_tables.id IN (?)',
step_ids, result_ids)
table_query = Table.distinct
.left_outer_joins(:step_table, :result_table, :result)
.where('step_tables.id IN (?) OR result_tables.id IN (?)', step_ids, result_ids)
if options[:whole_word].to_s == 'true' ||
options[:whole_phrase].to_s == 'true'
@ -111,9 +101,7 @@ class Table < ApplicationRecord
if page == Constants::SEARCH_NO_LIMIT
new_query
else
new_query
.limit(Constants::SEARCH_LIMIT)
.offset((page - 1) * Constants::SEARCH_LIMIT)
new_query.limit(Constants::SEARCH_LIMIT).offset((page - 1) * Constants::SEARCH_LIMIT)
end
end

View file

@ -24,23 +24,19 @@ class Tag < ApplicationRecord
page = 1,
_current_team = nil,
options = {})
project_ids =
Project
.search(user, include_archived, nil, Constants::SEARCH_NO_LIMIT)
.pluck(:id)
project_ids = Project.search(user, include_archived, nil, Constants::SEARCH_NO_LIMIT)
.pluck(:id)
new_query = Tag
.distinct
.where('tags.project_id IN (?)', project_ids)
.where(tags: { project_id: project_ids })
.where_attributes_like(:name, query, options)
# Show all results if needed
if page == Constants::SEARCH_NO_LIMIT
new_query
else
new_query
.limit(Constants::SEARCH_LIMIT)
.offset((page - 1) * Constants::SEARCH_LIMIT)
new_query.limit(Constants::SEARCH_LIMIT).offset((page - 1) * Constants::SEARCH_LIMIT)
end
end
end

View file

@ -369,24 +369,14 @@ class User < ApplicationRecord
team_to_ignore = nil
)
result = User.all
if active_only
result = result.where.not(confirmed_at: nil)
end
result = result.where.not(confirmed_at: nil) if active_only
if team_to_ignore.present?
ignored_ids =
UserTeam
.select(:user_id)
.where(team_id: team_to_ignore.id)
result =
result
.where("users.id NOT IN (?)", ignored_ids)
ignored_ids = UserTeam.select(:user_id).where(team_id: team_to_ignore.id)
result = result.where.not(users: { id: ignored_ids })
end
result
.where_attributes_like([:full_name, :email], query)
.distinct
result.where_attributes_like(%i(full_name email), query).distinct
end
# Whether user is active (= confirmed) or not

View file

@ -22,12 +22,10 @@ module PermissionExtends
%w(
READ
READ_ARCHIVED
ACTIVITIES_READ
MANAGE
TASKS_MANAGE
USERS_READ
USERS_MANAGE
READ_ARCHIVED
READ_CANVAS
ACTIVITIES_READ
).each { |permission| const_set(permission, "experiment_#{permission.underscore}") }