app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
include PublicActivity::StoreController
# Prevent CSRF attacks by raising an exception.
# Normal form authentication
protect_from_forgery with: :exception, unless: :is_api_call?
rescue_from CanCan::AccessDenied, with: :handle_access_denied
# Prevent this from being an error 500 in production
if Rails.env.production?
rescue_from ActionController::UnknownFormat, with: :handle_unknown_format
end
# API specific authentication
before_action :api_authenticate
before_filter :load_settings
before_filter :count_unapproved_artifacts
before_filter :set_current_locale
before_filter :store_location
before_filter :check_session_for_notifications
# When a controller gets the user via current_user
def load_user
@user = current_user
end
# For serving the juvia commenting script in a javascript tag we control
def comments_script
render layout: nil
end
private
def check_session_for_notifications
session[:notifications] ||= {}
session[:notifications]['survey'] ||= DateTime.now
end
def store_location
paths = ['/users/login', '/users/sign_up', '/users/password/new', '/users/password/edit', '/users/confirmation', '/users/logout']
auth_paths = /^\/users\/auth\//
names = ['download']
if request.method == 'GET' &&
!paths.include?(request.path) &&
!auth_paths.match(request.path) &&
!names.include?(action_name) &&
!request.xhr?
session[:previous_path] = request.fullpath
end
end
def after_sign_in_path_for(resource_or_scope)
session[:previous_path] || artifacts_path
end
def after_sign_out_path_for(resource_or_scope)
artifacts_path
end
def admin_dashboard_access_denied exception
redirect_to artifacts_path
end
def set_current_locale
I18n.locale = get_current_locale
end
def extract_locale_from_accept_language_header
str = request.env['HTTP_ACCEPT_LANGUAGE'] || ''
str = str.scan(/^[a-z]{2}/).first.to_s
mapping = {
'pt' => 'pt-BR'
}
locale = mapping[str] || str
if I18n.available_locales.include?(locale.to_sym)
locale
else
I18n.default_locale
end
end
def get_current_locale
locale = extract_locale_from_accept_language_header
locale = session[:locale] if session[:locale].present?
locale.to_sym
end
# Extracted from the Knock::Authenticatable module because it interfered with devise
# https://github.com/nsarno/knock/blob/master/lib/knock/authenticable.rb#L4
def api_authenticate
if current_user.blank? && request.headers['Authorization'].present?
@current_user ||= begin
token = request.headers['Authorization'].split.last
Knock::AuthToken.new(token: token).current_user
rescue JWT::DecodeError => e
# recover from specific exceptions
nil
end
head :unauthorized unless current_user
end
end
# Test for write calls which are JSON, so that we authenticate
# with JWT using it instead of Devise via HTTP
def is_api_call?
['POST', 'PUT'].include?(request.method) && request.format == 'application/json'
end
def load_settings
@setting = Setting.first
end
def count_unapproved_artifacts
@unapproved_artifacts = Artifact.where(approved: false).count
end
def handle_unknown_format(exception)
msg = "[UnknownFormat] error at #{request.path}"
logger.error msg
ExceptionNotifier.notify_exception exception, env: request.env, data: {message: msg}
render file: "#{Rails.root}/public/404.html", status: 404, format: :html, layout: false
end
end