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' @@ -60,4 +62,24 @@ end 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 = nil + @@authenticators.each do |authenticator| + if not user + user = authenticator.authenticate(login, password) + end + end + return user + end + end + end 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/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