authority 2.0.0 → 2.0.1

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/CHANGELOG.markdown CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  This is mainly to document major new features and backwards-incompatible changes.
4
4
 
5
+ ## v2.0.1
6
+
7
+ Documentation and test cleanup.
8
+
5
9
  ## v2.0.0
6
10
 
7
11
  - **Breaking change**: models now assume their authorizer is `ApplicationAuthorizer` unless told otherwise. Generator creates a blank `ApplicationAuthorizer`. This, combined with the change in v1.1.0, makes the `default_strategy` proc obsolete in favor of straightforward inheritance of a `default` method, so support for `config.default_strategy` is removed.
data/README.markdown CHANGED
@@ -87,9 +87,10 @@ The authorization process generally flows like this:
87
87
  | # calls `default`...
88
88
  v
89
89
  AdminAuthorizer.default(:creatable, current_user) # *You define this method.*
90
- # If you don't, the one inherited
91
- # from Authority::Authorizer just
92
- # returns false.
90
+ # If you don't, it will use the one
91
+ # inherited from ApplicationAuthorizer.
92
+ # (Its parent, Authority::Authorizer,
93
+ # defines the method as `return false`.)
93
94
 
94
95
  If the answer is `false` and the original caller was a controller, this is treated as a `SecurityViolation`. If it was a view, maybe you just don't show a link.
95
96
 
@@ -260,27 +261,47 @@ end
260
261
 
261
262
  Anytime a controller finds a user attempting something they're not authorized to do, a [Security Violation](#security_violations_and_logging) will result. Controllers get two ways to check authorization:
262
263
 
263
- - `authorize_actions_for Transaction` protects multiple controller actions with a `before_filter`, which performs a **class-level** check. If the current user is never allowed to delete a `Transaction`, they'll never even get to the controller's `destroy` method.
264
- - `authorize_action_for @transaction` can be called inside a single controller action, and performs an **instance-level** check. If called inside `update`, it will check whether the current user is allowed to update this particular `@transaction` instance.
264
+ - `authorize_actions_for Llama` protects multiple controller actions with a `before_filter`, which performs a **class-level** check. If the current user is never allowed to delete a `Llama`, they'll never even get to the controller's `destroy` method.
265
+ - `authorize_action_for @llama` can be called inside a single controller action, and performs an **instance-level** check. If called inside `update`, it will check whether the current user is allowed to update this particular `@llama` instance.
265
266
 
266
- The relationship between controller actions and abilities - like checking `readable_by?` on the `index` action - is configurable both globally, using `config.controller_action_map`, and per controller, as below.
267
+ How does Authority know to check `deletable_by?` before the controller's `destroy` action? It checks your configuration. These mappings are configurable globally from the initializer file. Defaults are as follows:
267
268
 
268
269
  ```ruby
269
- class LlamaController < ApplicationController
270
+ config.controller_action_map = {
271
+ :index => 'read', # `index` controller action will check `readable_by?`
272
+ :show => 'read',
273
+ :new => 'create', # `new` controller action will check `creatable_by?`
274
+ :create => 'create', # ...etc
275
+ :edit => 'update',
276
+ :update => 'update',
277
+ :destroy => 'delete'
278
+ }
279
+ ```
280
+
281
+ They are also configurable per controller, as follows:
282
+
283
+ ```ruby
284
+ class LlamasController < ApplicationController
270
285
 
271
286
  # Check class-level authorizations before all actions except :create
272
287
  # Also, to authorize this controller's 'neuter' action, ask whether `current_user.can_update?(Llama)`
273
288
  authorize_actions_for Llama, :except => :create, :actions => {:neuter => :update},
274
289
 
275
290
  # To authorize this controller's 'breed' action, ask whether `current_user.can_create?(Llama)`
276
- authority_action :breed => 'new'
291
+ authority_action :breed => 'create'
277
292
 
278
293
  ...
279
294
 
280
295
  def edit
281
296
  @llama = Llama.find(params[:id])
297
+ authorize_action_for(@llama) # Check to see if you're allowed to edit this llama. failure == SecurityViolation
298
+ end
299
+
300
+ def update
301
+ @llama = Llama.find(params[:id])
302
+ authorize_action_for(@llama) # Check to see if you're allowed to edit this llama.
282
303
  @llama.attributes = params[:llama] # Don't save the attributes before authorizing
283
- authorize_action_for(@llama) # failure == SecurityViolation
304
+ authorize_action_for(@llama) # Check again, to see if the changes are allowed.
284
305
  if @llama.save?
285
306
  # etc
286
307
  end
@@ -329,6 +350,8 @@ end
329
350
 
330
351
  If you want different error handling per controller, define `fire_ze_missiles` on each of them.
331
352
 
353
+ Your method will be handed the `SecurityViolation`, which has a `message` method. In case you want to build your own message, it also exposes `user`, `action` and `resource`.
354
+
332
355
  <a name="credits">
333
356
  ## Credits, AKA 'Shout-Outs'
334
357
 
data/TODO.markdown CHANGED
@@ -7,8 +7,5 @@
7
7
 
8
8
  ## Documentation
9
9
 
10
- - Example of checking clean/dirty attributes in instance-level checks. For example, if I'm only allowed to update blue laser cannons, can I make them red? Maybe I need to check whether the old value was blue?
11
-
12
10
  ## Features
13
11
 
14
- - It would be nice to have an `authorized_link_to` method, which determines from the given path and the user's permissions whether to show the link. Not sure yet how hard this would be.
@@ -27,6 +27,7 @@ module Authority
27
27
  RUBY
28
28
  end
29
29
 
30
+ # @return [Class] of the designated authorizer
30
31
  def authorizer
31
32
  @authorizer ||= authorizer_name.constantize # Get an actual reference to the authorizer class
32
33
  rescue NameError
@@ -1,7 +1,7 @@
1
1
  module Authority
2
2
  class Configuration
3
3
 
4
- # Has default settings, overrideable in the initializer.
4
+ # Has default settings, which can be overridden in the initializer.
5
5
 
6
6
  attr_accessor :abilities, :controller_action_map, :user_method, :security_violation_handler, :logger
7
7
 
@@ -11,7 +11,7 @@ module Authority
11
11
 
12
12
  def self.security_violation_callback
13
13
  Proc.new do |exception|
14
- # Through the magic of ActiveSupport's Proc#bind, `ActionController::Base#rescue_from`
14
+ # Through the magic of ActiveSupport's `Proc#bind`, `ActionController::Base#rescue_from`
15
15
  # can call this proc and make `self` the actual controller instance
16
16
  self.send(Authority.configuration.security_violation_handler, exception)
17
17
  end
@@ -59,13 +59,13 @@ module Authority
59
59
 
60
60
  private
61
61
 
62
- # The before filter that will be setup to run when the class method
62
+ # The `before_filter` that will be setup to run when the class method
63
63
  # `authorize_actions_for` is called
64
64
  def run_authorization_check
65
65
  authorize_action_for self.class.authority_resource
66
66
  end
67
67
 
68
- # Convenience wrapper for sending configured user_method to extract the
68
+ # Convenience wrapper for sending configured `user_method` to extract the
69
69
  # request's current user
70
70
  #
71
71
  # @return [Object] the user object returned from sending the user_method
@@ -73,7 +73,7 @@ module Authority
73
73
  send(Authority.configuration.user_method)
74
74
  end
75
75
 
76
- # To be run in a before_filter; ensure this controller action is allowed for the user
76
+ # To be run in a `before_filter`; ensure this controller action is allowed for the user
77
77
  #
78
78
  # @param authority_resource [Class], the model class associated with this controller
79
79
  # @raise [MissingAction] if controller action isn't a key in `config.controller_action_map`
@@ -1,3 +1,3 @@
1
1
  module Authority
2
- VERSION = "2.0.0"
2
+ VERSION = "2.0.1"
3
3
  end
@@ -25,7 +25,7 @@ module Authority
25
25
  private
26
26
 
27
27
  def create_authorizers_directory
28
- # creates empty directory if none; doesn't empty the directory
28
+ # Creates empty directory if none; doesn't empty the directory
29
29
  empty_directory "app/authorizers"
30
30
  end
31
31
 
@@ -10,6 +10,7 @@ Authority.configure do |config|
10
10
  # config.user_method = :current_user
11
11
 
12
12
  # CONTROLLER_ACTION_MAP
13
+ # =====================
13
14
  # For a given controller method, what verb must a user be able to do?
14
15
  # For example, a user can access 'show' if they 'can_read' the resource.
15
16
  #
@@ -29,6 +30,7 @@ Authority.configure do |config|
29
30
  # }
30
31
 
31
32
  # ABILITIES
33
+ # =========
32
34
  # Teach Authority how to understand the verbs and adjectives in your system. Perhaps you
33
35
  # need {:microwave => 'microwavable'}. I'm not saying you do, of course. Stop looking at
34
36
  # me like that.
@@ -43,6 +45,7 @@ Authority.configure do |config|
43
45
  # }
44
46
 
45
47
  # SECURITY_VIOLATION_HANDLER
48
+ # ==========================
46
49
  # If a SecurityViolation is raised, what controller method should be used to rescue it?
47
50
  #
48
51
  # Default is:
@@ -50,6 +53,7 @@ Authority.configure do |config|
50
53
  # config.security_violation_handler = :authority_forbidden # Defined in controller.rb
51
54
 
52
55
  # LOGGER
56
+ # ======
53
57
  # If a user tries to perform an unauthorized action, where should we log that fact?
54
58
  # Provide a logger object which responds to `.warn(message)`, unless your
55
59
  # security_violation_handler calls a different method.
@@ -35,14 +35,10 @@ describe Authority::Abilities do
35
35
  end
36
36
 
37
37
  it "should raise a friendly error if the authorizer doesn't exist" do
38
- AbilityModel.instance_variable_set(:@authorizer, nil)
39
- AbilityModel.authorizer_name = 'NonExistentAuthorizer'
40
- expect { AbilityModel.authorizer }.to raise_error(Authority::NoAuthorizerError)
41
-
42
- # Cleanup to prevent affecting other tests
43
- # TODO: Clean up this cleanup code. :)
44
- AbilityModel.instance_variable_set(:@authorizer, nil)
45
- AbilityModel.authorizer_name = 'ApplicationAuthorizer'
38
+ class NoAuthorizerModel < AbilityModel; end ;
39
+ NoAuthorizerModel.instance_variable_set(:@authorizer, nil)
40
+ NoAuthorizerModel.authorizer_name = 'NonExistentAuthorizer'
41
+ expect { NoAuthorizerModel.authorizer }.to raise_error(Authority::NoAuthorizerError)
46
42
  end
47
43
 
48
44
  end
@@ -91,8 +87,9 @@ describe Authority::Abilities do
91
87
  @ability_model.should respond_to(:authorizer)
92
88
  end
93
89
 
94
- # TODO: Nathan will comment more clearly in the future
95
- # aka "don't memoize" (to prevent dirty models from contaminating authorization)
90
+ # When checking instance methods, we want to ensure that every check uses a new
91
+ # instance of the authorizer. Otherwise, you might check, make a change to the
92
+ # model instance, check again, and get an outdated answer.
96
93
  it "should always create a new authorizer instance when accessing the authorizer" do
97
94
  @ability_model.class.authorizer.should_receive(:new).with(@ability_model).twice
98
95
  2.times { @ability_model.authorizer }
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.0.0
4
+ version: 2.0.1
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-04-30 00:00:00.000000000 Z
13
+ date: 2012-06-16 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rails
17
- requirement: &2152144680 !ruby/object:Gem::Requirement
17
+ requirement: &75848730 !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: *2152144680
25
+ version_requirements: *75848730
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.
@@ -90,20 +90,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
90
90
  version: '0'
91
91
  requirements: []
92
92
  rubyforge_project:
93
- rubygems_version: 1.8.16
93
+ rubygems_version: 1.8.10
94
94
  signing_key:
95
95
  specification_version: 3
96
96
  summary: Authority helps you authorize actions in your Rails app using plain Ruby
97
97
  methods on Authorizer classes.
98
- test_files:
99
- - spec/authority/abilities_spec.rb
100
- - spec/authority/authorizer_spec.rb
101
- - spec/authority/configuration_spec.rb
102
- - spec/authority/controller_spec.rb
103
- - spec/authority/user_abilities_spec.rb
104
- - spec/authority_spec.rb
105
- - spec/spec_helper.rb
106
- - spec/support/ability_model.rb
107
- - spec/support/example_controllers.rb
108
- - spec/support/mock_rails.rb
109
- - spec/support/user.rb
98
+ test_files: []