From f678092a250e2d5fe937dff638e67b155a5ae687 Mon Sep 17 00:00:00 2001 From: Braulio Bhavamitra Date: Sat, 16 Jul 2016 11:20:49 -0300 Subject: [PATCH] concerns: Organize existing concerns in application controller --- app/concerns/authenticated_system.rb | 169 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- app/controllers/application_controller.rb | 25 ++++++++++++++----------- app/controllers/concerns/authenticated_system.rb | 169 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ app/controllers/concerns/custom_design.rb | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ app/controllers/concerns/needs_profile.rb | 40 ++++++++++++++++++++++++++++++++++++++++ app/helpers/design_helper.rb | 50 -------------------------------------------------- config/initializers/00_dependencies.rb | 1 - lib/needs_profile.rb | 40 ---------------------------------------- test/unit/custom_design_test.rb | 19 +++++++++++++++++++ test/unit/design_helper_test.rb | 20 -------------------- 10 files changed, 292 insertions(+), 291 deletions(-) delete mode 100644 app/concerns/authenticated_system.rb create mode 100644 app/controllers/concerns/authenticated_system.rb create mode 100644 app/controllers/concerns/custom_design.rb create mode 100644 app/controllers/concerns/needs_profile.rb delete mode 100644 app/helpers/design_helper.rb delete mode 100644 lib/needs_profile.rb create mode 100644 test/unit/custom_design_test.rb delete mode 100644 test/unit/design_helper_test.rb diff --git a/app/concerns/authenticated_system.rb b/app/concerns/authenticated_system.rb deleted file mode 100644 index db82d73..0000000 --- a/app/concerns/authenticated_system.rb +++ /dev/null @@ -1,169 +0,0 @@ -module AuthenticatedSystem - - protected - - extend ActiveSupport::Concern - - included do - if self < ActionController::Base - around_filter :user_set_current - before_filter :override_user - before_filter :login_from_cookie - end - - # Inclusion hook to make #current_user and #logged_in? - # available as ActionView helper methods. - helper_method :current_user, :logged_in? - end - - # Returns true or false if the user is logged in. - # Preloads @current_user with the user model if they're logged in. - def logged_in? - current_user != nil - end - - # Accesses the current user from the session. - def current_user user_id = session[:user] - @current_user ||= begin - user = User.find_by id: user_id if user_id - user.session = session if user - User.current = user - user - end - end - - # Store the given user in the session. - def current_user=(new_user) - if new_user.nil? - session.delete(:user) - else - session[:user] = new_user.id - new_user.session = session - new_user.register_login - end - @current_user = User.current = new_user - end - - # See impl. from http://stackoverflow.com/a/2513456/670229 - def user_set_current - User.current = current_user - yield - ensure - # to address the thread variable leak issues in Puma/Thin webserver - User.current = nil - end - - # Check if the user is authorized. - # - # Override this method in your controllers if you want to restrict access - # to only a few actions or if you want to check if the user - # has the correct rights. - # - # Example: - # - # # only allow nonbobs - # def authorize? - # current_user.login != "bob" - # end - def authorized? - true - end - - # Filter method to enforce a login requirement. - # - # To require logins for all actions, use this in your controllers: - # - # before_filter :login_required - # - # To require logins for specific actions, use this in your controllers: - # - # before_filter :login_required, :only => [ :edit, :update ] - # - # To skip this in a subclassed controller: - # - # skip_before_filter :login_required - # - def login_required - username, passwd = get_auth_data - if username && passwd - self.current_user ||= User.authenticate(username, passwd) || nil - end - if logged_in? && authorized? - true - else - if params[:require_login_popup] - render :json => { :require_login_popup => true } - else - access_denied - end - end - end - - # Redirect as appropriate when an access request fails. - # - # The default action is to redirect to the login screen. - # - # Override this method in your controllers if you want to have special - # behavior in case the user is not authorized - # to access the requested action. For example, a popup window might - # simply close itself. - def access_denied - respond_to do |accepts| - accepts.html do - if request.xhr? - render :text => _('Access denied'), :status => 401 - else - store_location - redirect_to :controller => '/account', :action => 'login' - end - end - accepts.xml do - headers["Status"] = "Unauthorized" - headers["WWW-Authenticate"] = %(Basic realm="Web Password") - render :text => "Could't authenticate you", :status => '401 Unauthorized' - end - end - false - end - - # Store the URI of the current request in the session. - # - # We can return to this location by calling #redirect_back_or_default. - def store_location(location = request.url) - session[:return_to] = location - end - - # Redirect to the URI stored by the most recent store_location call or - # to the passed default. - def redirect_back_or_default(default) - if session[:return_to] - redirect_to(session.delete(:return_to)) - else - redirect_to(default) - end - end - - def override_user - return if params[:override_user].blank? - return unless logged_in? and user.is_admin? environment - @current_user = nil - current_user params[:override_user] - end - - # When called with before_filter :login_from_cookie will check for an :auth_token - # cookie and log the user back in if apropriate - def login_from_cookie - return if cookies[:auth_token].blank? or logged_in? - user = User.where(remember_token: cookies[:auth_token]).first - self.current_user = user if user and user.remember_token? - end - - private - @@http_auth_headers = %w(X-HTTP_AUTHORIZATION HTTP_AUTHORIZATION Authorization) - # gets BASIC auth info - def get_auth_data - auth_key = @@http_auth_headers.detect { |h| request.env.has_key?(h) } - auth_data = request.env[auth_key].to_s.split unless auth_key.blank? - return auth_data && auth_data[0] == 'Basic' ? Base64.decode64(auth_data[1]).split(':')[0..1] : [nil, nil] - end -end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index c4301a9..1e2fda5 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -14,6 +14,20 @@ class ApplicationController < ActionController::Base before_filter :redirect_to_current_user before_filter :set_session_theme + + # FIXME: only include necessary methods + include ApplicationHelper + + # concerns + include PermissionCheck + include CustomDesign + include NeedsProfile + + # implementations + include FindByContents + include Noosfero::Plugin::HotSpot + include SearchTermHelper + def set_session_theme if params[:theme] session[:theme] = environment.theme_ids.include?(params[:theme]) ? params[:theme] : nil @@ -48,7 +62,6 @@ class ApplicationController < ActionController::Base end end - include ApplicationHelper layout :get_layout def get_layout return false if request.format == :js or request.xhr? @@ -74,9 +87,6 @@ class ApplicationController < ActionController::Base helper :document helper :language - include DesignHelper - include PermissionCheck - before_filter :set_locale def set_locale FastGettext.available_locales = environment.available_locales @@ -89,8 +99,6 @@ class ApplicationController < ActionController::Base end end - include NeedsProfile - attr_reader :environment # declares that the given actions cannot be accessed by other HTTP @@ -151,8 +159,6 @@ class ApplicationController < ActionController::Base end end - include Noosfero::Plugin::HotSpot - # FIXME this filter just loads @plugins to children controllers and helpers def init_noosfero_plugins plugins @@ -184,9 +190,6 @@ class ApplicationController < ActionController::Base end end - include SearchTermHelper - include FindByContents - def find_suggestions(query, context, asset, options={}) plugins.dispatch_first(:find_suggestions, query, context, asset, options) end diff --git a/app/controllers/concerns/authenticated_system.rb b/app/controllers/concerns/authenticated_system.rb new file mode 100644 index 0000000..db82d73 --- /dev/null +++ b/app/controllers/concerns/authenticated_system.rb @@ -0,0 +1,169 @@ +module AuthenticatedSystem + + protected + + extend ActiveSupport::Concern + + included do + if self < ActionController::Base + around_filter :user_set_current + before_filter :override_user + before_filter :login_from_cookie + end + + # Inclusion hook to make #current_user and #logged_in? + # available as ActionView helper methods. + helper_method :current_user, :logged_in? + end + + # Returns true or false if the user is logged in. + # Preloads @current_user with the user model if they're logged in. + def logged_in? + current_user != nil + end + + # Accesses the current user from the session. + def current_user user_id = session[:user] + @current_user ||= begin + user = User.find_by id: user_id if user_id + user.session = session if user + User.current = user + user + end + end + + # Store the given user in the session. + def current_user=(new_user) + if new_user.nil? + session.delete(:user) + else + session[:user] = new_user.id + new_user.session = session + new_user.register_login + end + @current_user = User.current = new_user + end + + # See impl. from http://stackoverflow.com/a/2513456/670229 + def user_set_current + User.current = current_user + yield + ensure + # to address the thread variable leak issues in Puma/Thin webserver + User.current = nil + end + + # Check if the user is authorized. + # + # Override this method in your controllers if you want to restrict access + # to only a few actions or if you want to check if the user + # has the correct rights. + # + # Example: + # + # # only allow nonbobs + # def authorize? + # current_user.login != "bob" + # end + def authorized? + true + end + + # Filter method to enforce a login requirement. + # + # To require logins for all actions, use this in your controllers: + # + # before_filter :login_required + # + # To require logins for specific actions, use this in your controllers: + # + # before_filter :login_required, :only => [ :edit, :update ] + # + # To skip this in a subclassed controller: + # + # skip_before_filter :login_required + # + def login_required + username, passwd = get_auth_data + if username && passwd + self.current_user ||= User.authenticate(username, passwd) || nil + end + if logged_in? && authorized? + true + else + if params[:require_login_popup] + render :json => { :require_login_popup => true } + else + access_denied + end + end + end + + # Redirect as appropriate when an access request fails. + # + # The default action is to redirect to the login screen. + # + # Override this method in your controllers if you want to have special + # behavior in case the user is not authorized + # to access the requested action. For example, a popup window might + # simply close itself. + def access_denied + respond_to do |accepts| + accepts.html do + if request.xhr? + render :text => _('Access denied'), :status => 401 + else + store_location + redirect_to :controller => '/account', :action => 'login' + end + end + accepts.xml do + headers["Status"] = "Unauthorized" + headers["WWW-Authenticate"] = %(Basic realm="Web Password") + render :text => "Could't authenticate you", :status => '401 Unauthorized' + end + end + false + end + + # Store the URI of the current request in the session. + # + # We can return to this location by calling #redirect_back_or_default. + def store_location(location = request.url) + session[:return_to] = location + end + + # Redirect to the URI stored by the most recent store_location call or + # to the passed default. + def redirect_back_or_default(default) + if session[:return_to] + redirect_to(session.delete(:return_to)) + else + redirect_to(default) + end + end + + def override_user + return if params[:override_user].blank? + return unless logged_in? and user.is_admin? environment + @current_user = nil + current_user params[:override_user] + end + + # When called with before_filter :login_from_cookie will check for an :auth_token + # cookie and log the user back in if apropriate + def login_from_cookie + return if cookies[:auth_token].blank? or logged_in? + user = User.where(remember_token: cookies[:auth_token]).first + self.current_user = user if user and user.remember_token? + end + + private + @@http_auth_headers = %w(X-HTTP_AUTHORIZATION HTTP_AUTHORIZATION Authorization) + # gets BASIC auth info + def get_auth_data + auth_key = @@http_auth_headers.detect { |h| request.env.has_key?(h) } + auth_data = request.env[auth_key].to_s.split unless auth_key.blank? + return auth_data && auth_data[0] == 'Basic' ? Base64.decode64(auth_data[1]).split(':')[0..1] : [nil, nil] + end +end diff --git a/app/controllers/concerns/custom_design.rb b/app/controllers/concerns/custom_design.rb new file mode 100644 index 0000000..875c635 --- /dev/null +++ b/app/controllers/concerns/custom_design.rb @@ -0,0 +1,50 @@ +module CustomDesign + + extend ActiveSupport::Concern + + included do + extend ClassMethods + include InstanceMethods + before_filter :load_custom_design if self.respond_to? :before_filter + end + + module ClassMethods + + def no_design_blocks + @no_design_blocks = true + end + + def use_custom_design options = {} + @custom_design = options + end + + def custom_design + @custom_design ||= {} + end + + def uses_design_blocks? + !@no_design_blocks + end + + end + + module InstanceMethods + + protected + + def uses_design_blocks? + !@no_design_blocks && self.class.uses_design_blocks? + end + + def load_custom_design + # see also: LayoutHelper#body_classes + @layout_template = self.class.custom_design[:layout_template] + end + + def custom_design + @custom_design || self.class.custom_design + end + + end + +end diff --git a/app/controllers/concerns/needs_profile.rb b/app/controllers/concerns/needs_profile.rb new file mode 100644 index 0000000..8048f4c --- /dev/null +++ b/app/controllers/concerns/needs_profile.rb @@ -0,0 +1,40 @@ +module NeedsProfile + + module ClassMethods + def needs_profile + before_filter :load_profile + end + end + + def self.included(including) + including.send(:extend, NeedsProfile::ClassMethods) + end + + def boxes_holder + profile || environment # prefers profile, but defaults to environment + end + + def profile + @profile + end + + protected + + def load_profile + if params[:profile] + params[:profile].downcase! + @profile ||= environment.profiles.where(identifier: params[:profile]).first + end + + if @profile + profile_hostname = @profile.hostname + if profile_hostname && profile_hostname != request.host + params.delete(:profile) + redirect_to(Noosfero.url_options.merge(params).merge(:host => profile_hostname)) + end + else + render_not_found + end + end + +end diff --git a/app/helpers/design_helper.rb b/app/helpers/design_helper.rb deleted file mode 100644 index 9c78710..0000000 --- a/app/helpers/design_helper.rb +++ /dev/null @@ -1,50 +0,0 @@ -module DesignHelper - - extend ActiveSupport::Concern - - included do - extend ClassMethods - include InstanceMethods - before_filter :load_custom_design if self.respond_to? :before_filter - end - - module ClassMethods - - def no_design_blocks - @no_design_blocks = true - end - - def use_custom_design options = {} - @custom_design = options - end - - def custom_design - @custom_design ||= {} - end - - def uses_design_blocks? - !@no_design_blocks - end - - end - - module InstanceMethods - - protected - - def uses_design_blocks? - !@no_design_blocks && self.class.uses_design_blocks? - end - - def load_custom_design - # see also: LayoutHelper#body_classes - @layout_template = self.class.custom_design[:layout_template] - end - - def custom_design - @custom_design || self.class.custom_design - end - - end - -end diff --git a/config/initializers/00_dependencies.rb b/config/initializers/00_dependencies.rb index 3163697..f69ee43 100644 --- a/config/initializers/00_dependencies.rb +++ b/config/initializers/00_dependencies.rb @@ -25,6 +25,5 @@ require 'acts_as_customizable' require 'route_if' require 'maybe_add_http' require 'set_profile_region_from_city_state' -require 'needs_profile' require 'white_list_filter' diff --git a/lib/needs_profile.rb b/lib/needs_profile.rb deleted file mode 100644 index 8048f4c..0000000 --- a/lib/needs_profile.rb +++ /dev/null @@ -1,40 +0,0 @@ -module NeedsProfile - - module ClassMethods - def needs_profile - before_filter :load_profile - end - end - - def self.included(including) - including.send(:extend, NeedsProfile::ClassMethods) - end - - def boxes_holder - profile || environment # prefers profile, but defaults to environment - end - - def profile - @profile - end - - protected - - def load_profile - if params[:profile] - params[:profile].downcase! - @profile ||= environment.profiles.where(identifier: params[:profile]).first - end - - if @profile - profile_hostname = @profile.hostname - if profile_hostname && profile_hostname != request.host - params.delete(:profile) - redirect_to(Noosfero.url_options.merge(params).merge(:host => profile_hostname)) - end - else - render_not_found - end - end - -end diff --git a/test/unit/custom_design_test.rb b/test/unit/custom_design_test.rb new file mode 100644 index 0000000..ebcfbfc --- /dev/null +++ b/test/unit/custom_design_test.rb @@ -0,0 +1,19 @@ +require_relative "../test_helper" + +class CustomDesignTest < ActionView::TestCase + + include CustomDesign + include ActionView::Helpers::TagHelper + + def setup + end + + should 'allow class instance customization of custom design' do + self.class.use_custom_design boxes_limit: 1 + assert_equal({boxes_limit: 1}, self.custom_design) + @custom_design = {boxes_limit: 2} + assert_equal({boxes_limit: 2}, self.custom_design) + + end + +end diff --git a/test/unit/design_helper_test.rb b/test/unit/design_helper_test.rb deleted file mode 100644 index b51ce75..0000000 --- a/test/unit/design_helper_test.rb +++ /dev/null @@ -1,20 +0,0 @@ -require_relative "../test_helper" -require 'boxes_helper' - -class DesignHelperTest < ActionView::TestCase - - include DesignHelper - include ActionView::Helpers::TagHelper - - def setup - end - - should 'allow class instance customization of custom design' do - self.class.use_custom_design boxes_limit: 1 - assert_equal({boxes_limit: 1}, self.custom_design) - @custom_design = {boxes_limit: 2} - assert_equal({boxes_limit: 2}, self.custom_design) - - end - -end -- libgit2 0.21.2