diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 64160b21..4266de88 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -23,128 +23,133 @@ class ApplicationController < ActionController::Base protected - def current_user - begin - # check if there is a valid session and return the logged-in user (its object) - if session['user_and_subdomain'] - id, subdomain = session['user_and_subdomain'].split - # for shared-host installations. check if the cookie-subdomain fits to request. - return User.current_user = User.find(id) if request.subdomains.first == subdomain - end - rescue - reset_session - flash[:error]= _("An error has occurred. Please login again.") - redirect_to :controller => 'login' + def current_user + begin + # check if there is a valid session and return the logged-in user (its object) + if session['user_and_subdomain'] + id, subdomain = session['user_and_subdomain'].split + # for shared-host installations. check if the cookie-subdomain fits to request. + return User.current_user = User.find(id) if request.subdomains.first == subdomain end + rescue + reset_session + flash[:error]= _("An error has occurred. Please login again.") + redirect_to :controller => 'login' end + end - def current_user=(user) - session['user_and_subdomain'] = [user.id, request.subdomains.first].join(" ") - end + def current_user=(user) + session['user_and_subdomain'] = [user.id, request.subdomains.first].join(" ") + end - def return_to - session['return_to'] - end + def return_to + session['return_to'] + end - def return_to=(uri) - session['return_to'] = uri - end + def return_to=(uri) + session['return_to'] = uri + end - def deny_access - self.return_to = request.request_uri - redirect_to :controller => '/login', :action => 'denied' - return false - end + def deny_access + self.return_to = request.request_uri + redirect_to :controller => '/login', :action => 'denied' + return false + end private - def authenticate(role = 'any') - # Attempt to retrieve authenticated user from controller instance or session... - if !(user = current_user) - # No user at all: redirect to login page. - self.return_to = request.request_uri - redirect_to :controller => '/login' - return false + def authenticate(role = 'any') + # Attempt to retrieve authenticated user from controller instance or session... + if !(user = current_user) + # No user at all: redirect to login page. + self.return_to = request.request_uri + redirect_to :controller => '/login' + return false + else + # We have an authenticated user, now check role... + # Roles gets the user through his memberships. + hasRole = case role + when "admin" then user.role_admin? + when "finance" then user.role_finance? + when "article_meta" then user.role_article_meta? + when "suppliers" then user.role_suppliers? + when "orders" then user.role_orders? + when "any" then true # no role required + else false # any unknown role will always fail + end + if hasRole + @current_user = user else - # We have an authenticated user, now check role... - # Roles gets the user through his memberships. - hasRole = case role - when "admin" then user.role_admin? - when "finance" then user.role_finance? - when "article_meta" then user.role_article_meta? - when "suppliers" then user.role_suppliers? - when "orders" then user.role_orders? - when "any" then true # no role required - else false # any unknown role will always fail - end - if hasRole - @current_user = user - else - deny_access - end - end - end - - def authenticate_admin - authenticate('admin') - end - - def authenticate_finance - authenticate('finance') - end - - def authenticate_article_meta - authenticate('article_meta') - end - - def authenticate_suppliers - authenticate('suppliers') - end - - def authenticate_orders - authenticate('orders') - end - - # checks if the current_user is member of given group. - # if fails the user will redirected to startpage - def authenticate_membership_or_admin - @group = Group.find(params[:id]) - unless @group.member?(@current_user) or @current_user.role_admin? - flash[:error] = "Diese Aktion ist nur für Mitglieder der Gruppe erlaubt!" - if request.xml_http_request? - render(:update) {|page| page.redirect_to root_path } - else - redirect_to root_path - end + deny_access end end - - # Stores this controller instance as a thread local varibale to be accessible from outside ActionController/ActionView. - def store_controller - Thread.current[:application_controller] = self - end + end - # Sets the thread local variable that holds a reference to the current controller to nil. - def remove_controller - Thread.current[:application_controller] = nil - end + def authenticate_admin + authenticate('admin') + end + + def authenticate_finance + authenticate('finance') + end + + def authenticate_article_meta + authenticate('article_meta') + end - # Get supplier in nested resources - def find_supplier - @supplier = Supplier.find(params[:supplier_id]) if params[:supplier_id] - end + def authenticate_suppliers + authenticate('suppliers') + end - # Set config and database connection for each request - # It uses the subdomain to select the appropriate section in the config files - # Use this method as a before filter (first filter!) in ApplicationController - def select_foodcoop - if Foodsoft.config[:multi_coop_install] - # Get subdomain - subdomain = request.subdomains.first + def authenticate_orders + authenticate('orders') + end + + # checks if the current_user is member of given group. + # if fails the user will redirected to startpage + def authenticate_membership_or_admin + @group = Group.find(params[:id]) + unless @group.member?(@current_user) or @current_user.role_admin? + flash[:error] = "Diese Aktion ist nur für Mitglieder der Gruppe erlaubt!" + if request.xml_http_request? + render(:update) {|page| page.redirect_to root_path } + else + redirect_to root_path + end + end + end + + # Stores this controller instance as a thread local varibale to be accessible from outside ActionController/ActionView. + def store_controller + Thread.current[:application_controller] = self + end + + # Sets the thread local variable that holds a reference to the current controller to nil. + def remove_controller + Thread.current[:application_controller] = nil + end + + # Get supplier in nested resources + def find_supplier + @supplier = Supplier.find(params[:supplier_id]) if params[:supplier_id] + end + + # Set config and database connection for each request + # It uses the subdomain to select the appropriate section in the config files + # Use this method as a before filter (first filter!) in ApplicationController + def select_foodcoop + if Foodsoft.config[:multi_coop_install] + if !params[:foodcoop].blank? # Set Config - Foodsoft.env = subdomain + Foodsoft.env = params[:foodcoop] # Set database-connection - ActiveRecord::Base.establish_connection(Foodsoft.database(subdomain)) + ActiveRecord::Base.establish_connection(Foodsoft.database) + else + redirect_to root_path end + else + # Deactivate routing filter + RoutingFilter::Foodcoop.active = false end + end end diff --git a/config/environment.rb b/config/environment.rb index 0289b71a..94f56d76 100644 --- a/config/environment.rb +++ b/config/environment.rb @@ -68,6 +68,7 @@ Rails::Initializer.run do |config| config.gem "fastercsv" config.gem "prawn" config.gem "haml", :version => '>=2.0.6' + config.gem "routing-filter", :lib => "routing_filter" # The internationalization framework can be changed to have another default locale (standard is :en) or more load paths. # All files from config/locales/*.rb,yml are added automatically. diff --git a/config/routes.rb b/config/routes.rb index a8fcaa91..6506e4cd 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,4 +1,7 @@ ActionController::Routing::Routes.draw do |map| + + map.filter 'foodcoop', :file => File.join(RAILS_ROOT, "lib", "foodcoop_filter") + map.resources :pages, :collection => { :all => :get }, :member => {:version => :get, :revert => :get} map.wiki_page "/wiki/:permalink", :controller => 'pages', :action => 'show', :permalink => /[^\s]+/ map.wiki "/wiki", :controller => 'pages', :action => 'show', :permalink => 'Home' diff --git a/lib/foodcoop_filter.rb b/lib/foodcoop_filter.rb new file mode 100644 index 00000000..0505e96a --- /dev/null +++ b/lib/foodcoop_filter.rb @@ -0,0 +1,37 @@ +require 'routing_filter/base' + +module RoutingFilter + class Foodcoop < Base + def around_recognize(path, env, &block) + token = extract_token!(path) # remove the token from the beginning of the path + returning yield do |params| # invoke the given block (calls more filters and finally routing) + params[:foodcoop] = token if token # set recognized token to the resulting params hash + end + end + + def around_generate(*args, &block) + token = args.extract_options!.delete(:foodcoop) # extract the passed :token option + token = Foodsoft.env if token.nil? # default to Foodsoft.env + + returning yield do |result| + if token + url = result.is_a?(Array) ? result.first : result + prepend_token!(url, token) + end + end + end + + protected + + def extract_token!(path) + foodcoop = nil + path.sub! %r(^/([a-zA-Z0-9]*)(?=/|$)) do foodcoop = $1; '' end + foodcoop + end + + def prepend_token!(url, token) + url.sub!(%r(^(http.?://[^/]*)?(.*))) { "#{$1}/#{token}#{$2}" } + end + + end +end \ No newline at end of file