authority 2.3.1 → 2.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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.