
This is used to dynamically exclude some test results from being shown to users, but still allows them to run in the background (e.g., for research).
41 lines
1.8 KiB
Ruby
41 lines
1.8 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module FileParameters
|
|
def reject_illegal_file_attributes(exercise, params)
|
|
if exercise && params
|
|
# We only want to load the files once, to avoid multiple database queries.
|
|
# Further, we use `unscope` to avoid that the `order` scope is applied
|
|
# Optimization: We query for the `file_type` here, which is used in `CodeOcean::File#set_ancestor_values`.
|
|
files = CodeOcean::File.unscope(:order).where(id: params.values.pluck(:file_id)).includes(:file_type)
|
|
|
|
params.reject do |_, file_attributes|
|
|
# This mechanism seems cumbersome, but we cannot use an index here.
|
|
# The ordering of the files is not guaranteed to be the same as the ordering of the file attributes.
|
|
file = files.find {|f| f.id == file_attributes[:file_id].to_i }
|
|
|
|
next true if file.nil? || file.hidden || file.read_only
|
|
# avoid that public files from other contexts can be created
|
|
# `next` is similar to an early return and will proceed with the next iteration of the loop
|
|
next true if file.context_type == 'Exercise' && file.context_id != exercise.id
|
|
next true if file.context_type == 'Submission' && (file.context.user_id != current_user.id || file.context.user_type != current_user.class.name)
|
|
next true if file.context_type == 'CommunitySolution' && controller_name != 'community_solutions'
|
|
|
|
# Optimization: We already queried the ancestor file, let's reuse the object.
|
|
file_attributes[:file] = file
|
|
file_attributes.delete(:file_id)
|
|
|
|
false
|
|
end
|
|
else
|
|
[]
|
|
end
|
|
end
|
|
private :reject_illegal_file_attributes
|
|
|
|
def file_attributes
|
|
%w[content context_id feedback_message file_id file_type_id hidden id name native_file path read_only role weight
|
|
file_template_id hidden_feedback]
|
|
end
|
|
private :file_attributes
|
|
end
|