protector 0.2.1 → 0.2.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: 75c42dc51baa287fb4d302415f78e383687b88b0
4
- data.tar.gz: e11a06fc1a46d40deeb04c36295e5efce4795bbf
3
+ metadata.gz: 03db84c2cab1a1f3ea79576688e6102d14976aa1
4
+ data.tar.gz: e89e5f3d0be3758a229e399a7a5696ee71572075
5
5
  SHA512:
6
- metadata.gz: c5c613251c76af90245f55031a26711a193f84474e86d68f352b2afb1d9afb3fd9c77a92faaa396816f00dcf0a579a548fc242766920e600318dd73a1d0e87f0
7
- data.tar.gz: 14f326b243705cdfd75bf132b42c04a8d9e06db85ee6ffa69d9e955251cabe936da2d99a4ecafdd7fe6beb99e01512a84b4e705e7b80e49f1dc242a0017633e8
6
+ metadata.gz: 1606ca8a4e1eb3683912625aec8a7366177fe377029cd05eb1f2ba4a95eaf123edd75b3ac1763101a8b60778d1c15b8fdac8a0e02c2460d084110dcdad0ca07e
7
+ data.tar.gz: 0a093f6600af980f34673ea75217897e29e75b5b1eef34814feea309440bb8f8f142948b8b8f1f53d75054a15fac75418eb80e0397092d79468a646601319733
data/README.md CHANGED
@@ -62,6 +62,8 @@ Now that we have ACL described we can enable it as easy as:
62
62
  article.restrict!(current_user) # Assuming article is an instance of Article
63
63
  ```
64
64
 
65
+ Now if `current_user` is a guest we will get `nil` from `article.text`. At the same time we will get validation error if we pass any fields but title, text and user_id (equal to our own id) on creation.
66
+
65
67
  To make model unsafe again call:
66
68
 
67
69
  ```ruby
@@ -143,6 +145,33 @@ Foo.restrict!(current_user).preload(:bars).join(:bars).where(bars: {absolute: tr
143
145
 
144
146
  Such chain will force the usage of an additional request so the first query will not be scoped with `Bar` restriction.
145
147
 
148
+ ## Manual checks and custom actions
149
+
150
+ Each restricted model responds to the following methods:
151
+
152
+ * `visible?` – determines if the model is visible through restriction scope
153
+ * `creatable?` – determines if you pass validation on creation with the fields you set
154
+ * `updateable?` – determines if you pass validation on update with the fields you changed
155
+ * `destroyable?` – determines if you can destroy the model
156
+
157
+ In fact Protector does not limit you to `:view`, `:update` and `:create` actions. They are just used internally. You however can define any other to make custom roles and restrictions. All of them are able to work on a field level.
158
+
159
+ ```ruby
160
+ protect do
161
+ can :drink, :field1 # Allows `drink` action with field1
162
+ can :eat # Allows `eat` action with any field
163
+ end
164
+ ```
165
+
166
+ To check against custom actions use `can?` method:
167
+
168
+ ```ruby
169
+ model.can?(:drink, :field2) # Checks if model can drink field2
170
+ model.can?(:drink) # Checks if model can drink any field
171
+ ```
172
+
173
+ As you can see you don't have to use fields. You can use `can :foo` and `can? :foo`. While they will bound to fields internally it will work like you expect for empty sets.
174
+
146
175
  ## Ideology
147
176
 
148
177
  Protector is a successor to [Heimdallr](https://github.com/inossidabile/heimdallr). The latter being a proof-of-concept appeared to be way too paranoid and incompatible with the rest of the world. Protector re-implements same idea keeping the Ruby way:
@@ -10,7 +10,7 @@ GIT
10
10
  PATH
11
11
  remote: /Users/inossidabile/Repos/protector
12
12
  specs:
13
- protector (0.2.1)
13
+ protector (0.2.2)
14
14
  activesupport
15
15
  i18n
16
16
 
@@ -9,7 +9,7 @@ GIT
9
9
  PATH
10
10
  remote: /Users/inossidabile/Repos/protector
11
11
  specs:
12
- protector (0.2.1)
12
+ protector (0.2.2)
13
13
  activesupport
14
14
  i18n
15
15
 
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: /Users/inossidabile/Repos/protector
3
3
  specs:
4
- protector (0.2.1)
4
+ protector (0.2.2)
5
5
  activesupport
6
6
  i18n
7
7
 
@@ -110,6 +110,10 @@ module Protector
110
110
  def destroyable?
111
111
  protector_meta.destroyable?
112
112
  end
113
+
114
+ def can?(action, field)
115
+ protector_meta.can?(action, field)
116
+ end
113
117
  end
114
118
  end
115
119
  end
@@ -34,6 +34,7 @@ module Protector
34
34
 
35
35
  # Checks if current model can be selected in the context of current subject
36
36
  def visible?
37
+ return true unless protector_meta.scoped?
37
38
  protector_meta.relation.where(pk_hash).any?
38
39
  end
39
40
 
@@ -54,6 +55,10 @@ module Protector
54
55
  protector_meta.destroyable?
55
56
  end
56
57
 
58
+ def can?(action, field)
59
+ protector_meta.can?(action, field)
60
+ end
61
+
57
62
  # Basic security validations
58
63
  def validate
59
64
  super
@@ -156,7 +156,7 @@ module Protector
156
156
  def can?(action, field=false)
157
157
  return false unless @access[action]
158
158
  return !@access[action].empty? if field === false
159
- @access[action].has_key?(field)
159
+ @access[action].has_key?(field.to_s)
160
160
  end
161
161
 
162
162
  private
@@ -1,4 +1,4 @@
1
1
  module Protector
2
2
  # Gem version
3
- VERSION = "0.2.1"
3
+ VERSION = "0.2.2"
4
4
  end
@@ -41,75 +41,101 @@ describe Protector::DSL do
41
41
  end
42
42
 
43
43
  describe Protector::DSL::Meta do
44
- l = lambda {|x| x > 4 }
44
+ context "basic methods" do
45
+ l = lambda {|x| x > 4 }
45
46
 
46
- before :each do
47
- @meta = Protector::DSL::Meta.new
47
+ before :each do
48
+ @meta = Protector::DSL::Meta.new
48
49
 
49
- @meta << lambda {
50
- scope { 'relation' }
51
- }
50
+ @meta << lambda {
51
+ scope { 'relation' }
52
+ }
52
53
 
53
- @meta << lambda {|user|
54
- user.should == 'user'
54
+ @meta << lambda {|user|
55
+ user.should == 'user'
55
56
 
56
- can :view
57
- cannot :view, %w(field5), :field4
58
- }
57
+ can :view
58
+ cannot :view, %w(field5), :field4
59
+ }
59
60
 
60
- @meta << lambda {|user, entry|
61
- user.should == 'user'
62
- entry.should == 'entry'
61
+ @meta << lambda {|user, entry|
62
+ user.should == 'user'
63
+ entry.should == 'entry'
63
64
 
64
- can :update, %w(field1 field2 field3),
65
- field4: 0..5,
66
- field5: l
65
+ can :update, %w(field1 field2 field3),
66
+ field4: 0..5,
67
+ field5: l
67
68
 
68
- can :destroy
69
- }
70
- end
69
+ can :destroy
70
+ }
71
+ end
71
72
 
72
- it "evaluates" do
73
- @meta.evaluate(nil, 'user', [], 'entry')
74
- end
73
+ it "evaluates" do
74
+ @meta.evaluate(nil, 'user', [], 'entry')
75
+ end
75
76
 
76
- it "sets relation" do
77
- data = @meta.evaluate(nil, 'user', [], 'entry')
78
- data.relation.should == 'relation'
79
- end
77
+ it "sets relation" do
78
+ data = @meta.evaluate(nil, 'user', [], 'entry')
79
+ data.relation.should == 'relation'
80
+ end
80
81
 
81
- it "sets access" do
82
- data = @meta.evaluate(nil, 'user', %w(field1 field2 field3 field4 field5), 'entry')
83
- data.access.should == {
84
- update: {
85
- "field1" => nil,
86
- "field2" => nil,
87
- "field3" => nil,
88
- "field4" => 0..5,
89
- "field5" => l
90
- },
91
- view: {
92
- "field1" => nil,
93
- "field2" => nil,
94
- "field3" => nil
95
- },
96
- create: {}
97
- }
98
- end
82
+ it "sets access" do
83
+ data = @meta.evaluate(nil, 'user', %w(field1 field2 field3 field4 field5), 'entry')
84
+ data.access.should == {
85
+ update: {
86
+ "field1" => nil,
87
+ "field2" => nil,
88
+ "field3" => nil,
89
+ "field4" => 0..5,
90
+ "field5" => l
91
+ },
92
+ view: {
93
+ "field1" => nil,
94
+ "field2" => nil,
95
+ "field3" => nil
96
+ },
97
+ create: {}
98
+ }
99
+ end
99
100
 
100
- it "marks destroyable" do
101
- data = @meta.evaluate(nil, 'user', [], 'entry')
102
- data.destroyable?.should == true
103
- end
101
+ it "marks destroyable" do
102
+ data = @meta.evaluate(nil, 'user', [], 'entry')
103
+ data.destroyable?.should == true
104
+ end
105
+
106
+ it "marks updatable" do
107
+ data = @meta.evaluate(nil, 'user', [], 'entry')
108
+ data.updatable?.should == true
109
+ end
104
110
 
105
- it "marks updatable" do
106
- data = @meta.evaluate(nil, 'user', [], 'entry')
107
- data.updatable?.should == true
111
+ it "marks creatable" do
112
+ data = @meta.evaluate(nil, 'user', [], 'entry')
113
+ data.creatable?.should == false
114
+ end
108
115
  end
109
116
 
110
- it "marks creatable" do
111
- data = @meta.evaluate(nil, 'user', [], 'entry')
112
- data.creatable?.should == false
117
+ context "custom methods" do
118
+ before :each do
119
+ @meta = Protector::DSL::Meta.new
120
+
121
+ @meta << lambda {
122
+ can :drink, :field1
123
+ can :eat
124
+ cannot :eat, :field1
125
+ }
126
+ end
127
+
128
+ it "sets field-level restriction" do
129
+ box = @meta.evaluate(nil, 'user', %w(field1 field2), 'entry')
130
+ box.can?(:drink, :field1).should == true
131
+ box.can?(:drink).should == true
132
+ end
133
+
134
+ it "sets field-level protection" do
135
+ box = @meta.evaluate(nil, 'user', %w(field1 field2), 'entry')
136
+ box.can?(:eat, :field1).should == false
137
+ box.can?(:eat).should == true
138
+ end
113
139
  end
114
140
  end
115
141
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: protector
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Boris Staal