authority 2.9.0 → 2.10.0
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.
- checksums.yaml +4 -4
- data/.travis.yml +3 -3
- data/CHANGELOG.markdown +5 -0
- data/README.markdown +5 -3
- data/lib/authority.rb +25 -1
- data/lib/authority/controller.rb +22 -9
- data/lib/authority/version.rb +1 -1
- data/spec/authority/controller_spec.rb +31 -27
- data/spec/authority_spec.rb +31 -16
- metadata +12 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fdf6a52e9cb60311ecce6e69f4ee02cf0505596a
|
4
|
+
data.tar.gz: 89a0bca5f2c35bbc1983a11fd5e76906abe517dc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 232f1fa7a9aa66327c3ebc955d5a9b4132762f0d4e484a12c8731428034fc07533a138a76ec7795fb282283fd2476dd9a1480747ea8291c6786a9ec06d8fcbc1
|
7
|
+
data.tar.gz: ad56524c7282089b1bd2fd49f7bf5b76ccddc9fdd6ae1043a4394227978ceeb7e302022af1db47b988eea1e33fcf1e937af856b87677aeb3cf3f88f7184ca5cd
|
data/.travis.yml
CHANGED
@@ -4,10 +4,10 @@ rvm:
|
|
4
4
|
- 1.9.2
|
5
5
|
- 1.9.3
|
6
6
|
- 2.0.0
|
7
|
+
- 2.1.0
|
7
8
|
- jruby-18mode # JRuby in 1.8 mode
|
8
9
|
- jruby-19mode # JRuby in 1.9 mode
|
9
|
-
- rbx
|
10
|
-
- rbx-19mode
|
10
|
+
- rbx
|
11
11
|
|
12
12
|
gemfile:
|
13
13
|
- gemfiles/3.0.gemfile
|
@@ -23,5 +23,5 @@ matrix:
|
|
23
23
|
gemfile: gemfiles/4.0.gemfile
|
24
24
|
- rvm: jruby-18mode
|
25
25
|
gemfile: gemfiles/4.0.gemfile
|
26
|
-
- rvm: rbx
|
26
|
+
- rvm: rbx
|
27
27
|
gemfile: gemfiles/4.0.gemfile
|
data/CHANGELOG.markdown
CHANGED
@@ -2,6 +2,11 @@
|
|
2
2
|
|
3
3
|
Authority does its best to use [semantic versioning](http://semver.org).
|
4
4
|
|
5
|
+
## v2.10.0
|
6
|
+
|
7
|
+
- Ability to return options when looking up a class for `authorize_actions_for`, thanks to [Adam Milligan](https://github.com/orchardadam)
|
8
|
+
- Small refactor in controller code, thanks to [Stacey Touset](https://github.com/capicue)
|
9
|
+
|
5
10
|
## v2.9.0
|
6
11
|
|
7
12
|
Add `all_actions` option for `authorize_actions_for`, thanks to [Igor Davydov](https://github.com/div).
|
data/README.markdown
CHANGED
@@ -250,7 +250,7 @@ class ApplicationAuthorizer < Authority::Authorizer
|
|
250
250
|
|
251
251
|
protected
|
252
252
|
|
253
|
-
def has_role_granting(user, able)
|
253
|
+
def has_role_granting?(user, able)
|
254
254
|
# Does the user have any of the roles which give this permission?
|
255
255
|
(roles_which_grant(able) & user.roles).any?
|
256
256
|
end
|
@@ -390,9 +390,11 @@ class LlamasController < ApplicationController
|
|
390
390
|
authorize_actions_for :llama_class
|
391
391
|
|
392
392
|
def llama_class
|
393
|
-
#
|
394
|
-
# much more carefully
|
393
|
+
# This method can simply return a class...
|
395
394
|
[StandardLlama, LludicrousLlama].sample
|
395
|
+
|
396
|
+
# ... or an array with a class and some options
|
397
|
+
[OptionLladenLlama, {country: 'Peru'}]
|
396
398
|
end
|
397
399
|
end
|
398
400
|
```
|
data/lib/authority.rb
CHANGED
@@ -37,10 +37,10 @@ module Authority
|
|
37
37
|
unless action_authorized?(action, resource, user, options)
|
38
38
|
raise SecurityViolation.new(user, action, resource)
|
39
39
|
end
|
40
|
-
resource
|
41
40
|
end
|
42
41
|
|
43
42
|
def self.action_authorized?(action, resource, user, options = {})
|
43
|
+
raise MissingUser if user.nil?
|
44
44
|
resource_and_maybe_options = [resource, options].tap {|args| args.pop if args.last == {}}
|
45
45
|
user.send("can_#{action}?", *resource_and_maybe_options)
|
46
46
|
end
|
@@ -69,6 +69,30 @@ module Authority
|
|
69
69
|
require 'authority/user_abilities'
|
70
70
|
end
|
71
71
|
|
72
|
+
class MissingUser < StandardError
|
73
|
+
def message
|
74
|
+
"You tried to check authorization on `nil`. Authority doesn't know what
|
75
|
+
`nil` is allowed to do. There are two ways you can fix this.
|
76
|
+
|
77
|
+
1. Authenticate before authorizing. If the user isn't signed in, force
|
78
|
+
them to sign in before they can attempt any action that requires
|
79
|
+
authorization.
|
80
|
+
|
81
|
+
2. When the user is not signed in, return a Null Object instead of
|
82
|
+
`nil`. (You could create an AnonymousUser class, for example.) It should
|
83
|
+
respond to the normal methods Authority will call (like `can_delete?`),
|
84
|
+
possibly by including `Authority::UserAbilities` and teaching your authorizers
|
85
|
+
what an anonymous user can do.
|
86
|
+
|
87
|
+
The downside of solution #2 is that a user who forgot to sign in will be
|
88
|
+
told they are not authorized for an action they could normally do. This might
|
89
|
+
be confusing.
|
90
|
+
|
91
|
+
However, you might use both strategies in different parts of your application.
|
92
|
+
"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
72
96
|
end
|
73
97
|
|
74
98
|
require 'authority/configuration'
|
data/lib/authority/controller.rb
CHANGED
@@ -43,7 +43,8 @@ module Authority
|
|
43
43
|
# ones and any other options applicable to a before_filter
|
44
44
|
def authorize_actions_for(resource_or_finder, options = {})
|
45
45
|
self.authority_resource = resource_or_finder
|
46
|
-
|
46
|
+
add_actions(options.fetch(:actions, {}))
|
47
|
+
force_action(options[:all_actions]) if options[:all_actions]
|
47
48
|
before_filter :run_authorization_check, options
|
48
49
|
end
|
49
50
|
|
@@ -51,8 +52,9 @@ module Authority
|
|
51
52
|
#
|
52
53
|
# @param [Hash] action_map - controller actions and methods, to be merged with existing action_map
|
53
54
|
def authority_actions(action_map)
|
54
|
-
|
55
|
-
|
55
|
+
forced_action = action_map.delete(:all_actions)
|
56
|
+
add_actions(action_map)
|
57
|
+
force_action(forced_action) if forced_action
|
56
58
|
end
|
57
59
|
|
58
60
|
def authority_action(action_map)
|
@@ -78,13 +80,24 @@ module Authority
|
|
78
80
|
@authority_action_map ||= Authority.configuration.controller_action_map.dup
|
79
81
|
end
|
80
82
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
83
|
+
# Adds the passed in actions to the current action map.
|
84
|
+
#
|
85
|
+
# @param [Hash] action_map - controller actions and methods to be merged
|
86
|
+
# with the existing action map
|
87
|
+
def add_actions(action_map)
|
88
|
+
authority_action_map.merge!(action_map)
|
86
89
|
end
|
87
90
|
|
91
|
+
# Updates the current action map to use the forced action for all of it's
|
92
|
+
# actions.
|
93
|
+
#
|
94
|
+
# @param [String OR Symbol] forced_action - the authority action to use
|
95
|
+
# for all Rails actions in the action map
|
96
|
+
def force_action(forced_action)
|
97
|
+
add_actions(
|
98
|
+
Hash[authority_action_map.map {|key, _| [key, forced_action] }]
|
99
|
+
)
|
100
|
+
end
|
88
101
|
end
|
89
102
|
|
90
103
|
protected
|
@@ -120,7 +133,7 @@ module Authority
|
|
120
133
|
# The `before_filter` that will be setup to run when the class method
|
121
134
|
# `authorize_actions_for` is called
|
122
135
|
def run_authorization_check
|
123
|
-
authorize_action_for
|
136
|
+
authorize_action_for(*instance_authority_resource)
|
124
137
|
end
|
125
138
|
|
126
139
|
def instance_authority_resource
|
data/lib/authority/version.rb
CHANGED
@@ -109,16 +109,24 @@ describe Authority::Controller do
|
|
109
109
|
it "if :all_actions option is given, it overrides the action hash to use the action given" do
|
110
110
|
overridden_action_map = controller_class.authority_action_map
|
111
111
|
overridden_action_map.update(overridden_action_map) {|k,v| v = :annihilate}
|
112
|
-
child_controller.should_receive(:authority_actions).with(overridden_action_map)
|
113
112
|
child_controller.authorize_actions_for(resource_class, :all_actions => :annihilate)
|
113
|
+
child_controller.authority_action_map.should eq(overridden_action_map)
|
114
114
|
end
|
115
115
|
|
116
|
-
it "passes the action hash to the `
|
116
|
+
it "passes the action hash to the `add_actions` method" do
|
117
117
|
new_actions = {:synthesize => :create, :annihilate => 'delete'}
|
118
|
-
child_controller.should_receive(:
|
118
|
+
child_controller.should_receive(:add_actions).with(new_actions)
|
119
119
|
child_controller.authorize_actions_for(resource_class, :actions => new_actions)
|
120
120
|
end
|
121
121
|
|
122
|
+
it "updates the action map if :actions option is given" do
|
123
|
+
updated_map = child_controller.authority_action_map
|
124
|
+
updated_map[:synthesize] = :create
|
125
|
+
new_actions = {:synthesize => :create}
|
126
|
+
child_controller.authorize_actions_for(resource_class, :actions => new_actions)
|
127
|
+
expect(child_controller.authority_action_map).to eq(updated_map)
|
128
|
+
end
|
129
|
+
|
122
130
|
end
|
123
131
|
|
124
132
|
describe "authority_resource" do
|
@@ -178,25 +186,6 @@ describe Authority::Controller do
|
|
178
186
|
|
179
187
|
end
|
180
188
|
|
181
|
-
describe "overridden_actions" do
|
182
|
-
|
183
|
-
it "overrides authority action map if option :all_actions is present" do
|
184
|
-
options = { :all_actions => :display, :actions => {:show => :display, :synthesize => :create} }
|
185
|
-
expect(controller_class.overridden_actions(options).values.uniq).to eq([:display])
|
186
|
-
end
|
187
|
-
|
188
|
-
it "returns :actions hash if option :all_actions is not present" do
|
189
|
-
options = { :actions => {:show => :display, :synthesize => :create, :annihilate => 'delete'} }
|
190
|
-
expect(controller_class.overridden_actions(options)).to eq(options[:actions])
|
191
|
-
end
|
192
|
-
|
193
|
-
it "returns an empty hash if no :all_actions nor :actions options present" do
|
194
|
-
options = { :show => :display, :synthesize => :create, :annihilate => 'delete' }
|
195
|
-
expect(controller_class.overridden_actions(options)).to eq({})
|
196
|
-
end
|
197
|
-
|
198
|
-
end
|
199
|
-
|
200
189
|
describe "ensure_authorization_performed" do
|
201
190
|
|
202
191
|
let(:controller_instance) { controller_class.new }
|
@@ -294,13 +283,28 @@ describe Authority::Controller do
|
|
294
283
|
|
295
284
|
context "if the controller has such an instance method" do
|
296
285
|
|
297
|
-
|
298
|
-
|
286
|
+
context "and the method returns a class" do
|
287
|
+
before :each do
|
288
|
+
controller_instance.stub(:method_to_find_class).and_return(resource_class)
|
289
|
+
end
|
290
|
+
|
291
|
+
it "checks authorization on that class" do
|
292
|
+
controller_instance.should_receive(:authorize_action_for).with(resource_class)
|
293
|
+
controller_instance.send(:run_authorization_check)
|
294
|
+
end
|
299
295
|
end
|
300
296
|
|
301
|
-
|
302
|
-
|
303
|
-
|
297
|
+
context "and the method returns an array containing a class and some options" do
|
298
|
+
let(:some_options) { { :a => 1, :b => 2 } }
|
299
|
+
|
300
|
+
before :each do
|
301
|
+
controller_instance.stub(:method_to_find_class).and_return([resource_class, some_options])
|
302
|
+
end
|
303
|
+
|
304
|
+
it "checks authorization on that class and passes the options" do
|
305
|
+
controller_instance.should_receive(:authorize_action_for).with(resource_class, some_options)
|
306
|
+
controller_instance.send(:run_authorization_check)
|
307
|
+
end
|
304
308
|
end
|
305
309
|
|
306
310
|
end
|
data/spec/authority_spec.rb
CHANGED
@@ -39,34 +39,49 @@ describe Authority do
|
|
39
39
|
|
40
40
|
describe "enforcement" do
|
41
41
|
|
42
|
-
let(:user) { ExampleUser.new }
|
43
42
|
let(:resource_class) { ExampleResource }
|
44
43
|
|
45
|
-
describe "when given
|
44
|
+
describe "when given a user object" do
|
45
|
+
|
46
|
+
let(:user) { ExampleUser.new }
|
47
|
+
|
48
|
+
describe "when given options" do
|
49
|
+
|
50
|
+
it "checks the user's authorization, passing along the options" do
|
51
|
+
options = { :for => 'context' }
|
52
|
+
user.should_receive(:can_delete?).with(resource_class, options).and_return(true)
|
53
|
+
Authority.enforce(:delete, resource_class, user, options)
|
54
|
+
end
|
46
55
|
|
47
|
-
it "checks the user's authorization, passing along the options" do
|
48
|
-
options = { :for => 'context' }
|
49
|
-
user.should_receive(:can_delete?).with(resource_class, options).and_return(true)
|
50
|
-
Authority.enforce(:delete, resource_class, user, options)
|
51
56
|
end
|
52
57
|
|
53
|
-
|
58
|
+
describe "when not given options" do
|
54
59
|
|
55
|
-
|
60
|
+
it "checks the user's authorization, passing no options" do
|
61
|
+
user.should_receive(:can_delete?).with(resource_class).and_return(true)
|
62
|
+
Authority.enforce(:delete, resource_class, user)
|
63
|
+
end
|
56
64
|
|
57
|
-
it "checks the user's authorization, passing no options" do
|
58
|
-
user.should_receive(:can_delete?).with(resource_class).and_return(true)
|
59
|
-
Authority.enforce(:delete, resource_class, user)
|
60
65
|
end
|
61
66
|
|
62
|
-
|
67
|
+
it "raises a SecurityViolation if the action is unauthorized" do
|
68
|
+
expect { Authority.enforce(:update, resource_class, user) }.to raise_error(Authority::SecurityViolation)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "doesn't raise a SecurityViolation if the action is authorized" do
|
72
|
+
expect { Authority.enforce(:read, resource_class, user) }.not_to raise_error()
|
73
|
+
end
|
63
74
|
|
64
|
-
it "raises a SecurityViolation if the action is unauthorized" do
|
65
|
-
expect { Authority.enforce(:update, resource_class, user) }.to raise_error(Authority::SecurityViolation)
|
66
75
|
end
|
67
76
|
|
68
|
-
|
69
|
-
|
77
|
+
describe "when given a nil user" do
|
78
|
+
|
79
|
+
let(:user) { nil }
|
80
|
+
|
81
|
+
it "raises a helpful error" do
|
82
|
+
expect { Authority.enforce(:update, resource_class, user) }.to raise_error(Authority::MissingUser)
|
83
|
+
end
|
84
|
+
|
70
85
|
end
|
71
86
|
|
72
87
|
end
|
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.
|
4
|
+
version: 2.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nathan Long
|
@@ -9,34 +9,34 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2014-04-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
|
-
- -
|
18
|
+
- - ">="
|
19
19
|
- !ruby/object:Gem::Version
|
20
20
|
version: 3.0.0
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
|
-
- -
|
25
|
+
- - ">="
|
26
26
|
- !ruby/object:Gem::Version
|
27
27
|
version: 3.0.0
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: rake
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
31
31
|
requirements:
|
32
|
-
- -
|
32
|
+
- - ">="
|
33
33
|
- !ruby/object:Gem::Version
|
34
34
|
version: 0.8.7
|
35
35
|
type: :runtime
|
36
36
|
prerelease: false
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
|
-
- -
|
39
|
+
- - ">="
|
40
40
|
- !ruby/object:Gem::Version
|
41
41
|
version: 0.8.7
|
42
42
|
description: Authority helps you authorize actions in your Rails app. It's ORM-neutral
|
@@ -49,9 +49,9 @@ executables: []
|
|
49
49
|
extensions: []
|
50
50
|
extra_rdoc_files: []
|
51
51
|
files:
|
52
|
-
- .gitignore
|
53
|
-
- .rspec
|
54
|
-
- .travis.yml
|
52
|
+
- ".gitignore"
|
53
|
+
- ".rspec"
|
54
|
+
- ".travis.yml"
|
55
55
|
- CHANGELOG.markdown
|
56
56
|
- CONTRIBUTING.markdown
|
57
57
|
- Gemfile
|
@@ -97,17 +97,17 @@ require_paths:
|
|
97
97
|
- lib
|
98
98
|
required_ruby_version: !ruby/object:Gem::Requirement
|
99
99
|
requirements:
|
100
|
-
- -
|
100
|
+
- - ">="
|
101
101
|
- !ruby/object:Gem::Version
|
102
102
|
version: '0'
|
103
103
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
104
|
requirements:
|
105
|
-
- -
|
105
|
+
- - ">="
|
106
106
|
- !ruby/object:Gem::Version
|
107
107
|
version: '0'
|
108
108
|
requirements: []
|
109
109
|
rubyforge_project:
|
110
|
-
rubygems_version: 2.0
|
110
|
+
rubygems_version: 2.2.0
|
111
111
|
signing_key:
|
112
112
|
specification_version: 4
|
113
113
|
summary: Authority helps you authorize actions in your Rails app using plain Ruby
|