authority 2.0.0 → 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.markdown +4 -0
- data/README.markdown +32 -9
- data/TODO.markdown +0 -3
- data/lib/authority/abilities.rb +1 -0
- data/lib/authority/configuration.rb +1 -1
- data/lib/authority/controller.rb +4 -4
- data/lib/authority/version.rb +1 -1
- data/lib/generators/authority/install_generator.rb +1 -1
- data/lib/generators/templates/authority_initializer.rb +4 -0
- data/spec/authority/abilities_spec.rb +7 -10
- metadata +6 -17
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
|
91
|
-
# from
|
92
|
-
#
|
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
|
264
|
-
- `authorize_action_for @
|
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
|
-
|
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
|
-
|
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 => '
|
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) #
|
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.
|
data/lib/authority/abilities.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Authority
|
2
2
|
class Configuration
|
3
3
|
|
4
|
-
# Has default settings,
|
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
|
|
data/lib/authority/controller.rb
CHANGED
@@ -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
|
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
|
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
|
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`
|
data/lib/authority/version.rb
CHANGED
@@ -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
|
39
|
-
|
40
|
-
|
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
|
-
#
|
95
|
-
#
|
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.
|
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-
|
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: &
|
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: *
|
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.
|
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: []
|