Files
astuto/app/controllers/api/base_controller.rb
Riccardo Graziosi 31999a2af6 Add API (#427)
2024-11-08 16:40:53 +01:00

96 lines
3.1 KiB
Ruby

module Api
class BaseController < ApplicationController
include ApplicationHelper
include Pundit::Authorization
rescue_from StandardError, with: :unexpected_error # Must be at the top, catches exceptions not caught by other rescue_from
rescue_from ActiveRecord::InvalidForeignKey, with: :parameter_wrong
rescue_from ActiveRecord::RecordNotFound, with: :not_found
rescue_from ActionController::ParameterMissing, with: :parameter_missing
rescue_from Pundit::NotAuthorizedError, with: :not_authorized
rescue_from Api::V1::Helpers::ImpersonationError, with: :impersonation_error
skip_before_action :verify_authenticity_token
skip_before_action :check_tenant_is_private
skip_before_action :load_tenant_data
before_action :authenticate_with_api_key
prepend_before_action :set_current_tenant
attr_reader :current_user, :current_api_key
def pundit_user
current_api_key
end
protected
def set_current_tenant
Current.tenant = get_tenant_from_request(request)
# If current tenant is nil, return generic error message
request_http_token_authentication if Current.tenant.nil?
I18n.locale = I18n.default_locale
end
def not_authorized
render status: :unauthorized, json: {
errors: ['You are not authorized to perform this action.']
}
end
def parameter_missing
render status: :bad_request, json: {
errors: ['Some parameters are missing from the request. Please check the documentation.']
}
end
def parameter_wrong
render status: :bad_request, json: {
errors: ['Some parameters are wrong in the request. Please check the documentation.']
}
end
def not_found(exception)
render status: :not_found, json: {
errors: [exception.message]
}
end
def impersonation_error(exception)
render status: :unauthorized, json: {
errors: ["Impersonation error: #{exception.message}"]
}
end
def unexpected_error(exception)
if Rails.env.development?
error = '[DEV-ONLY MESSAGE] ' + exception.message
else
error = 'An unexpected error occurred.'
end
render status: :internal_server_error, json: {
errors: [error]
}
end
def authenticate_with_api_key
authenticate_or_request_with_http_token do |token, options|
@current_api_key = ApiKey.find_by_token(token)
@current_user = current_api_key&.user
end
end
# Override rails default 401 response to return JSON content-type
# with request for Bearer token
# https://api.rubyonrails.org/classes/ActionController/HttpAuthentication/Token/ControllerMethods.html
def request_http_token_authentication(realm = "Application", message = nil)
json_response = { errors: [message || "Access denied."] }
headers["WWW-Authenticate"] = %(Bearer realm="#{realm.tr('"', "")}")
render json: json_response, status: :unauthorized
end
end
end