protector 0.2.1 → 0.2.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: 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