restricted_attributes 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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
+