From 037df7b3932984be0c925c0a2ad4ca003c6c1069 Mon Sep 17 00:00:00 2001 From: Thomas Burkhalter Date: Fri, 11 Dec 2020 19:06:18 +0100 Subject: [PATCH] Add Devise strategy for API login --- app/controllers/application_controller.rb | 26 ---------------- config/initializers/devise.rb | 6 +++- config/initializers/devise_api_strategy.rb | 36 ++++++++++++++++++++++ 3 files changed, 41 insertions(+), 27 deletions(-) create mode 100644 config/initializers/devise_api_strategy.rb diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 7275b8e50..9ed695b4e 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -36,24 +36,6 @@ def controller_module_name private - # Filter for check if user is logged in or not - def authenticate - case request.path - when %r{\A/api/v\d+/} - @user = authenticate_or_request_with_http_basic('Puzzletime') { |u, p| ApiClient.new.authenticate(u, p) } - else - unless current_user - # allow ad-hoc login - if params[:user].present? && params[:pwd].present? - return true if login_with(params[:user], params[:pwd]) - - flash[:notice] = 'Ungültige Benutzerdaten' - end - redirect_to new_employee_session_path - end - end - end - def current_user @user ||= current_employee end @@ -70,14 +52,6 @@ def after_sign_in_path_for(resource_or_scope) stored_location_for(resource_or_scope) || super end - def login_with(user, pwd) - @user = Employee.login(user, pwd) - if @user - reset_session - session[:user_id] = @user.id - end - end - def set_period @period = nil p = session[:period] diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index 4e113e6f3..ad89d7c04 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -70,7 +70,7 @@ # given strategies, for example, `config.http_authenticatable = [:database]` will # enable it only for database authentication. The supported strategies are: # :database = Support basic authentication with authentication key + password - # config.http_authenticatable = false + config.http_authenticatable = [:database] # If 401 status code should be returned for AJAX requests. True by default. # config.http_authenticatable_on_xhr = true @@ -298,6 +298,10 @@ # manager.intercept_401 = false # manager.default_strategies(scope: :user).unshift :some_external_strategy # end + config.warden do |manager| + manager.strategies.add(:api, Devise::Strategies::API) + manager.default_strategies(scope: :employee).unshift :api + end # ==> Mountable engine configurations # When using Devise inside an engine, let's call it `MyEngine`, and this engine diff --git a/config/initializers/devise_api_strategy.rb b/config/initializers/devise_api_strategy.rb new file mode 100644 index 000000000..88e82dd87 --- /dev/null +++ b/config/initializers/devise_api_strategy.rb @@ -0,0 +1,36 @@ +module Devise + module Strategies + # The API Strategy is responsible for authenticating calls to the /api/vx/ endpoint. + # :reek:MissingSafeMethod { exclude: [ authenticate! ] } + class API < Base + def store? + false + end + + def valid? + user, pass = ActionController::HttpAuthentication::Basic.user_name_and_password(request) + user && pass && request.path.match?(%r{^/api/v\d+/}) + end + + def authenticate! + user = user_from_basic_auth + + if user.is_a? ApiClient + success!(user) + else + fail('Could not login with API Credentials') # rubocop:disable Style/SignalException + end + end + + private + + def user_from_basic_auth + request + .controller_instance + .authenticate_or_request_with_http_basic('Puzzletime') do |user, password| + ApiClient.new.authenticate(user, password) + end + end + end + end +end