Skip to content
This repository has been archived by the owner on Nov 19, 2019. It is now read-only.

Commit

Permalink
Allow authorization with options hash
Browse files Browse the repository at this point in the history
  • Loading branch information
Nathan Long committed Aug 10, 2012
1 parent e2f9373 commit 9330746
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 30 deletions.
16 changes: 12 additions & 4 deletions lib/authority/abilities.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,12 @@ module ClassMethods
Authority.adjectives.each do |adjective|

class_eval <<-RUBY, __FILE__, __LINE__ + 1
def #{adjective}_by?(user)
authorizer.#{adjective}_by?(user)
def #{adjective}_by?(user, options = {})
if options.empty?
authorizer.#{adjective}_by?(user)
else
authorizer.#{adjective}_by?(user, options)
end
end
RUBY
end
Expand All @@ -38,8 +42,12 @@ def authorizer
Authority.adjectives.each do |adjective|

class_eval <<-RUBY, __FILE__, __LINE__ + 1
def #{adjective}_by?(user)
authorizer.#{adjective}_by?(user)
def #{adjective}_by?(user, options = {})
if options.empty?
authorizer.#{adjective}_by?(user)
else
authorizer.#{adjective}_by?(user, options)
end
end
def authorizer
Expand Down
18 changes: 13 additions & 5 deletions lib/authority/authorizer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,31 @@ def initialize(resource)
# Each instance method simply calls the corresponding class method
Authority.adjectives.each do |adjective|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
def #{adjective}_by?(user)
self.class.#{adjective}_by?(user)
def #{adjective}_by?(user, options = {})
if options.empty?
self.class.#{adjective}_by?(user)
else
self.class.#{adjective}_by?(user, options)
end
end
RUBY
end

# Each class method simply calls the `default` method
Authority.adjectives.each do |adjective|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
def self.#{adjective}_by?(user)
default(:#{adjective}, user)
def self.#{adjective}_by?(user, options = {})
if options.empty?
default(:#{adjective}, user)
else
default(:#{adjective}, user, options)
end
end
RUBY
end

# Whitelisting approach: anything not specified will be forbidden
def self.default(adjective, user)
def self.default(adjective, user, options = {})
false
end

Expand Down
8 changes: 6 additions & 2 deletions lib/authority/user_abilities.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,12 @@ module UserAbilities

Authority.verbs.each do |verb|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
def can_#{verb}?(resource)
resource.#{Authority.abilities[verb]}_by?(self)
def can_#{verb}?(resource, options = {})
if options.empty?
resource.#{Authority.abilities[verb]}_by?(self)
else
resource.#{Authority.abilities[verb]}_by?(self, options)
end
end
RUBY
end
Expand Down
41 changes: 34 additions & 7 deletions spec/authority/abilities_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,22 @@ class NoAuthorizerModel < AbilityModel; end ;
AbilityModel.should respond_to(method_name)
end

it "should delegate `#{method_name}` to its authorizer class" do
AbilityModel.authorizer.should_receive(method_name).with(@user)
AbilityModel.send(method_name, @user)
describe "if given an options hash" do

it "should delegate `#{method_name}` to its authorizer class, passing the options" do
AbilityModel.authorizer.should_receive(method_name).with(@user, :lacking => 'nothing')
AbilityModel.send(method_name, @user, :lacking => 'nothing')
end

end

describe "if not given an options hash" do

it "should delegate `#{method_name}` to its authorizer class, passing no options" do
AbilityModel.authorizer.should_receive(method_name).with(@user)
AbilityModel.send(method_name, @user)
end

end

end
Expand All @@ -75,10 +88,24 @@ class NoAuthorizerModel < AbilityModel; end ;
@ability_model.should respond_to(method_name)
end

it "should delegate `#{method_name}` to a new authorizer instance" do
AbilityModel.authorizer.stub(:new).and_return(@authorizer)
@authorizer.should_receive(method_name).with(@user)
@ability_model.send(method_name, @user)
describe "if given an options hash" do

it "should delegate `#{method_name}` to a new authorizer instance, passing the options" do
AbilityModel.authorizer.stub(:new).and_return(@authorizer)
@authorizer.should_receive(method_name).with(@user, :with => 'mayo')
@ability_model.send(method_name, @user, :with => 'mayo')
end

end

describe "if not given an options hash" do

it "should delegate `#{method_name}` to a new authorizer instance, passing no options" do
AbilityModel.authorizer.stub(:new).and_return(@authorizer)
@authorizer.should_receive(method_name).with(@user)
@ability_model.send(method_name, @user)
end

end

end
Expand Down
57 changes: 48 additions & 9 deletions spec/authority/authorizer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,23 @@
@authorizer.should respond_to(method_name)
end

it "should delegate `#{method_name}` to the corresponding class method by default" do
@authorizer.class.should_receive(method_name).with(@user)
@authorizer.send(method_name, @user)

describe "if given an options hash" do

it "should delegate `#{method_name}` to the corresponding class method, passing the options" do
@authorizer.class.should_receive(method_name).with(@user, :under => 'God')
@authorizer.send(method_name, @user, :under => 'God')
end

end

describe "if not given an options hash" do

it "should delegate `#{method_name}` to the corresponding class method, passing no options" do
@authorizer.class.should_receive(method_name).with(@user)
@authorizer.send(method_name, @user)
end

end

end
Expand All @@ -41,10 +55,24 @@
Authority::Authorizer.should respond_to(method_name)
end

it "should delegate `#{method_name}` to the authorizer's `default` method by default" do
able = method_name.sub('_by?', '').to_sym
Authority::Authorizer.should_receive(:default).with(able, @user)
Authority::Authorizer.send(method_name, @user)
describe "if given an options hash" do

it "should delegate `#{method_name}` to the authorizer's `default` method, passing the options" do
able = method_name.sub('_by?', '').to_sym
Authority::Authorizer.should_receive(:default).with(able, @user, :with => 'gusto')
Authority::Authorizer.send(method_name, @user, :with => 'gusto')
end

end

describe "if not given an options hash" do

it "should delegate `#{method_name}` to the authorizer's `default` method, passing no options" do
able = method_name.sub('_by?', '').to_sym
Authority::Authorizer.should_receive(:default).with(able, @user)
Authority::Authorizer.send(method_name, @user)
end

end

end
Expand All @@ -53,8 +81,19 @@

describe "the default method" do

it "should return false" do
Authority::Authorizer.default(:implodable, @user).should be_false
describe "if given an options hash" do

it "should return false" do
Authority::Authorizer.default(:implodable, @user, {:for => "my_object"}).should be_false
end
end

describe "if not given an options hash" do

it "should return false" do
Authority::Authorizer.default(:implodable, @user).should be_false
end

end

end
Expand Down
20 changes: 17 additions & 3 deletions spec/authority/user_abilities_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,24 @@
@user.should respond_to(method_name)
end

it "should delegate the authorization check to the resource provided" do
@ability_model.should_receive("#{Authority.abilities[verb]}_by?").with(@user)
@user.send(method_name, @ability_model)
describe "if given options" do

it "should delegate the authorization check to the resource, passing the options" do
@ability_model.should_receive("#{Authority.abilities[verb]}_by?").with(@user, :size => 'wee')
@user.send(method_name, @ability_model, :size => 'wee')
end

end

describe "if not given options" do

it "should delegate the authorization check to the resource, passing no options" do
@ability_model.should_receive("#{Authority.abilities[verb]}_by?").with(@user)
@user.send(method_name, @ability_model)
end

end

end

end

0 comments on commit 9330746

Please sign in to comment.