require 'login_not_found' # The controller that implements the engine's endpoints. # # @!visibility private class Oauth2Controller < ApplicationController force_ssl if: -> { RailsApiAuth.force_ssl } # rubocop:disable MethodLength def create case params[:grant_type] when 'password' authenticate_with_credentials(params[:username], params[:password]) when 'facebook_auth_code' authenticate_with_facebook(params[:auth_code]) when 'google_auth_code' authenticate_with_google(params[:auth_code]) when 'edx_auth_code' authenticate_with_edx(params[:username], params[:auth_code]) when 'github_auth_code' authenticate_with_github(params[:auth_state], params[:auth_code]) else oauth2_error('unsupported_grant_type') end end # rubocop:enable MethodLength def destroy oauth2_error('unsupported_token_type') && return unless params[:token_type_hint] == 'access_token' login = Login.where(oauth2_token: params[:token]).first || LoginNotFound.new login.refresh_oauth2_token! head 200 end private def authenticate_with_credentials(identification, password) login = Login.where(identification: identification).first || LoginNotFound.new if login.authenticate(password) render json: { access_token: login.oauth2_token } else oauth2_error('invalid_grant') end end def authenticate_with_facebook(auth_code) oauth2_error('no_authorization_code') && return unless auth_code.present? login = FacebookAuthenticator.new(auth_code).authenticate! render json: { access_token: login.oauth2_token } rescue FacebookAuthenticator::ApiError head 502 end def authenticate_with_google(auth_code) oauth2_error('no_authorization_code') && return unless auth_code.present? login = GoogleAuthenticator.new(auth_code).authenticate! render json: { access_token: login.oauth2_token } rescue GoogleAuthenticator::ApiError head 502 end def authenticate_with_edx(username, auth_code) oauth2_error('no_authorization_code') && return unless auth_code.present? oauth2_error('no_username') && return unless username.present? login = EdxAuthenticator.new(username, auth_code).authenticate! render json: { access_token: login.oauth2_token } rescue EdxAuthenticator::ApiError head 502 end def authenticate_with_github(auth_state, auth_code) oauth2_error('no_authorization_code') && return unless auth_code.present? oauth2_error('no_auth_state') && return unless auth_state.present? login = GithubAuthenticator.new(auth_state, auth_code).authenticate! render json: { access_token: login.oauth2_token } rescue GithubAuthenticator::ApiError head 502 end def oauth2_error(error) render json: { error: error }, status: :bad_request end end