Fix permissions checking for active storage blobs belonging to different teams [SCI-9918] (#6871)

This commit is contained in:
Alex Kriuchykhin 2024-01-03 17:09:15 +01:00 committed by GitHub
parent 4fd6ecf112
commit dd312062d3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 21 additions and 38 deletions

View file

@ -13,11 +13,13 @@ module ActiveStorage
def check_read_permissions def check_read_permissions
return render_404 if @blob.attachments.blank? return render_404 if @blob.attachments.blank?
@blob.attachments.any? { |attachment| check_attachment_read_permissions(attachment) } render_403 unless @blob.attachments.any? { |attachment| check_attachment_read_permissions(attachment) }
end end
def check_attachment_read_permissions(attachment) def check_attachment_read_permissions(attachment)
current_user.permission_team = attachment.record.team || current_team if attachment.record.respond_to?(:team) current_user.permission_team = attachment.record.team if attachment.record.respond_to?(:team)
return false if attachment.record.blank?
case attachment.record_type case attachment.record_type
when 'Asset' when 'Asset'
@ -25,73 +27,52 @@ module ActiveStorage
when 'TinyMceAsset' when 'TinyMceAsset'
check_tinymce_asset_read_permissions(attachment.record) check_tinymce_asset_read_permissions(attachment.record)
when 'Experiment' when 'Experiment'
check_experiment_read_permissions(attachment.record) can_read_experiment?(attachment.record)
when 'Report' when 'Report'
check_report_read_permissions(attachment.record) can_read_project?(attachment.record.project)
when 'User' when 'User'
# No read restrictions for avatars # No read restrictions for avatars
true true
when 'ZipExport', 'TeamZipExport' when 'ZipExport', 'TeamZipExport'
check_zip_export_read_permissions(attachment.record) attachment.record.user == current_user
when 'TempFile' when 'TempFile'
check_temp_file_read_permissions(attachment.record) attachment.record.session_id == request.session_options[:id].to_s
else else
render_403 false
end end
end end
def check_asset_read_permissions(asset) def check_asset_read_permissions(asset)
return render_403 unless asset
if asset.step if asset.step
protocol = asset.step.protocol protocol = asset.step.protocol
render_403 unless can_read_protocol_in_module?(protocol) || can_read_protocol_in_repository?(protocol) can_read_protocol_in_module?(protocol) || can_read_protocol_in_repository?(protocol)
elsif asset.result elsif asset.result
experiment = asset.result.my_module.experiment experiment = asset.result.my_module.experiment
render_403 unless can_read_experiment?(experiment) can_read_experiment?(experiment)
elsif asset.repository_cell elsif asset.repository_cell
repository = asset.repository_cell.repository_column.repository repository = asset.repository_cell.repository_column.repository
render_403 unless can_read_repository?(repository) can_read_repository?(repository)
else else
render_403 false
end end
end end
def check_tinymce_asset_read_permissions(asset) def check_tinymce_asset_read_permissions(asset)
return render_403 unless asset
return true if asset.object.nil? && can_read_team?(asset.team) return true if asset.object.nil? && can_read_team?(asset.team)
case asset.object_type case asset.object_type
when 'MyModule' when 'MyModule'
render_403 unless can_read_my_module?(asset.object) can_read_my_module?(asset.object)
when 'Protocol' when 'Protocol'
render_403 unless can_read_protocol_in_module?(asset.object) || can_read_protocol_in_module?(asset.object) || can_read_protocol_in_repository?(asset.object)
can_read_protocol_in_repository?(asset.object)
when 'ResultText' when 'ResultText'
render_403 unless can_read_my_module?(asset.object.result.my_module) can_read_my_module?(asset.object.result.my_module)
when 'StepText' when 'StepText'
render_403 unless can_read_protocol_in_module?(asset.object.step.protocol) || can_read_protocol_in_module?(asset.object.step.protocol) ||
can_read_protocol_in_repository?(asset.object.step.protocol) can_read_protocol_in_repository?(asset.object.step.protocol)
else else
render_403 false
end end
end end
def check_experiment_read_permissions(experiment)
render_403 && return unless can_read_experiment?(experiment)
end
def check_report_read_permissions(report)
render_403 && return unless can_read_project?(report.project)
end
def check_zip_export_read_permissions(zip_export)
render_403 unless zip_export.user == current_user
end
def check_temp_file_read_permissions(temp_file)
render_403 unless temp_file.session_id == request.session_options[:id].to_s
end
end end
end end

View file

@ -76,6 +76,8 @@ class RepositoryAssetValue < ApplicationRecord
def snapshot!(cell_snapshot) def snapshot!(cell_snapshot)
value_snapshot = dup value_snapshot = dup
asset_snapshot = asset.dup asset_snapshot = asset.dup
# Needed to handle shared repositories from another teams
asset_snapshot.team_id = cell_snapshot.repository_column.repository.team_id
asset_snapshot.save! asset_snapshot.save!