Add privilegedExecution flag to database and Poseidon Strategy
This commit is contained in:

committed by
Sebastian Serth

parent
dffeca27de
commit
eb188dcd71
@ -113,9 +113,10 @@ class ExecutionEnvironmentsController < ApplicationController
|
||||
[]
|
||||
end
|
||||
|
||||
params[:execution_environment].permit(:docker_image, :editor_mode, :file_extension, :file_type_id, :help, :indent_size, :memory_limit, :cpu_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, exposed_ports: exposed_ports
|
||||
)
|
||||
params[:execution_environment]
|
||||
.permit(:docker_image, :editor_mode, :file_extension, :file_type_id, :help, :indent_size, :memory_limit, :cpu_limit, :name,
|
||||
:network_enabled, :privileged_execution, :permitted_execution_time, :pool_size, :run_command, :test_command, :testing_framework)
|
||||
.merge(user_id: current_user.id, user_type: current_user.class.name, exposed_ports: exposed_ports)
|
||||
end
|
||||
end
|
||||
private :execution_environment_params
|
||||
|
@ -27,6 +27,7 @@ class ExecutionEnvironment < ApplicationRecord
|
||||
validates :memory_limit,
|
||||
numericality: {greater_than_or_equal_to: MINIMUM_MEMORY_LIMIT, only_integer: true}, presence: true
|
||||
validates :network_enabled, boolean_presence: true
|
||||
validates :privileged_execution, boolean_presence: true
|
||||
validates :name, presence: true
|
||||
validates :permitted_execution_time, numericality: {only_integer: true}, presence: true
|
||||
validates :pool_size, numericality: {only_integer: true}, presence: true
|
||||
|
@ -28,6 +28,10 @@
|
||||
label.form-check-label
|
||||
= f.check_box(:network_enabled, class: 'form-check-input')
|
||||
= t('activerecord.attributes.execution_environment.network_enabled')
|
||||
.form-check.mb-3
|
||||
label.form-check-label
|
||||
= f.check_box(:privileged_execution, class: 'form-check-input')
|
||||
= t('activerecord.attributes.execution_environment.privileged_execution')
|
||||
.mb-3
|
||||
= f.label(:permitted_execution_time, class: 'form-label')
|
||||
= f.number_field(:permitted_execution_time, class: 'form-control', min: 1)
|
||||
|
@ -15,6 +15,7 @@ h1.d-inline-block = ExecutionEnvironment.model_name.human(count: 2)
|
||||
th = t('activerecord.attributes.execution_environment.memory_limit')
|
||||
th = t('activerecord.attributes.execution_environment.cpu_limit')
|
||||
th = t('activerecord.attributes.execution_environment.network_enabled')
|
||||
th = t('activerecord.attributes.execution_environment.privileged_execution')
|
||||
th = t('activerecord.attributes.execution_environment.permitted_execution_time')
|
||||
th colspan=5 = t('shared.actions')
|
||||
tbody
|
||||
@ -26,6 +27,7 @@ h1.d-inline-block = ExecutionEnvironment.model_name.human(count: 2)
|
||||
td = execution_environment.memory_limit
|
||||
td = execution_environment.cpu_limit
|
||||
td = symbol_for(execution_environment.network_enabled)
|
||||
td = symbol_for(execution_environment.privileged_execution)
|
||||
td = execution_environment.permitted_execution_time
|
||||
td = link_to(t('shared.show'), execution_environment) if policy(execution_environment).show?
|
||||
td = link_to(t('shared.edit'), edit_execution_environment_path(execution_environment)) if policy(execution_environment).edit?
|
||||
|
@ -11,7 +11,7 @@ h1.d-inline-block = @execution_environment
|
||||
= row(label: 'execution_environment.name', value: @execution_environment.name)
|
||||
= row(label: 'execution_environment.user', value: link_to_if(policy(@execution_environment.author).show?, @execution_environment.author, @execution_environment.author))
|
||||
= row(label: 'execution_environment.file_type', value: @execution_environment.file_type.present? ? link_to(@execution_environment.file_type, @execution_environment.file_type) : nil)
|
||||
- [:docker_image, :exposed_ports_list, :memory_limit, :cpu_limit, :network_enabled, :permitted_execution_time, :pool_size].each do |attribute|
|
||||
- [:docker_image, :exposed_ports_list, :memory_limit, :cpu_limit, :network_enabled, :privileged_execution, :permitted_execution_time, :pool_size].each do |attribute|
|
||||
= row(label: "execution_environment.#{attribute}", value: @execution_environment.send(attribute))
|
||||
- [:run_command, :test_command].each do |attribute|
|
||||
= row(label: "execution_environment.#{attribute}") do
|
||||
|
@ -24,6 +24,7 @@ de:
|
||||
test_command: Testbefehl
|
||||
testing_framework: Testing-Framework
|
||||
user: Autor
|
||||
privileged_execution: Priviligierte Ausführung als "root"
|
||||
exercise:
|
||||
average_score_percentage: "Durchschnittliche Bewertung in Prozent"
|
||||
description: Beschreibung
|
||||
|
@ -24,6 +24,7 @@ en:
|
||||
test_command: Test Command
|
||||
testing_framework: Testing Framework
|
||||
user: Author
|
||||
privileged_execution: Privileged Execution as "root"
|
||||
exercise:
|
||||
average_score_percentage: "Average Score Percentage"
|
||||
description: Description
|
||||
|
@ -0,0 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class AddPrivilegedExecutionToExecutionEnvironment < ActiveRecord::Migration[6.1]
|
||||
def change
|
||||
add_column :execution_environments, :privileged_execution, :boolean, default: false, null: false
|
||||
end
|
||||
end
|
@ -10,7 +10,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 2022_09_06_142603) do
|
||||
ActiveRecord::Schema.define(version: 2022_09_23_214003) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "pg_trgm"
|
||||
@ -163,6 +163,7 @@ ActiveRecord::Schema.define(version: 2022_09_06_142603) do
|
||||
t.boolean "network_enabled"
|
||||
t.integer "cpu_limit", default: 20, null: false
|
||||
t.integer "exposed_ports", default: [], array: true
|
||||
t.boolean "privileged_execution", default: false, null: false
|
||||
end
|
||||
|
||||
create_table "exercise_collection_items", id: :serial, force: :cascade do |t|
|
||||
@ -240,7 +241,7 @@ ActiveRecord::Schema.define(version: 2022_09_06_142603) do
|
||||
t.string "name"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.boolean "platform_admin", default: false, null: false
|
||||
t.boolean "platform_admin", default: false
|
||||
end
|
||||
|
||||
create_table "file_templates", id: :serial, force: :cascade do |t|
|
||||
@ -305,7 +306,7 @@ ActiveRecord::Schema.define(version: 2022_09_06_142603) do
|
||||
t.string "activation_state"
|
||||
t.string "activation_token"
|
||||
t.datetime "activation_token_expires_at"
|
||||
t.boolean "platform_admin", default: false, null: false
|
||||
t.boolean "platform_admin", default: false
|
||||
t.index ["activation_token"], name: "index_internal_users_on_activation_token"
|
||||
t.index ["email"], name: "index_internal_users_on_email", unique: true
|
||||
t.index ["remember_me_token"], name: "index_internal_users_on_remember_me_token"
|
||||
|
@ -245,7 +245,11 @@ class Runner::Strategy::Poseidon < Runner::Strategy
|
||||
|
||||
def execute_command(command)
|
||||
url = "#{runner_url}/execute"
|
||||
body = {command: command, timeLimit: @execution_environment.permitted_execution_time}
|
||||
body = {
|
||||
command: command,
|
||||
timeLimit: @execution_environment.permitted_execution_time,
|
||||
privilegedExecution: @execution_environment.privileged_execution,
|
||||
}
|
||||
Rails.logger.debug { "#{Time.zone.now.getutc.inspect}: Preparing command execution at #{url}: #{command}" }
|
||||
response = self.class.http_connection.post url, body.to_json
|
||||
|
||||
|
@ -10,6 +10,7 @@ FactoryBot.define do
|
||||
help
|
||||
name { 'CoffeeScript' }
|
||||
network_enabled { false }
|
||||
privileged_execution { false }
|
||||
permitted_execution_time { 10.seconds }
|
||||
pool_size { 0 }
|
||||
run_command { 'coffee' }
|
||||
@ -25,6 +26,7 @@ FactoryBot.define do
|
||||
help
|
||||
name { 'HTML5' }
|
||||
network_enabled { false }
|
||||
privileged_execution { false }
|
||||
permitted_execution_time { 10.seconds }
|
||||
pool_size { 0 }
|
||||
run_command { 'touch' }
|
||||
@ -42,6 +44,7 @@ FactoryBot.define do
|
||||
help
|
||||
name { 'Java 8' }
|
||||
network_enabled { false }
|
||||
privileged_execution { false }
|
||||
permitted_execution_time { 10.seconds }
|
||||
pool_size { 0 }
|
||||
run_command { 'make run' }
|
||||
@ -59,6 +62,7 @@ FactoryBot.define do
|
||||
help
|
||||
name { 'JRuby 1.7' }
|
||||
network_enabled { false }
|
||||
privileged_execution { false }
|
||||
permitted_execution_time { 10.seconds }
|
||||
pool_size { 0 }
|
||||
run_command { 'jruby %{filename}' }
|
||||
@ -76,6 +80,7 @@ FactoryBot.define do
|
||||
help
|
||||
name { 'Node.js' }
|
||||
network_enabled { false }
|
||||
privileged_execution { false }
|
||||
permitted_execution_time { 10.seconds }
|
||||
pool_size { 0 }
|
||||
run_command { 'node %{filename}' }
|
||||
@ -91,6 +96,7 @@ FactoryBot.define do
|
||||
help
|
||||
name { 'Python 3.4' }
|
||||
network_enabled { false }
|
||||
privileged_execution { false }
|
||||
permitted_execution_time { 10.seconds }
|
||||
pool_size { 0 }
|
||||
run_command { 'python3 %{filename}' }
|
||||
@ -108,6 +114,7 @@ FactoryBot.define do
|
||||
help
|
||||
name { 'Ruby 2.2' }
|
||||
network_enabled { false }
|
||||
privileged_execution { false }
|
||||
permitted_execution_time { 10.seconds }
|
||||
pool_size { 0 }
|
||||
run_command { 'ruby %{filename}' }
|
||||
@ -126,6 +133,7 @@ FactoryBot.define do
|
||||
help
|
||||
name { 'Sinatra' }
|
||||
network_enabled { true }
|
||||
privileged_execution { false }
|
||||
permitted_execution_time { 15.minutes }
|
||||
pool_size { 0 }
|
||||
run_command { 'ruby %{filename}' }
|
||||
@ -143,6 +151,7 @@ FactoryBot.define do
|
||||
help
|
||||
name { 'SQLite' }
|
||||
network_enabled { false }
|
||||
privileged_execution { false }
|
||||
permitted_execution_time { 1.minute }
|
||||
pool_size { 0 }
|
||||
run_command { 'sqlite3 /database.db -init %{filename} -html' }
|
||||
|
@ -247,7 +247,11 @@ describe Runner::Strategy::Poseidon do
|
||||
WebMock
|
||||
.stub_request(:post, "#{described_class.config[:url]}/runners/#{runner_id}/execute")
|
||||
.with(
|
||||
body: {command: command, timeLimit: execution_environment.permitted_execution_time},
|
||||
body: {
|
||||
command: command,
|
||||
timeLimit: execution_environment.permitted_execution_time,
|
||||
privilegedExecution: execution_environment.privileged_execution,
|
||||
},
|
||||
headers: {'Content-Type' => 'application/json'}
|
||||
)
|
||||
.to_return(body: response_body, status: response_status)
|
||||
|
@ -3,7 +3,7 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe ExecutionEnvironment do
|
||||
let(:execution_environment) { described_class.create.tap {|execution_environment| execution_environment.update(network_enabled: nil) } }
|
||||
let(:execution_environment) { described_class.create.tap {|execution_environment| execution_environment.update(network_enabled: nil, privileged_execution: nil) } }
|
||||
|
||||
it 'validates that the Docker image works' do
|
||||
allow(execution_environment).to receive(:validate_docker_image?).and_return(true)
|
||||
@ -56,6 +56,12 @@ describe ExecutionEnvironment do
|
||||
expect(execution_environment.errors[:network_enabled]).to be_blank
|
||||
end
|
||||
|
||||
it 'validates the presence of the privileged_execution enabled flag' do
|
||||
expect(execution_environment.errors[:privileged_execution]).to be_present
|
||||
execution_environment.update(privileged_execution: false)
|
||||
expect(execution_environment.errors[:privileged_execution]).to be_blank
|
||||
end
|
||||
|
||||
it 'validates the numericality of the permitted run time' do
|
||||
execution_environment.update(permitted_execution_time: Math::PI)
|
||||
expect(execution_environment.errors[:permitted_execution_time]).to be_present
|
||||
|
Reference in New Issue
Block a user