authority 2.3.1 → 2.3.2

Sign up to get free protection for your applications and to get access to all the features.
data/.travis.yml CHANGED
@@ -3,6 +3,7 @@ rvm:
3
3
  - 1.8.7
4
4
  - 1.9.2
5
5
  - 1.9.3
6
+ - 2.0.0
6
7
  - jruby-18mode # JRuby in 1.8 mode
7
8
  - jruby-19mode # JRuby in 1.9 mode
8
9
  - rbx-18mode
data/TODO.markdown CHANGED
@@ -6,10 +6,6 @@
6
6
  - Test `ActionController` integration
7
7
  - Add tests for the generators
8
8
 
9
- ## Code
10
-
11
- - Look into using the `Forwardable` module for delegation in various places. (Does it handle passing options if given and nothing if not?)
12
-
13
9
  ## Structural changes
14
10
 
15
11
  - Consider the huge change from authorizer objects to modules for permissions. This eliminates the awkwardness of "to check a resource instance, let's go instantiate an authorizer and give it this resource instance..." If we make this change, describe a detailed upgrade path.
data/lib/authority.rb CHANGED
@@ -2,6 +2,7 @@ require 'active_support/concern'
2
2
  require 'active_support/core_ext/class/attribute'
3
3
  require 'active_support/core_ext/hash/keys'
4
4
  require 'active_support/core_ext/string/inflections'
5
+ require 'forwardable'
5
6
  require 'logger'
6
7
  require 'authority/security_violation'
7
8
 
@@ -9,6 +9,7 @@ module Authority
9
9
 
10
10
  module Abilities
11
11
  extend ActiveSupport::Concern
12
+ extend Forwardable
12
13
 
13
14
  # Assume authorizer is `ApplicationAuthorizer` (but let the user change that)
14
15
  included do
@@ -16,19 +17,21 @@ module Authority
16
17
  self.authorizer_name = "ApplicationAuthorizer"
17
18
  end
18
19
 
20
+ def authorizer
21
+ self.class.authorizer.new(self) # instantiate on every check, in case model has changed
22
+ end
23
+
24
+ # Send all calls like `editable_by?` to an authorizer instance
25
+ Authority.adjectives.each do |adjective|
26
+ def_delegators :authorizer, :"#{adjective}_by?"
27
+ end
28
+
19
29
  module ClassMethods
30
+ extend Forwardable
20
31
 
32
+ # Send all calls like `editable_by?` to the authorizer class
21
33
  Authority.adjectives.each do |adjective|
22
-
23
- class_eval <<-RUBY, __FILE__, __LINE__ + 1
24
- def #{adjective}_by?(user, options = {})
25
- if options.empty?
26
- authorizer.#{adjective}_by?(user)
27
- else
28
- authorizer.#{adjective}_by?(user, options)
29
- end
30
- end
31
- RUBY
34
+ def_delegators :authorizer, :"#{adjective}_by?"
32
35
  end
33
36
 
34
37
  # @return [Class] of the designated authorizer
@@ -39,23 +42,7 @@ module Authority
39
42
  "#{authorizer_name} is set as the authorizer for #{self}, but the constant is missing"
40
43
  )
41
44
  end
42
- end
43
-
44
- Authority.adjectives.each do |adjective|
45
45
 
46
- class_eval <<-RUBY, __FILE__, __LINE__ + 1
47
- def #{adjective}_by?(user, options = {})
48
- if options.empty?
49
- authorizer.#{adjective}_by?(user)
50
- else
51
- authorizer.#{adjective}_by?(user, options)
52
- end
53
- end
54
-
55
- def authorizer
56
- self.class.authorizer.new(self) # instantiate on every check, in case model has changed
57
- end
58
- RUBY
59
46
  end
60
47
 
61
48
  end
@@ -1,5 +1,6 @@
1
1
  module Authority
2
2
  class Authorizer
3
+ extend Forwardable
3
4
 
4
5
  # The base Authorizer class, from which all the authorizers in an app will
5
6
  # descend. Provides the authorizer with both class and instance methods
@@ -14,17 +15,14 @@ module Authority
14
15
  @resource = resource
15
16
  end
16
17
 
18
+ # Whitelisting approach: anything not specified will be forbidden
19
+ def self.default(adjective, user, options = {})
20
+ false
21
+ end
22
+
17
23
  # Each instance method simply calls the corresponding class method
18
24
  Authority.adjectives.each do |adjective|
19
- class_eval <<-RUBY, __FILE__, __LINE__ + 1
20
- def #{adjective}_by?(user, options = {})
21
- if options.empty?
22
- self.class.#{adjective}_by?(user)
23
- else
24
- self.class.#{adjective}_by?(user, options)
25
- end
26
- end
27
- RUBY
25
+ def_delegator :"self.class", :"#{adjective}_by?"
28
26
  end
29
27
 
30
28
  # Each class method simply calls the `default` method
@@ -40,11 +38,6 @@ module Authority
40
38
  RUBY
41
39
  end
42
40
 
43
- # Whitelisting approach: anything not specified will be forbidden
44
- def self.default(adjective, user, options = {})
45
- false
46
- end
47
-
48
41
  end
49
42
 
50
43
  class NoAuthorizerError < StandardError ; end
@@ -21,12 +21,13 @@ module Authority
21
21
  end
22
22
 
23
23
  def can?(action, options = {})
24
+ self_and_maybe_options = [self, (options == {} ? nil : options)].compact # throw out if nil
24
25
  begin
25
- ApplicationAuthorizer.send("authorizes_to_#{action}?", self, options)
26
+ ApplicationAuthorizer.send("authorizes_to_#{action}?", *self_and_maybe_options)
26
27
  rescue NoMethodError => original_exception
27
28
  begin
28
29
  # For backwards compatibility
29
- response = ApplicationAuthorizer.send("can_#{action}?", self, options)
30
+ response = ApplicationAuthorizer.send("can_#{action}?", *self_and_maybe_options)
30
31
  Authority.logger.warn(
31
32
  "DEPRECATION WARNING: Please rename `ApplicationAuthorizer.can_#{action}?` to `authorizes_to_#{action}?`"
32
33
  )
@@ -1,3 +1,3 @@
1
1
  module Authority
2
- VERSION = "2.3.1"
2
+ VERSION = "2.3.2"
3
3
  end
@@ -49,6 +49,16 @@ describe Authority::UserAbilities do
49
49
  expect(user.can?(:mimic_lemurs)).to eq('yessir')
50
50
  end
51
51
 
52
+ it "passes along options if any were given" do
53
+ ApplicationAuthorizer.should_receive(:authorizes_to_mimic_lemurs?).with(user, :for => :academic_credit)
54
+ user.can?(:mimic_lemurs, :for => :academic_credit)
55
+ end
56
+
57
+ it "doesn't pass along options if none were given" do
58
+ ApplicationAuthorizer.should_receive(:authorizes_to_mimic_lemurs?).with(user)
59
+ user.can?(:mimic_lemurs)
60
+ end
61
+
52
62
  end
53
63
 
54
64
  context "when ApplicationAuthorizer does not respond to a matching `authorizes_to?` call" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: authority
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.1
4
+ version: 2.3.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,11 +10,11 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-12-10 00:00:00.000000000 Z
13
+ date: 2012-12-11 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rails
17
- requirement: &2152639540 !ruby/object:Gem::Requirement
17
+ requirement: &2152546080 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,7 +22,7 @@ dependencies:
22
22
  version: 3.0.0
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *2152639540
25
+ version_requirements: *2152546080
26
26
  description: Authority helps you authorize actions in your Rails app. It's ORM-neutral
27
27
  and has very little fancy syntax; just group your models under one or more Authorizer
28
28
  classes and write plain Ruby methods on them.