Skip to content

Instantly share code, notes, and snippets.

@aishek
Last active August 29, 2015 14:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aishek/e60172ffc9e6b365e12f to your computer and use it in GitHub Desktop.
Save aishek/e60172ffc9e6b365e12f to your computer and use it in GitHub Desktop.
Ruby on Rails 4.1 auth concern with six gem
# app/controllers/web/application_controller.rb
class Web::ApplicationController < ApplicationController
include Concerns::Auth
rescue_from AccessDenied, :with => :access_denied_handler
private
def can?(action, subject = current_user)
abilities << subject
abilities.allowed?(current_user, action, subject)
end
def current_user_session
@current_user_session ||= ::User::Session.find
end
def current_user
@current_user ||= (current_user_session && current_user_session.record) || Guest.new
end
def access_denied_handler
flash[:error] = t('helpers.auth.unauthorized')
redirect_back_or_default auth_login_path
end
end
# app/controllers/concerns/auth.rb
module Concerns::Auth
extend ActiveSupport::Concern
class AccessDenied < RuntimeError; end
included do
helper_method :can?
after_action :store_location, :if => lambda {|controller| controller.request.get? && controller.request.format == :html}
end
private
def abilities
@abilities ||= Six.new
end
def can?(action, subject)
# override like:
#
# abilities << subject
# abilities.allowed?(current_user, action, subject)
raise NotImplementedError
end
def authorize!(action, subject = self)
raise AccessDenied unless can?(action, subject)
end
def store_location
session[:return_to] = request.protocol + request.host_with_port + request.path
true
end
def redirect_back_or_default(default, options = {})
return_to = session[:return_to].blank? ? default : session[:return_to]
session[:return_to] = nil
respond_to do |format|
format.js { render :js => "window.location.href = '\#{j return_to}';" }
format.html { redirect_to return_to, options }
end
end
end
# app/models/guest.rb
class Guest
include Allowed::GuestRules
end
# lib/allowed/guest_rules.rb
module Allowed::GuestRules
extend ActiveSupport::Concern
def allowed(object, subject)
rules = []
return rules unless subject.kind_of?(::Guest)
rules
end
end
# lib/allowed/user_rules.rb
module Allowed::UserRules
extend ActiveSupport::Concern
def allowed(object, subject)
rules = []
return rules unless subject.kind_of?(::User)
if object && object.persisted?
rules << :show
rules << :friends if subject == object
rules << :update if subject == object
else
rules << :create
end
rules
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment