diff --git a/app/controllers/login_controller.rb b/app/controllers/login_controller.rb --- a/app/controllers/login_controller.rb +++ b/app/controllers/login_controller.rb @@ -1,5 +1,7 @@ class LoginController < ApplicationController + @@authenticators = [] + def index # show login screen reset_session @@ -7,7 +9,7 @@ end def login - user = User.authenticate(params[:login], params[:password]) + user = get_authenticated_user(params[:login], params[:password]) unless user flash[:notice] = 'Wrong password' redirect_to :controller => 'main', :action => 'login' @@ -64,4 +66,24 @@ redirect_to root_path end + def self.add_authenticator(authenticator) + @@authenticators << authenticator + end + + protected + + def get_authenticated_user(login, password) + if @@authenticators.empty? + return User.authenticate(login, password) + else + user = User.authenticate(login, password) + @@authenticators.each do |authenticator| + if not user + user = authenticator.authenticate(login, password) + end + end + return user + end + end + end diff --git a/app/controllers/problems_controller.rb b/app/controllers/problems_controller.rb --- a/app/controllers/problems_controller.rb +++ b/app/controllers/problems_controller.rb @@ -2,10 +2,6 @@ before_action :admin_authorization - #NOTE: ghost from the past? - #before_action :testcase_authorization, only: [:show_testcase] - - in_place_edit_for :problem, :name in_place_edit_for :problem, :full_name in_place_edit_for :problem, :full_score @@ -26,7 +22,7 @@ def create @problem = Problem.new(problem_params) - @description = Description.new(problem_params[:description]) + @description = Description.new(description_params) if @description.body!='' if !@description.save render :action => new and return @@ -305,7 +301,7 @@ end def description_params - params.require(:description).permit(:body, :markdown) + params.require(:description).permit(:body, :markdowned) end end diff --git a/app/models/submission.rb b/app/models/submission.rb --- a/app/models/submission.rb +++ b/app/models/submission.rb @@ -127,8 +127,10 @@ end def assign_language - self.language = Submission.find_language_in_source(self.source, - self.source_filename) + if self.language == nil + self.language = Submission.find_language_in_source(self.source, + self.source_filename) + end end # validation codes @@ -138,8 +140,8 @@ # for output_only tasks return if self.problem!=nil and self.problem.output_only - if self.language==nil - errors.add('source',"Cannot detect language. Did you submit a correct source file?") unless self.language!=nil + if self.language == nil + errors.add('source',"Cannot detect language. Did you submit a correct source file?") end end diff --git a/app/models/user.rb b/app/models/user.rb --- a/app/models/user.rb +++ b/app/models/user.rb @@ -40,7 +40,7 @@ validates_length_of :full_name, :minimum => 1 validates_presence_of :password, :if => :password_required? - validates_length_of :password, :within => 4..20, :if => :password_required? + validates_length_of :password, :within => 4..50, :if => :password_required? validates_confirmation_of :password, :if => :password_required? validates_format_of :email, diff --git a/app/views/submissions/edit.html.haml b/app/views/submissions/edit.html.haml --- a/app/views/submissions/edit.html.haml +++ b/app/views/submissions/edit.html.haml @@ -85,4 +85,3 @@ - diff --git a/config/initializers/cafe_grader_config.rb.SAMPLE b/config/initializers/cafe_grader_config.rb.SAMPLE --- a/config/initializers/cafe_grader_config.rb.SAMPLE +++ b/config/initializers/cafe_grader_config.rb.SAMPLE @@ -28,3 +28,6 @@ # Uncomment so that configuration is read only once when the server is loaded # CONFIGURATION_CACHE_ENABLED = true + +# Uncomment to allow authentication and user import from programming.in.th +# LoginController.add_authenticator(ProgrammingAuthenticator.new) diff --git a/db/seeds.rb b/db/seeds.rb --- a/db/seeds.rb +++ b/db/seeds.rb @@ -102,6 +102,14 @@ :default_value => 'false', :description => 'When true, any user can view/download test data' }, + + { + :key => 'system.online_registration', + :value_type => 'boolean', + :default_value => 'false', + :description => 'This option enables online registration.' + }, + # If Configuration['system.online_registration'] is true, the # system allows online registration, and will use these # information for sending confirmation emails. diff --git a/lib/programming_authenticator.rb b/lib/programming_authenticator.rb new file mode 100644 --- /dev/null +++ b/lib/programming_authenticator.rb @@ -0,0 +1,33 @@ +# Authentication and user imports through programming.in.th web request +require 'net/http' +require 'uri' +require 'json' + +class ProgrammingAuthenticator + PROGRAMMING_AUTHEN_URL = "https://programming.in.th/authen.php" + + def find_or_create_user(result) + user = User.find_by(login: result['username']) + if not user + user = User.new(login: result['username'], + full_name: result['firstname'] + ' ' + result['surname'], + alias: result['display'], + email: result['email']) + user.password = User.random_password + user.save + end + return user + end + + def authenticate(login, password) + uri = URI(PROGRAMMING_AUTHEN_URL) + result = Net::HTTP.post_form(uri, 'username' => login, 'password' => password) + request_result = JSON.parse(result.body) + + if request_result.fetch('status', 'incorrect') == 'OK' + return find_or_create_user(request_result) + else + return nil + end + end +end