allowy 0.2.4 → 0.2.4.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.
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: