access-granted 0.1.1 → 0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ada45684334e5433ed3504e66d2183464bcf4203
4
- data.tar.gz: b0c59ba381cc29461dcb70d13a771dd72c268495
3
+ metadata.gz: 73df010b82397adef1ad1fbfdb345d0e5875ae86
4
+ data.tar.gz: f6db604ca6be5fc22d24225728b700df5ed4db5b
5
5
  SHA512:
6
- metadata.gz: 2db7e6b39316cffabd20ef32e1b93af44f86812af6e93fc4153a03355326608b4727b99b78ac7843a47d3f8c85b3995cae01dd81335f692900f043feeb396c31
7
- data.tar.gz: 0c19dd7e52f3ccf791a00ae436cd983df5e64377bf2cf3a6dd1511805f4e62b8cf429b974a3c20b22eca4cd4b564c2fe7d5af5bad1c88c98f5d0fea0d4ee2054
6
+ metadata.gz: 98ae394fea6d7a5e4695e76746dc6e0701da2be4c21f9145edc979644e22faa2e3f5149bea758ee6799c2914e833d13bb678c051e7a8df8e35a6c42decae21a4
7
+ data.tar.gz: 92f00c7b8668b51f25b4041022e26f095d65e302b79a5853aa500901dd851735b107336fa39e03899e4be723dd29fb78c7506a0e458737a89917e91fb1b831df
@@ -1,10 +1,11 @@
1
1
  language: ruby
2
+ sudo: false
2
3
  rvm:
3
4
  - 1.9.3
4
- - 2.0.0
5
- - 2.1.0
6
- - rbx-2.1.1
7
- - rbx-2.2.3
5
+ - 2.0
6
+ - 2.1
7
+ - 2.2
8
+ - rbx-2
8
9
  - rbx
9
- - jruby-1.7.6
10
+ - jruby-1
10
11
  - jruby
data/Gemfile CHANGED
@@ -8,8 +8,10 @@ group :test, :development do
8
8
  gem 'simplecov', require: false
9
9
  gem 'rake'
10
10
  gem 'pry'
11
+ gem 'cancan'
12
+ gem 'benchmark-ips'
11
13
  end
12
14
 
13
15
  platforms :rbx do
14
- gem 'rubysl', '~> 2.0'
16
+ gem 'rubysl', '~> 2.1'
15
17
  end
data/README.md CHANGED
@@ -5,120 +5,78 @@
5
5
 
6
6
  Multi-role and whitelist based authorization gem for Rails. And it's lightweight (~300 lines of code)!
7
7
 
8
+
9
+ ## Installation
10
+
11
+ gem 'access-granted'
12
+
8
13
  ### Supported Ruby versions
9
14
 
10
- Guaranteed to work on MRI 1.9.3/2.0/2.1, Rubinius >= 2.1.1 and JRuby >= 1.7.6.
15
+ Guaranteed to work on all major Ruby versions MRI 1.9.3-2.2, Rubinius >= 2.X and JRuby >= 1.7.
11
16
 
12
- # Summary
17
+ ## Summary
13
18
 
14
19
  AccessGranted is meant as a replacement for CanCan to solve three major problems:
15
20
 
16
- 1. **built-in support for roles**
21
+ 1. Performance
22
+ On average AccessGranted is 50-60% faster in resolving identical dependencies and takes less memory.
23
+ See [benchmarks](https://github.com/chaps-io/access-granted/blob/master/benchmarks).
24
+
25
+ 2. Built-in support for user roles
17
26
 
18
27
  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.
28
+ Additionally, permissions are forced to be unique in the scope of a role. This greatly simplifies resolving permissions and makes it faster.
21
29
 
22
- 2. **white-list based**
30
+ 3. white-list based
23
31
 
24
- This means that you define what a role **can** do, which results in clean, readable policies regardless of complexity.
32
+ This means that you define what the user **can** do, which results in clean, readable policies regardless of app complexity.
25
33
  You don't have to worry about juggling `can`s and `cannot`s in a very convoluted way!
26
34
 
27
35
  _Note_: `cannot` is still available, but has a very specifc use. See [Usage](#usage) below.
28
36
 
29
- 3. **framework agnostic**
37
+ 4. framework agnostic
30
38
 
31
39
  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!
35
-
36
- See [Usage](#usage) for an example of a complete AccessPolicy file.
37
-
38
- ## Compatibility with CanCan
39
-
40
- This gem was created as a replacement for CanCan and therefore it requires minimum work to switch.
41
-
42
- ### Main differences
43
-
44
- 1. AccessGranted does not extend ActiveRecord in any way, so it does not have the `accessible_by?`
45
- method which could be used for querying objects available to current user.
46
- This was very complex and only worked with permissions defined using hash conditions, so
47
- I decided to not implement this functionality as it was mostly ignored by CanCan users.
48
-
49
- 2. Both `can?`/`cannot?` and `authorize!` methods work in Rails controllers and views, just like in CanCan.
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.
52
-
53
- 3. Syntax for defining permissions in AccessPolicy file (Ability in CanCan) is exactly the same,
54
- with added roles on top. See [Usage](#usage) below.
55
-
56
-
57
- ## Installation
58
-
59
- ### Rails
60
-
61
- This includes Rails-specific integration (`can?`, `cannot?`, `current_policy` helpers and more):
62
-
63
- gem 'access-granted-rails'
64
-
65
- ### Others
66
-
67
- gem 'access-granted'
40
+ but it has Rails support of out the box :)
41
+ It **does not depend on any libraries**, pure and clean Ruby code. Guaranteed to always work,
42
+ even when software around changes.
68
43
 
69
44
  ## Usage
70
45
 
71
46
  Roles are defined using blocks (or by passing custom classes to keep things tidy).
72
- Order of the roles is important, because they are being traversed in the top-to-bottom order. Generally at the top you will have
73
- an admin or other important role giving the user top permissions, and as you go down you define less-privileged roles.
74
47
 
75
- See full example:
48
+ **Order of the roles is VERY important**, because they are being traversed in the top-to-bottom order.
49
+ At the top you must have an admin or other important role giving the user top permissions, and as you go down you define less-privileged roles.
50
+
51
+ ### 1. Defining access policy
52
+
53
+ Let's start with a complete example of what can be achieved:
76
54
 
77
55
  ```ruby
78
- class Policy
56
+ # app/policies/access_policy.rb
57
+
58
+ class AccessPolicy
79
59
  include AccessGranted::Policy
80
60
 
81
61
  def configure(user)
82
- # The most important role prohibiting banned
83
- # users from doing anything.
84
- # (even if they are moderators or admins)
85
- role :banned, { is_banned: true } do
86
- cannot [:create, :update, :destroy], Post
87
-
88
- # same as above, :manage is just a shortcut for
89
- # `[:read, :create, :update, :destroy]`
90
- cannot :manage, Comment
91
- end
92
62
 
93
- # Takes precedences over roles placed lower
94
- # and explicitly lets admin manage everything.
63
+ # The most important admin role, gets checked first
64
+
95
65
  role :admin, { is_admin: true } do
96
66
  can :manage, Post
97
67
  can :manage, Comment
98
68
  end
99
69
 
100
- # You can also use Procs to determine
101
- # if the role should apply to a given user.
70
+ # Less privileged moderator role
102
71
  role :moderator, proc {|u| u.moderator? } do
103
- # takes precedence over :update/:destroy
104
- # permissions defined in member role below
105
- # and lets moderators edit and delete all posts
106
72
  can [:update, :destroy], Post
107
-
108
- # and a new permission which lets moderators
109
- # modify user accounts
110
73
  can :update, User
111
74
  end
112
75
 
113
- # The basic role.
114
- # Applies to everyone logged in.
76
+ # The basic role. Applies to every user.
115
77
  role :member do
116
78
  can :create, Post
117
79
 
118
- # For more advanced permissions
119
- # you must use blocks. Hash
120
- # conditions should be used for
121
- # simple checks only.
122
80
  can [:update, :destroy], Post do |post|
123
81
  post.user_id == user.id && post.comments.empty?
124
82
  end
@@ -127,6 +85,192 @@ class Policy
127
85
  end
128
86
  ```
129
87
 
88
+ #### Defining roles
89
+
90
+ Each `role` method accepts the name of the role you're creating and an optional matcher.
91
+ Matchers are used to check if user belongs to that role and if the permissions inside should be executed against him.
92
+
93
+ The simplest role can be defined as follows:
94
+
95
+ ```ruby
96
+ role :member do
97
+ can :read, Post
98
+ can :create, Post
99
+ end
100
+ ```
101
+
102
+ This role will allow everyone (since we didn't supply a matcher) to read and create posts.
103
+
104
+ But now we want to let admins delete those posts (for example spam posts).
105
+ In this case we create a new role above the `:member` to add more permissions for the admin:
106
+
107
+ ```ruby
108
+ role :admin, { is_admin: true } do
109
+ can :destroy, Post
110
+ end
111
+
112
+ role :member do
113
+ can :read, Post
114
+ can :create, Post
115
+ end
116
+ ```
117
+
118
+ The `{ is_admin: true }` hash is compared with the user's attributes to see if the role should be applied to him.
119
+ So, if the user has an attribute `is_admin` set to `true`, then the role will be applied to him.
120
+
121
+ **Note:** you can use more keys in the hash to check many attributes at once.
122
+
123
+ #### Hash conditions
124
+
125
+ Hashes can be used as matchers as a check if action is permitted.
126
+ For example, we may allow users to only see published posts, like this:
127
+
128
+ ```ruby
129
+ role :member do
130
+ can :read, Post, { published: true }
131
+ end
132
+ ```
133
+
134
+ #### Block conditions
135
+
136
+ "But wait! User should also be able to edit his posts, and only his posts!" you are wondering.
137
+ This can be done using a block condition in `can` method, like this:
138
+
139
+ ```ruby
140
+ role :member do
141
+ can :update, Post do |post|
142
+ post.author_id == user.id
143
+ end
144
+ end
145
+ ```
146
+
147
+ When the given block evaluates to `true`, the user is then given the permission to update the post.
148
+
149
+ #### Roles in order of importance
150
+
151
+ Additionally we can allow admins to update **all** posts despite them not being authors like this:
152
+
153
+
154
+ ```ruby
155
+ role :admin, { is_admin: true } do
156
+ can :update, Post
157
+ end
158
+
159
+ role :member do
160
+ can :update, Post do |post|
161
+ post.author_id == user.id
162
+ end
163
+ end
164
+ ```
165
+
166
+ As stated before: **`:admin` role takes precedence over `:member`** role, so when AccessGranted sees that admin can update all posts, it stops looking at the less important roles.
167
+
168
+ That way you can keep a tidy and readable policy file which is basically human readable.
169
+
170
+ ### Using in Rails
171
+
172
+ AccessGranted comes with a set of helpers available in Ruby on Rails apps:
173
+
174
+ #### Authorizing controller actions
175
+
176
+ ```ruby
177
+ class PostsController
178
+ def show
179
+ @post = Post.find(params[:id])
180
+ authorize! :read, @post
181
+ end
182
+
183
+ def create
184
+ authorize! :create, Post
185
+ # (...)
186
+ end
187
+ end
188
+ ```
189
+
190
+ `authorize!` throws an exception when current user doesn't have a given permission.
191
+ You can rescue from it using `rescue_from`:
192
+
193
+ ```ruby
194
+ class ApplicationController < ActionController::Base
195
+ rescue_from "AccessGranted::AccessDenied" do |exception|
196
+ redirect_to root_path, alert: "You don't have permissions to access this page."
197
+ end
198
+ end
199
+ ```
200
+
201
+ #### Checking permissions in controllers
202
+
203
+ To check if the user has a permission to perform an action, use `can?` and `cannot?` methods.
204
+
205
+ **Example:**
206
+
207
+ ```ruby
208
+ class UsersController
209
+ def update
210
+ # (...)
211
+
212
+ # only admins can elevate users to moderator status
213
+
214
+ if can? :make_moderator, @user
215
+ @user.moderator = params[:user][:moderator]
216
+ end
217
+
218
+ # (...)
219
+ end
220
+ end
221
+
222
+ #### Checking permissions in views
223
+
224
+ Usually you don't want to show "Create" buttons for people who can't create something.
225
+ You can hide any part of the page from users without permissions like this:
226
+
227
+ ```html
228
+ # app/views/categories/index.html.erb
229
+
230
+ <% if can? :create, Category %>
231
+ <%= link_to "Create new category", new_category_path %>
232
+ <% end %>
233
+ ```
234
+
235
+ #### Customizing policy
236
+
237
+ By default AccessGranted adds this method to your controllers:
238
+
239
+ ```ruby
240
+ def current_policy
241
+ @current_policy ||= ::AccessPolicy.new(current_user)
242
+ end
243
+ ```
244
+
245
+ If you have a different policy class or if your user is not stored in `current_user` variable, then you can override it in any controllers and modify the logic as you please.
246
+
247
+ You can even have different policies for different controllers!
248
+
249
+ ### Using in pure Ruby
250
+
251
+ Initialize the Policy class:
252
+
253
+ ```ruby
254
+
255
+ policy = AccessPolicy.new(current_user)
256
+ ```
257
+
258
+ Check the ability to do something:
259
+
260
+ with `can?`:
261
+
262
+ ```ruby
263
+ policy.can?(:create, Post) #=> true
264
+ policy.can?(:update, @post) #=> false
265
+ ```
266
+
267
+ or with `cannot?`:
268
+
269
+ ```ruby
270
+ policy.cannot?(:create, Post) #=> false
271
+ policy.cannot?(:update, @ost) #=> true
272
+ ```
273
+
130
274
  ## Common examples
131
275
 
132
276
  ### Extracting roles to separate files
@@ -165,6 +309,24 @@ class MemberRole < AccessGranted::Role
165
309
  end
166
310
  ```
167
311
 
312
+ ## Compatibility with CanCan
313
+
314
+ This gem was created as a replacement for CanCan and therefore it requires minimum work to switch.
315
+
316
+ ### Main differences
317
+
318
+ 1. AccessGranted does not extend ActiveRecord in any way, so it does not have the `accessible_by?`
319
+ method which could be used for querying objects available to current user.
320
+ This was very complex and only worked with permissions defined using hash conditions, so
321
+ I decided to not implement this functionality as it was mostly ignored by CanCan users.
322
+
323
+ 2. Both `can?`/`cannot?` and `authorize!` methods work in Rails controllers and views, just like in CanCan.
324
+ The only change you have to make is to replace all `can? :manage, Class` with the exact action to check against.
325
+ `can :manage` is still available for **defining** methods and serves as a shortcut for defining `:read`, `:create`, `:update`, `:destroy` all in one line.
326
+
327
+ 3. Syntax for defining permissions in AccessPolicy file (Ability in CanCan) is exactly the same,
328
+ with added roles on top. See [Usage](#usage) below.
329
+
168
330
 
169
331
  ## Contributing
170
332
 
@@ -1,11 +1,10 @@
1
1
  # coding: utf-8
2
2
  lib = File.expand_path('../lib', __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'access-granted/version'
5
4
 
6
5
  Gem::Specification.new do |spec|
7
6
  spec.name = "access-granted"
8
- spec.version = AccessGranted::VERSION
7
+ spec.version = "0.2"
9
8
  spec.authors = ["Piotrek Okoński"]
10
9
  spec.email = ["piotrek@okonski.org"]
11
10
  spec.description = %q{Role based authorization gem}
@@ -19,5 +18,5 @@ Gem::Specification.new do |spec|
19
18
  spec.require_paths = ["lib"]
20
19
 
21
20
  spec.add_development_dependency "bundler", "~> 1.3"
22
- spec.add_development_dependency "rspec"
21
+ spec.add_development_dependency "rspec", "~> 3.0"
23
22
  end
@@ -0,0 +1,24 @@
1
+ # Benchmark results
2
+
3
+ Benchmarks ran on Ubuntu 15.10 64bit, i5 2500k @ 4.4Ghz, 16 GB RAM with Ruby 2.2.
4
+
5
+ ## permissions.rb
6
+
7
+ This benchmark runs `can?` method for the 3 user roles for 20 seconds each, for both CanCan and AccessGranted.
8
+
9
+ ```
10
+ Calculating -------------------------------------
11
+ ag-admin 21.361k i/100ms
12
+ cancan-admin 13.631k i/100ms
13
+ ag-moderator 22.328k i/100ms
14
+ cancan-moderator 11.679k i/100ms
15
+ ag-user 25.860k i/100ms
16
+ cancan-user 16.308k i/100ms
17
+ -------------------------------------------------
18
+ ag-admin 283.174k (± 1.1%) i/s - 5.682M
19
+ cancan-admin 160.450k (± 1.0%) i/s - 3.217M
20
+ ag-moderator 301.290k (± 1.1%) i/s - 6.029M
21
+ cancan-moderator 134.591k (± 1.3%) i/s - 2.698M
22
+ ag-user 353.259k (± 0.9%) i/s - 7.086M
23
+ cancan-user 198.579k (± 1.6%) i/s - 3.979M
24
+ ```
@@ -0,0 +1,36 @@
1
+ class Ability
2
+ include CanCan::Ability
3
+
4
+ def initialize(user)
5
+ if user.is_admin == true
6
+ can :destroy, String
7
+ end
8
+
9
+ if user.is_moderator == true
10
+ can :update, String
11
+ end
12
+
13
+ can :read, String
14
+ end
15
+ end
16
+
17
+ class AccessPolicy
18
+ include AccessGranted::Policy
19
+
20
+ def configure(user)
21
+ role :administrator, { is_admin: true } do
22
+ can :destroy, String
23
+ end
24
+
25
+ role :moderator, { is_moderator: true } do
26
+ can :update, String
27
+ end
28
+
29
+ role :member do
30
+ can :read, String
31
+ end
32
+ end
33
+ end
34
+
35
+ class User < Struct.new(:is_admin, :is_moderator)
36
+ end
@@ -0,0 +1,45 @@
1
+ require 'benchmark/ips'
2
+ require 'access-granted'
3
+ require 'cancan'
4
+ require_relative './config'
5
+
6
+ admin = User.new(true, false)
7
+ mod = User.new(false, true)
8
+ user = User.new(false, false)
9
+
10
+ user_policy = AccessPolicy.new(user)
11
+ admin_policy = AccessPolicy.new(admin)
12
+ mod_policy = AccessPolicy.new(mod)
13
+
14
+ user_ability = Ability.new(user)
15
+ admin_ability = Ability.new(admin)
16
+ mod_ability = Ability.new(mod)
17
+
18
+ Benchmark.ips do |x|
19
+ x.config(time: 20, warmup: 2)
20
+
21
+ x.report("ag-admin") do
22
+ admin_policy.can?(:read, String)
23
+ end
24
+
25
+ x.report("ag-moderator") do
26
+ mod_policy.can?(:read, String)
27
+ end
28
+
29
+ x.report("ag-user") do
30
+ user_policy.can?(:read, String)
31
+ end
32
+
33
+ x.report("cancan-admin") do
34
+ admin_ability.can?(:read, String)
35
+ end
36
+
37
+ x.report("cancan-moderator") do
38
+ mod_ability.can?(:read, String)
39
+ end
40
+
41
+ x.report("cancan-user") do
42
+ user_ability.can?(:read, String)
43
+ end
44
+
45
+ end
@@ -1,9 +1,15 @@
1
- require "access-granted/version"
2
1
  require "access-granted/exceptions"
3
2
  require "access-granted/policy"
4
3
  require "access-granted/permission"
5
4
  require "access-granted/role"
5
+ require 'access-granted/rails/controller_methods'
6
6
 
7
7
  module AccessGranted
8
8
 
9
9
  end
10
+
11
+ if defined? ActionController::Base
12
+ ActionController::Base.class_eval do
13
+ include AccessGranted::Rails::ControllerMethods
14
+ end
15
+ end
@@ -26,7 +26,8 @@ module AccessGranted
26
26
  end
27
27
 
28
28
  def can?(action, subject)
29
- matching_roles.each do |role|
29
+ roles.each do |role|
30
+ next unless role.applies_to?(@user)
30
31
  permission = role.find_permission(action, subject)
31
32
  return permission.granted if permission
32
33
  end
@@ -37,10 +38,6 @@ module AccessGranted
37
38
  !can?(*args)
38
39
  end
39
40
 
40
- def matching_roles
41
- roles.select { |role| role.applies_to?(@user) }
42
- end
43
-
44
41
  def authorize!(action, subject)
45
42
  if cannot?(action, subject)
46
43
  raise AccessDenied
@@ -0,0 +1,25 @@
1
+ module AccessGranted
2
+ module Rails
3
+ module ControllerMethods
4
+ def current_policy
5
+ @current_policy ||= ::AccessPolicy.new(current_user)
6
+ end
7
+
8
+ def self.included(base)
9
+ base.helper_method :can?, :cannot?, :current_policy
10
+ end
11
+
12
+ def can?(*args)
13
+ current_policy.can?(*args)
14
+ end
15
+
16
+ def cannot?(*args)
17
+ current_policy.cannot?(*args)
18
+ end
19
+
20
+ def authorize!(*args)
21
+ current_policy.authorize!(*args)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -28,8 +28,8 @@ module AccessGranted
28
28
  end
29
29
 
30
30
  def find_permission(action, subject)
31
- relevant_permissions(action, subject).detect do |permission|
32
- permission.matches_conditions?(subject)
31
+ permissions_by_action(action).detect do |permission|
32
+ permission.matches_subject?(subject) && permission.matches_conditions?(subject)
33
33
  end
34
34
  end
35
35
 
@@ -44,12 +44,6 @@ module AccessGranted
44
44
  end
45
45
  end
46
46
 
47
- def relevant_permissions(action, subject)
48
- permissions_by_action(action).select do |perm|
49
- perm.matches_subject?(subject)
50
- end
51
- end
52
-
53
47
  def matches_hash?(user, conditions = {})
54
48
  conditions.all? do |name, value|
55
49
  user.send(name) == value
@@ -58,7 +52,7 @@ module AccessGranted
58
52
 
59
53
  def add_permission(granted, action, subject, conditions, block)
60
54
  prepare_actions(action).each do |a|
61
- raise DuplicatePermission if relevant_permissions(a, subject).any?
55
+ raise DuplicatePermission if permission_exists?(a, subject)
62
56
  @permissions << Permission.new(granted, a, subject, conditions, block)
63
57
  @permissions_by_action[a] ||= []
64
58
  @permissions_by_action[a] << @permissions.size - 1
@@ -67,11 +61,17 @@ module AccessGranted
67
61
 
68
62
  private
69
63
 
64
+ def permission_exists?(action, subject)
65
+ permissions_by_action(action).any? do |permission|
66
+ permission.matches_subject?(subject)
67
+ end
68
+ end
69
+
70
70
  def prepare_actions(action)
71
71
  if action == :manage
72
72
  actions = [:read, :create, :update, :destroy]
73
73
  else
74
- actions = [action].flatten
74
+ actions = Array(*[action])
75
75
  end
76
76
  end
77
77
 
@@ -0,0 +1,42 @@
1
+ require "spec_helper"
2
+
3
+ describe AccessGranted::Rails::ControllerMethods do
4
+ before(:each) do
5
+ @current_user = double("User")
6
+ @controller_class = Class.new
7
+ @controller = @controller_class.new
8
+ allow(@controller_class).to receive(:helper_method).with(:can?, :cannot?, :current_policy)
9
+ @controller_class.send(:include, AccessGranted::Rails::ControllerMethods)
10
+ allow(@controller).to receive(:current_user).and_return(@current_user)
11
+ end
12
+
13
+ it "should have current_policy method returning Policy instance" do
14
+ expect(@controller.current_policy).to be_kind_of(AccessGranted::Policy)
15
+ end
16
+
17
+ it "provides can? and cannot? method delegated to current_policy" do
18
+ expect(@controller.can?(:read, String)).to eq(false)
19
+ expect(@controller.cannot?(:read, String)).to eq(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
+ allow(@controller).to receive(:current_policy).and_return(policy)
39
+ expect(@controller.authorize!(:read, String)).to eq(String)
40
+ end
41
+ end
42
+ end
@@ -4,22 +4,13 @@ describe AccessGranted::Role do
4
4
  subject { AccessGranted::Role }
5
5
 
6
6
  it "requires a role name" do
7
- expect { subject.new }.to raise_error
7
+ expect { subject.new }.to raise_error(ArgumentError)
8
8
  end
9
9
 
10
10
  it "creates a default role without conditions" do
11
11
  expect(subject.new(:member).conditions).to be_nil
12
12
  end
13
13
 
14
- describe "#relevant_permissions?" do
15
- it "returns only matching permissions" do
16
- role = subject.new(:member)
17
- role.can :read, String
18
- role.can :read, Hash
19
- expect(role.relevant_permissions(:read, String)).to eq([AccessGranted::Permission.new(true, :read, String)])
20
- end
21
- end
22
-
23
14
  describe "#applies_to?" do
24
15
  it "matches user when no conditions given" do
25
16
  role = subject.new(:member)
@@ -1,5 +1,6 @@
1
1
  require 'rubygems'
2
2
  require 'bundler/setup'
3
+
3
4
  if ENV["COV"]
4
5
  require 'simplecov'
5
6
  SimpleCov.start
@@ -19,12 +20,13 @@ module ActionController
19
20
  end
20
21
  end
21
22
  end
23
+
22
24
  require 'access-granted'
23
25
 
24
26
  class FakePost < Struct.new(:user_id)
25
27
  end
26
28
 
27
- class Policy
29
+ class AccessPolicy
28
30
  include AccessGranted::Policy
29
31
  end
30
32
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: access-granted
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: '0.2'
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: 2015-07-30 00:00:00.000000000 Z
11
+ date: 2015-08-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -28,16 +28,16 @@ dependencies:
28
28
  name: rspec
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: '3.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
- version: '0'
40
+ version: '3.0'
41
41
  description: Role based authorization gem
42
42
  email:
43
43
  - piotrek@okonski.org
@@ -53,12 +53,16 @@ files:
53
53
  - README.md
54
54
  - Rakefile
55
55
  - access-granted.gemspec
56
+ - benchmarks/README.md
57
+ - benchmarks/config.rb
58
+ - benchmarks/permissions.rb
56
59
  - lib/access-granted.rb
57
60
  - lib/access-granted/exceptions.rb
58
61
  - lib/access-granted/permission.rb
59
62
  - lib/access-granted/policy.rb
63
+ - lib/access-granted/rails/controller_methods.rb
60
64
  - lib/access-granted/role.rb
61
- - lib/access-granted/version.rb
65
+ - spec/controller_methods_spec.rb
62
66
  - spec/permission_spec.rb
63
67
  - spec/policy_spec.rb
64
68
  - spec/role_spec.rb
@@ -89,6 +93,7 @@ specification_version: 4
89
93
  summary: Elegant whitelist and role based authorization with ability to prioritize
90
94
  roles.
91
95
  test_files:
96
+ - spec/controller_methods_spec.rb
92
97
  - spec/permission_spec.rb
93
98
  - spec/policy_spec.rb
94
99
  - spec/role_spec.rb
@@ -1,3 +0,0 @@
1
- module AccessGranted
2
- VERSION = "0.1.1"
3
- end