Merge remote-tracking branch 'origin/master' into flowr

# Conflicts:
#	app/assets/javascripts/editor/evaluation.js
#	app/assets/javascripts/editor/participantsupport.js
#	app/views/exercises/_editor_output.html.slim
#	config/code_ocean.yml.example
#	config/routes.rb
This commit is contained in:
Maximilian Grundke
2018-11-28 13:14:21 +01:00
500 changed files with 12187 additions and 3430 deletions

View File

@ -6,7 +6,7 @@ class ApplicationController < ActionController::Base
after_action :verify_authorized, except: [:help, :welcome]
before_action :set_locale, :allow_iframe_requests
protect_from_forgery(with: :exception)
protect_from_forgery(with: :exception, prepend: true)
rescue_from Pundit::NotAuthorizedError, with: :render_not_authorized
def current_user
@ -14,11 +14,8 @@ class ApplicationController < ActionController::Base
@current_user ||= ExternalUser.find_by(id: session[:external_user_id]) || login_from_session || login_from_other_sources
end
def help
end
def render_not_authorized
redirect_to(:root, alert: t('application.not_authorized'))
redirect_to(request.referrer || :root, alert: t('application.not_authorized'))
end
private :render_not_authorized

View File

@ -0,0 +1,45 @@
module CodeOcean
class ErrorsController < ApplicationController
before_action :set_execution_environment
def authorize!
authorize(@error || @errors)
end
private :authorize!
def create
@error = CodeOcean::Error.new(error_params)
authorize!
hint = Whistleblower.new(execution_environment: @error.execution_environment).generate_hint(@error.message)
respond_to do |format|
format.json do
if hint
render(json: {hint: hint})
else
head (@error.save ? :created : :unprocessable_entity)
end
end
end
end
def error_params
params[:error].permit(:message, :submission_id).merge(execution_environment_id: @execution_environment.id) if params[:error].present?
end
private :error_params
def index
@errors = CodeOcean::Error.for_execution_environment(@execution_environment).grouped_by_message.paginate(page: params[:page])
authorize!
end
def set_execution_environment
@execution_environment = ExecutionEnvironment.find(params[:execution_environment_id])
end
private :set_execution_environment
def show
@error = CodeOcean::Error.find(params[:id])
authorize!
end
end
end

View File

@ -41,7 +41,7 @@ module CodeOcean
end
def file_params
params[:code_ocean_file].permit(file_attributes).merge(context_type: 'Submission', role: 'user_defined_file')
params[:code_ocean_file].permit(file_attributes).merge(context_type: 'Submission', role: 'user_defined_file') if params[:code_ocean_file].present?
end
private :file_params
end

View File

@ -23,9 +23,9 @@ module Lti
session.delete(:consumer_id)
session.delete(:external_user_id)
else
LtiParameter.destroy_all(consumers_id: consumer_id,
external_users_id: user_id,
exercises_id: exercise_id)
LtiParameter.where(consumers_id: consumer_id,
external_users_id: user_id,
exercises_id: exercise_id).destroy_all
end
end
private :clear_lti_session_data
@ -138,7 +138,7 @@ module Lti
external_users_id: @current_user.id,
exercises_id: @exercise.id)
lti_parameters.lti_parameters = options[:parameters].slice(*SESSION_PARAMETERS).to_json
lti_parameters.lti_parameters = options[:parameters].slice(*SESSION_PARAMETERS).permit!.to_h
lti_parameters.save!
@lti_parameters = lti_parameters

View File

@ -2,7 +2,7 @@ module RemoteEvaluationParameters
include FileParameters
def remote_evaluation_params
remote_evaluation_params = params[:remote_evaluation].permit(:validation_token, files_attributes: file_attributes)
remote_evaluation_params = params[:remote_evaluation].permit(:validation_token, files_attributes: file_attributes) if params[:remote_evaluation].present?
end
private :remote_evaluation_params
end

View File

@ -16,7 +16,7 @@ module SubmissionParameters
current_user_id = current_user.id
current_user_class_name = current_user.class.name
end
submission_params = params[:submission].permit(:cause, :exercise_id, files_attributes: file_attributes).merge(user_id: current_user_id, user_type: current_user_class_name)
submission_params = params[:submission].present? ? params[:submission].permit(:cause, :exercise_id, files_attributes: file_attributes).merge(user_id: current_user_id, user_type: current_user_class_name) : {}
reject_illegal_file_attributes!(submission_params)
submission_params
end

View File

@ -22,7 +22,7 @@ class ConsumersController < ApplicationController
end
def consumer_params
params[:consumer].permit(:name, :oauth_key, :oauth_secret)
params[:consumer].permit(:name, :oauth_key, :oauth_secret) if params[:consumer].present?
end
private :consumer_params

View File

@ -81,6 +81,6 @@ class ErrorTemplateAttributesController < ApplicationController
# Never trust parameters from the scary internet, only allow the white list through.
def error_template_attribute_params
params[:error_template_attribute].permit(:key, :description, :regex, :important)
params[:error_template_attribute].permit(:key, :description, :regex, :important) if params[:error_template_attribute].present?
end
end

View File

@ -99,6 +99,6 @@ class ErrorTemplatesController < ApplicationController
# Never trust parameters from the scary internet, only allow the white list through.
def error_template_params
params[:error_template].permit(:name, :execution_environment_id, :signature, :description, :hint)
params[:error_template].permit(:name, :execution_environment_id, :signature, :description, :hint) if params[:error_template].present?
end
end

View File

@ -1,43 +0,0 @@
class ErrorsController < ApplicationController
before_action :set_execution_environment
def authorize!
authorize(@error || @errors)
end
private :authorize!
def create
@error = Error.new(error_params)
authorize!
hint = Whistleblower.new(execution_environment: @error.execution_environment).generate_hint(@error.message)
respond_to do |format|
format.json do
if hint
render(json: {hint: hint})
else
render(nothing: true, status: @error.save ? :created : :unprocessable_entity)
end
end
end
end
def error_params
params[:error].permit(:message, :submission_id).merge(execution_environment_id: @execution_environment.id)
end
private :error_params
def index
@errors = Error.for_execution_environment(@execution_environment).grouped_by_message.paginate(page: params[:page])
authorize!
end
def set_execution_environment
@execution_environment = ExecutionEnvironment.find(params[:execution_environment_id])
end
private :set_execution_environment
def show
@error = Error.find(params[:id])
authorize!
end
end

View File

@ -86,11 +86,11 @@ class ExecutionEnvironmentsController < ApplicationController
working_time_statistics = {}
user_statistics = {}
ActiveRecord::Base.connection.execute(working_time_query).each do |tuple|
ApplicationRecord.connection.execute(working_time_query).each do |tuple|
working_time_statistics[tuple["exercise_id"].to_i] = tuple
end
ActiveRecord::Base.connection.execute(user_query).each do |tuple|
ApplicationRecord.connection.execute(user_query).each do |tuple|
user_statistics[tuple["exercise_id"].to_i] = tuple
end
@ -101,7 +101,7 @@ class ExecutionEnvironmentsController < ApplicationController
end
def execution_environment_params
params[:execution_environment].permit(:docker_image, :exposed_ports, :editor_mode, :file_extension, :file_type_id, :help, :indent_size, :memory_limit, :name, :network_enabled, :permitted_execution_time, :pool_size, :run_command, :test_command, :testing_framework).merge(user_id: current_user.id, user_type: current_user.class.name)
params[:execution_environment].permit(:docker_image, :exposed_ports, :editor_mode, :file_extension, :file_type_id, :help, :indent_size, :memory_limit, :name, :network_enabled, :permitted_execution_time, :pool_size, :run_command, :test_command, :testing_framework).merge(user_id: current_user.id, user_type: current_user.class.name) if params[:execution_environment].present?
end
private :execution_environment_params

View File

@ -51,7 +51,7 @@ class ExerciseCollectionsController < ApplicationController
end
def exercise_collection_params
sanitized_params = params[:exercise_collection].permit(:name, :use_anomaly_detection, :user_id, :user_type, :exercise_ids => []).merge(user_type: InternalUser.name)
sanitized_params = params[:exercise_collection].present? ? params[:exercise_collection].permit(:name, :use_anomaly_detection, :user_id, :user_type, :exercise_ids => []).merge(user_type: InternalUser.name) : {}
sanitized_params[:exercise_ids] = sanitized_params[:exercise_ids].reject {|v| v.nil? or v == ''}
sanitized_params.tap {|p| p[:exercise_collection_items] = p[:exercise_ids].map.with_index {|_id, index| ExerciseCollectionItem.find_or_create_by(exercise_id: _id, exercise_collection_id: @exercise_collection.id, position: index)}; p.delete(:exercise_ids)}
end

View File

@ -12,9 +12,9 @@ class ExercisesController < ApplicationController
before_action :set_file_types, only: [:create, :edit, :new, :update]
before_action :set_course_token, only: [:implement]
skip_before_filter :verify_authenticity_token, only: [:import_proforma_xml]
skip_before_action :verify_authenticity_token, only: [:import_proforma_xml]
skip_after_action :verify_authorized, only: [:import_proforma_xml]
skip_after_action :verify_policy_scoped, only: [:import_proforma_xml]
skip_after_action :verify_policy_scoped, only: [:import_proforma_xml], raise: false
def authorize!
authorize(@exercise || @exercises)
@ -77,7 +77,7 @@ class ExercisesController < ApplicationController
def create
@exercise = Exercise.new(exercise_params)
collect_set_and_unset_exercise_tags
myparam = exercise_params
myparam = exercise_params.present? ? exercise_params : { }
checked_exercise_tags = @exercise_tags.select { | et | myparam[:tag_ids].include? et.tag.id.to_s }
removed_exercise_tags = @exercise_tags.reject { | et | myparam[:tag_ids].include? et.tag.id.to_s }
@ -160,19 +160,21 @@ class ExercisesController < ApplicationController
private :user_by_code_harbor_token
def exercise_params
params[:exercise].permit(:description, :execution_environment_id, :file_id, :instructions, :public, :hide_file_tree, :allow_file_creation, :allow_auto_completion, :title, :expected_difficulty, files_attributes: file_attributes, :tag_ids => []).merge(user_id: current_user.id, user_type: current_user.class.name)
params[:exercise].permit(:description, :execution_environment_id, :file_id, :instructions, :public, :hide_file_tree, :allow_file_creation, :allow_auto_completion, :title, :expected_difficulty, files_attributes: file_attributes, :tag_ids => []).merge(user_id: current_user.id, user_type: current_user.class.name) if params[:exercise].present?
end
private :exercise_params
def handle_file_uploads
exercise_params[:files_attributes].try(:each) do |index, file_attributes|
if file_attributes[:content].respond_to?(:read)
file_params = params[:exercise][:files_attributes][index]
if FileType.find_by(id: file_attributes[:file_type_id]).try(:binary?)
file_params[:content] = nil
file_params[:native_file] = file_attributes[:content]
else
file_params[:content] = file_attributes[:content].read
if exercise_params
exercise_params[:files_attributes].try(:each) do |index, file_attributes|
if file_attributes[:content].respond_to?(:read)
file_params = params[:exercise][:files_attributes][index]
if FileType.find_by(id: file_attributes[:file_type_id]).try(:binary?)
file_params[:content] = nil
file_params[:native_file] = file_attributes[:content]
else
file_params[:content] = file_attributes[:content].read
end
end
end
end
@ -185,28 +187,8 @@ class ExercisesController < ApplicationController
count_interventions_today = UserExerciseIntervention.where(user: current_user).where("created_at >= ?", Time.zone.now.beginning_of_day).count
user_got_intervention_in_exercise = UserExerciseIntervention.where(user: current_user, exercise: @exercise).size >= max_intervention_count_per_exercise
user_got_enough_interventions = count_interventions_today >= max_intervention_count_per_day or user_got_intervention_in_exercise
@is_experimental_course = @course_token and experimental_course?(@course_token)
@experiment_group = UserGroupSeparator.getInterventionGroup(current_user)
showInterventions = (@is_experimental_course and not user_solved_exercise and not user_got_enough_interventions) ? "true" : "false"
case @experiment_group
when :rfc_intervention_stale_rfc
@show_rfc_interventions = showInterventions
when :break_intervention_stale_rfc
@show_break_interventions = showInterventions
when :no_intervention_stale_rfc
when :no_intervention_hide_rfc
@hide_rfc_button = "true"
when :break_intervention_show_rfc
@show_break_interventions = showInterventions
when :no_intervention_show_rfc
when :rfc_intervention_show_rfc
@show_rfc_interventions = showInterventions
end
@show_rfc_interventions = (not user_solved_exercise and not user_got_enough_interventions).to_s
@search = Search.new
@ -364,7 +346,7 @@ class ExercisesController < ApplicationController
query = "SELECT user_id, MAX(score) AS maximum_score, COUNT(id) AS runs
FROM submissions WHERE exercise_id = #{@exercise.id} GROUP BY
user_id;"
ActiveRecord::Base.connection.execute(query).each do |tuple|
ApplicationRecord.connection.execute(query).each do |tuple|
user_statistics[tuple["user_id"].to_i] = tuple
end
render locals: {
@ -428,11 +410,6 @@ class ExercisesController < ApplicationController
return
end
if @is_experimental_course and (@rfc_group == :hide_rfc)
redirect_to_lti_return_path
return
end
rfc = @submission.own_unsolved_rfc
if rfc
# set a message that informs the user that his own RFC should be closed.

View File

@ -57,7 +57,7 @@ class ExternalUsersController < ApplicationController
statistics = {}
ActiveRecord::Base.connection.execute(working_time_query(params[:tag])).each do |tuple|
ApplicationRecord.connection.execute(working_time_query(params[:tag])).each do |tuple|
statistics[tuple["exercise_id"].to_i] = tuple
end

View File

@ -89,6 +89,6 @@ class FileTemplatesController < ApplicationController
# Never trust parameters from the scary internet, only allow the white list through.
def file_template_params
params[:file_template].permit(:name, :file_type_id, :content)
params[:file_template].permit(:name, :file_type_id, :content) if params[:file_template].present?
end
end

View File

@ -23,7 +23,7 @@ class FileTypesController < ApplicationController
end
def file_type_params
params[:file_type].permit(:binary, :editor_mode, :executable, :file_extension, :name, :indent_size, :renderable).merge(user_id: current_user.id, user_type: current_user.class.name)
params[:file_type].permit(:binary, :editor_mode, :executable, :file_extension, :name, :indent_size, :renderable).merge(user_id: current_user.id, user_type: current_user.class.name) if params[:file_type].present?
end
private :file_type_params
@ -38,7 +38,7 @@ class FileTypesController < ApplicationController
end
def set_editor_modes
@editor_modes = Dir.glob('vendor/assets/javascripts/ace/mode-*.js').map do |filename|
@editor_modes = Dir.glob('vendor/assets/javascripts/ace/mode-*.js').sort.map do |filename|
name = filename.gsub(/\w+\/|mode-|.js$/, '')
[name, "ace/mode/#{name}"]
end

View File

@ -23,7 +23,7 @@ class HintsController < ApplicationController
end
def hint_params
params[:hint].permit(:locale, :message, :name, :regular_expression).merge(execution_environment_id: @execution_environment.id)
params[:hint].permit(:locale, :message, :name, :regular_expression).merge(execution_environment_id: @execution_environment.id) if params[:hint].present?
end
private :hint_params

View File

@ -21,7 +21,7 @@ class InternalUsersController < ApplicationController
if @user.update(params[:internal_user].permit(:password, :password_confirmation))
@user.change_password!(params[:internal_user][:password])
format.html { redirect_to(sign_in_path, notice: t('.success')) }
format.json { render(nothing: true, status: :ok) }
format.json { head :ok }
else
respond_with_invalid_object(format, object: @user, template: :reset_password)
end
@ -66,7 +66,7 @@ class InternalUsersController < ApplicationController
end
def internal_user_params
params[:internal_user].permit(:consumer_id, :email, :name, :role)
params[:internal_user].permit(:consumer_id, :email, :name, :role) if params[:internal_user].present?
end
private :internal_user_params
@ -105,7 +105,7 @@ class InternalUsersController < ApplicationController
if @user.update(params[:internal_user].permit(:password, :password_confirmation))
@user.activate!
format.html { redirect_to(sign_in_path, notice: t('.success')) }
format.json { render(nothing: true, status: :ok) }
format.json { head :ok }
else
respond_with_invalid_object(format, object: @user, template: :activate)
end

View File

@ -22,7 +22,7 @@ class InterventionsController < ApplicationController
end
def intervention_params
params[:intervention].permit(:name)
params[:intervention].permit(:name) if params[:intervention].present?
end
private :intervention_params

View File

@ -39,7 +39,7 @@ class ProxyExercisesController < ApplicationController
end
def proxy_exercise_params
params[:proxy_exercise].permit(:description, :title, :exercise_ids => [])
params[:proxy_exercise].permit(:description, :title, :exercise_ids => []) if params[:proxy_exercise].present?
end
private :proxy_exercise_params

View File

@ -15,14 +15,12 @@ class RemoteEvaluationController < ApplicationController
# todo extra: validiere, ob files wirklich zur Übung gehören (wenn allowNewFiles-flag nicht gesetzt ist)
if (remote_evaluation_mapping = RemoteEvaluationMapping.find_by(:validation_token => validation_token))
puts remote_evaluation_mapping.exercise_id
puts remote_evaluation_mapping.user_id
_params = remote_evaluation_params.except(:validation_token)
_params[:exercise_id] = remote_evaluation_mapping.exercise_id
_params[:user_id] = remote_evaluation_mapping.user_id
_params[:cause] = "remoteAssess"
_params[:user_type] = "ExternalUser"
_params[:user_type] = remote_evaluation_mapping.user_type
@submission = Submission.create(_params)
render json: score_submission(@submission)

View File

@ -115,7 +115,7 @@ class SubmissionsController < ApplicationController
if @file.native_file?
send_file(@file.native_file.path, disposition: 'inline')
else
render(text: @file.content)
render(plain: @file.content)
end
end
@ -140,7 +140,7 @@ class SubmissionsController < ApplicationController
# probably add:
# ensure
# #guarantee that the thread is releasing the DB connection after it is done
# ActiveRecord::Base.connectionpool.releaseconnection
# ApplicationRecord.connectionpool.releaseconnection
# end
Thread.new { EventMachine.run } unless EventMachine.reactor_running? && EventMachine.reactor_thread.alive?
@ -329,7 +329,7 @@ class SubmissionsController < ApplicationController
def set_file
@file = @files.detect { |file| file.name_with_extension == params[:filename] }
render(nothing: true, status: 404) unless @file
head :not_found unless @file
end
private :set_file
@ -362,11 +362,11 @@ class SubmissionsController < ApplicationController
DockerClient.destroy_container(container)
rescue Docker::Error::NotFoundError
ensure
render(nothing: true)
head :ok
end
def store_error(stderr)
::Error.create(submission_id: @submission.id, execution_environment_id: @submission.execution_environment.id, message: stderr)
CodeOcean::Error.create(submission_id: @submission.id, execution_environment_id: @submission.execution_environment.id, message: stderr)
end
private :store_error
@ -398,13 +398,13 @@ class SubmissionsController < ApplicationController
private :with_server_sent_events
def create_remote_evaluation_mapping
user_id = @submission.user_id
user = @submission.user
exercise_id = @submission.exercise_id
remote_evaluation_mapping = RemoteEvaluationMapping.create(:user_id => user_id, :exercise_id => exercise_id)
remote_evaluation_mapping = RemoteEvaluationMapping.create(user: user, exercise_id: exercise_id)
# create .co file
path = "tmp/" + user_id.to_s + ".co"
path = "tmp/" + user.id.to_s + ".co"
# parse validation token
content = "#{remote_evaluation_mapping.validation_token}\n"
# parse remote request url

View File

@ -56,7 +56,7 @@ class SubscriptionsController < ApplicationController
def subscription_params
current_user_id = current_user.try(:id)
current_user_class_name = current_user.try(:class).try(:name)
params[:subscription].permit(:request_for_comment_id, :subscription_type).merge(user_id: current_user_id, user_type: current_user_class_name, deleted: false)
params[:subscription].permit(:request_for_comment_id, :subscription_type).merge(user_id: current_user_id, user_type: current_user_class_name, deleted: false) if params[:subscription].present?
end
private :subscription_params
end

View File

@ -22,7 +22,7 @@ class TagsController < ApplicationController
end
def tag_params
params[:tag].permit(:name)
params[:tag].permit(:name) if params[:tag].present?
end
private :tag_params

View File

@ -1,8 +1,7 @@
class UserExerciseFeedbacksController < ApplicationController
include CommonBehavior
before_action :set_user_exercise_feedback, only: [:edit, :update]
before_action :set_user_exercise_feedback_by_id, only: [:show, :destroy]
before_action :set_user_exercise_feedback, only: [:edit, :update, :show, :destroy]
def comment_presets
[[0,t('user_exercise_feedback.difficulty_easy')],
@ -103,16 +102,12 @@ class UserExerciseFeedbacksController < ApplicationController
end
def set_user_exercise_feedback
@exercise = Exercise.find(params[:user_exercise_feedback][:exercise_id])
@uef = UserExerciseFeedback.find_by(exercise_id: params[:user_exercise_feedback][:exercise_id], user: current_user)
end
def set_user_exercise_feedback_by_id
@uef = UserExerciseFeedback.find(params[:id])
@exercise = @uef.exercise
end
def uef_params
params[:user_exercise_feedback].permit(:feedback_text, :difficulty, :exercise_id, :user_estimated_worktime).merge(user_id: current_user.id, user_type: current_user.class.name)
params[:user_exercise_feedback].permit(:feedback_text, :difficulty, :exercise_id, :user_estimated_worktime).merge(user_id: current_user.id, user_type: current_user.class.name) if params[:user_exercise_feedback].present?
end
def validate_inputs(uef_params)