Skip to content

Commit

Permalink
Merge pull request #686 from hoboman313/547
Browse files Browse the repository at this point in the history
MarkUs API should support multiple formats
  • Loading branch information
benjaminvialle committed Feb 27, 2012
2 parents 97b0650 + 338284d commit 7348abf
Show file tree
Hide file tree
Showing 27 changed files with 338 additions and 272 deletions.
33 changes: 21 additions & 12 deletions app/controllers/api/main_api_controller.rb
Expand Up @@ -10,13 +10,14 @@ module Api
# should go here.
class MainApiController < ActionController::Base

before_filter :check_format
before_filter :authenticate

#=== Description
# Dummy action (for authentication testing)
# No public route matches this action.
def index
render :file => "#{::Rails.root.to_s}/public/200.xml", :status => 200
render 'shared/http_status', :locals => { :code => "200", :message => HttpStatusHelper::ERROR_CODE["message"]["200"] }, :status => 200
end

private
Expand All @@ -28,23 +29,23 @@ def index
# user's private key.
def authenticate
if MarkusConfigurator.markus_config_remote_user_auth
#Check if authentication was already done and REMOTE_USER was set
# Check if authentication was already done and REMOTE_USER was set
markus_auth_remote_user = request.env["HTTP_X_FORWARDED_USER"]
if !markus_auth_remote_user.blank?
#REMOTE_USER authentication used, find the user and bypass regular auth
# REMOTE_USER authentication used, find the user and bypass regular auth
@current_user = User.find_by_user_name(markus_auth_remote_user)
else
#REMOTE_USER_AUTH is true, but REMOTE_USER wasn't set, bail out
render :file => "#{::Rails.root.to_s}/public/403.xml", :status => 403
# REMOTE_USER_AUTH is true, but REMOTE_USER wasn't set, bail out
render 'shared/http_status', :locals => { :code => "403", :message => HttpStatusHelper::ERROR_CODE["message"]["403"] }, :status => 403
return
end
else
#REMOTE_USER authentication not used, proceed with regular auth
# REMOTE_USER authentication not used, proceed with regular auth
auth_token = parse_auth_token(request.headers["HTTP_AUTHORIZATION"])
# pretend resource not found if missing or wrong authentication
# is provided
if auth_token.nil?
render :file => "#{::Rails.root.to_s}/public/403.xml", :status => 403
render 'shared/http_status', :locals => { :code => "403", :message => HttpStatusHelper::ERROR_CODE["message"]["403"] }, :status => 403
return
end
# Find user by api_key_md5
Expand All @@ -53,25 +54,34 @@ def authenticate

if @current_user.nil?
# Key/username does not exist, so bail out
render :file => "#{::Rails.root.to_s}/public/403.xml", :status => 403
render 'shared/http_status', :locals => { :code => "403", :message => HttpStatusHelper::ERROR_CODE["message"]["403"] }, :status => 403
return
elsif markus_auth_remote_user.blank?
# see if the MD5 matches only if REMOTE_USER wasn't used
curr_user_md5 = Base64.decode64(@current_user.api_key)
if (Base64.decode64(auth_token) != curr_user_md5)
# MD5 mismatch, bail out
render :file => "#{::Rails.root.to_s}/public/403.xml", :status => 403
render 'shared/http_status', :locals => { :code => "403", :message => HttpStatusHelper::ERROR_CODE["message"]["403"] }, :status => 403
return
end
end
# Student's aren't allowed yet
if @current_user.student?
# API is available for TAs and Admins only
render :file => "#{::Rails.root.to_s}/public/403.xml", :status => 403
render 'shared/http_status', :locals => { :code => "403", :message => HttpStatusHelper::ERROR_CODE["message"]["403"] }, :status => 403
return
end
end

#=== Description
# Make sure that the passed format is either text, xml or json
def check_format
# support only plain text, xml and json
if request.format.symbol != :text and request.format.symbol != :xml and request.format.symbol != :json
# 406 is the default status code when the format is not support
render :nothing => true, :status => 406
end
end

#=== Description
# Helper method for parsing the authentication token
Expand All @@ -85,5 +95,4 @@ def parse_auth_token(token)
end

end

end # end Api module
end # end Api module
17 changes: 6 additions & 11 deletions app/controllers/api/submission_downloads_controller.rb
Expand Up @@ -18,14 +18,9 @@ class SubmissionDownloadsController < MainApiController
#=== Returns
# The requested file, or a zip file containing all requested files
def show
if !request.get?
# pretend this URL does not exist
render :file => "#{::Rails.root.to_s}/public/404.html", :status => 404
return
end
if !has_required_http_params?(params)
# incomplete/invalid HTTP params
render :file => "#{::Rails.root.to_s}/public/422.xml", :status => 422
render 'shared/http_status', :locals => { :code => "422", :message => HttpStatusHelper::ERROR_CODE["message"]["422"] }, :status => 422
return
end

Expand All @@ -35,16 +30,16 @@ def show

if submission.nil?
# no such submission
render :file => "#{::Rails.root.to_s}/public/422.xml", :status => 422
render 'shared/http_status', :locals => { :code => "422", :message => "Submission was not found" }, :status => 422
return
end

#If requested a single file
# If requested a single file
if !params[:filename].blank?
files = [SubmissionFile.find_by_filename_and_submission_id(params[:filename], submission.id)]
single_file = true
else
#otherwise we give them the whole directory of files
# otherwise we give them the whole directory of files
files = SubmissionFile.find_all_by_submission_id(submission.id)
single_file = false
FileUtils.remove_file("downloads/submissions.zip", true)
Expand All @@ -53,7 +48,7 @@ def show
files.each do |file|
if file.nil?
# no such submission file
render :file => "#{::Rails.root.to_s}/public/422.xml", :status => 422
render 'shared/http_status', :locals => { :code => "422", :message => "Submission was not found" }, :status => 422
return
end

Expand All @@ -66,7 +61,7 @@ def show
end
rescue Exception => e
# could not retrieve file
render :file => "#{::Rails.root.to_s}/public/500.xml", :status => 500
render 'shared/http_status', :locals => { :code => "500", :message => HttpStatusHelper::ERROR_CODE["message"]["500"] }, :status => 500
return
end

Expand Down
58 changes: 19 additions & 39 deletions app/controllers/api/test_results_controller.rb
Expand Up @@ -15,22 +15,17 @@ class TestResultsController < MainApiController
#=== Returns
# An XML response, indicating the success/failure for the request
def create
if !request.post?
# pretend this URL does not exist
render :file => "#{::Rails.root.to_s}/public/404.html", :status => 404
return
end
if !has_required_http_params_including_file_content?(params)
# incomplete/invalid HTTP params
render :file => "#{::Rails.root.to_s}/public/422.xml", :status => 422
render 'shared/http_status', :locals => { :code => "422", :message => HttpStatusHelper::ERROR_CODE["message"]["422"] }, :status => 422
return
end
# check if there's a valid submission
submission = Submission.get_submission_by_group_and_assignment(params[:group_name],
params[:assignment])
if submission.nil?
# no such submission
render :file => "#{::Rails.root.to_s}/public/422.xml", :status => 422
render 'shared/http_status', :locals => { :code => "404", :message => "Submission was not found" }, :status => 404
return
end
# Request seems good. Check if filename already exists.
Expand All @@ -41,22 +36,22 @@ def create
:file_content => params[:file_content],
:submission_id => submission.id)
# All good, so return a success response
render :file => "#{::Rails.root.to_s}/public/200.xml", :status => 200
render 'shared/http_status', :locals => { :code => "200", :message => "Success" }, :status => 200
return
else
# Some other error occurred
render :file => "#{::Rails.root.to_s}/public/500.xml", :status => 500
render 'shared/http_status', :locals => { :code => "500", :message => HttpStatusHelper::ERROR_CODE["message"]["500"] }, :status => 500
return
end
else
new_test_result.file_content = params[:file_content]
if new_test_result.save
# All good, so return a success response
render :file => "#{::Rails.root.to_s}/public/200.xml", :status => 200
render 'shared/http_status', :locals => { :code => "200", :message => "Success" }, :status => 200
return
else
# Some other error occurred
render :file => "#{::Rails.root.to_s}/public/500.xml", :status => 500
render 'shared/http_status', :locals => { :code => "500", :message => HttpStatusHelper::ERROR_CODE["message"]["500"] }, :status => 500
return
end
end
Expand All @@ -71,39 +66,34 @@ def create
#=== Returns
# An XML response, indicating the success/failure for the request
def destroy
if !request.delete?
# pretend this URL does not exist
render :file => "#{::Rails.root.to_s}/public/404.html", :status => 404
return
end
if !has_required_http_params?(params)
# incomplete/invalid HTTP params
render :file => "#{::Rails.root.to_s}/public/422.xml", :status => 422
render 'shared/http_status', :locals => { :code => "422", :message => HttpStatusHelper::ERROR_CODE["message"]["422"] }, :status => 422
return
end
# check if there's a valid submission
submission = Submission.get_submission_by_group_and_assignment(params[:group_name],
params[:assignment])
if submission.nil?
# no such submission
render :file => "#{::Rails.root.to_s}/public/422.xml", :status => 422
render 'shared/http_status', :locals => { :code => "404", :message => "Submission was not found" }, :status => 404
return
end
# request seems good
test_result = submission.test_results.find_by_filename(params[:filename])
if !test_result.nil?
if test_result.destroy
# Everything went fine; report success
render :file => "#{::Rails.root.to_s}/public/200.xml", :status => 200
render 'shared/http_status', :locals => { :code => "200", :message => HttpStatusHelper::ERROR_CODE["message"]["200"]}, :status => 200
return
else
# Some other error occurred
render :file => "#{::Rails.root.to_s}/public/500.xml", :status => 500
render 'shared/http_status', :locals => { :code => "500", :message => HttpStatusHelper::ERROR_CODE["message"]["500"] }, :status => 500
return
end
end
# The test result in question does not exist
render :file => "#{::Rails.root.to_s}/public/404.xml", :status => 404
render 'shared/http_status', :locals => { :code => "404", :message => "Test result was not found"}, :status => 404
return
end

Expand All @@ -117,39 +107,34 @@ def destroy
#=== Returns
# An XML response, indicating the success/failure for the request
def update
if !request.put?
# pretend this URL does not exist
render :file => "#{::Rails.root.to_s}/public/404.html", :status => 404
return
end
if !has_required_http_params_including_file_content?(params)
# incomplete/invalid HTTP params
render :file => "#{::Rails.root.to_s}/public/422.xml", :status => 422
render 'shared/http_status', :locals => { :code => "422", :message => HttpStatusHelper::ERROR_CODE["message"]["422"] }, :status => 422
return
end
# check if there's a valid submission
submission = Submission.get_submission_by_group_and_assignment(params[:group_name],
params[:assignment])
if submission.nil?
# no such submission
render :file => "#{::Rails.root.to_s}/public/422.xml", :status => 422
render 'shared/http_status', :locals => { :code => "404", :message => "Submission was not found" }, :status => 404
return
end
# request seems good
test_result = submission.test_results.find_by_filename(params[:filename])
if !test_result.nil?
if test_result.update_file_content(params[:file_content])
# Everything went fine; report success
render :file => "#{::Rails.root.to_s}/public/200.xml", :status => 200
render 'shared/http_status', :locals => { :code => "200", :message => HttpStatusHelper::ERROR_CODE["message"]["200"]}, :status => 200
return
else
# Some other error occurred
render :file => "#{::Rails.root.to_s}/public/500.xml", :status => 500
render 'shared/http_status', :locals => { :code => "500", :message => HttpStatusHelper::ERROR_CODE["message"]["500"] }, :status => 500
return
end
end
# The test result in question does not exist
render :file => "#{::Rails.root.to_s}/public/404.xml", :status => 404
render 'shared/http_status', :locals => { :code => "404", :message => "Test result not found" }, :status => 404
return
end

Expand All @@ -162,22 +147,17 @@ def update
#=== Returns
# The content of the test result file in question
def show
if !request.get?
# pretend this URL does not exist
render :file => "#{::Rails.root.to_s}/public/404.html", :status => 404
return
end
if !has_required_http_params?(params)
# incomplete/invalid HTTP params
render :file => "#{::Rails.root.to_s}/public/422.xml", :status => 422
render 'shared/http_status', :locals => { :code => "422", :message => HttpStatusHelper::ERROR_CODE["message"]["422"] }, :status => 422
return
end
# check if there's a valid submission
submission = Submission.get_submission_by_group_and_assignment(params[:group_name],
params[:assignment])
if submission.nil?
# no such submission
render :file => "#{::Rails.root.to_s}/public/422.xml", :status => 422
render 'shared/http_status', :locals => { :code => "404", :message => "Submission was not found" }, :status => 404
return
end
# request seems good
Expand All @@ -189,7 +169,7 @@ def show
return
end
# The test result in question does not exist
render :file => "#{::Rails.root.to_s}/public/404.xml", :status => 404
render 'shared/http_status', :locals => { :code => "404", :message => "Test result was not found" }, :status => 404
return
end

Expand Down

0 comments on commit 7348abf

Please sign in to comment.