znamenica/allslavic

View on GitHub
app/controllers/application_controller.rb

Summary

Maintainability
A
1 hr
Test Coverage
# frozen_string_literal: true

class ApplicationController < ActionController::Base
   include Pundit::Authorization

   protect_from_forgery with: :null_session, if: :json_request?
   protect_from_forgery with: :exception, unless: :json_request?
   before_action :authenticate_user!, except: [:home]
   before_action :set_paging, only: :index
   before_action :set_order, only: :index
   before_action :set_objects, only: :index

   rescue_from Exception, with: :render_exception
   # NOTE https://stackoverflow.com/a/48744792/446267
   rescue_from ActionController::UnknownFormat, with: -> { render nothing: true }
   rescue_from ActiveRecord::RecordNotFound, with: :render_invalid_record
   rescue_from Pundit::NotAuthorizedError, with: :render_unauthorized

   def home
   end

   protected
      def authenticate_user! opts = {}
         if json_request?
            @current_user = Token.find_by!(code: auth_token, kind: :access).user
         else
            super
         end
      rescue ActiveRecord::RecordNotFound => e
         Rails.logger.error("[#{e}]: #{e.message}\n\t#{e.backtrace.join("\n\t")}")

         render_unauthenticated
      end

      def auth_token
         params[:auth_token] || request.headers["X-AUTH-TOKEN"]
      end

      def current_user
         @current_user ||= super
      end

      def json_request?
         @json_request ||= request.format.json? || request.content_type == "application/json"
      end

      def render_unauthorized
         respond_to do |format|
            format.json { render json: { error: { message: "Unauthorized" } }, status: 403 }
         end
      end

      def render_unauthenticated
         respond_to do |format|
            format.json { render json: { error: { message: "Unauthenticated" } }, status: :unauthorized }
         end
      end

      def render_exception e
         Rails.logger.error("[#{e}]: #{e.message}\n\t#{e.backtrace.join("\n\t")}")

         respond_to do |format|
            format.json { render json: { error: { message: e.message } }, status: :internal_server_error }
         end
      end

      def render_invalid_record e
         Rails.logger.error("[#{e}]: #{e.message}\n\t#{e.backtrace.join("\n\t")}")

         respond_to do |format|
            format.json { render json: { error: { message: e.message } }, status: :locked }
         end
      end

      def set_order
         sort = params[:sort] || ""
         hash = sort.split(",").to_h { |x| (x.split(":") | ["asc"])[0..1] }

         order = hash.keys & model.attribute_names rescue []
         @order = order.index_with { |x| hash[x] }
      end

      def set_paging
         @page = params.fetch(:p, 1).to_i
         @per = params.fetch(:per, 25).to_i
      end

      def set_objects
         @objects = apply_scopes(model).page(@page).per(@per).order(@order) rescue []
      end
end