PageRenderTime 63ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/app/controllers/application_controller.rb

http://github.com/fatfreecrm/fat_free_crm
Ruby | 261 lines | 184 code | 37 blank | 40 comment | 22 complexity | 15af233f91fa500fa15ac6ebf5b8028d MD5 | raw file
Possible License(s): AGPL-3.0
  1. # frozen_string_literal: true
  2. # Copyright (c) 2008-2013 Michael Dvorkin and contributors.
  3. #
  4. # Fat Free CRM is freely distributable under the terms of MIT license.
  5. # See MIT-LICENSE file or http://www.opensource.org/licenses/mit-license.php
  6. #------------------------------------------------------------------------------
  7. class ApplicationController < ActionController::Base
  8. protect_from_forgery with: :exception
  9. before_action :configure_devise_parameters, if: :devise_controller?
  10. before_action :authenticate_user!
  11. before_action :set_paper_trail_whodunnit
  12. before_action :set_context
  13. before_action :clear_setting_cache
  14. before_action :cors_preflight_check
  15. before_action { hook(:app_before_filter, self) }
  16. after_action { hook(:app_after_filter, self) }
  17. after_action :cors_set_access_control_headers
  18. helper_method :called_from_index_page?, :called_from_landing_page?
  19. helper_method :klass
  20. respond_to :html, only: %i[index show auto_complete]
  21. respond_to :js
  22. respond_to :json, :xml, except: :edit
  23. respond_to :atom, :csv, :rss, :xls, only: :index
  24. rescue_from ActiveRecord::RecordNotFound, with: :respond_to_not_found
  25. rescue_from CanCan::AccessDenied, with: :respond_to_access_denied
  26. include ERB::Util # to give us h and j methods
  27. # Common auto_complete handler for all core controllers.
  28. #----------------------------------------------------------------------------
  29. def auto_complete
  30. @query = params[:term] || ''
  31. @auto_complete = hook(:auto_complete, self, query: @query, user: current_user)
  32. if @auto_complete.empty?
  33. exclude_ids = auto_complete_ids_to_exclude(params[:related])
  34. @auto_complete = klass.my(current_user).text_search(@query).ransack(id_not_in: exclude_ids).result.limit(10)
  35. else
  36. @auto_complete = @auto_complete.last
  37. end
  38. session[:auto_complete] = controller_name.to_sym
  39. respond_to do |format|
  40. format.any(:js, :html) { render partial: 'auto_complete' }
  41. format.json do
  42. results = @auto_complete.map do |a|
  43. {
  44. id: a.id,
  45. text: a.respond_to?(:full_name) ? a.full_name : a.name
  46. }
  47. end
  48. render json: {
  49. results: results
  50. }
  51. end
  52. end
  53. end
  54. private
  55. #
  56. # In rails 3, the default behaviour for handle_unverified_request is to delete the session
  57. # and continue executing the request. However, we use cookie based authentication and need
  58. # to halt proceedings. In Rails 4, use "protect_from_forgery with: :exception"
  59. # See http://blog.nvisium.com/2014/09/understanding-protectfromforgery.html for more details.
  60. #----------------------------------------------------------------------------
  61. def handle_unverified_request
  62. raise ActionController::InvalidAuthenticityToken
  63. end
  64. #
  65. # Takes { related: 'campaigns/7' } or { related: '5' }
  66. # and returns array of object ids that should be excluded from search
  67. # assumes controller_name is a method on 'related' class that returns a collection
  68. #----------------------------------------------------------------------------
  69. def auto_complete_ids_to_exclude(related)
  70. return [] if related.blank?
  71. return [related.to_i].compact unless related.index('/')
  72. related_class, id = related.split('/')
  73. obj = related_class.classify.constantize.find_by_id(id)
  74. if obj&.respond_to?(controller_name)
  75. obj.send(controller_name).map(&:id)
  76. else
  77. []
  78. end
  79. end
  80. #----------------------------------------------------------------------------
  81. def klass
  82. @klass ||= controller_name.classify.constantize
  83. end
  84. #----------------------------------------------------------------------------
  85. def clear_setting_cache
  86. Setting.clear_cache!
  87. end
  88. #----------------------------------------------------------------------------
  89. def set_context
  90. Time.zone = ActiveSupport::TimeZone[session[:timezone_offset]] if session[:timezone_offset]
  91. if current_user.present? && (locale = current_user.preference[:locale]).present?
  92. I18n.locale = locale
  93. elsif Setting.locale.present?
  94. I18n.locale = Setting.locale
  95. end
  96. end
  97. #----------------------------------------------------------------------------
  98. def set_current_tab(tab = controller_name)
  99. @current_tab = tab
  100. end
  101. #----------------------------------------------------------------------------
  102. def store_location
  103. session[:return_to] = request.fullpath
  104. end
  105. #----------------------------------------------------------------------------
  106. def redirect_back_or_default(default)
  107. redirect_to(session[:return_to] || default)
  108. session[:return_to] = nil
  109. end
  110. #----------------------------------------------------------------------------
  111. def can_signup?
  112. User.can_signup?
  113. end
  114. #----------------------------------------------------------------------------
  115. def called_from_index_page?(controller = controller_name)
  116. request.referer =~ if controller != "tasks"
  117. %r{/#{controller}$}
  118. else
  119. /tasks\?*/
  120. end
  121. end
  122. #----------------------------------------------------------------------------
  123. def called_from_landing_page?(controller = controller_name)
  124. request.referer =~ %r{/#{controller}/\w+}
  125. end
  126. # Proxy current page for any of the controllers by storing it in a session.
  127. #----------------------------------------------------------------------------
  128. def current_page=(page)
  129. p = page.to_i
  130. @current_page = session[:"#{controller_name}_current_page"] = (p.zero? ? 1 : p)
  131. end
  132. #----------------------------------------------------------------------------
  133. def current_page
  134. page = params[:page] || session[:"#{controller_name}_current_page"] || 1
  135. @current_page = page.to_i
  136. end
  137. # Proxy current search query for any of the controllers by storing it in a session.
  138. #----------------------------------------------------------------------------
  139. def current_query=(query)
  140. if session[:"#{controller_name}_current_query"].to_s != query.to_s # nil.to_s == ""
  141. self.current_page = params[:page] # reset paging otherwise results might be hidden, defaults to 1 if nil
  142. end
  143. @current_query = session[:"#{controller_name}_current_query"] = query
  144. end
  145. #----------------------------------------------------------------------------
  146. def current_query
  147. @current_query = params[:query] || session[:"#{controller_name}_current_query"] || ''
  148. end
  149. #----------------------------------------------------------------------------
  150. def asset
  151. controller_name.singularize
  152. end
  153. #----------------------------------------------------------------------------
  154. def respond_to_not_found(*_types)
  155. flash[:warning] = t(:msg_asset_not_available, asset)
  156. respond_to do |format|
  157. format.html { redirect_to(redirection_url) }
  158. format.js { render plain: 'window.location.reload();' }
  159. format.json { render plain: flash[:warning], status: :not_found }
  160. format.xml { render xml: [flash[:warning]], status: :not_found }
  161. end
  162. end
  163. #----------------------------------------------------------------------------
  164. def respond_to_related_not_found(related, *_types)
  165. asset = "note" if asset == "comment"
  166. flash[:warning] = t(:msg_cant_create_related, asset: asset, related: related)
  167. url = send("#{related.pluralize}_path")
  168. respond_to do |format|
  169. format.html { redirect_to(url) }
  170. format.js { render plain: %(window.location.href = "#{url}";) }
  171. format.json { render plain: flash[:warning], status: :not_found }
  172. format.xml { render xml: [flash[:warning]], status: :not_found }
  173. end
  174. end
  175. #----------------------------------------------------------------------------
  176. def respond_to_access_denied
  177. flash[:warning] = t(:msg_not_authorized, default: 'You are not authorized to take this action.')
  178. respond_to do |format|
  179. format.html { redirect_to(redirection_url) }
  180. format.js { render plain: 'window.location.reload();' }
  181. format.json { render plain: flash[:warning], status: :unauthorized }
  182. format.xml { render xml: [flash[:warning]], status: :unauthorized }
  183. end
  184. end
  185. #----------------------------------------------------------------------------
  186. def redirection_url
  187. # Try to redirect somewhere sensible. Note: not all controllers have an index action
  188. if current_user.present?
  189. respond_to?(:index) && action_name != 'index' ? { action: 'index' } : root_url
  190. else
  191. login_url
  192. end
  193. end
  194. def cors_set_access_control_headers
  195. headers['Access-Control-Allow-Origin'] = '*'
  196. headers['Access-Control-Allow-Methods'] = 'POST, GET, PUT, DELETE, OPTIONS'
  197. headers['Access-Control-Allow-Headers'] = 'Origin, Content-Type, Accept, Authorization, Token'
  198. headers['Access-Control-Max-Age'] = "1728000"
  199. end
  200. def cors_preflight_check
  201. if request.method == 'OPTIONS'
  202. headers['Access-Control-Allow-Origin'] = '*'
  203. headers['Access-Control-Allow-Methods'] = 'POST, GET, PUT, DELETE, OPTIONS'
  204. headers['Access-Control-Allow-Headers'] = 'X-Requested-With, X-Prototype-Version, Token'
  205. headers['Access-Control-Max-Age'] = '1728000'
  206. render plain: ''
  207. end
  208. end
  209. def configure_devise_parameters
  210. devise_parameter_sanitizer.permit(:sign_up) do |user_params|
  211. user_params.permit(:username, :email, :password, :password_confirmation)
  212. end
  213. end
  214. def find_class(asset)
  215. Rails.application.eager_load! unless Rails.application.config.cache_classes
  216. classes = ActiveRecord::Base.descendants.map(&:name)
  217. find = classes.find { |m| m == asset.classify }
  218. if find
  219. find.safe_constantize
  220. else
  221. raise "Unknown resource"
  222. end
  223. end
  224. end