allowy 0.2.6 → 0.3.0

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
@@ -103,6 +103,33 @@ class PagesController < ApplicationController
103
103
  end
104
104
  ```
105
105
 
106
+
107
+ ## Customising access class
108
+
109
+ The "access" class, by convention, will be determined by the class of the original object plus the "Access" suffix.
110
+ It may be a problem if you decorate the class using `draper` gem or using similar approach where the actual class name is different.
111
+
112
+ The version `0.3` of has built-in support for the `draper` gem and it should "just work".
113
+
114
+ But additionally it provides a customisation option for you if you need that.
115
+
116
+ So if you need to change the access class for your object you need to do the following:
117
+
118
+
119
+ ```ruby
120
+ # This will just work provided there's a PageAccess class
121
+ class PageDecorator < Draper::Decorator
122
+ end
123
+
124
+ class PageViewModel < SimpleDelegator
125
+ # This will allow using PageViewModel as it would be just Page
126
+ def self.source_class
127
+ Page
128
+ end
129
+ end
130
+
131
+ ```
132
+
106
133
  ## More comprehensive example
107
134
 
108
135
  You probably have multiple classes that you want to protect.
@@ -1,6 +1,6 @@
1
1
  module Allowy
2
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 `?`.
3
+ # In order to use it, mix it into a plain Ruby class and define methods ending with `?`.
4
4
  # For example:
5
5
  #
6
6
  # @example
@@ -10,6 +10,7 @@ module Allowy
10
10
  # def view?(page)
11
11
  # page and page.wiki? and context.user_signed_in?
12
12
  # end
13
+ # end
13
14
  #
14
15
  # And then you can check the permissions from a controller:
15
16
  #
@@ -20,17 +21,20 @@ module Allowy
20
21
  # end
21
22
  #
22
23
  #
23
- # You can also check the permissions outside of the controller, but you need a similar `Allowy::Context` class:
24
+ # You can also check the permissions outside of the controller, but you need an object that
25
+ # includes `Allowy::Context` class:
24
26
  #
25
27
  # @example
26
28
  # class CucumberContext
27
29
  # include Allowy::Context
28
30
  # attr_accessor :current_user
31
+ #
29
32
  # def initialize(user)
30
33
  # @current_user = user
31
34
  # end
32
35
  # end
33
36
  #
37
+ # CucumberContext.new(that_user).can?(:create, Blog)
34
38
  # CucumberContext.new(that_user).should be_able_to :create, Blog
35
39
  #
36
40
  module AccessControl
@@ -2,11 +2,11 @@ module Allowy
2
2
 
3
3
  # This module provides the default and common context for checking the permissions.
4
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.
5
+ # in other parts of the application (RSpec, Cucumber or standalone).
6
6
  # For example, you can use this code in your Cucumber features:
7
7
  #
8
8
  # @example
9
- # class CustomContext
9
+ # class CucumberContext
10
10
  # include Allowy::Context
11
11
  # attr_accessor :current_user
12
12
  #
@@ -17,7 +17,8 @@ module Allowy
17
17
  # And then you can easily check the permissions like so:
18
18
  #
19
19
  # @example
20
- # CustomContext.new(that_user).should be_able_to :create, Blog
20
+ # CucumberContext.new(that_user).can?(:create, Blog)
21
+ # CucumberContext.new(that_user).should be_able_to :create, Blog
21
22
  module Context
22
23
  extend ActiveSupport::Concern
23
24
 
@@ -13,8 +13,12 @@ module Allowy
13
13
 
14
14
  def access_control_for(subject)
15
15
  return unless subject
16
+
17
+ # Try subject as decorated object
18
+ clazz = class_for "#{subject.class.source_class.name}Access" if subject.class.respond_to?(:source_class)
19
+
16
20
  # Try subject as an object
17
- clazz = class_for "#{subject.class.name}Access"
21
+ clazz = class_for "#{subject.class.name}Access" unless clazz
18
22
 
19
23
  # Try subject as a class
20
24
  clazz = class_for "#{subject.name}Access" if !clazz && subject.is_a?(Class)
@@ -25,7 +29,7 @@ module Allowy
25
29
  end
26
30
 
27
31
  def class_for(name)
28
- name.constantize rescue nil #TODO: Handle just the NameError
32
+ name.safe_constantize
29
33
  end
30
34
 
31
35
  end
@@ -1,3 +1,3 @@
1
1
  module Allowy
2
- VERSION = "0.2.6"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -31,6 +31,16 @@ module Allowy
31
31
  first.should === secnd
32
32
  end
33
33
 
34
+ it "should support objects that provide source_class method (such as Draper)" do
35
+ decorator_class = Class.new do
36
+ def self.source_class
37
+ Sample
38
+ end
39
+ end
40
+ decorated_object = decorator_class.new
41
+ subject.access_control_for!(decorated_object).should be_a SampleAccess
42
+ end
43
+
34
44
  end
35
45
  end
36
46
  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.6
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-06-25 00:00:00.000000000 Z
12
+ date: 2013-02-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: i18n