Skip to content

Commit

Permalink
ft: adds denied callback
Browse files Browse the repository at this point in the history
  • Loading branch information
wbotelhos committed Sep 12, 2021
1 parent 84ec131 commit 2b92ec1
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 29 deletions.
11 changes: 10 additions & 1 deletion lib/authorizy/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,21 @@

module Authorizy
class Config
attr_accessor :aliases, :cop, :current_user, :dependencies, :field, :redirect_url
attr_accessor :aliases, :cop, :current_user, :denied, :dependencies, :field, :redirect_url

def initialize
@aliases = {}
@cop = Authorizy::BaseCop
@current_user = ->(context) { context.respond_to?(:current_user) ? context.current_user : nil }

@denied = lambda { |context|
info = I18n.t('authorizy.denied', controller: context.params[:controller], action: context.params[:action])

return context.render(json: { message: info }, status: 403) if context.request.xhr?

context.redirect_to(redirect_url.call(self), info: info)
}

@dependencies = {}
@field = ->(current_user) { current_user.respond_to?(:authorizy) ? current_user.authorizy : {} }
@redirect_url = ->(context) { context.respond_to?(:root_url) ? context.root_url : '/' }
Expand Down
6 changes: 1 addition & 5 deletions lib/authorizy/extension.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,7 @@ module Extension
def authorizy
return if Authorizy::Core.new(authorizy_user, params, session, cop: authorizy_cop).access?

info = I18n.t('authorizy.denied', controller: params[:controller], action: params[:action])

return render(json: { message: info }, status: 401) if request.xhr?

redirect_to Authorizy.config.redirect_url.call(self), info: info
Authorizy.config.denied.call(self)
end

def authorizy?(controller, action)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,28 @@
# https://github.com/wbotelhos/authorizy#cop
# config.cop = Authorizy::BaseCop

# The current user from we fetch the permissions
# The current user from where we fetch the permissions
# https://github.com/wbotelhos/authorizy#current-user
# config.current_user = -> (context) { context.respond_to?(:current_user) ? context.current_user : nil }

# Callback called when access is denied
# https://github.com/wbotelhos/authorizy#denied
# config.denied = lambda { |context|
# info = I18n.t('authorizy.denied', controller: context.params[:controller], action: context.params[:action])

# return context.render(json: { message: info }, status: 403) if context.request.xhr?

# context.redirect_to(redirect_url.call(self), info: info)
# }

# Inherited permissions from some other permission the user already has
# https://github.com/wbotelhos/authorizy#dependencies
# config.dependencies = {}

# Field used to fetch the Authorizy permissions
# https://github.com/wbotelhos/authorizy#field
# config.field = ->(current_user) { current_user.respond_to?(:authorizy) ? current_user.authorizy : {} }

# URL to be redirect when user has no permission to access some resource
# https://github.com/wbotelhos/authorizy#dependencies
# config.redirect_url = -> (context) { context.respond_to?(:root_url) ? context.root_url : '/' }
Expand Down
49 changes: 49 additions & 0 deletions spec/authorizy/config/denied_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# frozen_string_literal: true

RSpec.describe Authorizy::Config, '#denied' do
let!(:config) { described_class.new }

context 'with default denied callback' do
context 'when is a xhr request' do
let!(:context) do
double('context',
params: { controller: 'users', action: 'index' },
request: OpenStruct.new(xhr?: true)
)
end

it 'renders' do
allow(context).to receive(:render)

config.denied.call(context)

expect(context).to have_received(:render).with(json: { message: 'Action denied for users#index' }, status: 403)
end
end

context 'when is not a xhr request' do
let!(:context) do
double('context',
params: { controller: 'users', action: 'index' },
request: OpenStruct.new(xhr?: false)
)
end

it 'renders' do
allow(context).to receive(:redirect_to)

config.denied.call(context)

expect(context).to have_received(:redirect_to).with('/', info: 'Action denied for users#index')
end
end
end

context 'with custom denied callback' do
it 'calls the callback' do
config.denied = ->(context) { context[:key] }

expect(config.denied.call(key: :value)).to eq(:value)
end
end
end
4 changes: 2 additions & 2 deletions spec/authorizy/config/redirect_url_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@

context 'when uses custom value' do
it 'executes what you want' do
config.redirect_url = ->(context) { context[:value] }
config.redirect_url = ->(context) { context[:key] }

expect(config.redirect_url.call({ value: 'value' })).to eq('value')
expect(config.redirect_url.call({ key: :value })).to eq(:value)
end
end
end
26 changes: 6 additions & 20 deletions spec/authorizy/extension/authorizy_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,15 @@
require 'support/controllers/dummy_controller'

RSpec.describe DummyController, '#authorizy', type: :controller do
let!(:config) { Authorizy.config }
let!(:parameters) { ActionController::Parameters.new(key: 'value', controller: 'dummy', action: 'action') }
let!(:user) { nil }

before { allow(Authorizy).to receive(:config).and_return(config) }

context 'when user has access' do
let!(:authorizy_core) { instance_double('Authorizy::Core', access?: true) }

before do
allow(Authorizy::Core).to receive(:new)
.with(user, parameters, session, cop: config.cop)
.with(user, parameters, session, cop: Authorizy.config.cop)
.and_return(authorizy_core)
end

Expand Down Expand Up @@ -42,27 +39,16 @@

before do
allow(Authorizy::Core).to receive(:new)
.with(user, parameters, session, cop: config.cop)
.with(user, parameters, session, cop: Authorizy.config.cop)
.and_return(authorizy_core)
end

context 'when is a xhr request' do
it 'receives the default values and denied the access' do
get :action, xhr: true, params: { key: 'value' }
it 'calls denied callback' do
allow(Authorizy.config.denied).to receive(:call)

expect(response.body).to eq('{"message":"Action denied for dummy#action"}')
expect(response.status).to be(401)
end
end
get :action, xhr: true, params: { key: 'value' }

context 'when is a html request' do
it 'receives the default values and do not denied the access' do
get :action, params: { key: 'value' }

expect(response).to redirect_to '/'

# expect(flash[:info]).to eq('Action denied for dummy#action') # TODO: get flash message
end
expect(Authorizy.config.denied).to have_received(:call).with(subject)
end
end
end

0 comments on commit 2b92ec1

Please sign in to comment.