access-granted 0.1.1 → 0.2

Sign up to get free protection for your applications and to get access to all the features.
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