Implemented routing filter for foodcoop select.
* Allows now a multi coop installation for one domain! * SSL, we are coming... * TODO: Remove all the hardcoded urls, check email-links etc.
This commit is contained in:
parent
b9576dd669
commit
e7af7e82b5
4 changed files with 151 additions and 105 deletions
|
@ -23,128 +23,133 @@ class ApplicationController < ActionController::Base
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def current_user
|
def current_user
|
||||||
begin
|
begin
|
||||||
# check if there is a valid session and return the logged-in user (its object)
|
# check if there is a valid session and return the logged-in user (its object)
|
||||||
if session['user_and_subdomain']
|
if session['user_and_subdomain']
|
||||||
id, subdomain = session['user_and_subdomain'].split
|
id, subdomain = session['user_and_subdomain'].split
|
||||||
# for shared-host installations. check if the cookie-subdomain fits to request.
|
# for shared-host installations. check if the cookie-subdomain fits to request.
|
||||||
return User.current_user = User.find(id) if request.subdomains.first == subdomain
|
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
|
||||||
|
rescue
|
||||||
|
reset_session
|
||||||
|
flash[:error]= _("An error has occurred. Please login again.")
|
||||||
|
redirect_to :controller => 'login'
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def current_user=(user)
|
def current_user=(user)
|
||||||
session['user_and_subdomain'] = [user.id, request.subdomains.first].join(" ")
|
session['user_and_subdomain'] = [user.id, request.subdomains.first].join(" ")
|
||||||
end
|
end
|
||||||
|
|
||||||
def return_to
|
def return_to
|
||||||
session['return_to']
|
session['return_to']
|
||||||
end
|
end
|
||||||
|
|
||||||
def return_to=(uri)
|
def return_to=(uri)
|
||||||
session['return_to'] = uri
|
session['return_to'] = uri
|
||||||
end
|
end
|
||||||
|
|
||||||
def deny_access
|
def deny_access
|
||||||
self.return_to = request.request_uri
|
self.return_to = request.request_uri
|
||||||
redirect_to :controller => '/login', :action => 'denied'
|
redirect_to :controller => '/login', :action => 'denied'
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def authenticate(role = 'any')
|
def authenticate(role = 'any')
|
||||||
# Attempt to retrieve authenticated user from controller instance or session...
|
# Attempt to retrieve authenticated user from controller instance or session...
|
||||||
if !(user = current_user)
|
if !(user = current_user)
|
||||||
# No user at all: redirect to login page.
|
# No user at all: redirect to login page.
|
||||||
self.return_to = request.request_uri
|
self.return_to = request.request_uri
|
||||||
redirect_to :controller => '/login'
|
redirect_to :controller => '/login'
|
||||||
return false
|
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
|
else
|
||||||
# We have an authenticated user, now check role...
|
deny_access
|
||||||
# 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
|
|
||||||
end
|
end
|
||||||
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 authenticate_admin
|
||||||
def remove_controller
|
authenticate('admin')
|
||||||
Thread.current[:application_controller] = nil
|
end
|
||||||
end
|
|
||||||
|
def authenticate_finance
|
||||||
|
authenticate('finance')
|
||||||
|
end
|
||||||
|
|
||||||
|
def authenticate_article_meta
|
||||||
|
authenticate('article_meta')
|
||||||
|
end
|
||||||
|
|
||||||
# Get supplier in nested resources
|
def authenticate_suppliers
|
||||||
def find_supplier
|
authenticate('suppliers')
|
||||||
@supplier = Supplier.find(params[:supplier_id]) if params[:supplier_id]
|
end
|
||||||
end
|
|
||||||
|
|
||||||
# Set config and database connection for each request
|
def authenticate_orders
|
||||||
# It uses the subdomain to select the appropriate section in the config files
|
authenticate('orders')
|
||||||
# Use this method as a before filter (first filter!) in ApplicationController
|
end
|
||||||
def select_foodcoop
|
|
||||||
if Foodsoft.config[:multi_coop_install]
|
# checks if the current_user is member of given group.
|
||||||
# Get subdomain
|
# if fails the user will redirected to startpage
|
||||||
subdomain = request.subdomains.first
|
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
|
# Set Config
|
||||||
Foodsoft.env = subdomain
|
Foodsoft.env = params[:foodcoop]
|
||||||
# Set database-connection
|
# Set database-connection
|
||||||
ActiveRecord::Base.establish_connection(Foodsoft.database(subdomain))
|
ActiveRecord::Base.establish_connection(Foodsoft.database)
|
||||||
|
else
|
||||||
|
redirect_to root_path
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
# Deactivate routing filter
|
||||||
|
RoutingFilter::Foodcoop.active = false
|
||||||
end
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -68,6 +68,7 @@ Rails::Initializer.run do |config|
|
||||||
config.gem "fastercsv"
|
config.gem "fastercsv"
|
||||||
config.gem "prawn"
|
config.gem "prawn"
|
||||||
config.gem "haml", :version => '>=2.0.6'
|
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.
|
# 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.
|
# All files from config/locales/*.rb,yml are added automatically.
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
ActionController::Routing::Routes.draw do |map|
|
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.resources :pages, :collection => { :all => :get }, :member => {:version => :get, :revert => :get}
|
||||||
map.wiki_page "/wiki/:permalink", :controller => 'pages', :action => 'show', :permalink => /[^\s]+/
|
map.wiki_page "/wiki/:permalink", :controller => 'pages', :action => 'show', :permalink => /[^\s]+/
|
||||||
map.wiki "/wiki", :controller => 'pages', :action => 'show', :permalink => 'Home'
|
map.wiki "/wiki", :controller => 'pages', :action => 'show', :permalink => 'Home'
|
||||||
|
|
37
lib/foodcoop_filter.rb
Normal file
37
lib/foodcoop_filter.rb
Normal file
|
@ -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
|
Loading…
Reference in a new issue