Commit 67680b11 authored by Dominic Althaus's avatar Dominic Althaus

inital commit

parents
.bundle/
log/*.log
pkg/
test/dummy/db/*.sqlite3
test/dummy/db/*.sqlite3-journal
test/dummy/log/*.log
test/dummy/tmp/
.idea
source 'https://rubygems.org'
# Declare your gem's dependencies in java_submission_tester.gemspec.
# Bundler will treat runtime dependencies like base dependencies, and
# development dependencies will be added by default to the :development group.
gemspec
# Declare any dependencies that are still in development here instead of in
# your gemspec. These might include edge Rails or gems from your path or
# Git. Remember to move these dependencies to your gemspec before releasing
# your gem to rubygems.org.
# To use a debugger
# gem 'byebug', group: [:development, :test]
PATH
remote: .
specs:
java_submission_tester (0.1.0)
rails (>= 5.0.0.rc1, < 5.1)
rubyzip
GEM
remote: https://rubygems.org/
specs:
actioncable (5.0.0.rc1)
actionpack (= 5.0.0.rc1)
nio4r (~> 1.2)
websocket-driver (~> 0.6.1)
actionmailer (5.0.0.rc1)
actionpack (= 5.0.0.rc1)
actionview (= 5.0.0.rc1)
activejob (= 5.0.0.rc1)
mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 1.0, >= 1.0.5)
actionpack (5.0.0.rc1)
actionview (= 5.0.0.rc1)
activesupport (= 5.0.0.rc1)
rack (~> 2.x)
rack-test (~> 0.6.3)
rails-dom-testing (~> 1.0, >= 1.0.5)
rails-html-sanitizer (~> 1.0, >= 1.0.2)
actionview (5.0.0.rc1)
activesupport (= 5.0.0.rc1)
builder (~> 3.1)
erubis (~> 2.7.0)
rails-dom-testing (~> 1.0, >= 1.0.5)
rails-html-sanitizer (~> 1.0, >= 1.0.2)
activejob (5.0.0.rc1)
activesupport (= 5.0.0.rc1)
globalid (>= 0.3.6)
activemodel (5.0.0.rc1)
activesupport (= 5.0.0.rc1)
activerecord (5.0.0.rc1)
activemodel (= 5.0.0.rc1)
activesupport (= 5.0.0.rc1)
arel (~> 7.0)
activesupport (5.0.0.rc1)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (~> 0.7)
minitest (~> 5.1)
tzinfo (~> 1.1)
arel (7.0.0)
builder (3.2.2)
concurrent-ruby (1.0.2)
erubis (2.7.0)
globalid (0.3.6)
activesupport (>= 4.1.0)
i18n (0.7.0)
json (1.8.3)
loofah (2.0.3)
nokogiri (>= 1.5.9)
mail (2.6.4)
mime-types (>= 1.16, < 4)
method_source (0.8.2)
mime-types (3.1)
mime-types-data (~> 3.2015)
mime-types-data (3.2016.0521)
mini_portile2 (2.0.0)
minitest (5.9.0)
nio4r (1.2.1)
nokogiri (1.6.7.2)
mini_portile2 (~> 2.0.0.rc2)
rack (2.0.0.rc1)
json
rack-test (0.6.3)
rack (>= 1.0)
rails (5.0.0.rc1)
actioncable (= 5.0.0.rc1)
actionmailer (= 5.0.0.rc1)
actionpack (= 5.0.0.rc1)
actionview (= 5.0.0.rc1)
activejob (= 5.0.0.rc1)
activemodel (= 5.0.0.rc1)
activerecord (= 5.0.0.rc1)
activesupport (= 5.0.0.rc1)
bundler (>= 1.3.0, < 2.0)
railties (= 5.0.0.rc1)
sprockets-rails (>= 2.0.0)
rails-deprecated_sanitizer (1.0.3)
activesupport (>= 4.2.0.alpha)
rails-dom-testing (1.0.7)
activesupport (>= 4.2.0.beta, < 5.0)
nokogiri (~> 1.6.0)
rails-deprecated_sanitizer (>= 1.0.1)
rails-html-sanitizer (1.0.3)
loofah (~> 2.0)
railties (5.0.0.rc1)
actionpack (= 5.0.0.rc1)
activesupport (= 5.0.0.rc1)
method_source
rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0)
rake (11.1.2)
rubyzip (1.2.0)
sprockets (3.6.0)
concurrent-ruby (~> 1.0)
rack (> 1, < 3)
sprockets-rails (3.0.4)
actionpack (>= 4.0)
activesupport (>= 4.0)
sprockets (>= 3.0.0)
sqlite3 (1.3.11)
thor (0.19.1)
thread_safe (0.3.5)
tzinfo (1.2.2)
thread_safe (~> 0.1)
websocket-driver (0.6.4)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.2)
PLATFORMS
ruby
DEPENDENCIES
java_submission_tester!
sqlite3
BUNDLED WITH
1.11.2
Copyright 2016 Dominic Althaus
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# JavaSubmissionTester
Short description and motivation.
## Usage
How to use my plugin.
## Installation
Add this line to your application's Gemfile:
```ruby
gem 'java_submission_tester'
```
And then execute:
```bash
$ bundle
```
Or install it yourself as:
```bash
$ gem install java_submission_tester
```
## Contributing
Contribution directions go here.
## License
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
begin
require 'bundler/setup'
rescue LoadError
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
end
require 'rdoc/task'
RDoc::Task.new(:rdoc) do |rdoc|
rdoc.rdoc_dir = 'rdoc'
rdoc.title = 'JavaSubmissionTester'
rdoc.options << '--line-numbers'
rdoc.rdoc_files.include('README.md')
rdoc.rdoc_files.include('lib/**/*.rb')
end
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
load 'rails/tasks/engine.rake'
load 'rails/tasks/statistics.rake'
require 'bundler/gem_tasks'
require 'rake/testtask'
Rake::TestTask.new(:test) do |t|
t.libs << 'lib'
t.libs << 'test'
t.pattern = 'test/**/*_test.rb'
t.verbose = false
end
task default: :test
//= link_directory ../javascripts/java_submission_tester .js
//= link_directory ../stylesheets/java_submission_tester .css
// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file. JavaScript code in this file should be added after the last require_* statement.
//
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require_tree .
/*
* This is a manifest file that'll be compiled into application.css, which will include all the files
* listed below.
*
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
*
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
* files in this directory. Styles in this file should be added after the last require_* statement.
* It is generally better to create a new file per style scope.
*
*= require_tree .
*= require_self
*/
module JavaSubmissionTester
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
end
end
module JavaSubmissionTester
module ApplicationHelper
end
end
module JavaSubmissionTester
class ApplicationJob < ActiveJob::Base
end
end
module JavaSubmissionTester
class ApplicationMailer < ActionMailer::Base
default from: 'from@example.com'
layout 'mailer'
end
end
module JavaSubmissionTester
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
end
end
require 'zip'
class JavaSubmissionTestRunner
LANGUAGE_NAME = 'Java'
JUNIT_CODEBASE_PATH = '/usr/share/java/*'
JUNIT_CLASSPATH = '/usr/share/java/junit.jar:/usr/share/java/hamcrest/core.jar'
JUNIT_REPORT_PATH = Pathname.new(File.dirname(__FILE__)).join('JunitReport.jar').to_s
SUBMISSION_SHELL_SAFE_DEFAULT_NAME = 'submission.jar'
TEST_TIMEOUT_DURATION = '2m'
attr_reader :test_suits
def prepare_test(submission_test)
@dir = Dir.mktmpdir
@path = Pathname.new @dir
unzip submission_test.submission.current_path, @path
@submissions = find_submissions @path
@test_suits = find_test_suits submission_test.test.current_path
@policy_file = Tempfile.new 'deny_all.policy', @dir
@submission_shell_safe_path = @path.join(SUBMISSION_SHELL_SAFE_DEFAULT_NAME).to_s
write_policy @policy_file, @submission_shell_safe_path, submission_test.test.current_path
@policy_file.close
end
def clean_after_test(submission_test)
@policy_file.unlink
FileUtils.remove_entry_secure @dir
end
def test_cases(submission_test, test_suit)
run_test '', submission_test.test.current_path, test_suit, @policy_file.path
cmd = "java -cp \"#{JUNIT_REPORT_PATH}:#{JUNIT_CLASSPATH}:#{submission_test.test.current_path}\" de.thm.mni.JunitJSONTestList \"#{test_suit}\""
JSON.parse `#{cmd}`
end
def test(submission_test, submission, test_suit)
# the Name of the jar could be valid shell commands, so we rename it to prevent "Shell injection attacks"
File.rename @path.join(submission).to_s, @submission_shell_safe_path
run_test @submission_shell_safe_path, submission_test.test.current_path, test_suit, @policy_file.path
end
def submissions
@submissions.map { |e| File.basename e }
end
private
def run_test(submission_path, test_path, test_suit, policy_file)
output_file = Tempfile.new
output_file.close
cmd = "timeout #{TEST_TIMEOUT_DURATION}" +
" java -Djava.security.manager -Djava.security.policy=#{policy_file} -cp" +
" \"#{JUNIT_REPORT_PATH}:" +
"#{JUNIT_CLASSPATH}:" +
"#{test_path}:" + #test_path need to be before submission_path or the submission could override the test_suit
"#{submission_path}\"" +
" de.thm.mni.JunitJSONReportRunner #{output_file.path} #{test_suit}"
`#{cmd}` # => outputs to outputfile
output_file.open
result = JSON.load output_file
output_file.close! #close and Delete tempfile
return result
end
def write_policy(file, submission_codebase_path, test_path)
#TODO I may need to change JUNIT_REPORT_PATH to a path that uses / instead of \ on windows
policy_file_content = "grant codeBase \"file:#{JUNIT_CODEBASE_PATH}\" {permission java.security.AllPermission \"\", \"\";};" +
"grant codeBase \"file:#{JUNIT_REPORT_PATH}\" {permission java.security.AllPermission \"\", \"\";};" +
"grant codeBase \"file:#{test_path}\" {permission java.security.AllPermission \"\", \"\";};" +
"grant codeBase \"file:#{submission_codebase_path}\" {};"
file.write policy_file_content
end
def unzip(file, dest_dir)
Zip::File.open(file) do |zip_file|
zip_file.each do |entry|
output_path = dest_dir.join entry.name
FileUtils.mkdir_p output_path.dirname
zip_file.extract entry, output_path unless File.exist? output_path
end
end
end
def find_test_suits(file)
Zip::File.open(file) do |zip_file|
test_suit_entries = zip_file.entries.find_all { |entry|
basename = File.basename(entry.name)
entry.ftype != :directory and (basename.start_with? 'Test' or basename.end_with? 'Test.class')
}
test_suit_entries.map {|entry|
basename = Pathname.new(entry.name).sub_ext ''
basename.to_s.gsub(File::SEPARATOR, '.')
}
end
end
def find_submissions(path)
Dir[path.join('*.jar').to_s]
end
end
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<title>Java submission tester</title>
<%= stylesheet_link_tag "java_submission_tester/application", media: "all" %>
<%= javascript_include_tag "java_submission_tester/application" %>
<%= csrf_meta_tags %>
</head>
<body>
<%= yield %>
</body>
</html>
#!/usr/bin/env ruby
# This command will automatically be run when you run "rails" with Rails gems
# installed from the root of your application.
ENGINE_ROOT = File.expand_path('../..', __FILE__)
ENGINE_PATH = File.expand_path('../../lib/java_submission_tester/engine', __FILE__)
# Set up gems listed in the Gemfile.
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
require 'rails/all'
require 'rails/engine/commands'
JavaSubmissionTester::Engine.routes.draw do
end
$:.push File.expand_path("../lib", __FILE__)
# Maintain your gem's version:
require "java_submission_tester/version"
# Describe your gem and declare its dependencies:
Gem::Specification.new do |s|
s.name = "java_submission_tester"
s.version = JavaSubmissionTester::VERSION
s.authors = ["Dominic Althaus"]
s.email = ["althaus.dominic@gmail.com"]
s.homepage = "https://git.thm.de/dalt40/java-submission-tester"
s.summary = "allows testing of java applications"
s.description = "allows testing of java applications"
s.license = "MIT"
s.files = Dir["{app,config,db,lib}/**/*", "MIT-LICENSE", "Rakefile", "README.md"]
s.add_dependency "rails", ">= 5.0.0.rc1", "< 5.1"
s.add_dependency "rubyzip"
s.add_development_dependency "sqlite3"
end
require 'java_submission_tester/engine'
module JavaSubmissionTester
# Your code goes here...
end
module JavaSubmissionTester
class Engine < ::Rails::Engine
isolate_namespace JavaSubmissionTester
end
end
module JavaSubmissionTester
VERSION = '0.1.0'
end
# desc "Explaining what the task does"
# task :java_submission_tester do
# # Task goes here
# end
# Add your own tasks in files placed in lib/tasks ending in .rake,
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
require_relative 'config/application'
Rails.application.load_tasks
//= link_tree ../images
//= link_directory ../javascripts .js
//= link_directory ../stylesheets .css
//= link java_submission_tester_manifest.js
// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file. JavaScript code in this file should be added after the last require_* statement.
//
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require_tree .
// Action Cable provides the framework to deal with WebSockets in Rails.
// You can generate new channels where WebSocket features live using the rails generate channel command.
//
//= require action_cable
//= require_self
//= require_tree ./channels
(function() {
this.App || (this.App = {});
App.cable = ActionCable.createConsumer();
}).call(this);
/*
* This is a manifest file that'll be compiled into application.css, which will include all the files
* listed below.
*
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
*
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
* files in this directory. Styles in this file should be added after the last require_* statement.
* It is generally better to create a new file per style scope.
*
*= require_tree .
*= require_self
*/
# Be sure to restart your server when you modify this file. Action Cable runs in a loop that does not support auto reloading.
module ApplicationCable
class Channel < ActionCable::Channel::Base
end
end
# Be sure to restart your server when you modify this file. Action Cable runs in a loop that does not support auto reloading.
module ApplicationCable
class Connection < ActionCable::Connection::Base
end
end
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
end
class ApplicationJob < ActiveJob::Base
end
class ApplicationMailer < ActionMailer::Base
default from: 'from@example.com'
layout 'mailer'
end
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
end
<!DOCTYPE html>
<html>
<head>
<title>Dummy</title>
<%= csrf_meta_tags %>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
</head>
<body>
<%= yield %>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style>
/* Email styles need to be inline */
</style>
</head>
<body>
<%= yield %>
</body>
</html>
#!/usr/bin/env ruby
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
load Gem.bin_path('bundler', 'bundle')
#!/usr/bin/env ruby
APP_PATH = File.expand_path('../config/application', __dir__)
require_relative '../config/boot'
require 'rails/commands'
#!/usr/bin/env ruby
require_relative '../config/boot'
require 'rake'
Rake.application.run
#!/usr/bin/env ruby
require 'pathname'
require 'fileutils'
include FileUtils
# path to your application root.
APP_ROOT = Pathname.new File.expand_path('../../', __FILE__)
def system!(*args)
system(*args) || abort("\n== Command #{args} failed ==")
end
chdir APP_ROOT do
# This script is a starting point to setup your application.
# Add necessary setup steps to this file.
puts '== Installing dependencies =='
system! 'gem install bundler --conservative'
system('bundle check') || system!('bundle install')
# puts "\n== Copying sample files =="
# unless File.exist?('config/database.yml')
# cp 'config/database.yml.sample', 'config/database.yml'
# end
puts "\n== Preparing database =="
system! 'bin/rails db:setup'
puts "\n== Removing old logs and tempfiles =="
system! 'bin/rails log:clear tmp:clear'
puts "\n== Restarting application server =="
system! 'bin/rails restart'
end
#!/usr/bin/env ruby
require 'pathname'
require 'fileutils'
include FileUtils
# path to your application root.
APP_ROOT = Pathname.new File.expand_path('../../', __FILE__)
def system!(*args)
system(*args) || abort("\n== Command #{args} failed ==")
end
chdir APP_ROOT do
# This script is a way to update your development environment automatically.
# Add necessary update steps to this file.
puts '== Installing dependencies =='
system! 'gem install bundler --conservative'
system('bundle check') || system!('bundle install')
puts "\n== Updating database =="
system! 'bin/rails db:migrate'
puts "\n== Removing old logs and tempfiles =="
system! 'bin/rails log:clear tmp:clear'
puts "\n== Restarting application server =="
system! 'bin/rails restart'
end