restricted_attributes 1.0.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/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 [name of plugin creator]
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,499 @@
1
+ RestrictedAttributes
2
+ ====================
3
+
4
+ This restricted_attributes plugin provides the capabilities to restrict attributes(fields)
5
+ of db table's while add or update a record. It validate your attributes values before
6
+ your validation stuff.
7
+
8
+ Features
9
+ ========
10
+
11
+ - Provides four different ways of restriction on fields (i.e read_only, create_only, update_only and hidden)
12
+ - Restrict to add/modify values of particular attributes at model level while creating/updating a record.
13
+ - Restrict functionality perform at before validation.
14
+ - Able to set restriction on instance varibles also.
15
+ - OPTIONAL : It can also works on the basis of declarative_authorization roles system.
16
+ - So, able to set role wise restriction/permission on various users to change the value of an attributes.
17
+
18
+
19
+
20
+
21
+ *NOTE: Try its simple version(i.e simple_restricted_attributes plugin) if you are NOT using declarative_authorization plugin/gem. Find more information about that plugin on following link
22
+ (More Info - https://github.com/gkathare/simple_restricted_attributes)
23
+
24
+
25
+
26
+
27
+
28
+ Method
29
+ ======
30
+ has_restricted_attributes(options = {})
31
+
32
+ This method accepts the options in a hash:
33
+
34
+ 1 :read_only # In this you can add attributes to restrict from add/update the value.
35
+ # Access attributes values: can read, But can't add or modify
36
+ # Format for single attribute -
37
+ # :read_only => :name or :read_only => "name"
38
+ # Format for array of attributes -
39
+ # :read_only => [:name, :bio] or :read_only => ["name", "bio"]
40
+
41
+ 2 :create_only # In this you can add attributes to restrict from update the value.
42
+ # Access attributes values: can read and add, But can't modify.
43
+ # Format for single attribute -
44
+ # :create_only => :name or :create_only => "name"
45
+ # Format for array of attributes -
46
+ # :create_only => [:name, :bio] or :create_only => ["name", "bio"]
47
+
48
+ 3 :update_only # In this you can add attributes to restrict from add the value.
49
+ # Access attributes values: can read and modify, But can't add.
50
+ # Format for single attribute -
51
+ # :update_only => :name or :update_only => "name"
52
+ # Format for array of attributes -
53
+ # :update_only => [:name, :bio] or :update_only => ["name", "bio"]
54
+
55
+ 4 :hidden_only # In this you can add attributes to restrict from add/update the value.
56
+ # Mainly used with 'is_restricted?()' helper Method & instance Method to
57
+ # check has a read access or not.
58
+ # Access attributes values: can read, But can't add or modify.
59
+ # Format for single attribute -
60
+ # :hidden_only => :name or :hidden_only => "name"
61
+ # Format for array of attributes -
62
+ # :hidden_only => [:name, :bio] or :hidden_only => ["name", "bio"]
63
+
64
+ *5 :declarative # IMPORTANT - Useful only if you are using declarative_authorization
65
+ # plugin or gem in your application.
66
+ # -Provides capability to set restriction on the basis of
67
+ # declarative_authorization(plugin/gem) role system.
68
+ # -So you can restrict/permit to change the value of a
69
+ # attributes role wise for various users in the application.
70
+
71
+ # Format - :declarative => false or :declarative => true .
72
+ # Use :declarative tag if you want follow role system with
73
+ # declarative_authorization.
74
+ # Default - it is false (:declarative => false) .
75
+
76
+ NOTE: if you are using :declarative => true then first you need create
77
+ permissions.yml file in your Project/config folder.
78
+
79
+
80
+ 6 :read_only_message # validation message for read_only attributes
81
+ # Format - :read_only_message => "blah blah" (string type)
82
+ # Default message - "is a read only attribute."
83
+
84
+ 7 :create_only_message # validation message for create_only attributes
85
+ # Format - :create_only_message => "blah blah" (string type)
86
+ # Default message - "can't update, its permitted to create only."
87
+
88
+ 8 :update_only_message # validation message for update_only attributes
89
+ # Format - :update_only_message => "blah blah" (string type)
90
+ # Default message - "can't add, its permitted to update only."
91
+
92
+ 9 :hidden_only_message # validation message for hidden_only attributes
93
+ # Format - :hidden_only_message => "blah blah" (string type)
94
+ # Default message - "is a hidden attribute."
95
+
96
+
97
+ Requirements (Only if you want to use :declarative tag feature)
98
+ ==============================================================
99
+
100
+ - declarative_authorization plugin/gem.
101
+
102
+ - create permissions.yml file in your Project/config folder.
103
+
104
+ config/permissions.yml
105
+ ---------------------
106
+
107
+ You need create permissions.yml file in your Project/config folder.
108
+
109
+ Format : /config/permissions.yml
110
+ _____________________________________________________________
111
+ |:default: |
112
+ | :readonly: [:attribute1, :attribute2] |
113
+ | :hiddenonly: [:attribute1, :attribute2] |
114
+ | :createonly: [:attribute1, :attribute2] |
115
+ | :updateonly: [:attribute1, :attribute2] |
116
+ |:role_1: |
117
+ | :class_name_1: |
118
+ | :readonly: [:attribute1, :attribute2] |
119
+ | :hiddenonly: [:attribute1, :attribute2] |
120
+ | :createonly: [:attribute1, :attribute2] |
121
+ | :updateonly: [:attribute1, :attribute2] |
122
+ | :permit_to: [:attribute1, :attribute2] |
123
+ | :class_name_2: |
124
+ | :permit_to: [:attribute1, :attribute2] |
125
+ |:role_2: |
126
+ | :class_name_1: |
127
+ | :permit_to: [:attribute1, :attribute2] |
128
+ | :class_name_2: |
129
+ | :permit_to: [:attribute1, :attribute2] |
130
+ | |
131
+ | |
132
+ | |
133
+ |___________________________________________________________|
134
+
135
+ where
136
+ - role_1, role_2 are the roles of user
137
+ - class_name_1, class_name_2 are the class name or Model name
138
+ - readonly, hiddenonly, createonly, updateonly - To set restriction on specific role.
139
+ - permit_to: [] feature to set permission to change value of added attributes.
140
+ - default: provides common restricted attributes for all classes of all roles like id, create_at, updated_at.
141
+
142
+
143
+
144
+
145
+ ======================================================================================================================
146
+ ------------------------------------------ Examples Set 1 ------------------------------------------------------------
147
+
148
+
149
+ # Example 1 Simple one (without use of :declarative tag feature)
150
+ ================================================================
151
+
152
+ class Post < ActiveRecord::Base
153
+ has_restricted_attributes :read_only => [:status],
154
+ :create_only => [:title, :publish],
155
+ :update_only => [:tags],
156
+ :hidden_only => [:activated],
157
+ :read_only_message => "is a read only attribute",
158
+ :create_only_message => "can't update, its permitted to create only.",
159
+ :update_only_message => "can't add, its permitted to update only."
160
+ end
161
+
162
+
163
+
164
+ So, the restricted attributes will be as shown in following table.
165
+
166
+ #Post Model :
167
+
168
+ |-----------|-------------------------------------------------------------|
169
+ | |( Read/Hidden Only ) | ( Create Only ) | (Update Only ) |
170
+ | | :status /:activated | :title, :publish | :tags |
171
+ | |-------------------------------------------------------------|
172
+ | Can -> | Create | Update | Create | Update | Create | Update |
173
+ |-----------|-----------|---------|-------------------|-------------------|
174
+ | Any | | | | | | |
175
+ | User | NO | NO | YES | NO | NO | YES |
176
+ | | | | | | | |
177
+ ---------------------------------------------------------------------------
178
+
179
+ Console Output :
180
+ ---------------
181
+
182
+ >> post = Post.new(:status => true, :title => "New Title", :tags => "new, topic")
183
+ >> post.save
184
+ => false
185
+
186
+ >> post.errors
187
+ => #<OrderedHash {:status => ["is a read only attribute"], :tags=>["can't add, its permitted to update only."]}>
188
+
189
+ # for hidden attributes
190
+ >> post = Post.new(:activated => true)
191
+ >> post.save
192
+ => false
193
+
194
+ >> post.errors
195
+ => #<OrderedHash {:status => ["is a hidden attribute"]}>
196
+ OR
197
+ >> post.is_restricted?(:read, :activated) # To check :activated field is restricted to read.
198
+ => true
199
+
200
+
201
+
202
+ ----------------------------------------------------------------------------------------------------------------------
203
+
204
+
205
+ # Example 2 : (with :declarative => true tag feature)
206
+ =====================================================
207
+
208
+ Step 1 :
209
+
210
+ class User < ActiveRecord::Base
211
+ has_restricted_attributes :read_only => [:logged_in],
212
+ :create_only => [:login, :email],
213
+ :update_only => [:bio],
214
+ :declarative => true
215
+
216
+ end
217
+
218
+ class Post < ActiveRecord::Base
219
+ has_restricted_attributes :read_only => [:status],
220
+ :create_only => [:title, :publish],
221
+ :update_only => [:tags],
222
+ :hidden_only => [:activated],
223
+ :declarative => true,
224
+ :read_only_message => "is a read only attribute",
225
+ :create_only_message => "can't update, its permitted to create only.",
226
+ :update_only_message => "can't add, its permitted to update only."
227
+ end
228
+
229
+
230
+ Step 2 :
231
+
232
+ Create permissions.yml file in your Project/config/ folder.
233
+ and add roles & permissions for the user as shown in following example.
234
+
235
+ *Here you can set permission to change the value of restricted attributes on the basis of role system.
236
+
237
+ Example:
238
+ ## /config/permissions.yml
239
+ ___________________________________________________________
240
+ |:default: |
241
+ | :readonly: [:created_at, :updated_at] |
242
+ |:global_admin: |
243
+ | :user: |
244
+ | :permit_to: [:logged_in, :login, :email, :bio] |
245
+ | :post: |
246
+ | :permit_to: [:title, :status, :publish, :tags] |
247
+ |:member: |
248
+ | :user: |
249
+ | :permit_to: [:email] |
250
+ | :post: |
251
+ | :permit_to: [:publish] |
252
+ | |
253
+ | |
254
+ | |
255
+ | |
256
+ |___________________________________________________________|
257
+
258
+ # where in that,
259
+ 1 :global_admin , :member are the roles of user. [ROLE]
260
+ 2 :user , :post are the class names [CLASS/MODEL]
261
+ 3 :permit_to: [] here you can add those attributes which will be permitted for appropriate User [ATTRIBUTES]
262
+ 4 :default: you can add common attributes to restrict the access for all classes.
263
+
264
+ Result :
265
+
266
+ So, the permissions on restricted attributes for global_admin and member
267
+ user will be as shown in following table.
268
+ #Post Model :
269
+
270
+ |---------------|-----------------------------------------------------------------|
271
+ | | ( Read Only ) | ( Create Only ) | (Update Only ) |
272
+ | | :status | :title, :publish | :tags |
273
+ | |-----------------------------------------------------------------|
274
+ | Can -> | Create | Update | Create | Update | Create | Update |
275
+ |---------------|----------|---------|----------|-------------|-------------------|
276
+ | | | | | | | |
277
+ | User | YES | YES | YES | YES | YES | YES |
278
+ |(global_admin) | | | | | | |
279
+ | | | | | | | |
280
+ ---------------------------------------------------------------- ----------------
281
+ | | | | | | | |
282
+ | User | NO | NO | YES | NO-:title | NO | YES |
283
+ | (member) | | | |YES-:publish | | |
284
+ | | | | | | | |
285
+ |---------------------------------------------------------------------------------|
286
+
287
+
288
+
289
+ --------------------------------------------- End Examples Set 1 -----------------------------------------------------
290
+ ======================================================================================================================
291
+
292
+
293
+
294
+
295
+
296
+ Helper Method & Instance Method ( For View & Controller files )
297
+ ===============================================================
298
+
299
+
300
+ 1 Helper Method `is_restricted?()` :
301
+ ------------------------------------
302
+
303
+ Syntax:
304
+ ------------------------------------------------------------
305
+ | is_restricted?(Klass, action, field, user(optional)) |
306
+ ------------------------------------------------------------
307
+
308
+ This method accepts min 3 to max 4 arguments :
309
+
310
+ 1 Klass # This is a mandatory & first argument of this method.
311
+ # Should be valid class (i.e Model Name), no String.
312
+ # Should be in constantize format
313
+ # Ex : User , Post, Comment
314
+
315
+ 2 action # This is a mandatory & second argument of this method.
316
+ # Valid actions : "create" or "update" or "read".
317
+ # Should be either in symbol or in string format
318
+ # Ex : :create or :update or :read or "create" or "update" or "read"
319
+
320
+ 3 field # This is a mandatory & third argument of this method.
321
+ # Should be valid attributes/field of that model or related db table.
322
+ # Should be either in symbol or in string format
323
+ # Ex : :title or "title"
324
+
325
+ *4 user # This is Optional & last argument of this method.
326
+ # IMPORTANT NOTE - Useful only if you are using declarative_authorization plugin/gem and
327
+ # has_restricted_attributes method with :declarative => true tag in your specified model.
328
+
329
+ # Should be either valid User object or nil (don't pass any fourth argument)
330
+ # Ex : current_user (where current_user should be object of valid User record.)
331
+
332
+
333
+
334
+ 2 Instance Method `is_restricted?()` :
335
+ --------------------------------------
336
+
337
+ Syntax:
338
+ --------------------------------------------------------------
339
+ | object.is_restricted?(action, field, user(optional)) |
340
+ --------------------------------------------------------------
341
+
342
+ This method accepts min 2 to max 3 arguments :
343
+
344
+ 1 action # This is a mandatory & first argument of this method.
345
+ # Valid actions : "create" or "update" or "read".
346
+ # Should be either in symbol or in string format
347
+ # Ex : :create or :update or :read or "create" or "update" or "read"
348
+
349
+ 2 field # This is a mandatory & second argument of this method.
350
+ # Should be valid attributes/field of that model or related db table.
351
+ # Should be either in symbol or in string format
352
+ # Ex : :title or "title"
353
+
354
+ *3 user # This is Optional & last argument of this method.
355
+ # IMPORTANT NOTE - Useful only if you are using declarative_authorization plugin/gem and
356
+ # has_restricted_attributes method with :declarative => true tag in your specified model.
357
+
358
+ # Should be either valid User object or nil (don't pass any fourth argument)
359
+ # Ex : current_user (where current_user should be object of valid User record.)
360
+
361
+
362
+
363
+
364
+ ======================================================================================================================
365
+ ------------------------------------------ Examples Set 2 ------------------------------------------------------------
366
+
367
+
368
+
369
+ # Example 1 ( Use of Helper Method )
370
+ ====================================
371
+
372
+ # /models/post.rb
373
+ class Post < ActiveRecord::Base
374
+ has_restricted_attributes :read_only => [:active],
375
+ :create_only => [:title],
376
+ :declarative => true,
377
+ :update_only => [:abuse],
378
+ :read_only_message => "is a read only attribute"
379
+ end
380
+
381
+ ## /config/permissions.yml
382
+ ___________________________________________________________
383
+ |:global_admin: |
384
+ | :post: |
385
+ | :permit_to: [:title, :description] |
386
+ |___________________________________________________________|
387
+ Here I added permission for global_admin role.
388
+
389
+
390
+ So for this post class we can check its particular field is restricted or not.
391
+ (You can use this method in controller, view and helper file.)
392
+
393
+ # CASE 1 - :declarative => true
394
+
395
+ -----------------------------------------------------
396
+ | is_restricted?(Post, :update, :title) |
397
+ -----------------------------------------------------
398
+
399
+ - return true(:title is restricted) for logged in user if his role is NOT a global_admin
400
+ - return false(:title is NOT restricted) for logged in user if his role is a global_admin
401
+
402
+ OR
403
+
404
+ -----------------------------------------------------------------
405
+ | user = User.find(params[:id]) # any global_admin user |
406
+ | is_restricted?(Post, :update, :title, user) |
407
+ -----------------------------------------------------------------
408
+
409
+ - return true(:title is restricted) for `user` if his role is NOT a global_admin
410
+ - return false(:title is NOT restricted) for `user` if his role is a global_admin
411
+
412
+
413
+ # CASE 2 - :declarative => false or if not added in model.
414
+
415
+ ---------------------------------------------------------------------------------
416
+ | is_restricted?(Post, :update, :title) # don't pass fourth argument |
417
+ ---------------------------------------------------------------------------------
418
+
419
+ - return true(:title is restricted)
420
+
421
+
422
+
423
+
424
+
425
+
426
+ # Example 2 ( Use of Instance Method )
427
+ =======================================
428
+
429
+ # /models/post.rb
430
+ class Post < ActiveRecord::Base
431
+ has_restricted_attributes :read_only => [:active],
432
+ :create_only => [:title],
433
+ :declarative => true,
434
+ :update_only => [:abuse],
435
+ :read_only_message => "is a read only attribute"
436
+ end
437
+
438
+ ## /config/permissions.yml
439
+ ___________________________________________________________
440
+ |:global_admin: |
441
+ | :post: |
442
+ | :permit_to: [:title, :description] |
443
+ |___________________________________________________________|
444
+ Here I added permission for global_admin role.
445
+
446
+
447
+ So for this post class we can check its particular field is restricted or not.
448
+
449
+ # CASE 1 - :declarative => true
450
+
451
+ -----------------------------------------------------
452
+ | post = Post.find(params[:id]) |
453
+ | post.is_restricted?(:update, :title) |
454
+ -----------------------------------------------------
455
+
456
+ - return true(:title is restricted) for logged in user if his role is NOT a global_admin
457
+ - return false(:title is NOT restricted) for logged in user if his role is a global_admin
458
+
459
+ OR
460
+
461
+ -------------------------------------------------------------------------
462
+ | user = User.find(params[:id]) # any global_admin user |
463
+ | post = Post.find(params[:id]) |
464
+ | post.is_restricted?(:update, :title, user) |
465
+ -------------------------------------------------------------------------
466
+
467
+ - return true(:title is restricted) for `user` if his role is NOT a global_admin
468
+ - return false(:title is NOT restricted) for `user` if his role is a global_admin
469
+
470
+
471
+ # CASE 2 - :declarative => false or if not added in model.
472
+
473
+ -----------------------------------------------------------------------------
474
+ | post = Post.find(params[:id]) |
475
+ | is_restricted?(:update, :title) # don't pass third argument |
476
+ -----------------------------------------------------------------------------
477
+
478
+ - return true(:title is restricted)
479
+
480
+
481
+
482
+
483
+ --------------------------------------------- End Examples Set 2 -----------------------------------------------------
484
+ ======================================================================================================================
485
+
486
+
487
+
488
+
489
+
490
+ Valuable Contribution :
491
+ Rahul Agarwal, Kevin Williams.
492
+
493
+ ===========================================================================
494
+ Easiest way to contact me(Ganesh Kathare):
495
+ My email - kathare[dot]ganesh[at]gmail[dot]com (kathare.ganesh@gmail.com)
496
+ ===========================================================================
497
+
498
+ Copyright (c) 2011 Ganesh Kathare, Navi Mumbai MH, India. released under the MIT license
499
+
data/Rakefile ADDED
@@ -0,0 +1,37 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/clean'
4
+ require 'rake/gempackagetask'
5
+ require 'rake/rdoctask'
6
+ require 'rake/testtask'
7
+
8
+
9
+ PKG_FILES = FileList[
10
+ '[a-zA-Z]*',
11
+ 'lib/**/*',
12
+ 'test/**/*'
13
+ ]
14
+
15
+ spec = Gem::Specification.new do |s|
16
+ s.name = "restricted_attributes"
17
+ s.version = "1.0.0"
18
+ s.author = "Ganesh Kathare"
19
+ s.email = "kathare.ganesh@gmail.com"
20
+ s.homepage = "https://github.com/gkathare"
21
+ s.platform = Gem::Platform::RUBY
22
+ s.summary = "Sharing restricted_attributes"
23
+ s.files = PKG_FILES.to_a
24
+ s.require_path = "lib"
25
+ s.has_rdoc = false
26
+ s.extra_rdoc_files = ["README"]
27
+ s.description = <<EOF
28
+ This restricted_attributes plugin/gem provides the capabilities to restrict attributes(fields)
29
+ of db table's while add or update a record. It validate your attributes values before
30
+ your validation stuff.
31
+ EOF
32
+ end
33
+
34
+ Rake::GemPackageTask.new(spec) do |pkg|
35
+ pkg.need_zip = true
36
+ pkg.need_tar = true
37
+ end
data/init.rb ADDED
@@ -0,0 +1,3 @@
1
+ # Include hook code here
2
+ $:.unshift "#{File.dirname(__FILE__)}/lib"
3
+ require 'restricted_attributes'
@@ -0,0 +1,130 @@
1
+ module RestrictedAttrib
2
+
3
+ ## Class Methods
4
+ module ClassMethods
5
+ def self.extended(base)
6
+ base.before_validation :check_for_restricted_values
7
+ end
8
+ end
9
+
10
+ ## Instance Methods
11
+ module InstanceMethods
12
+ # check the changed attributes of a class are restricted or not.
13
+ def check_for_restricted_values
14
+
15
+ if self.declarative # Using declarative_authorization roles system
16
+ roles = RestrictedRightsManager.get_roles(Authorization.current_user,self)
17
+ restrict_read_only = RestrictedRightsManager.get_readonly_fields(roles,self)
18
+ restrict_create_only = RestrictedRightsManager.get_createonly_fields(roles,self)
19
+ restrict_update_only = RestrictedRightsManager.get_updateonly_fields(roles,self)
20
+ restrict_hidden_only = RestrictedRightsManager.get_hiddenonly_fields(roles,self)
21
+ else # simple one
22
+ restrict_read_only = self.read_only
23
+ restrict_create_only = self.create_only
24
+ restrict_update_only = self.update_only
25
+ restrict_hidden_only = self.hidden_only
26
+ end
27
+
28
+ # check for read only attributes
29
+ unless restrict_read_only.blank?
30
+ restrict_read_only.each do |ro|
31
+ if self.changed.include?(ro) || !eval("self.instance_variable_get :@#{ro}").blank?
32
+ self.errors.add(ro.humanize, self.read_only_message)
33
+ end
34
+ end
35
+ end
36
+
37
+ # check for create only attributes
38
+ if !restrict_create_only.blank? && !self.new_record?
39
+ restrict_create_only.each do |co|
40
+ if self.changed.include?(co) || !eval("self.instance_variable_get :@#{co}").blank?
41
+ self.errors.add(co.humanize, self.create_only_message)
42
+ end
43
+ end
44
+ end
45
+
46
+ # check for update only attributes
47
+ if !restrict_update_only.blank? && self.new_record?
48
+ restrict_update_only.each do |uo|
49
+ if self.changed.include?(uo) || !eval("self.instance_variable_get :@#{uo}").blank?
50
+ self.errors.add(uo.humanize, self.update_only_message)
51
+ end
52
+ end
53
+ end
54
+
55
+ # check for hidden only attributes
56
+ if !restrict_hidden_only.blank?
57
+ restrict_hidden_only.each do |ho|
58
+ if self.changed.include?(ho) || !eval("self.instance_variable_get :@#{ho}").blank?
59
+ self.errors.add(ho.humanize, self.hidden_only_message)
60
+ end
61
+ end
62
+ end
63
+
64
+ # will return validation result
65
+ return false unless self.errors.blank?
66
+ end
67
+
68
+ def is_restricted?(action, field, user = nil)
69
+ action = action.to_s
70
+ field = field.to_s
71
+ klass = self.class
72
+ klass_object = self
73
+
74
+ unless klass_object.methods.include?("read_only")
75
+ raise NoMethodError, "undefined method `is_restricted?` for #{klass} model. You need to add `has_restricted_method` method in #{klass} model."
76
+ end
77
+
78
+ if action.nil? || !['create', 'update', 'read'].include?(action)
79
+ raise ArgumentError, "Invalid action - (#{action}), Pass valid action - :read or :create or :update or 'read' or 'create' or 'update'"
80
+ end
81
+
82
+ klass_attributes = klass_object.attributes.keys
83
+ if field.nil? || (!klass_attributes.include?(field) && !klass_object.methods.include?("#{field}="))
84
+ raise ActiveRecord::UnknownAttributeError, "#{klass}: unknown attribute(field): #{field}"
85
+ end
86
+
87
+ if klass_object.declarative
88
+ begin
89
+ user.roles if user
90
+ rescue
91
+ raise ArgumentError, "invalid user (#{user}) paramater sent with `is_restricted?` method."
92
+ end
93
+ present_user = Authorization.current_user
94
+ Authorization.current_user = user if user && user.roles
95
+
96
+ roles = RestrictedRightsManager.get_roles(Authorization.current_user,klass_object)
97
+ restrict_read_only = RestrictedRightsManager.get_readonly_fields(roles,klass_object)
98
+ restrict_create_only = RestrictedRightsManager.get_createonly_fields(roles,klass_object)
99
+ restrict_update_only = RestrictedRightsManager.get_updateonly_fields(roles,klass_object)
100
+ restrict_hidden_only = RestrictedRightsManager.get_hiddenonly_fields(roles,klass_object)
101
+
102
+ Authorization.current_user = present_user if user && user.roles
103
+ else
104
+ restrict_read_only = klass_object.read_only
105
+ restrict_create_only = klass_object.create_only
106
+ restrict_update_only = klass_object.update_only
107
+ restrict_hidden_only = klass_object.hidden_only
108
+ end
109
+
110
+ if action == "create" || action == "update" || action == "read"
111
+ return true if !restrict_hidden_only.blank? && restrict_hidden_only.include?(field)
112
+ end
113
+
114
+ if action == "create" || action == "update"
115
+ return true if !restrict_read_only.blank? && restrict_read_only.include?(field)
116
+ end
117
+
118
+ if action == "create"
119
+ return true if !restrict_update_only.blank? && restrict_update_only.include?(field)
120
+ end
121
+
122
+ if action == "update"
123
+ return true if !restrict_create_only.blank? && restrict_create_only.include?(field)
124
+ end
125
+ return false
126
+ end
127
+
128
+ end
129
+ end
130
+
@@ -0,0 +1,154 @@
1
+ require "restricted/restricted_attrib"
2
+ require "restricted_rights_manager"
3
+
4
+ module RestrictedAttributes
5
+
6
+ module Restricted
7
+
8
+ def has_restricted_attributes(options = {})
9
+ cattr_accessor :read_only, :create_only, :update_only, :hidden_only
10
+ cattr_accessor :read_only_message, :create_only_message, :update_only_message, :hidden_only_message
11
+ cattr_accessor :declarative
12
+
13
+ if options[:declarative] && options[:declarative] == true
14
+ # To check existence of declarative_authorization plugin/gem in present application.
15
+ begin
16
+ Authorization.current_user
17
+ rescue Exception => e
18
+ raise "Sorry, :declarative tag can't support to your application. Please follow documentation of restricted_attributes" if e.class == NameError
19
+ end
20
+ self.declarative = true
21
+ RestrictedRightsManager.load_config
22
+ RestrictedRightsManager.version=Time.now.utc.to_i
23
+ else
24
+ self.declarative = false
25
+ end
26
+
27
+ # set the read only attributes of a class
28
+ if options[:read_only]
29
+ only_read = []
30
+ if options[:read_only].is_a?(Array)
31
+ only_read = options[:read_only].collect {|r| r.to_s }
32
+ else
33
+ only_read << options[:read_only].to_s
34
+ end
35
+ self.read_only = only_read
36
+ end
37
+
38
+ # set the create only attributes of a class
39
+ if options[:create_only]
40
+ only_create = []
41
+ if options[:create_only].is_a?(Array)
42
+ only_create = options[:create_only].collect {|c| c.to_s }
43
+ else
44
+ only_create << options[:create_only].to_s
45
+ end
46
+ self.create_only = only_create
47
+ end
48
+
49
+ # set the create only attributes of a class
50
+ if options[:update_only]
51
+ only_update = []
52
+ if options[:update_only].is_a?(Array)
53
+ only_update = options[:update_only].collect {|u| u.to_s }
54
+ else
55
+ only_update << options[:update_only].to_s
56
+ end
57
+ self.update_only = only_update
58
+ end
59
+
60
+ # set the hidden only attributes of a class
61
+ if options[:hidden_only]
62
+ only_hidden = []
63
+ if options[:hidden_only].is_a?(Array)
64
+ only_hidden = options[:hidden_only].collect {|u| u.to_s }
65
+ else
66
+ only_hidden << options[:hidden_only].to_s
67
+ end
68
+ self.hidden_only = only_hidden
69
+ end
70
+
71
+ # Default validation messages
72
+ ro_msg = "is a read only attribute."
73
+ co_msg = "can't update, its permitted to create only."
74
+ uo_msg = "can't add, its permitted to update only."
75
+ ho_msg = "is a hidden attribute."
76
+
77
+ # assign validation messages to restricted attributes
78
+ self.read_only_message = options[:read_only_message] ? options[:read_only_message].to_s : ro_msg
79
+ self.create_only_message = options[:create_only_message] ? options[:create_only_message].to_s : co_msg
80
+ self.update_only_message = options[:update_only_message] ? options[:update_only_message].to_s : uo_msg
81
+ self.hidden_only_message = options[:hidden_only_message] ? options[:hidden_only_message].to_s : ho_msg
82
+
83
+ extend RestrictedAttrib::ClassMethods
84
+ include RestrictedAttrib::InstanceMethods
85
+ end
86
+ end
87
+
88
+ module RestrictedHelpers
89
+ def is_restricted?(klass, action, field, user = nil)
90
+ action = action.to_s
91
+ field = field.to_s
92
+ raise ArgumentError, "Must pass valid class" if klass.nil? || !klass.is_a?(Class)
93
+
94
+ klass_object = klass.new
95
+
96
+ unless klass_object.methods.include?("read_only")
97
+ raise NoMethodError, "undefined method `is_restricted?` for #{klass} model. You need to add `has_restricted_attributes` method in #{klass} model."
98
+ end
99
+
100
+ if action.nil? || !['create', 'update', 'read'].include?(action)
101
+ raise ArgumentError, "Invalid action - (#{action}), Pass valid action - :read or :create or :update or 'read' or 'create' or 'update'"
102
+ end
103
+
104
+ klass_attributes = klass_object.attributes.keys
105
+ if field.nil? || !klass_attributes.include?(field)
106
+ raise ActiveRecord::UnknownAttributeError, "#{klass}: unknown attribute(field): #{field}"
107
+ end
108
+
109
+ if klass_object.declarative
110
+ begin
111
+ user.roles if user
112
+ rescue
113
+ raise ArgumentError, "invalid user (#{user}) paramater sent with `is_restricted?` method."
114
+ end
115
+ present_user = Authorization.current_user
116
+ Authorization.current_user = user if user && user.roles
117
+
118
+ roles = RestrictedRightsManager.get_roles(Authorization.current_user,klass_object)
119
+ restrict_read_only = RestrictedRightsManager.get_readonly_fields(roles,klass_object)
120
+ restrict_create_only = RestrictedRightsManager.get_createonly_fields(roles,klass_object)
121
+ restrict_update_only = RestrictedRightsManager.get_updateonly_fields(roles,klass_object)
122
+ restrict_hidden_only = RestrictedRightsManager.get_hiddenonly_fields(roles,klass_object)
123
+
124
+ Authorization.current_user = present_user if user && user.roles
125
+ else
126
+ restrict_read_only = klass_object.read_only
127
+ restrict_create_only = klass_object.create_only
128
+ restrict_update_only = klass_object.update_only
129
+ restrict_hidden_only = klass_object.hidden_only
130
+ end
131
+
132
+ if action == "create" || action == "update" || action == "read"
133
+ return true if !restrict_hidden_only.blank? && restrict_hidden_only.include?(field)
134
+ end
135
+
136
+ if action == "create" || action == "update"
137
+ return true if !restrict_read_only.blank? && restrict_read_only.include?(field)
138
+ end
139
+
140
+ if action == "create"
141
+ return true if !restrict_update_only.blank? && restrict_update_only.include?(field)
142
+ end
143
+
144
+ if action == "update"
145
+ return true if !restrict_create_only.blank? && restrict_create_only.include?(field)
146
+ end
147
+ return false
148
+ end
149
+ end
150
+ end
151
+
152
+ ActiveRecord::Base.send(:extend, RestrictedAttributes::Restricted)
153
+ ActionView::Base.send(:include, RestrictedAttributes::RestrictedHelpers)
154
+ ActionController::Base.send(:include, RestrictedAttributes::RestrictedHelpers)
@@ -0,0 +1,114 @@
1
+ require "active_model"
2
+
3
+ class RestrictedRightsManager
4
+
5
+ cattr_accessor :rights, :version
6
+ attr_accessor :obj_name, :role_name
7
+
8
+ def initialize(attribs={})
9
+ self.obj_name=attribs[:obj_name]
10
+ self.role_name=attribs[:role_name]
11
+ end
12
+
13
+ def self.get_readonly_fields(roles, obj)
14
+ resp=Rails.cache.fetch([RestrictedRightsManager.version,roles.to_s,obj.class.name,"read_only_fields"].join("_")){
15
+ RestrictedRightsManager.get_restricted_fields(roles, obj, :readonly)
16
+ }
17
+ resp
18
+ end
19
+
20
+ def self.get_createonly_fields(roles, obj)
21
+ resp=Rails.cache.fetch([RestrictedRightsManager.version,roles.to_s,obj.class.name,"create_only_fields"].join("_")){
22
+ RestrictedRightsManager.get_restricted_fields(roles, obj, :createonly)
23
+ }
24
+ resp
25
+ end
26
+
27
+ def self.get_updateonly_fields(roles, obj)
28
+ resp=Rails.cache.fetch([RestrictedRightsManager.version,roles.to_s,obj.class.name,"update_only_fields"].join("_")){
29
+ RestrictedRightsManager.get_restricted_fields(roles, obj, :updateonly)
30
+ }
31
+ resp
32
+ end
33
+
34
+ def self.get_hiddenonly_fields(roles, obj)
35
+ resp=Rails.cache.fetch([RestrictedRightsManager.version,roles.to_s,obj.class.name,"hidden_only_fields"].join("_")){
36
+ RestrictedRightsManager.get_restricted_fields(roles, obj, :hiddenonly)
37
+ }
38
+ resp
39
+ end
40
+
41
+
42
+ def self.get_restricted_fields(roles, obj, access_type)
43
+ resp=Rails.cache.fetch([RestrictedRightsManager.version,roles.to_s,obj.class.name,access_type.to_s].join("_")){
44
+ #obj_name=obj.class.name.underscore.downcase
45
+
46
+
47
+ # get default fields for all objects
48
+ begin
49
+ case access_type
50
+ when :readonly
51
+ default_fields = obj.read_only || []
52
+ when :createonly
53
+ default_fields = obj.create_only || []
54
+ when :updateonly
55
+ default_fields = obj.update_only || []
56
+ when :hiddenonly
57
+ default_fields = obj.hidden_only || []
58
+ else
59
+ default_fields = []
60
+ end
61
+ rescue
62
+ default_fields = []
63
+ end
64
+
65
+ begin
66
+ if RestrictedRightsManager.rights[:default] && RestrictedRightsManager.rights[:default][access_type]
67
+ default_fields2 = RestrictedRightsManager.rights[:default][access_type]
68
+ else
69
+ default_fields2 = []
70
+ end
71
+ rescue
72
+ default_fields2 = []
73
+ end
74
+ default_fields2 = default_fields2.collect{|d| d.to_s}
75
+ default_fields |= default_fields2
76
+
77
+ begin
78
+ permitted_fields, role_fields = [], []
79
+ roles.each do |role_name|
80
+ if RestrictedRightsManager.rights[role_name]
81
+ self_klass_name = obj.class.name.underscore.downcase
82
+ base_klass_name = obj.class.base_class.name.underscore.downcase
83
+ klass_name = RestrictedRightsManager.rights[role_name].include?(self_klass_name) ? self_klass_name : base_klass_name
84
+
85
+ if RestrictedRightsManager.rights[role_name][klass_name]
86
+ permitted_fields |= RestrictedRightsManager.rights[role_name][klass_name][:permit_to] || []
87
+ role_fields |= RestrictedRightsManager.rights[role_name][klass_name][access_type] || []
88
+ end
89
+ end
90
+ end
91
+ rescue
92
+ permitted_fields, role_fields = [], []
93
+ end
94
+ permitted_fields = permitted_fields.collect{|p| p.to_s}
95
+ role_fields = role_fields.collect{|p| p.to_s}
96
+ ro_fields = default_fields - permitted_fields
97
+ ro_fields |= role_fields }
98
+ resp
99
+ end
100
+
101
+ def self.load_config
102
+ RestrictedRightsManager.rights = HashWithIndifferentAccess.new(YAML.load_file("#{Rails.root}/config/permissions.yml"))
103
+ end
104
+
105
+ def self.get_roles(user,obj)
106
+ roles=user.roles
107
+ return (roles.blank?) ? [] : roles.collect {|role| role.title }
108
+ end
109
+ end
110
+
111
+
112
+
113
+
114
+
@@ -0,0 +1,8 @@
1
+ require 'test_helper'
2
+
3
+ class RestrictedAttributesTest < ActiveSupport::TestCase
4
+ # Replace this with your real tests.
5
+ test "the truth" do
6
+ assert true
7
+ end
8
+ end
@@ -0,0 +1,3 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'active_support'
metadata ADDED
@@ -0,0 +1,64 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: restricted_attributes
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 1.0.0
6
+ platform: ruby
7
+ authors:
8
+ - Ganesh Kathare
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-07-19 00:00:00 +05:30
14
+ default_executable:
15
+ dependencies: []
16
+
17
+ description: " This restricted_attributes plugin/gem provides the capabilities to restrict attributes(fields) \n of db table's while add or update a record. It validate your attributes values before\n your validation stuff.\n"
18
+ email: kathare.ganesh@gmail.com
19
+ executables: []
20
+
21
+ extensions: []
22
+
23
+ extra_rdoc_files:
24
+ - README
25
+ files:
26
+ - init.rb
27
+ - MIT-LICENSE
28
+ - Rakefile
29
+ - README
30
+ - lib/restricted_attributes.rb
31
+ - lib/restricted_rights_manager.rb
32
+ - lib/restricted/restricted_attrib.rb
33
+ - test/restricted_attributes_test.rb
34
+ - test/test_helper.rb
35
+ has_rdoc: true
36
+ homepage: https://github.com/gkathare
37
+ licenses: []
38
+
39
+ post_install_message:
40
+ rdoc_options: []
41
+
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ none: false
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: "0"
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: "0"
56
+ requirements: []
57
+
58
+ rubyforge_project:
59
+ rubygems_version: 1.5.1
60
+ signing_key:
61
+ specification_version: 3
62
+ summary: Sharing restricted_attributes
63
+ test_files: []
64
+