access-granted 0.1.0 → 0.1.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.
- checksums.yaml +4 -4
- data/README.md +64 -25
- data/access-granted.gemspec +1 -1
- data/lib/access-granted.rb +0 -7
- data/lib/access-granted/permission.rb +1 -1
- data/lib/access-granted/policy.rb +5 -10
- data/lib/access-granted/role.rb +2 -4
- data/lib/access-granted/version.rb +1 -1
- data/spec/permission_spec.rb +23 -8
- data/spec/policy_spec.rb +61 -32
- data/spec/role_spec.rb +17 -21
- data/spec/spec_helper.rb +0 -1
- metadata +13 -16
- data/lib/access-granted/controller_methods.rb +0 -24
- data/spec/controller_methods_spec.rb +0 -42
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ada45684334e5433ed3504e66d2183464bcf4203
|
4
|
+
data.tar.gz: b0c59ba381cc29461dcb70d13a771dd72c268495
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2db7e6b39316cffabd20ef32e1b93af44f86812af6e93fc4153a03355326608b4727b99b78ac7843a47d3f8c85b3995cae01dd81335f692900f043feeb396c31
|
7
|
+
data.tar.gz: 0c19dd7e52f3ccf791a00ae436cd983df5e64377bf2cf3a6dd1511805f4e62b8cf429b974a3c20b22eca4cd4b564c2fe7d5af5bad1c88c98f5d0fea0d4ee2054
|
data/README.md
CHANGED
@@ -1,4 +1,7 @@
|
|
1
|
-
# AccessGranted [](https://travis-ci.org/chaps-io/access-granted) [](https://codeclimate.com/github/pokonski/access-granted)
|
2
|
+
|
3
|
+
## [](https://chaps.io) proudly made by [Chaps](https://chaps.io)
|
4
|
+
|
2
5
|
|
3
6
|
Multi-role and whitelist based authorization gem for Rails. And it's lightweight (~300 lines of code)!
|
4
7
|
|
@@ -8,24 +11,27 @@ Guaranteed to work on MRI 1.9.3/2.0/2.1, Rubinius >= 2.1.1 and JRuby >= 1.7.6.
|
|
8
11
|
|
9
12
|
# Summary
|
10
13
|
|
11
|
-
AccessGranted is meant as replacement for CanCan to solve three major problems:
|
14
|
+
AccessGranted is meant as a replacement for CanCan to solve three major problems:
|
12
15
|
|
13
|
-
1. built-in support for roles
|
16
|
+
1. **built-in support for roles**
|
14
17
|
|
15
|
-
Easy to read access policy code where permissions are cleanly grouped into roles
|
16
|
-
Additionally permissions are forced to be unique in the scope a role.
|
17
|
-
|
18
|
+
Easy to read access policy code where permissions are cleanly grouped into roles.
|
19
|
+
Additionally, permissions are forced to be unique in the scope of a role. This greatly simplifies the resolving
|
20
|
+
permissions while substantially reducing the code-base.
|
18
21
|
|
19
|
-
2. white-list based
|
22
|
+
2. **white-list based**
|
20
23
|
|
21
|
-
This means that you define what a role **can** do,
|
22
|
-
|
24
|
+
This means that you define what a role **can** do, which results in clean, readable policies regardless of complexity.
|
25
|
+
You don't have to worry about juggling `can`s and `cannot`s in a very convoluted way!
|
23
26
|
|
24
|
-
|
27
|
+
_Note_: `cannot` is still available, but has a very specifc use. See [Usage](#usage) below.
|
25
28
|
|
26
|
-
3.
|
27
|
-
|
28
|
-
|
29
|
+
3. **framework agnostic**
|
30
|
+
|
31
|
+
Permissions can work on basically any object and AccessGranted is framework-agnostic,
|
32
|
+
But we offer extensions for your favourite frameworks as gems:
|
33
|
+
- Rails: [access-granted-rails](https://github.com/pokonski/access-granted-rails)
|
34
|
+
- ... more to come!
|
29
35
|
|
30
36
|
See [Usage](#usage) for an example of a complete AccessPolicy file.
|
31
37
|
|
@@ -41,11 +47,8 @@ This gem was created as a replacement for CanCan and therefore it requires minim
|
|
41
47
|
I decided to not implement this functionality as it was mostly ignored by CanCan users.
|
42
48
|
|
43
49
|
2. Both `can?`/`cannot?` and `authorize!` methods work in Rails controllers and views, just like in CanCan.
|
44
|
-
The only change you have to make is replace all `can? :manage, Class` with
|
45
|
-
`can :manage` is
|
46
|
-
in one line.
|
47
|
-
|
48
|
-
Due to introduction of Roles checking for generic `:manage` permission is very complicated and also confusing for developers.
|
50
|
+
The only change you have to make is to replace all `can? :manage, Class` with the exact action to check against.
|
51
|
+
`can :manage` is still available for **defining** methods and serves as a shortcut for defining `:read`, `:create`, `:update`, `:destroy` all in one line.
|
49
52
|
|
50
53
|
3. Syntax for defining permissions in AccessPolicy file (Ability in CanCan) is exactly the same,
|
51
54
|
with added roles on top. See [Usage](#usage) below.
|
@@ -53,17 +56,15 @@ This gem was created as a replacement for CanCan and therefore it requires minim
|
|
53
56
|
|
54
57
|
## Installation
|
55
58
|
|
56
|
-
|
59
|
+
### Rails
|
57
60
|
|
58
|
-
|
59
|
-
|
60
|
-
And then execute:
|
61
|
+
This includes Rails-specific integration (`can?`, `cannot?`, `current_policy` helpers and more):
|
61
62
|
|
62
|
-
|
63
|
+
gem 'access-granted-rails'
|
63
64
|
|
64
|
-
|
65
|
+
### Others
|
65
66
|
|
66
|
-
|
67
|
+
gem 'access-granted'
|
67
68
|
|
68
69
|
## Usage
|
69
70
|
|
@@ -126,6 +127,44 @@ class Policy
|
|
126
127
|
end
|
127
128
|
```
|
128
129
|
|
130
|
+
## Common examples
|
131
|
+
|
132
|
+
### Extracting roles to separate files
|
133
|
+
|
134
|
+
Let's say your app is getting bigger and more complex. This means your policy file is also getting longer.
|
135
|
+
|
136
|
+
Below you can see an extracted `:member` role:
|
137
|
+
|
138
|
+
```ruby
|
139
|
+
class AccessPolicy
|
140
|
+
include AccessGranted::Policy
|
141
|
+
|
142
|
+
def configure(user)
|
143
|
+
role :administrator, is_admin: true do
|
144
|
+
can :manage, User
|
145
|
+
end
|
146
|
+
|
147
|
+
role :member, MemberRole, lambda { |user| !u.guest? }
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
```
|
152
|
+
|
153
|
+
And roles should look like this
|
154
|
+
|
155
|
+
```ruby
|
156
|
+
# app/roles/member_role.rb
|
157
|
+
|
158
|
+
class MemberRole < AccessGranted::Role
|
159
|
+
def configure(user)
|
160
|
+
can :create, Post
|
161
|
+
can :destroy, Post do |post|
|
162
|
+
post.author == user
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
```
|
167
|
+
|
129
168
|
|
130
169
|
## Contributing
|
131
170
|
|
data/access-granted.gemspec
CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
|
|
10
10
|
spec.email = ["piotrek@okonski.org"]
|
11
11
|
spec.description = %q{Role based authorization gem}
|
12
12
|
spec.summary = %q{Elegant whitelist and role based authorization with ability to prioritize roles.}
|
13
|
-
spec.homepage = "https://github.com/
|
13
|
+
spec.homepage = "https://github.com/chaps-io/access-granted"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
16
16
|
spec.files = `git ls-files`.split($/)
|
data/lib/access-granted.rb
CHANGED
@@ -2,15 +2,8 @@ require "access-granted/version"
|
|
2
2
|
require "access-granted/exceptions"
|
3
3
|
require "access-granted/policy"
|
4
4
|
require "access-granted/permission"
|
5
|
-
require "access-granted/controller_methods"
|
6
5
|
require "access-granted/role"
|
7
6
|
|
8
7
|
module AccessGranted
|
9
8
|
|
10
9
|
end
|
11
|
-
|
12
|
-
if defined? ActionController::Base
|
13
|
-
ActionController::Base.class_eval do
|
14
|
-
include AccessGranted::ControllerMethods
|
15
|
-
end
|
16
|
-
end
|
@@ -5,7 +5,6 @@ module AccessGranted
|
|
5
5
|
def initialize(user)
|
6
6
|
@user = user
|
7
7
|
@roles = []
|
8
|
-
@last_priority = 0
|
9
8
|
configure(@user)
|
10
9
|
end
|
11
10
|
|
@@ -17,19 +16,17 @@ module AccessGranted
|
|
17
16
|
if roles.select {|r| r.name == name }.any?
|
18
17
|
raise DuplicateRole, "Role '#{name}' already defined"
|
19
18
|
end
|
20
|
-
@last_priority += 1
|
21
19
|
r = if conditions_or_klass.is_a?(Class) && conditions_or_klass <= AccessGranted::Role
|
22
|
-
conditions_or_klass.new(name,
|
20
|
+
conditions_or_klass.new(name, conditions, @user, block)
|
23
21
|
else
|
24
|
-
Role.new(name,
|
22
|
+
Role.new(name, conditions_or_klass, @user, block)
|
25
23
|
end
|
26
24
|
roles << r
|
27
|
-
roles.sort_by! {|r| r.priority }
|
28
25
|
r
|
29
26
|
end
|
30
27
|
|
31
28
|
def can?(action, subject)
|
32
|
-
|
29
|
+
matching_roles.each do |role|
|
33
30
|
permission = role.find_permission(action, subject)
|
34
31
|
return permission.granted if permission
|
35
32
|
end
|
@@ -40,10 +37,8 @@ module AccessGranted
|
|
40
37
|
!can?(*args)
|
41
38
|
end
|
42
39
|
|
43
|
-
def
|
44
|
-
roles.select
|
45
|
-
role.applies_to?(user)
|
46
|
-
end
|
40
|
+
def matching_roles
|
41
|
+
roles.select { |role| role.applies_to?(@user) }
|
47
42
|
end
|
48
43
|
|
49
44
|
def authorize!(action, subject)
|
data/lib/access-granted/role.rb
CHANGED
@@ -1,11 +1,10 @@
|
|
1
1
|
module AccessGranted
|
2
2
|
class Role
|
3
|
-
attr_reader :name, :user, :
|
3
|
+
attr_reader :name, :user, :conditions, :permissions
|
4
4
|
|
5
|
-
def initialize(name,
|
5
|
+
def initialize(name, conditions = nil, user = nil, block = nil)
|
6
6
|
@user = user
|
7
7
|
@name = name
|
8
|
-
@priority = priority
|
9
8
|
@conditions = conditions
|
10
9
|
@block = block
|
11
10
|
@permissions = []
|
@@ -45,7 +44,6 @@ module AccessGranted
|
|
45
44
|
end
|
46
45
|
end
|
47
46
|
|
48
|
-
|
49
47
|
def relevant_permissions(action, subject)
|
50
48
|
permissions_by_action(action).select do |perm|
|
51
49
|
perm.matches_subject?(subject)
|
data/spec/permission_spec.rb
CHANGED
@@ -6,51 +6,66 @@ describe AccessGranted::Permission do
|
|
6
6
|
describe "#matches_conditions?" do
|
7
7
|
it "matches when no conditions given" do
|
8
8
|
perm = subject.new(true, :read, String)
|
9
|
-
perm.matches_conditions?(String).
|
9
|
+
expect(perm.matches_conditions?(String)).to eq(true)
|
10
10
|
end
|
11
11
|
|
12
12
|
it "matches proc conditions" do
|
13
13
|
sub = double("Element", published?: true)
|
14
14
|
perm = subject.new(true, :read, sub.class, {}, proc {|el| el.published? })
|
15
|
-
perm.matches_conditions?(sub).
|
15
|
+
expect(perm.matches_conditions?(sub)).to eq(true)
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
19
|
describe "#matches_hash_conditions?" do
|
20
20
|
it "matches condition hash is empty" do
|
21
21
|
perm = subject.new(true, :read, String)
|
22
|
-
perm.matches_hash_conditions?(String).
|
22
|
+
expect(perm.matches_hash_conditions?(String)).to eq(true)
|
23
23
|
end
|
24
24
|
|
25
25
|
it "matches when conditions given" do
|
26
26
|
sub = double("Element", published: true)
|
27
27
|
perm = subject.new(true, :read, sub, { published: true })
|
28
|
-
perm.matches_hash_conditions?(sub).
|
28
|
+
expect(perm.matches_hash_conditions?(sub)).to eq(true)
|
29
29
|
end
|
30
30
|
|
31
31
|
it "does not match if one of the conditions mismatches" do
|
32
32
|
sub = double("Element", published: true, readable: false)
|
33
33
|
perm = subject.new(true, :read, sub, { published: true, readable: true })
|
34
|
-
perm.matches_hash_conditions?(sub).
|
34
|
+
expect(perm.matches_hash_conditions?(sub)).to eq(false)
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
38
|
describe "#matches_action?" do
|
39
39
|
it "matches if actions are identical" do
|
40
40
|
perm = subject.new(true, :read, String)
|
41
|
-
perm.matches_action?(:read).
|
41
|
+
expect(perm.matches_action?(:read)).to_not be_nil
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
45
|
describe "#matches_subject?" do
|
46
46
|
it "matches if subjects are identical" do
|
47
47
|
perm = subject.new(true, :read, String)
|
48
|
-
expect(perm.matches_subject? String).to
|
48
|
+
expect(perm.matches_subject? String).to eq(true)
|
49
49
|
end
|
50
50
|
|
51
51
|
it "matches if class is equal to subject" do
|
52
52
|
perm = subject.new(true, :read, String)
|
53
|
-
expect(perm.matches_subject? "test").to
|
53
|
+
expect(perm.matches_subject? "test").to eq(true)
|
54
|
+
end
|
55
|
+
|
56
|
+
it "matches if superclass is equal to subject" do
|
57
|
+
perm = subject.new(true, :read, Object)
|
58
|
+
expect(perm.matches_subject? "test").to eq(true)
|
59
|
+
end
|
60
|
+
|
61
|
+
it "matches if any ancestor is equal to subject" do
|
62
|
+
perm = subject.new(true, :read, BasicObject)
|
63
|
+
expect(perm.matches_subject? "test").to eq(true)
|
64
|
+
end
|
65
|
+
|
66
|
+
it "does not match if any descendant is equal to subject" do
|
67
|
+
perm = subject.new(true, :read, String)
|
68
|
+
expect(perm.matches_subject? Object.new).to eq(false)
|
54
69
|
end
|
55
70
|
end
|
56
71
|
end
|
data/spec/policy_spec.rb
CHANGED
@@ -1,11 +1,8 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe AccessGranted::Policy do
|
4
|
-
|
5
|
-
|
6
|
-
include AccessGranted::Policy
|
7
|
-
end.new(nil)
|
8
|
-
end
|
4
|
+
let(:klass) { Class.new { include AccessGranted::Policy } }
|
5
|
+
subject(:policy) { klass.new(nil) }
|
9
6
|
|
10
7
|
describe "#configure" do
|
11
8
|
before :each do
|
@@ -33,14 +30,14 @@ describe AccessGranted::Policy do
|
|
33
30
|
end
|
34
31
|
end
|
35
32
|
end
|
36
|
-
klass.new(@admin).can?(:destroy, String).
|
37
|
-
klass.new(@admin).can?(:read, String).
|
33
|
+
expect(klass.new(@admin).can?(:destroy, String)).to eq(true)
|
34
|
+
expect(klass.new(@admin).can?(:read, String)).to eq(true)
|
38
35
|
|
39
|
-
klass.new(@member).cannot?(:destroy, String).
|
40
|
-
klass.new(@member).can?(:read, String).
|
36
|
+
expect(klass.new(@member).cannot?(:destroy, String)).to eq(true)
|
37
|
+
expect(klass.new(@member).can?(:read, String)).to eq(true)
|
41
38
|
|
42
|
-
klass.new(@mod).can?(:read, String).
|
43
|
-
klass.new(@mod).cannot?(:destroy, String).
|
39
|
+
expect(klass.new(@mod).can?(:read, String)).to eq(true)
|
40
|
+
expect(klass.new(@mod).cannot?(:destroy, String)).to eq(true)
|
44
41
|
end
|
45
42
|
|
46
43
|
context "when multiple roles define the same permission" do
|
@@ -62,9 +59,9 @@ describe AccessGranted::Policy do
|
|
62
59
|
end
|
63
60
|
end
|
64
61
|
|
65
|
-
|
66
|
-
|
67
|
-
|
62
|
+
expect(klass.new(@admin).can?(:destroy, user_post)).to eq(true)
|
63
|
+
expect(klass.new(@member).can?(:destroy, user_post)).to eq(true)
|
64
|
+
expect(klass.new(@member).cannot?(:destroy, other_post)).to eq(true)
|
68
65
|
end
|
69
66
|
end
|
70
67
|
describe "#cannot" do
|
@@ -82,8 +79,28 @@ describe AccessGranted::Policy do
|
|
82
79
|
end
|
83
80
|
end
|
84
81
|
end
|
85
|
-
klass.new(@member).can?(:create, String).
|
86
|
-
klass.new(@banned).cannot?(:create, String).
|
82
|
+
expect(klass.new(@member).can?(:create, String)).to eq(true)
|
83
|
+
expect(klass.new(@banned).cannot?(:create, String)).to eq(true)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe "#authorize!" do
|
88
|
+
let(:klass) do
|
89
|
+
Class.new do
|
90
|
+
include AccessGranted::Policy
|
91
|
+
|
92
|
+
def configure(user)
|
93
|
+
role(:member) { can :create, String }
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
it "raises AccessDenied if actions is not allowed" do
|
99
|
+
expect { klass.new(@member).authorize!(:create, Integer) }.to raise_error AccessGranted::AccessDenied
|
100
|
+
end
|
101
|
+
|
102
|
+
it "returns the subject if allowed" do
|
103
|
+
expect(klass.new(@member).authorize!(:create, String)).to equal String
|
87
104
|
end
|
88
105
|
end
|
89
106
|
end
|
@@ -95,39 +112,51 @@ describe AccessGranted::Policy do
|
|
95
112
|
can :read, String
|
96
113
|
end
|
97
114
|
end
|
98
|
-
|
99
|
-
|
115
|
+
subject.role(:member, klass_role)
|
116
|
+
expect(policy.roles.first.class).to eq(klass_role)
|
117
|
+
end
|
118
|
+
|
119
|
+
it "returns roles in the order of priority" do
|
120
|
+
policy.role(:admin)
|
121
|
+
policy.role(:moderator)
|
122
|
+
policy.role(:user)
|
123
|
+
policy.role(:guest)
|
124
|
+
|
125
|
+
expect(policy.roles.map(&:name)).to eq([:admin, :moderator, :user, :guest])
|
100
126
|
end
|
101
127
|
|
102
128
|
it "allows defining a default role" do
|
103
|
-
|
104
|
-
|
129
|
+
policy.role(:member)
|
130
|
+
expect(policy.roles.map(&:name)).to include(:member)
|
105
131
|
end
|
106
132
|
|
107
133
|
it "does not allow duplicate role names" do
|
108
|
-
|
109
|
-
expect {
|
134
|
+
policy.role(:member)
|
135
|
+
expect { policy.role(:member) }.to raise_error AccessGranted::DuplicateRole
|
110
136
|
end
|
111
137
|
|
112
138
|
it "allows nesting `can` calls inside a block" do
|
113
|
-
role =
|
139
|
+
role = policy.role(:member) do
|
114
140
|
can :read, String
|
115
141
|
end
|
116
142
|
|
117
|
-
role.find_permission(:read, String).granted.
|
143
|
+
expect(role.find_permission(:read, String).granted).to eq(true)
|
118
144
|
end
|
119
145
|
end
|
120
146
|
|
121
|
-
describe "#
|
122
|
-
|
123
|
-
user = double("User", is_moderator: true, is_admin: true)
|
147
|
+
describe "#matching_roles" do
|
148
|
+
let(:user) { double("User", is_moderator: true, is_admin: true) }
|
124
149
|
|
125
|
-
|
126
|
-
|
127
|
-
|
150
|
+
before do
|
151
|
+
policy.role(:administrator, { is_admin: true })
|
152
|
+
policy.role(:moderator, { is_moderator: true })
|
153
|
+
policy.role(:member)
|
154
|
+
end
|
128
155
|
|
129
|
-
|
156
|
+
shared_examples 'role matcher' do
|
157
|
+
it "returns all matching roles in the order of priority" do
|
158
|
+
expect(subject.map(&:name)).to eq([:administrator, :moderator, :member])
|
159
|
+
end
|
130
160
|
end
|
131
161
|
end
|
132
|
-
|
133
162
|
end
|
data/spec/role_spec.rb
CHANGED
@@ -7,52 +7,48 @@ describe AccessGranted::Role do
|
|
7
7
|
expect { subject.new }.to raise_error
|
8
8
|
end
|
9
9
|
|
10
|
-
it "requires priority" do
|
11
|
-
expect { subject.new(:member) }.to raise_error
|
12
|
-
end
|
13
|
-
|
14
10
|
it "creates a default role without conditions" do
|
15
|
-
subject.new(:member
|
11
|
+
expect(subject.new(:member).conditions).to be_nil
|
16
12
|
end
|
17
13
|
|
18
14
|
describe "#relevant_permissions?" do
|
19
15
|
it "returns only matching permissions" do
|
20
|
-
role = subject.new(:member
|
16
|
+
role = subject.new(:member)
|
21
17
|
role.can :read, String
|
22
18
|
role.can :read, Hash
|
23
|
-
role.relevant_permissions(:read, String).
|
19
|
+
expect(role.relevant_permissions(:read, String)).to eq([AccessGranted::Permission.new(true, :read, String)])
|
24
20
|
end
|
25
21
|
end
|
26
22
|
|
27
23
|
describe "#applies_to?" do
|
28
24
|
it "matches user when no conditions given" do
|
29
|
-
role = subject.new(:member
|
25
|
+
role = subject.new(:member)
|
30
26
|
user = double("User")
|
31
|
-
role.applies_to?(user).
|
27
|
+
expect(role.applies_to?(user)).to eq(true)
|
32
28
|
end
|
33
29
|
|
34
30
|
it "matches user by hash conditions" do
|
35
|
-
role = subject.new(:moderator,
|
31
|
+
role = subject.new(:moderator, { is_moderator: true })
|
36
32
|
user = double("User", is_moderator: true)
|
37
|
-
role.applies_to?(user).
|
33
|
+
expect(role.applies_to?(user)).to eq(true)
|
38
34
|
end
|
39
35
|
|
40
36
|
it "doesn't match user if any of hash conditions is not met" do
|
41
|
-
role = subject.new(:moderator,
|
37
|
+
role = subject.new(:moderator, { is_moderator: true, is_admin: true })
|
42
38
|
user = double("User", is_moderator: true, is_admin: false)
|
43
|
-
role.applies_to?(user).
|
39
|
+
expect(role.applies_to?(user)).to eq(false)
|
44
40
|
end
|
45
41
|
|
46
42
|
it "matches user by Proc conditions" do
|
47
|
-
role = subject.new(:moderator,
|
43
|
+
role = subject.new(:moderator, proc {|user| user.is_moderator? })
|
48
44
|
user = double("User", is_moderator?: true)
|
49
|
-
role.applies_to?(user).
|
45
|
+
expect(role.applies_to?(user)).to eq(true)
|
50
46
|
end
|
51
47
|
end
|
52
48
|
|
53
49
|
describe "#can" do
|
54
50
|
before :each do
|
55
|
-
@role = AccessGranted::Role.new(:member
|
51
|
+
@role = AccessGranted::Role.new(:member)
|
56
52
|
end
|
57
53
|
|
58
54
|
it "forbids creating actions with the same name" do
|
@@ -62,25 +58,25 @@ describe AccessGranted::Role do
|
|
62
58
|
|
63
59
|
it "accepts :manage shortcut for CRUD actions" do
|
64
60
|
@role.can :manage, String
|
65
|
-
@role.permissions.map(&:action).
|
61
|
+
expect(@role.permissions.map(&:action)).to include(:read, :create, :update, :destroy)
|
66
62
|
end
|
67
63
|
|
68
64
|
describe "when action is an Array" do
|
69
65
|
it "creates multiple permissions" do
|
70
66
|
@role.can [:read, :create], String
|
71
|
-
@role.permissions.
|
67
|
+
expect(@role.permissions.size).to eq(2)
|
72
68
|
end
|
73
69
|
end
|
74
70
|
|
75
71
|
describe "when no conditions given" do
|
76
72
|
it "should be able to read a class" do
|
77
73
|
@role.can :read, String
|
78
|
-
@role.find_permission(:read, String).
|
74
|
+
expect(@role.find_permission(:read, String)).to_not be_nil
|
79
75
|
end
|
80
76
|
|
81
77
|
it "should be able to read instance of class" do
|
82
78
|
@role.can :read, String
|
83
|
-
@role.find_permission(:read, "text").
|
79
|
+
expect(@role.find_permission(:read, "text")).to_not be_nil
|
84
80
|
end
|
85
81
|
end
|
86
82
|
|
@@ -88,7 +84,7 @@ describe AccessGranted::Role do
|
|
88
84
|
it "should be able to read when conditions match" do
|
89
85
|
sub = double("Element", published: true)
|
90
86
|
@role.can :read, sub.class, { published: true }
|
91
|
-
@role.find_permission(:read, sub).
|
87
|
+
expect(@role.find_permission(:read, sub)).to_not be_nil
|
92
88
|
end
|
93
89
|
end
|
94
90
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,41 +1,41 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: access-granted
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotrek Okoński
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-07-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '1.3'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.3'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rspec
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
description: Role based authorization gem
|
@@ -45,27 +45,25 @@ executables: []
|
|
45
45
|
extensions: []
|
46
46
|
extra_rdoc_files: []
|
47
47
|
files:
|
48
|
-
- .gitignore
|
49
|
-
- .rspec
|
50
|
-
- .travis.yml
|
48
|
+
- ".gitignore"
|
49
|
+
- ".rspec"
|
50
|
+
- ".travis.yml"
|
51
51
|
- Gemfile
|
52
52
|
- LICENSE.txt
|
53
53
|
- README.md
|
54
54
|
- Rakefile
|
55
55
|
- access-granted.gemspec
|
56
56
|
- lib/access-granted.rb
|
57
|
-
- lib/access-granted/controller_methods.rb
|
58
57
|
- lib/access-granted/exceptions.rb
|
59
58
|
- lib/access-granted/permission.rb
|
60
59
|
- lib/access-granted/policy.rb
|
61
60
|
- lib/access-granted/role.rb
|
62
61
|
- lib/access-granted/version.rb
|
63
|
-
- spec/controller_methods_spec.rb
|
64
62
|
- spec/permission_spec.rb
|
65
63
|
- spec/policy_spec.rb
|
66
64
|
- spec/role_spec.rb
|
67
65
|
- spec/spec_helper.rb
|
68
|
-
homepage: https://github.com/
|
66
|
+
homepage: https://github.com/chaps-io/access-granted
|
69
67
|
licenses:
|
70
68
|
- MIT
|
71
69
|
metadata: {}
|
@@ -75,23 +73,22 @@ require_paths:
|
|
75
73
|
- lib
|
76
74
|
required_ruby_version: !ruby/object:Gem::Requirement
|
77
75
|
requirements:
|
78
|
-
- -
|
76
|
+
- - ">="
|
79
77
|
- !ruby/object:Gem::Version
|
80
78
|
version: '0'
|
81
79
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
80
|
requirements:
|
83
|
-
- -
|
81
|
+
- - ">="
|
84
82
|
- !ruby/object:Gem::Version
|
85
83
|
version: '0'
|
86
84
|
requirements: []
|
87
85
|
rubyforge_project:
|
88
|
-
rubygems_version: 2.
|
86
|
+
rubygems_version: 2.4.5
|
89
87
|
signing_key:
|
90
88
|
specification_version: 4
|
91
89
|
summary: Elegant whitelist and role based authorization with ability to prioritize
|
92
90
|
roles.
|
93
91
|
test_files:
|
94
|
-
- spec/controller_methods_spec.rb
|
95
92
|
- spec/permission_spec.rb
|
96
93
|
- spec/policy_spec.rb
|
97
94
|
- spec/role_spec.rb
|
@@ -1,24 +0,0 @@
|
|
1
|
-
module AccessGranted
|
2
|
-
module ControllerMethods
|
3
|
-
def current_policy
|
4
|
-
@current_policy ||= ::Policy.new(current_user)
|
5
|
-
end
|
6
|
-
|
7
|
-
def self.included(base)
|
8
|
-
base.helper_method :can?, :cannot?, :current_policy
|
9
|
-
end
|
10
|
-
|
11
|
-
def can?(*args)
|
12
|
-
current_policy.can?(*args)
|
13
|
-
end
|
14
|
-
|
15
|
-
def cannot?(*args)
|
16
|
-
current_policy.cannot?(*args)
|
17
|
-
end
|
18
|
-
|
19
|
-
def authorize!(*args)
|
20
|
-
current_policy.authorize!(*args)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
@@ -1,42 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
describe AccessGranted::ControllerMethods do
|
4
|
-
before(:each) do
|
5
|
-
@current_user = double("User")
|
6
|
-
@controller_class = Class.new
|
7
|
-
@controller = @controller_class.new
|
8
|
-
@controller_class.stub(:helper_method).with(:can?, :cannot?, :current_policy)
|
9
|
-
@controller_class.send(:include, AccessGranted::ControllerMethods)
|
10
|
-
@controller.stub(:current_user).and_return(@current_user)
|
11
|
-
end
|
12
|
-
|
13
|
-
it "should have current_policy method returning Policy instance" do
|
14
|
-
@controller.current_policy.should be_kind_of(AccessGranted::Policy)
|
15
|
-
end
|
16
|
-
|
17
|
-
it "provides can? and cannot? method delegated to current_policy" do
|
18
|
-
@controller.can?(:read, String).should be_false
|
19
|
-
@controller.cannot?(:read, String).should be_true
|
20
|
-
end
|
21
|
-
|
22
|
-
describe "#authorize!" do
|
23
|
-
it "raises exception when authorization fails" do
|
24
|
-
expect { @controller.authorize!(:read, String) }.to raise_error(AccessGranted::AccessDenied)
|
25
|
-
end
|
26
|
-
|
27
|
-
it "returns subject if authorization succeeds" do
|
28
|
-
klass = Class.new do
|
29
|
-
include AccessGranted::Policy
|
30
|
-
|
31
|
-
def configure(user)
|
32
|
-
role :member, 1 do
|
33
|
-
can :read, String
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
policy = klass.new(@current_user)
|
38
|
-
@controller.stub(:current_policy).and_return(policy)
|
39
|
-
@controller.authorize!(:read, String).should == String
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|