Prepare for API v1 (PR #570)
This commit is contained in:
parent
d9ae0d11b0
commit
fd96b6ccc1
21 changed files with 536 additions and 217 deletions
4
Gemfile
4
Gemfile
|
@ -3,7 +3,6 @@ source "https://rubygems.org"
|
||||||
|
|
||||||
gem "rails", '~> 4.2'
|
gem "rails", '~> 4.2'
|
||||||
|
|
||||||
|
|
||||||
gem 'sass-rails'
|
gem 'sass-rails'
|
||||||
gem 'less-rails'
|
gem 'less-rails'
|
||||||
gem 'uglifier', '>= 1.0.3'
|
gem 'uglifier', '>= 1.0.3'
|
||||||
|
@ -30,6 +29,9 @@ gem 'simple_form'
|
||||||
gem 'inherited_resources'
|
gem 'inherited_resources'
|
||||||
gem 'localize_input', git: "https://github.com/bennibu/localize_input.git"
|
gem 'localize_input', git: "https://github.com/bennibu/localize_input.git"
|
||||||
gem 'daemons'
|
gem 'daemons'
|
||||||
|
gem 'doorkeeper'
|
||||||
|
gem 'doorkeeper-i18n'
|
||||||
|
gem 'rack-cors', require: 'rack/cors'
|
||||||
gem 'twitter-bootstrap-rails', '~> 2.2.8'
|
gem 'twitter-bootstrap-rails', '~> 2.2.8'
|
||||||
gem 'simple-navigation', '~> 3.14.0' # 3.x for simple_navigation_bootstrap
|
gem 'simple-navigation', '~> 3.14.0' # 3.x for simple_navigation_bootstrap
|
||||||
gem 'simple-navigation-bootstrap'
|
gem 'simple-navigation-bootstrap'
|
||||||
|
|
|
@ -148,6 +148,9 @@ GEM
|
||||||
diff-lcs (1.3)
|
diff-lcs (1.3)
|
||||||
diffy (3.2.1)
|
diffy (3.2.1)
|
||||||
docile (1.3.1)
|
docile (1.3.1)
|
||||||
|
doorkeeper (5.0.1)
|
||||||
|
railties (>= 4.2)
|
||||||
|
doorkeeper-i18n (4.0.0)
|
||||||
email_reply_trimmer (0.1.12)
|
email_reply_trimmer (0.1.12)
|
||||||
erubi (1.7.1)
|
erubi (1.7.1)
|
||||||
erubis (2.7.0)
|
erubis (2.7.0)
|
||||||
|
@ -284,6 +287,7 @@ GEM
|
||||||
rack (1.6.10)
|
rack (1.6.10)
|
||||||
rack-contrib (1.8.0)
|
rack-contrib (1.8.0)
|
||||||
rack (~> 1.4)
|
rack (~> 1.4)
|
||||||
|
rack-cors (1.0.2)
|
||||||
rack-protection (1.5.5)
|
rack-protection (1.5.5)
|
||||||
rack
|
rack
|
||||||
rack-test (0.6.3)
|
rack-test (0.6.3)
|
||||||
|
@ -498,6 +502,8 @@ DEPENDENCIES
|
||||||
daemons
|
daemons
|
||||||
database_cleaner
|
database_cleaner
|
||||||
date_time_attribute
|
date_time_attribute
|
||||||
|
doorkeeper
|
||||||
|
doorkeeper-i18n
|
||||||
exception_notification
|
exception_notification
|
||||||
factory_bot_rails
|
factory_bot_rails
|
||||||
faker
|
faker
|
||||||
|
@ -526,6 +532,7 @@ DEPENDENCIES
|
||||||
pry-rescue
|
pry-rescue
|
||||||
pry-stack_explorer
|
pry-stack_explorer
|
||||||
quiet_assets
|
quiet_assets
|
||||||
|
rack-cors
|
||||||
rails (~> 4.2)
|
rails (~> 4.2)
|
||||||
rails-assets-listjs (= 0.2.0.beta.4)
|
rails-assets-listjs (= 0.2.0.beta.4)
|
||||||
rails-i18n
|
rails-i18n
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
class Admin::BaseController < ApplicationController
|
class Admin::BaseController < ApplicationController
|
||||||
before_filter :authenticate_admin
|
before_filter :authenticate_admin
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@user = self.current_user
|
@user = current_user
|
||||||
@groups = Group.where(deleted_at: nil).order('created_on DESC').limit(10)
|
@groups = Group.where(deleted_at: nil).order('created_on DESC').limit(10)
|
||||||
@users = User.order('created_on DESC').limit(10)
|
@users = User.order('created_on DESC').limit(10)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
60
app/controllers/api/v1/base_controller.rb
Normal file
60
app/controllers/api/v1/base_controller.rb
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
class Api::V1::BaseController < ApplicationController
|
||||||
|
protect_from_forgery with: :null_session
|
||||||
|
|
||||||
|
before_action :skip_session
|
||||||
|
rescue_from ActiveRecord::RecordNotFound, with: :not_found_handler
|
||||||
|
rescue_from ActiveRecord::RecordNotSaved, with: :not_acceptable_handler
|
||||||
|
rescue_from ActiveRecord::RecordInvalid, with: :not_acceptable_handler
|
||||||
|
rescue_from Api::Errors::PermissionRequired, with: :permission_required_handler
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def authenticate
|
||||||
|
doorkeeper_authorize!
|
||||||
|
super if current_user
|
||||||
|
end
|
||||||
|
|
||||||
|
# @return [User] Current user, or +nil+ if no valid token.
|
||||||
|
def current_user
|
||||||
|
@current_user ||= User.undeleted.find(doorkeeper_token.resource_owner_id) if doorkeeper_token
|
||||||
|
end
|
||||||
|
|
||||||
|
# @return [Ordergroup] Current user's ordergroup, or +nil+ if no valid token or user has no ordergroup.
|
||||||
|
def current_ordergroup
|
||||||
|
current_user.try(:ordergroup)
|
||||||
|
end
|
||||||
|
|
||||||
|
def require_ordergroup
|
||||||
|
authenticate
|
||||||
|
raise Api::Errors::PermissionRequired unless current_user.ordergroup.present?
|
||||||
|
end
|
||||||
|
|
||||||
|
def skip_session
|
||||||
|
request.session_options[:skip] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
def not_found_handler(e)
|
||||||
|
# remove where-clauses from error message (not suitable for end-users)
|
||||||
|
msg = e.message.try {|m| m.sub(/\s*\[.*?\]\s*$/, '')} || 'Not found'
|
||||||
|
render status: 404, json: {error: 'not_found', error_description: msg}
|
||||||
|
end
|
||||||
|
|
||||||
|
def not_acceptable_handler(e)
|
||||||
|
render status: 422, json: {error: 'not_acceptable', error_description: e.message || 'Data not acceptable' }
|
||||||
|
end
|
||||||
|
|
||||||
|
def doorkeeper_unauthorized_render_options(error:)
|
||||||
|
{json: {error: error.name, error_description: error.description}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def permission_required_handler(e)
|
||||||
|
msg = e.message || 'Forbidden, user has no access'
|
||||||
|
render status: 403, json: {error: 'forbidden', error_description: msg}
|
||||||
|
end
|
||||||
|
|
||||||
|
# @todo something with ApplicationHelper#show_user
|
||||||
|
def show_user(user = current_user, **options)
|
||||||
|
user.display
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -1,142 +1,24 @@
|
||||||
# encoding: utf-8
|
# encoding: utf-8
|
||||||
class ApplicationController < ActionController::Base
|
class ApplicationController < ActionController::Base
|
||||||
include Foodsoft::ControllerExtensions::Locale
|
include Concerns::FoodcoopScope
|
||||||
|
include Concerns::Auth
|
||||||
|
include Concerns::Locale
|
||||||
|
helper_method :current_user
|
||||||
helper_method :available_locales
|
helper_method :available_locales
|
||||||
|
|
||||||
protect_from_forgery
|
protect_from_forgery
|
||||||
before_filter :select_foodcoop, :authenticate, :set_user_last_activity, :store_controller, :items_per_page
|
before_filter :authenticate, :set_user_last_activity, :store_controller, :items_per_page
|
||||||
after_filter :remove_controller
|
after_filter :remove_controller
|
||||||
around_filter :set_time_zone, :set_currency
|
around_filter :set_time_zone, :set_currency
|
||||||
|
|
||||||
|
|
||||||
# Returns the controller handling the current request.
|
# Returns the controller handling the current request.
|
||||||
def self.current
|
def self.current
|
||||||
Thread.current[:application_controller]
|
Thread.current[:application_controller]
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
|
||||||
|
|
||||||
def current_user
|
|
||||||
# check if there is a valid session and return the logged-in user (its object)
|
|
||||||
if session[:user_id] && params[:foodcoop]
|
|
||||||
# for shared-host installations. check if the cookie-subdomain fits to request.
|
|
||||||
@current_user ||= User.undeleted.find_by_id(session[:user_id]) if session[:scope] == FoodsoftConfig.scope
|
|
||||||
end
|
|
||||||
end
|
|
||||||
helper_method :current_user
|
|
||||||
|
|
||||||
def deny_access
|
|
||||||
session[:return_to] = request.original_url
|
|
||||||
redirect_to root_url, alert: I18n.t('application.controller.error_denied', sign_in: ActionController::Base.helpers.link_to(t('application.controller.error_denied_sign_in'), login_path))
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def login(user)
|
|
||||||
session[:user_id] = user.id
|
|
||||||
session[:scope] = FoodsoftConfig.scope # Save scope in session to not allow switching between foodcoops with one account
|
|
||||||
session[:locale] = user.locale
|
|
||||||
end
|
|
||||||
|
|
||||||
def login_and_redirect_to_return_to(user, *args)
|
|
||||||
login user
|
|
||||||
if session[:return_to].present?
|
|
||||||
redirect_to_url = session[:return_to]
|
|
||||||
session[:return_to] = nil
|
|
||||||
else
|
|
||||||
redirect_to_url = root_url
|
|
||||||
end
|
|
||||||
redirect_to redirect_to_url, *args
|
|
||||||
end
|
|
||||||
|
|
||||||
def logout
|
|
||||||
session[:user_id] = nil
|
|
||||||
session[:return_to] = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
def authenticate(role = 'any')
|
|
||||||
# Attempt to retrieve authenticated user from controller instance or session...
|
|
||||||
if !current_user
|
|
||||||
# No user at all: redirect to login page.
|
|
||||||
logout
|
|
||||||
session[:return_to] = request.original_url
|
|
||||||
redirect_to_login :alert => I18n.t('application.controller.error_authn')
|
|
||||||
else
|
|
||||||
# We have an authenticated user, now check role...
|
|
||||||
# Roles gets the user through his memberships.
|
|
||||||
hasRole = case role
|
|
||||||
when "admin" then current_user.role_admin?
|
|
||||||
when "finance" then current_user.role_finance?
|
|
||||||
when "article_meta" then current_user.role_article_meta?
|
|
||||||
when "pickups" then current_user.role_pickups?
|
|
||||||
when "suppliers" then current_user.role_suppliers?
|
|
||||||
when "orders" then current_user.role_orders?
|
|
||||||
when "finance_or_orders" then (current_user.role_finance? || current_user.role_orders?)
|
|
||||||
when "pickups_or_orders" then (current_user.role_pickups? || current_user.role_orders?)
|
|
||||||
when "any" then true # no role required
|
|
||||||
else false # any unknown role will always fail
|
|
||||||
end
|
|
||||||
if hasRole
|
|
||||||
current_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_pickups
|
|
||||||
authenticate('pickups')
|
|
||||||
end
|
|
||||||
|
|
||||||
def authenticate_suppliers
|
|
||||||
authenticate('suppliers')
|
|
||||||
end
|
|
||||||
|
|
||||||
def authenticate_orders
|
|
||||||
authenticate('orders')
|
|
||||||
end
|
|
||||||
|
|
||||||
def authenticate_finance_or_orders
|
|
||||||
authenticate('finance_or_orders')
|
|
||||||
end
|
|
||||||
|
|
||||||
def authenticate_pickups_or_orders
|
|
||||||
authenticate('pickups_or_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_id = params[:id])
|
|
||||||
@group = Group.find(group_id)
|
|
||||||
unless @group.member?(@current_user) || @current_user.role_admin?
|
|
||||||
redirect_to root_path, alert: I18n.t('application.controller.error_members_only')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def authenticate_or_token(prefix, role = 'any')
|
|
||||||
if not params[:token].blank?
|
|
||||||
begin
|
|
||||||
TokenVerifier.new(prefix).verify(params[:token])
|
|
||||||
rescue ActiveSupport::MessageVerifier::InvalidSignature
|
|
||||||
redirect_to root_path, alert: I18n.t('application.controller.error_token')
|
|
||||||
end
|
|
||||||
else
|
|
||||||
authenticate(role)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def set_user_last_activity
|
def set_user_last_activity
|
||||||
if current_user && (session[:last_activity] == nil || session[:last_activity] < 1.minutes.ago)
|
if current_user && (session[:last_activity] == nil || session[:last_activity] < 1.minutes.ago)
|
||||||
current_user.update_attribute(:last_activity, Time.now)
|
current_user.update_attribute(:last_activity, Time.now)
|
||||||
|
@ -167,16 +49,11 @@ class ApplicationController < ActionController::Base
|
||||||
redirect_to root_path, alert: I18n.t('application.controller.error_feature_disabled')
|
redirect_to root_path, alert: I18n.t('application.controller.error_feature_disabled')
|
||||||
end
|
end
|
||||||
|
|
||||||
# Redirect to the login page, used in authenticate, plugins can override this.
|
|
||||||
def redirect_to_login(options={})
|
|
||||||
redirect_to login_url, options
|
|
||||||
end
|
|
||||||
|
|
||||||
# Stores this controller instance as a thread local varibale to be accessible from outside ActionController/ActionView.
|
# Stores this controller instance as a thread local varibale to be accessible from outside ActionController/ActionView.
|
||||||
def store_controller
|
def store_controller
|
||||||
Thread.current[:application_controller] = self
|
Thread.current[:application_controller] = self
|
||||||
end
|
end
|
||||||
|
|
||||||
# Sets the thread local variable that holds a reference to the current controller to nil.
|
# Sets the thread local variable that holds a reference to the current controller to nil.
|
||||||
def remove_controller
|
def remove_controller
|
||||||
Thread.current[:application_controller] = nil
|
Thread.current[:application_controller] = nil
|
||||||
|
@ -187,23 +64,6 @@ class ApplicationController < ActionController::Base
|
||||||
@supplier = Supplier.find(params[:supplier_id]) if params[:supplier_id]
|
@supplier = Supplier.find(params[:supplier_id]) if params[:supplier_id]
|
||||||
end
|
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
|
|
||||||
return unless FoodsoftConfig[:multi_coop_install]
|
|
||||||
|
|
||||||
foodcoop = params[:foodcoop]
|
|
||||||
if foodcoop.blank?
|
|
||||||
FoodsoftConfig.select_default_foodcoop
|
|
||||||
redirect_to root_url
|
|
||||||
elsif FoodsoftConfig.allowed_foodcoop? foodcoop
|
|
||||||
FoodsoftConfig.select_foodcoop foodcoop
|
|
||||||
else
|
|
||||||
raise ActionController::RoutingError.new 'Foodcoop Not Found'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def items_per_page
|
def items_per_page
|
||||||
if params[:per_page] && params[:per_page].to_i > 0 && params[:per_page].to_i <= 500
|
if params[:per_page] && params[:per_page].to_i > 0 && params[:per_page].to_i <= 500
|
||||||
@per_page = params[:per_page].to_i
|
@per_page = params[:per_page].to_i
|
||||||
|
@ -212,11 +72,6 @@ class ApplicationController < ActionController::Base
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Always stay in foodcoop url scope
|
|
||||||
def default_url_options(options = {})
|
|
||||||
{foodcoop: FoodsoftConfig.scope}
|
|
||||||
end
|
|
||||||
|
|
||||||
# Set timezone according to foodcoop preference.
|
# Set timezone according to foodcoop preference.
|
||||||
# @see http://stackoverflow.com/questions/4362663/timezone-with-rails-3
|
# @see http://stackoverflow.com/questions/4362663/timezone-with-rails-3
|
||||||
# @see http://archives.ryandaigle.com/articles/2008/1/25/what-s-new-in-edge-rails-easier-timezones
|
# @see http://archives.ryandaigle.com/articles/2008/1/25/what-s-new-in-edge-rails-easier-timezones
|
||||||
|
|
148
app/controllers/concerns/auth.rb
Normal file
148
app/controllers/concerns/auth.rb
Normal file
|
@ -0,0 +1,148 @@
|
||||||
|
# Controller concern for authentication methods
|
||||||
|
#
|
||||||
|
# Split off from main +ApplicationController+ to allow e.g.
|
||||||
|
# Doorkeeper to use it too.
|
||||||
|
module Concerns::Auth
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def current_user
|
||||||
|
# check if there is a valid session and return the logged-in user (its object)
|
||||||
|
if session[:user_id] && params[:foodcoop]
|
||||||
|
# for shared-host installations. check if the cookie-subdomain fits to request.
|
||||||
|
@current_user ||= User.undeleted.find_by_id(session[:user_id]) if session[:scope] == FoodsoftConfig.scope
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def deny_access
|
||||||
|
session[:return_to] = request.original_url
|
||||||
|
redirect_to root_url, alert: I18n.t('application.controller.error_denied', sign_in: ActionController::Base.helpers.link_to(t('application.controller.error_denied_sign_in'), login_path))
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def login(user)
|
||||||
|
session[:user_id] = user.id
|
||||||
|
session[:scope] = FoodsoftConfig.scope # Save scope in session to not allow switching between foodcoops with one account
|
||||||
|
session[:locale] = user.locale
|
||||||
|
end
|
||||||
|
|
||||||
|
def login_and_redirect_to_return_to(user, *args)
|
||||||
|
login user
|
||||||
|
if session[:return_to].present?
|
||||||
|
redirect_to_url = session[:return_to]
|
||||||
|
session[:return_to] = nil
|
||||||
|
else
|
||||||
|
redirect_to_url = root_url
|
||||||
|
end
|
||||||
|
redirect_to redirect_to_url, *args
|
||||||
|
end
|
||||||
|
|
||||||
|
def logout
|
||||||
|
session[:user_id] = nil
|
||||||
|
session[:return_to] = nil
|
||||||
|
expire_access_tokens
|
||||||
|
end
|
||||||
|
|
||||||
|
def authenticate(role = 'any')
|
||||||
|
# Attempt to retrieve authenticated user from controller instance or session...
|
||||||
|
if !current_user
|
||||||
|
# No user at all: redirect to login page.
|
||||||
|
logout
|
||||||
|
session[:return_to] = request.original_url
|
||||||
|
redirect_to_login :alert => I18n.t('application.controller.error_authn')
|
||||||
|
else
|
||||||
|
# We have an authenticated user, now check role...
|
||||||
|
# Roles gets the user through his memberships.
|
||||||
|
hasRole = case role
|
||||||
|
when 'admin' then current_user.role_admin?
|
||||||
|
when 'finance' then current_user.role_finance?
|
||||||
|
when 'article_meta' then current_user.role_article_meta?
|
||||||
|
when 'pickups' then current_user.role_pickups?
|
||||||
|
when 'suppliers' then current_user.role_suppliers?
|
||||||
|
when 'orders' then current_user.role_orders?
|
||||||
|
when 'finance_or_orders' then (current_user.role_finance? || current_user.role_orders?)
|
||||||
|
when 'pickups_or_orders' then (current_user.role_pickups? || current_user.role_orders?)
|
||||||
|
when 'any' then true # no role required
|
||||||
|
else false # any unknown role will always fail
|
||||||
|
end
|
||||||
|
if hasRole
|
||||||
|
current_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_pickups
|
||||||
|
authenticate('pickups')
|
||||||
|
end
|
||||||
|
|
||||||
|
def authenticate_suppliers
|
||||||
|
authenticate('suppliers')
|
||||||
|
end
|
||||||
|
|
||||||
|
def authenticate_orders
|
||||||
|
authenticate('orders')
|
||||||
|
end
|
||||||
|
|
||||||
|
def authenticate_finance_or_orders
|
||||||
|
authenticate('finance_or_orders')
|
||||||
|
end
|
||||||
|
|
||||||
|
def authenticate_pickups_or_orders
|
||||||
|
authenticate('pickups_or_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_id = params[:id])
|
||||||
|
@group = Group.find(group_id)
|
||||||
|
unless @group.member?(@current_user) || @current_user.role_admin?
|
||||||
|
redirect_to root_path, alert: I18n.t('application.controller.error_members_only')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def authenticate_or_token(prefix, role = 'any')
|
||||||
|
if not params[:token].blank?
|
||||||
|
begin
|
||||||
|
TokenVerifier.new(prefix).verify(params[:token])
|
||||||
|
rescue ActiveSupport::MessageVerifier::InvalidSignature
|
||||||
|
redirect_to root_path, alert: I18n.t('application.controller.error_token')
|
||||||
|
end
|
||||||
|
else
|
||||||
|
authenticate(role)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Expires any access tokens for the current user (unless they have the 'offline_access' scope)
|
||||||
|
# @see https://github.com/doorkeeper-gem/doorkeeper/issues/71#issuecomment-5471317
|
||||||
|
def expire_access_tokens
|
||||||
|
return unless @current_user
|
||||||
|
Doorkeeper::AccessToken.transaction do
|
||||||
|
token_scope = Doorkeeper::AccessToken.where(revoked_at: nil, resource_owner_id: @current_user.id)
|
||||||
|
token_scope.each do |token|
|
||||||
|
token.destroy! unless token.scopes.include?('offline_access')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Redirect to the login page, used in authenticate, plugins can override this.
|
||||||
|
def redirect_to_login(options={})
|
||||||
|
redirect_to login_url, options
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
36
app/controllers/concerns/foodcoop_scope.rb
Normal file
36
app/controllers/concerns/foodcoop_scope.rb
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
# Controller concern to handle foodcoop scope
|
||||||
|
#
|
||||||
|
# Includes a +before_filter+ for selecting foodcoop from url.
|
||||||
|
#
|
||||||
|
module Concerns::FoodcoopScope
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
included do
|
||||||
|
before_filter :select_foodcoop
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
# 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
|
||||||
|
return unless FoodsoftConfig[:multi_coop_install]
|
||||||
|
|
||||||
|
foodcoop = params[:foodcoop]
|
||||||
|
if foodcoop.blank?
|
||||||
|
FoodsoftConfig.select_default_foodcoop
|
||||||
|
redirect_to root_url
|
||||||
|
elsif FoodsoftConfig.allowed_foodcoop? foodcoop
|
||||||
|
FoodsoftConfig.select_foodcoop foodcoop
|
||||||
|
else
|
||||||
|
raise ActionController::RoutingError.new 'Foodcoop Not Found'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Always stay in foodcoop url scope
|
||||||
|
def default_url_options(options = {})
|
||||||
|
super().merge({foodcoop: FoodsoftConfig.scope})
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
51
app/controllers/concerns/locale.rb
Normal file
51
app/controllers/concerns/locale.rb
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
module Concerns::Locale
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
included do
|
||||||
|
before_filter :set_locale
|
||||||
|
end
|
||||||
|
|
||||||
|
def explicitly_requested_language
|
||||||
|
params[:locale]
|
||||||
|
end
|
||||||
|
|
||||||
|
def user_settings_language
|
||||||
|
current_user&.locale
|
||||||
|
end
|
||||||
|
|
||||||
|
def session_language
|
||||||
|
session[:locale]
|
||||||
|
end
|
||||||
|
|
||||||
|
def browser_language
|
||||||
|
request.env['HTTP_ACCEPT_LANGUAGE'] ? request.env['HTTP_ACCEPT_LANGUAGE'].scan(/^[a-z]{2}/).first : nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def default_language
|
||||||
|
FoodsoftConfig[:default_locale] || ::I18n.default_locale
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def select_language_according_to_priority
|
||||||
|
language = explicitly_requested_language || session_language || user_settings_language
|
||||||
|
language ||= browser_language unless FoodsoftConfig[:ignore_browser_locale]
|
||||||
|
language.presence&.to_sym unless language.blank?
|
||||||
|
end
|
||||||
|
|
||||||
|
def available_locales
|
||||||
|
::I18n.available_locales
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_locale
|
||||||
|
if available_locales.include?(select_language_according_to_priority)
|
||||||
|
::I18n.locale = select_language_according_to_priority
|
||||||
|
else
|
||||||
|
::I18n.locale = default_language
|
||||||
|
end
|
||||||
|
|
||||||
|
locale = session[:locale] = ::I18n.locale
|
||||||
|
logger.info("Set locale to #{locale}")
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -6,6 +6,8 @@
|
||||||
- url = action_name == 'show' ? nil : admin_config_path(tab: tab)
|
- url = action_name == 'show' ? nil : admin_config_path(tab: tab)
|
||||||
%li{class: ('active' if @current_tab==tab)}= link_to t("config.tabs.#{tab}"), "#{url}#tab-#{tab}", data: ({toggle: 'tab'} unless url)
|
%li{class: ('active' if @current_tab==tab)}= link_to t("config.tabs.#{tab}"), "#{url}#tab-#{tab}", data: ({toggle: 'tab'} unless url)
|
||||||
|
|
||||||
-# make this a button to give some indicator that navigation away might lose changes
|
-# make these buttons to give some indicator that navigation away might lose changes
|
||||||
%li.pull-right{class: ('active' if @current_tab=='list')}
|
%li.pull-right{class: ('active' if @current_tab=='list')}
|
||||||
= link_to t('config.tabs.list'), list_admin_config_path, class: ('btn' unless @current_tab=='list')
|
= link_to t('config.tabs.list'), list_admin_config_path, class: ('btn' unless @current_tab=='list')
|
||||||
|
%li.pull-right
|
||||||
|
= link_to t('config.tabs.applications'), oauth_applications_path, class: 'btn'
|
||||||
|
|
|
@ -6,6 +6,7 @@ default: &defaults
|
||||||
multi_coop_install: false
|
multi_coop_install: false
|
||||||
|
|
||||||
# If multi_coop_install you have to use a coop name, which you you wanna be selected by default
|
# If multi_coop_install you have to use a coop name, which you you wanna be selected by default
|
||||||
|
# Please use basic characters for scope names, matching /[-a-zA-Z0-9_]+/
|
||||||
default_scope: 'f'
|
default_scope: 'f'
|
||||||
|
|
||||||
# name of this foodcoop
|
# name of this foodcoop
|
||||||
|
|
|
@ -48,7 +48,7 @@ module Foodsoft
|
||||||
# parameters by using an attr_accessible or attr_protected declaration.
|
# parameters by using an attr_accessible or attr_protected declaration.
|
||||||
# TODO Re-activate this. Uncommenting this line will currently cause rspec to fail.
|
# TODO Re-activate this. Uncommenting this line will currently cause rspec to fail.
|
||||||
config.active_record.whitelist_attributes = false
|
config.active_record.whitelist_attributes = false
|
||||||
|
|
||||||
# Enable the asset pipeline
|
# Enable the asset pipeline
|
||||||
config.assets.enabled = true
|
config.assets.enabled = true
|
||||||
|
|
||||||
|
@ -62,6 +62,14 @@ module Foodsoft
|
||||||
# Load legacy scripts from vendor
|
# Load legacy scripts from vendor
|
||||||
config.assets.precompile += [ 'vendor/assets/javascripts/*.js' ]
|
config.assets.precompile += [ 'vendor/assets/javascripts/*.js' ]
|
||||||
|
|
||||||
|
# CORS for API
|
||||||
|
config.middleware.insert_before 0, 'Rack::Cors' do
|
||||||
|
allow do
|
||||||
|
origins '*'
|
||||||
|
# this restricts Foodsoft scopes to certain characters - let's discuss it when it becomes an actual problem
|
||||||
|
resource %r{\A/[-a-zA-Z0-9_]+/api/v1/}, headers: :any, methods: :any
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Foodsoft version
|
# Foodsoft version
|
||||||
|
|
113
config/initializers/doorkeeper.rb
Normal file
113
config/initializers/doorkeeper.rb
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
Doorkeeper.configure do
|
||||||
|
# Change the ORM that doorkeeper will use (needs plugins)
|
||||||
|
orm :active_record
|
||||||
|
|
||||||
|
# This block will be called to check whether the resource owner is authenticated or not.
|
||||||
|
resource_owner_authenticator do
|
||||||
|
authenticate
|
||||||
|
end
|
||||||
|
|
||||||
|
resource_owner_from_credentials do
|
||||||
|
User.authenticate(params[:username], params[:password])
|
||||||
|
end
|
||||||
|
|
||||||
|
admin_authenticator do
|
||||||
|
authenticate_admin
|
||||||
|
end
|
||||||
|
|
||||||
|
# Authorization Code expiration time (default 10 minutes).
|
||||||
|
# authorization_code_expires_in 10.minutes
|
||||||
|
|
||||||
|
# Access token expiration time (default 2 hours).
|
||||||
|
# If you want to disable expiration, set this to nil.
|
||||||
|
# access_token_expires_in 2.hours
|
||||||
|
|
||||||
|
# Assign a custom TTL for implicit grants.
|
||||||
|
# custom_access_token_expires_in do |oauth_client|
|
||||||
|
# oauth_client.application.additional_settings.implicit_oauth_expiration
|
||||||
|
# end
|
||||||
|
|
||||||
|
# Use a custom class for generating the access token.
|
||||||
|
# https://github.com/doorkeeper-gem/doorkeeper#custom-access-token-generator
|
||||||
|
# access_token_generator "::Doorkeeper::JWT"
|
||||||
|
|
||||||
|
# Reuse access token for the same resource owner within an application (disabled by default)
|
||||||
|
# Rationale: https://github.com/doorkeeper-gem/doorkeeper/issues/383
|
||||||
|
# reuse_access_token
|
||||||
|
|
||||||
|
# Issue access tokens with refresh token (disabled by default)
|
||||||
|
use_refresh_token
|
||||||
|
|
||||||
|
# Provide support for an owner to be assigned to each registered application (disabled by default)
|
||||||
|
# Optional parameter :confirmation => true (default false) if you want to enforce ownership of
|
||||||
|
# a registered application
|
||||||
|
# Note: you must also run the rails g doorkeeper:application_owner generator to provide the necessary support
|
||||||
|
# enable_application_owner :confirmation => false
|
||||||
|
|
||||||
|
# Define access token scopes for your provider
|
||||||
|
# For more information go to
|
||||||
|
# https://github.com/doorkeeper-gem/doorkeeper/wiki/Using-Scopes
|
||||||
|
# default_scopes :public
|
||||||
|
# optional_scopes :write, :update
|
||||||
|
|
||||||
|
# Change the way client credentials are retrieved from the request object.
|
||||||
|
# By default it retrieves first from the `HTTP_AUTHORIZATION` header, then
|
||||||
|
# falls back to the `:client_id` and `:client_secret` params from the `params` object.
|
||||||
|
# Check out the wiki for more information on customization
|
||||||
|
# client_credentials :from_basic, :from_params
|
||||||
|
|
||||||
|
# Change the way access token is authenticated from the request object.
|
||||||
|
# By default it retrieves first from the `HTTP_AUTHORIZATION` header, then
|
||||||
|
# falls back to the `:access_token` or `:bearer_token` params from the `params` object.
|
||||||
|
# Check out the wiki for more information on customization
|
||||||
|
# access_token_methods :from_bearer_authorization, :from_access_token_param, :from_bearer_param
|
||||||
|
|
||||||
|
# Change the native redirect uri for client apps
|
||||||
|
# When clients register with the following redirect uri, they won't be redirected to any server and the authorization code will be displayed within the provider
|
||||||
|
# The value can be any string. Use nil to disable this feature. When disabled, clients must provide a valid URL
|
||||||
|
# (Similar behaviour: https://developers.google.com/accounts/docs/OAuth2InstalledApp#choosingredirecturi)
|
||||||
|
#
|
||||||
|
# native_redirect_uri 'urn:ietf:wg:oauth:2.0:oob'
|
||||||
|
|
||||||
|
# Forces the usage of the HTTPS protocol in non-native redirect uris (enabled
|
||||||
|
# by default in non-development environments). OAuth2 delegates security in
|
||||||
|
# communication to the HTTPS protocol so it is wise to keep this enabled.
|
||||||
|
#
|
||||||
|
# force_ssl_in_redirect_uri !Rails.env.development?
|
||||||
|
|
||||||
|
# Specify what grant flows are enabled in array of Strings. The valid
|
||||||
|
# strings and the flows they enable are:
|
||||||
|
#
|
||||||
|
# "authorization_code" => Authorization Code Grant Flow
|
||||||
|
# "implicit" => Implicit Grant Flow
|
||||||
|
# "password" => Resource Owner Password Credentials Grant Flow
|
||||||
|
# "client_credentials" => Client Credentials Grant Flow
|
||||||
|
#
|
||||||
|
# If not specified, Doorkeeper enables authorization_code and
|
||||||
|
# client_credentials.
|
||||||
|
#
|
||||||
|
# implicit and password grant flows have risks that you should understand
|
||||||
|
# before enabling:
|
||||||
|
# http://tools.ietf.org/html/rfc6819#section-4.4.2
|
||||||
|
# http://tools.ietf.org/html/rfc6819#section-4.4.3
|
||||||
|
#
|
||||||
|
grant_flows %w(authorization_code implicit password)
|
||||||
|
|
||||||
|
# Under some circumstances you might want to have applications auto-approved,
|
||||||
|
# so that the user skips the authorization step.
|
||||||
|
# For example if dealing with a trusted application.
|
||||||
|
# skip_authorization do |resource_owner, client|
|
||||||
|
# client.superapp? or resource_owner.admin?
|
||||||
|
# end
|
||||||
|
skip_authorization { true } # right now only admins can add apps, so this is ok
|
||||||
|
|
||||||
|
# WWW-Authenticate Realm (default "Doorkeeper").
|
||||||
|
realm 'Foodsoft'
|
||||||
|
end
|
||||||
|
|
||||||
|
# my take on https://github.com/doorkeeper-gem/doorkeeper/issues/465
|
||||||
|
ActiveSupport.on_load(:after_initialize) do
|
||||||
|
Doorkeeper::ApplicationController.send :include, Concerns::Locale
|
||||||
|
Doorkeeper::ApplicationController.send :include, Concerns::FoodcoopScope
|
||||||
|
Doorkeeper::ApplicationController.send :include, Concerns::Auth
|
||||||
|
end
|
|
@ -663,6 +663,7 @@ de:
|
||||||
use_wiki: Wiki verwenden
|
use_wiki: Wiki verwenden
|
||||||
webstats_tracking_code: Code für Websiteanalysetool
|
webstats_tracking_code: Code für Websiteanalysetool
|
||||||
tabs:
|
tabs:
|
||||||
|
applications: Apps
|
||||||
foodcoop: Foodcoop
|
foodcoop: Foodcoop
|
||||||
language: Sprache
|
language: Sprache
|
||||||
layout: Layout
|
layout: Layout
|
||||||
|
|
|
@ -666,6 +666,7 @@ en:
|
||||||
use_wiki: Enable wiki
|
use_wiki: Enable wiki
|
||||||
webstats_tracking_code: Tracking code
|
webstats_tracking_code: Tracking code
|
||||||
tabs:
|
tabs:
|
||||||
|
applications: Apps
|
||||||
foodcoop: Foodcoop
|
foodcoop: Foodcoop
|
||||||
language: Language
|
language: Language
|
||||||
layout: Layout
|
layout: Layout
|
||||||
|
|
|
@ -638,6 +638,7 @@ nl:
|
||||||
use_wiki: Wiki gebruiken
|
use_wiki: Wiki gebruiken
|
||||||
webstats_tracking_code: Tracking code
|
webstats_tracking_code: Tracking code
|
||||||
tabs:
|
tabs:
|
||||||
|
applications: Apps
|
||||||
foodcoop: Foodcoop
|
foodcoop: Foodcoop
|
||||||
language: Taal
|
language: Taal
|
||||||
layout: Layout
|
layout: Layout
|
||||||
|
|
|
@ -10,6 +10,8 @@ Foodsoft::Application.routes.draw do
|
||||||
|
|
||||||
scope '/:foodcoop' do
|
scope '/:foodcoop' do
|
||||||
|
|
||||||
|
use_doorkeeper
|
||||||
|
|
||||||
# Root path
|
# Root path
|
||||||
root to: 'home#index'
|
root to: 'home#index'
|
||||||
|
|
||||||
|
|
42
db/migrate/20160309153440_create_doorkeeper_tables.rb
Normal file
42
db/migrate/20160309153440_create_doorkeeper_tables.rb
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
class CreateDoorkeeperTables < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
create_table :oauth_applications do |t|
|
||||||
|
t.string :name, null: false
|
||||||
|
t.string :uid, null: false
|
||||||
|
t.string :secret, null: false
|
||||||
|
t.text :redirect_uri, null: false
|
||||||
|
t.string :scopes, null: false, default: ''
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
|
||||||
|
add_index :oauth_applications, :uid, unique: true
|
||||||
|
|
||||||
|
create_table :oauth_access_grants do |t|
|
||||||
|
t.integer :resource_owner_id, null: false
|
||||||
|
t.integer :application_id, null: false
|
||||||
|
t.string :token, null: false
|
||||||
|
t.integer :expires_in, null: false
|
||||||
|
t.text :redirect_uri, null: false
|
||||||
|
t.datetime :created_at, null: false
|
||||||
|
t.datetime :revoked_at
|
||||||
|
t.string :scopes
|
||||||
|
end
|
||||||
|
|
||||||
|
add_index :oauth_access_grants, :token, unique: true
|
||||||
|
|
||||||
|
create_table :oauth_access_tokens do |t|
|
||||||
|
t.integer :resource_owner_id
|
||||||
|
t.integer :application_id
|
||||||
|
t.string :token, null: false
|
||||||
|
t.string :refresh_token
|
||||||
|
t.integer :expires_in
|
||||||
|
t.datetime :revoked_at
|
||||||
|
t.datetime :created_at, null: false
|
||||||
|
t.string :scopes
|
||||||
|
end
|
||||||
|
|
||||||
|
add_index :oauth_access_tokens, :token, unique: true
|
||||||
|
add_index :oauth_access_tokens, :resource_owner_id
|
||||||
|
add_index :oauth_access_tokens, :refresh_token, unique: true
|
||||||
|
end
|
||||||
|
end
|
40
db/schema.rb
40
db/schema.rb
|
@ -262,6 +262,46 @@ ActiveRecord::Schema.define(version: 20171201000000) do
|
||||||
t.binary "received_email"
|
t.binary "received_email"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
create_table "oauth_access_grants", force: :cascade do |t|
|
||||||
|
t.integer "resource_owner_id", limit: 4, null: false
|
||||||
|
t.integer "application_id", limit: 4, null: false
|
||||||
|
t.string "token", limit: 255, null: false
|
||||||
|
t.integer "expires_in", limit: 4, null: false
|
||||||
|
t.text "redirect_uri", limit: 65535, null: false
|
||||||
|
t.datetime "created_at", null: false
|
||||||
|
t.datetime "revoked_at"
|
||||||
|
t.string "scopes", limit: 255
|
||||||
|
end
|
||||||
|
|
||||||
|
add_index "oauth_access_grants", ["token"], name: "index_oauth_access_grants_on_token", unique: true, using: :btree
|
||||||
|
|
||||||
|
create_table "oauth_access_tokens", force: :cascade do |t|
|
||||||
|
t.integer "resource_owner_id", limit: 4
|
||||||
|
t.integer "application_id", limit: 4
|
||||||
|
t.string "token", limit: 255, null: false
|
||||||
|
t.string "refresh_token", limit: 255
|
||||||
|
t.integer "expires_in", limit: 4
|
||||||
|
t.datetime "revoked_at"
|
||||||
|
t.datetime "created_at", null: false
|
||||||
|
t.string "scopes", limit: 255
|
||||||
|
end
|
||||||
|
|
||||||
|
add_index "oauth_access_tokens", ["refresh_token"], name: "index_oauth_access_tokens_on_refresh_token", unique: true, using: :btree
|
||||||
|
add_index "oauth_access_tokens", ["resource_owner_id"], name: "index_oauth_access_tokens_on_resource_owner_id", using: :btree
|
||||||
|
add_index "oauth_access_tokens", ["token"], name: "index_oauth_access_tokens_on_token", unique: true, using: :btree
|
||||||
|
|
||||||
|
create_table "oauth_applications", force: :cascade do |t|
|
||||||
|
t.string "name", limit: 255, null: false
|
||||||
|
t.string "uid", limit: 255, null: false
|
||||||
|
t.string "secret", limit: 255, null: false
|
||||||
|
t.text "redirect_uri", limit: 65535, null: false
|
||||||
|
t.string "scopes", limit: 255, default: "", null: false
|
||||||
|
t.datetime "created_at"
|
||||||
|
t.datetime "updated_at"
|
||||||
|
end
|
||||||
|
|
||||||
|
add_index "oauth_applications", ["uid"], name: "index_oauth_applications_on_uid", unique: true, using: :btree
|
||||||
|
|
||||||
create_table "order_articles", force: :cascade do |t|
|
create_table "order_articles", force: :cascade do |t|
|
||||||
t.integer "order_id", limit: 4, default: 0, null: false
|
t.integer "order_id", limit: 4, default: 0, null: false
|
||||||
t.integer "article_id", limit: 4, default: 0, null: false
|
t.integer "article_id", limit: 4, default: 0, null: false
|
||||||
|
|
5
lib/api/errors.rb
Normal file
5
lib/api/errors.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
module Api::Errors
|
||||||
|
class Error < StandardError; end
|
||||||
|
# Authentication is handled by Doorkeeper, so no errors for that here
|
||||||
|
class PermissionRequired < Error; end
|
||||||
|
end
|
|
@ -1,56 +0,0 @@
|
||||||
# -*- encoding : utf-8 -*-
|
|
||||||
module Foodsoft
|
|
||||||
module ControllerExtensions
|
|
||||||
module Locale
|
|
||||||
extend ActiveSupport::Concern
|
|
||||||
|
|
||||||
included do
|
|
||||||
before_filter :set_locale
|
|
||||||
end
|
|
||||||
|
|
||||||
def explicitly_requested_language
|
|
||||||
params[:locale]
|
|
||||||
end
|
|
||||||
|
|
||||||
def user_settings_language
|
|
||||||
current_user.locale if current_user
|
|
||||||
end
|
|
||||||
|
|
||||||
def session_language
|
|
||||||
session[:locale]
|
|
||||||
end
|
|
||||||
|
|
||||||
def browser_language
|
|
||||||
request.env['HTTP_ACCEPT_LANGUAGE'] ? request.env['HTTP_ACCEPT_LANGUAGE'].scan(/^[a-z]{2}/).first : nil
|
|
||||||
end
|
|
||||||
|
|
||||||
def default_language
|
|
||||||
FoodsoftConfig[:default_locale] or ::I18n.default_locale
|
|
||||||
end
|
|
||||||
|
|
||||||
protected
|
|
||||||
|
|
||||||
def select_language_according_to_priority
|
|
||||||
language = explicitly_requested_language || session_language || user_settings_language
|
|
||||||
language ||= browser_language unless FoodsoftConfig[:ignore_browser_locale]
|
|
||||||
language.to_sym unless language.blank?
|
|
||||||
end
|
|
||||||
|
|
||||||
def available_locales
|
|
||||||
::I18n.available_locales
|
|
||||||
end
|
|
||||||
|
|
||||||
def set_locale
|
|
||||||
if available_locales.include?(select_language_according_to_priority)
|
|
||||||
::I18n.locale = select_language_according_to_priority
|
|
||||||
else
|
|
||||||
::I18n.locale = default_language
|
|
||||||
end
|
|
||||||
|
|
||||||
locale = session[:locale] = ::I18n.locale
|
|
||||||
logger.info("Set locale to #{locale}")
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -4,13 +4,13 @@ module FoodsoftDiscourse
|
||||||
def self.included(base) # :nodoc:
|
def self.included(base) # :nodoc:
|
||||||
base.class_eval do
|
base.class_eval do
|
||||||
|
|
||||||
alias orig_redirect_to_login redirect_to_login
|
alias foodsoft_discourse_orig_redirect_to_login redirect_to_login
|
||||||
|
|
||||||
def redirect_to_login(options={})
|
def redirect_to_login(options={})
|
||||||
if FoodsoftDiscourse.enabled? && !FoodsoftConfig[:discourse_sso]
|
if FoodsoftDiscourse.enabled? && !FoodsoftConfig[:discourse_sso]
|
||||||
redirect_to discourse_initiate_path
|
redirect_to discourse_initiate_path
|
||||||
else
|
else
|
||||||
orig_redirect_to_login(options)
|
foodsoft_discourse_orig_redirect_to_login(options)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -22,5 +22,5 @@ end
|
||||||
|
|
||||||
# modify existing helper
|
# modify existing helper
|
||||||
ActiveSupport.on_load(:after_initialize) do
|
ActiveSupport.on_load(:after_initialize) do
|
||||||
ApplicationController.send :include, FoodsoftDiscourse::RedirectToLogin
|
Concerns::Auth.send :include, FoodsoftDiscourse::RedirectToLogin
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue