allowy 0.2.4 → 0.2.4.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -14,10 +14,10 @@ CanCan doesn't work very well for me when Ability definitions grow above 20 line
14
14
 
15
15
  - it becomes **really hard to track down** why something was (or not) allowed.
16
16
  - **DSL enforces** you to use ActiveRecord-like scopes or blocks. It gets harder to maintain.
17
- - The Ability class contains **all the definitions for everything**. Hard to test, hard to maintain unless carefully refactor it.
18
- - Implicit permission - CanCan tries to be very smart (and is indeed) using aliases such as `:manage` but it makes even harder to maintain.
17
+ - The Ability class contains **all the definitions for everything**. Hard to test, hard to maintain unless you carefully refactor it.
18
+ - Implicit permission - CanCan tries to be very smart (and is indeed) using aliases such as `:manage` but it makes even harder to understand it.
19
19
  - Implicit permission - you can use any symbol to check permissions. `:love_people` will do, even if you never defined it.
20
- - A little bit **tight to ORM**. When using with database such as neo4j, some smalish things don't work. So I prefer to be explicit.
20
+ - A little bit **tight to ORM**. When using with database such as neo4j, some small-ish things don't work. So I prefer to be explicit.
21
21
  - **Testing** an ability for a single class often depends on too many others.
22
22
  - **Refacoring** of the abilities feels like rolling your own authorization library.
23
23
 
@@ -36,7 +36,7 @@ gem 'allowy'
36
36
 
37
37
  Then `bundle install`.
38
38
 
39
- Or use `allowy` gem any other way you are not in Rails.
39
+ Or use `allowy` gem as usually.
40
40
 
41
41
  # Usage
42
42
 
@@ -53,7 +53,7 @@ If you want to safeguard `Page` class then define `PageAccess` class:
53
53
  class PageAccess
54
54
  include Allowy::AccessControl
55
55
 
56
- # This will allow you to ask: can? :view, page
56
+ # This will allow you to ask: `can? :view, page`
57
57
  # The truthy result of this function will grant access, otherwise not.
58
58
  def view?(page)
59
59
  page and page.published?
@@ -64,11 +64,11 @@ class PageAccess
64
64
  end
65
65
  end
66
66
 
67
- # Then, in rails, you would use it:
67
+ # Then, in rails controller/view, you would use it:
68
68
  can? :view, page
69
69
  cannot? :edit, page
70
70
  authorize! :view, page # raises Allowy::AccessDenied if can?(:view, page) returns false
71
- can? :love_people, page # Will raise error because `love_people` is not defined on the Access Control class
71
+ can? :love_people, page # Will raise NoMethodError because `love_people` is not defined on the Access Control class
72
72
  ```
73
73
 
74
74
  ## Context
@@ -82,18 +82,23 @@ class PageAccess
82
82
  include Allowy::AccessControl
83
83
 
84
84
  def view?(page)
85
- return true if context.params[:hiddedn_hack_for_admin]
85
+ return true if context.params[:hidden_hack_for_admin]
86
86
  context.user_signed_in? and page.published?
87
87
  end
88
88
  end
89
89
  ```
90
90
 
91
- If you want to change the context in Rails then just override it in the controller or globally in the `ApplicationController`:
91
+ If you want to change the context in Rails then just override it in the controller or globally in the `ApplicationController`.
92
+ The only requirement for the context is that it should mix-in the `Allowy::Context` module.
92
93
 
93
94
  ```ruby
95
+ class CmsContext < Hash
96
+ include Allowy::Context
97
+ end
98
+
94
99
  class PagesController < ApplicationController
95
100
  def allowy_context
96
- {realy: 'anything', can_be: 'here', even: params}
101
+ CmsContext.new {realy: 'anything', can_be: 'here', even: params}
97
102
  end
98
103
  end
99
104
  ```
@@ -101,7 +106,7 @@ end
101
106
  ## More comprehensive example
102
107
 
103
108
  You probably have multiple classes that you want to protect.
104
- I recommend creating your own base class to provide common context and maybe some utility methods:
109
+ I recommend creating your own base class or module to provide common context and maybe some utility methods:
105
110
 
106
111
  ```ruby
107
112
  class DefaultAccess
@@ -179,7 +184,11 @@ To test the access control classes you can just instantiate those passing contex
179
184
  Most of the time you will stub out the context, so the test isolation is a piece of cake.
180
185
 
181
186
  You need to `require 'allowy/rspec'`.
182
- It will give you RSpec matcher `be_able_to` and `ignore_authorization!` macro for controller specs.
187
+ It will give you:
188
+
189
+ - `be_able_to` RSpec matcher;
190
+ - `ignore_authorization!` macro for controller specs;
191
+ - `should_authorize_for!` macro for controller specs (can **only** be used with `ignore_authorization!`).
183
192
 
184
193
 
185
194
  ```ruby
@@ -197,17 +206,32 @@ describe PageAccess do
197
206
  subject.view?(page).should be_false
198
207
  end
199
208
 
200
- context "when published" do
201
- before { page.publish! }
202
- it { should be_able_to :view, page }
209
+ context "I prefer RSpec contexts" do
210
+ subject { PageAccess.new(stub(:current_user: user)).view?(page) }
211
+
212
+ context "when logged in" do
213
+ let(:user) { stub 'User' }
214
+ context "and page is wiki" do
215
+ before { page.stub(wiki?: true) }
216
+ it { should be_true }
217
+ end
218
+ context "and page is not wiki" do
219
+ before { page.stub(wiki?: false) }
220
+ it { should be_false }
221
+ end
222
+ end
223
+
224
+ context "when anonim" do
225
+ let(:user) { nil }
226
+ it { should be_false }
227
+ end
203
228
  end
204
- end
205
229
 
206
- # and so on
230
+ end
207
231
  end
208
232
 
209
233
 
210
- # Example of a controller specs
234
+ # Example of a controller spec
211
235
  describe PagesController do
212
236
  # This will always grant access, so you don't have to create too many objects
213
237
  # But make sure you test PageAccess separately as in the example above
@@ -225,25 +249,6 @@ end
225
249
 
226
250
  ```
227
251
 
228
- But if you don't want to stub the context because you access its `can?`, `cannot?` or `authorize!` methods
229
- (allwing permission delegation) then you can simply mix the `Allowy::Context` in:
230
-
231
- ```ruby
232
- class ControllerLikeContext
233
- include Alllowy::Context
234
- attr_accessor :current_user
235
-
236
- def initialize(user)
237
- @current_user = user
238
- end
239
- end
240
-
241
- # Then you can simply instantiate it to check the permissions:
242
- ControllerLikeContext.new(that_user).should be_able_to :edit, Blog
243
- ControllerLikeContext.new(this_user).should_not be_able_to :edit, Blog
244
- ```
245
-
246
-
247
252
  # Development
248
253
 
249
254
 
@@ -1,4 +1,38 @@
1
1
  module Allowy
2
+ # This module provides the interface for implementing the access control actions.
3
+ # In order to use it, mix it into a poor Ruby class and define methods ending with `?`.
4
+ # For example:
5
+ #
6
+ # @example
7
+ # class PageAccess
8
+ # include Allowy::AccessControl
9
+ #
10
+ # def view?(page)
11
+ # page and page.wiki? and context.user_signed_in?
12
+ # end
13
+ #
14
+ # And then you can check the permissions from a controller:
15
+ #
16
+ # @example
17
+ # def show
18
+ # @page = Page.find params[:id]
19
+ # authorize! :view, @page
20
+ # end
21
+ #
22
+ #
23
+ # You can also check the permissions outside of the controller, but you need a similar `Allowy::Context` class:
24
+ #
25
+ # @example
26
+ # class CucumberContext
27
+ # include Allowy::Context
28
+ # attr_accessor :current_user
29
+ # def initialize(user)
30
+ # @current_user = user
31
+ # end
32
+ # end
33
+ #
34
+ # CucumberContext.new(that_user).should be_able_to :create, Blog
35
+ #
2
36
  module AccessControl
3
37
  extend ActiveSupport::Concern
4
38
  included do
@@ -1,8 +1,8 @@
1
1
  module Allowy
2
2
 
3
- # This module provides the default and common context to for checking the permissions.
4
- # It is mixed into the Controller in Rails by default and provides an wasy way to reuse it
5
- # in other parts of the application (in RSpec or Cucumber) without needint a controller.
3
+ # This module provides the default and common context for checking the permissions.
4
+ # It is mixed into controllers in Rails by default and provides an easy way to reuse it
5
+ # in other parts of the application (in RSpec or Cucumber) without needing a controller.
6
6
  # For example, you can use this code in your Cucumber features:
7
7
  #
8
8
  # @example
@@ -14,7 +14,7 @@ module Allowy
14
14
  # @current_user = user
15
15
  # end
16
16
  #
17
- # And the you can easily check the permissions simply using something like:
17
+ # And the you can easily check the permissions like so:
18
18
  #
19
19
  # @example
20
20
  # CustomContext.new(that_user).should be_able_to :create, Blog
@@ -1,3 +1,3 @@
1
1
  module Allowy
2
- VERSION = "0.2.4"
2
+ VERSION = "0.2.4.1"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: allowy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.2.4.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-04-18 00:00:00.000000000 Z
12
+ date: 2012-04-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: i18n
16
- requirement: &70247249036100 !ruby/object:Gem::Requirement
16
+ requirement: &70101345958680 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70247249036100
24
+ version_requirements: *70101345958680
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: activesupport
27
- requirement: &70247249035480 !ruby/object:Gem::Requirement
27
+ requirement: &70101345957600 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '3.2'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70247249035480
35
+ version_requirements: *70101345957600
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rspec
38
- requirement: &70247249034940 !ruby/object:Gem::Requirement
38
+ requirement: &70101345946120 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *70247249034940
46
+ version_requirements: *70101345946120
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: pry
49
- requirement: &70247249034400 !ruby/object:Gem::Requirement
49
+ requirement: &70101345945020 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *70247249034400
57
+ version_requirements: *70101345945020
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: guard
60
- requirement: &70247249033880 !ruby/object:Gem::Requirement
60
+ requirement: &70101345944200 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '0'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *70247249033880
68
+ version_requirements: *70101345944200
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: guard-rspec
71
- requirement: &70247249023080 !ruby/object:Gem::Requirement
71
+ requirement: &70101345943120 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,7 +76,7 @@ dependencies:
76
76
  version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *70247249023080
79
+ version_requirements: *70101345943120
80
80
  description: Allowy provides CanCan-like way of checking permission but doesn't enforce
81
81
  a tight DSL giving you more control
82
82
  email: