trust 0.8.3 → 1.4.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +33 -1
  3. data/lib/trust.rb +9 -0
  4. data/lib/trust/authorization.rb +83 -36
  5. data/lib/trust/controller.rb +32 -8
  6. data/lib/trust/controller/properties.rb +12 -0
  7. data/lib/trust/controller/resource.rb +79 -11
  8. data/lib/trust/permissions.rb +177 -24
  9. data/lib/trust/version.rb +1 -1
  10. data/test/dummy/app/controllers/accounts_controller.rb +2 -2
  11. data/test/dummy/app/controllers/clients_controller.rb +1 -1
  12. data/test/dummy/app/controllers/mongo_accounts_controller.rb +5 -4
  13. data/test/dummy/app/controllers/mongo_clients_controller.rb +1 -1
  14. data/test/dummy/app/controllers/users_controller.rb +1 -5
  15. data/test/dummy/app/models/account.rb +1 -1
  16. data/test/dummy/app/models/client.rb +1 -1
  17. data/test/dummy/app/models/permissions.rb +18 -11
  18. data/test/dummy/app/models/user.rb +1 -1
  19. data/test/dummy/app/views/accounts/edit.html.erb +1 -1
  20. data/test/dummy/app/views/accounts/show.html.erb +1 -1
  21. data/test/dummy/app/views/mongo_accounts/_form.html.erb +1 -1
  22. data/test/dummy/app/views/mongo_accounts/edit.html.erb +2 -2
  23. data/test/dummy/app/views/mongo_accounts/index.html.erb +3 -3
  24. data/test/dummy/app/views/mongo_accounts/show.html.erb +2 -2
  25. data/test/dummy/bin/bundle +3 -0
  26. data/test/dummy/bin/rails +4 -0
  27. data/test/dummy/bin/rake +4 -0
  28. data/test/dummy/bin/setup +29 -0
  29. data/test/dummy/config/application.rb +3 -34
  30. data/test/dummy/config/boot.rb +4 -9
  31. data/test/dummy/config/environment.rb +3 -3
  32. data/test/dummy/config/environments/development.rb +22 -18
  33. data/test/dummy/config/environments/production.rb +46 -34
  34. data/test/dummy/config/environments/test.rb +19 -14
  35. data/test/dummy/config/initializers/assets.rb +11 -0
  36. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  37. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  38. data/test/dummy/config/initializers/inflections.rb +6 -5
  39. data/test/dummy/config/initializers/mime_types.rb +0 -1
  40. data/test/dummy/config/initializers/session_store.rb +1 -6
  41. data/test/dummy/config/initializers/wrap_parameters.rb +6 -6
  42. data/test/dummy/config/locales/en.yml +20 -2
  43. data/test/dummy/config/mongoid.yml +16 -18
  44. data/test/dummy/config/routes.rb +3 -3
  45. data/test/dummy/config/secrets.yml +22 -0
  46. data/test/dummy/db/test.sqlite3 +0 -0
  47. data/test/dummy/log/development.log +30 -0
  48. data/test/dummy/log/test.log +6382 -0
  49. data/test/dummy/test/functional/accounts_controller_test.rb +2 -2
  50. data/test/dummy/test/functional/mongo_accounts_controller_test.rb +8 -8
  51. data/test/dummy/test/functional/mongo_clients_controller_test.rb +1 -1
  52. data/test/dummy/test/unit/permissions_test.rb +1 -1
  53. data/test/dummy/tmp/cache/assets/test/sprockets/0e74e8595d4c5c03160356ab9bf6f67c +0 -0
  54. data/test/dummy/tmp/cache/assets/test/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
  55. data/test/dummy/tmp/cache/assets/test/sprockets/189460d2a0f63f35d55c384e0beb9cc4 +0 -0
  56. data/test/dummy/tmp/cache/assets/test/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
  57. data/test/dummy/tmp/cache/assets/test/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
  58. data/test/dummy/tmp/cache/assets/test/sprockets/371bf96e99717688ed7313a0c53f4212 +0 -0
  59. data/test/dummy/tmp/cache/assets/test/sprockets/4050a4e5062ab95c9f32e9b6940821ea +0 -0
  60. data/test/dummy/tmp/cache/assets/test/sprockets/5f1a0d05e77ca8b9a1fc2a47e17a8174 +0 -0
  61. data/test/dummy/tmp/cache/assets/test/sprockets/6fc757c2c8329244ca95d6909865bbc2 +0 -0
  62. data/test/dummy/tmp/cache/assets/test/sprockets/75f67b2244ba6a4914d71df068f5fda9 +0 -0
  63. data/test/dummy/tmp/cache/assets/test/sprockets/7ed0985e7e627ac5280078ee9c7078fe +0 -0
  64. data/test/dummy/tmp/cache/assets/test/sprockets/86d19eda31629412e6817570ffde9a93 +0 -0
  65. data/test/dummy/tmp/cache/assets/test/sprockets/87b209c0c9da28094a8d5581a21262c6 +0 -0
  66. data/test/dummy/tmp/cache/assets/test/sprockets/954318d0d3412eec67db5c2508ae5169 +0 -0
  67. data/test/dummy/tmp/cache/assets/test/sprockets/95c1a034126598a432130d7fc227c189 +0 -0
  68. data/test/dummy/tmp/cache/assets/test/sprockets/b55283b385e5692ecf1b59332bbc5a11 +0 -0
  69. data/test/dummy/tmp/cache/assets/test/sprockets/b678ce3482f77c68a19e697960645cb6 +0 -0
  70. data/test/dummy/tmp/cache/assets/test/sprockets/ca9d9c205bcfa05de1ddd180f8ecc168 +0 -0
  71. data/test/dummy/tmp/cache/assets/test/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
  72. data/test/dummy/tmp/cache/assets/test/sprockets/d36f675d4251ea3868635d299f3bb166 +0 -0
  73. data/test/dummy/tmp/cache/assets/test/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
  74. data/test/dummy/tmp/cache/assets/test/sprockets/f56253b5f374fff1a33fbbc9881c9124 +0 -0
  75. data/test/dummy/tmp/cache/assets/test/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
  76. data/test/dummy/tmp/cache/assets/test/sprockets/fe1f20fb032685e2e1fcad23f0ad6601 +0 -0
  77. data/test/test_helper.rb +6 -2
  78. data/test/trust_test.rb +4 -0
  79. data/test/unit/trust/authorization_test.rb +165 -71
  80. data/test/unit/trust/controller/properties_test.rb +15 -0
  81. data/test/unit/trust/controller/resource_test.rb +29 -9
  82. data/test/unit/trust/controller_test.rb +53 -40
  83. data/test/unit/trust/permissions_test.rb +196 -69
  84. metadata +93 -28
@@ -109,16 +109,25 @@ module Trust
109
109
  #
110
110
  class Permissions
111
111
 
112
+ class SubjectInaccessible < StandardError; end
113
+
112
114
  include InheritableAttribute
113
- attr_reader :user, :action, :klass, :subject, :parent
115
+ attr_reader :user, :action, :klass, :parent
116
+ attr_accessor :subject
114
117
  inheritable_attr :permissions
118
+ inheritable_attr :member_permissions
119
+ inheritable_attr :entity_required
120
+ inheritable_attr :entity_attributes
115
121
  class_attribute :action_aliases, :instance_writer => false, :instance_reader => false
116
122
  self.permissions = {}
123
+ self.member_permissions = {}
124
+ self.entity_required = nil # for require
125
+ self.entity_attributes = [] # for permit
117
126
  self.action_aliases = {
118
- read: [:index, :show],
119
- create: [:create, :new],
120
- update: [:update, :edit],
121
- manage: [:index, :show, :create, :new, :update, :edit, :destroy]
127
+ # read: [:index, :show],
128
+ # create: [:create, :new],
129
+ # update: [:update, :edit],
130
+ # manage: [:index, :show, :create, :new, :update, :edit, :destroy]
122
131
  }
123
132
  @@can_expressions = 0
124
133
 
@@ -140,25 +149,77 @@ module Trust
140
149
  @user, @action, @klass, @subject, @parent = user, action, klass, subject, parent
141
150
  end
142
151
 
143
- # Returns true if the user is authorized to perform the action
152
+ # Returns params_handler if the user is authorized to perform the action
153
+ #
154
+ # The handler contains information used by the resource on retrieing parametes later
144
155
  def authorized?
145
- authorized = nil
146
- user && user.role_symbols.each do |role|
147
- (permissions[role] || {}).each do |act, opt|
148
- if act == action
149
- break if (authorized = opt.any? ? eval_expr(opt) : true)
150
- end
151
- end
152
- break if authorized
156
+ trace 'authorized?', 0, "@user: #{@user.inspect}, @action: #{@action.inspect}, @klass: #{@klass.inspect}, @subject: #{@subject.inspect}, @parent: #{@parent.inspect}"
157
+ if params_handler = (user && (permission_by_role || permission_by_member_role))
158
+ params_handler = params_handler_default(params_handler)
153
159
  end
154
- authorized
160
+ params_handler
155
161
  end
156
-
157
- protected
162
+
163
+ def preload
164
+ @preload = true
165
+ params_handler = authorized? || {}
166
+ @preload = false
167
+ params_handler
168
+ end
169
+
170
+ # Implement this in your permissions class if using membership roles
171
+ #
172
+ # One example is that you have teams or projects that have members with role and you want to
173
+ # Authorize against that role instead of any of the roles associated with the user directly
174
+ #
175
+ # === Example:
176
+ #
177
+ # class Sprint < Trust::Permissions
178
+ # member_role :scrum_master, can(:update)
179
+ # def members_role()
180
+ # @members_role ||= subject.memberships.where(user_id: user.id).first.role_symbol
181
+ # end
182
+ def members_role()
183
+ {}
184
+ end
185
+
186
+ # Returns subject if subject is an instance, otherwise parent
187
+ #
188
+ def subject_or_parent
189
+ (@subject.nil? || subject.is_a?(Class)) ? parent : subject
190
+ end
191
+
192
+ def subject
193
+ raise SubjectInaccessible, 'You cannot access subject when declaring require or permit for new_actions. You may test with :preload?' if @preload
194
+ @subject
195
+ end
196
+
197
+ # returns true if permissions are currently being preloaded
198
+ # In new_actions, the framework must load require and permit in order to set permitted variables before the authorization can be
199
+ # evaluated. At that time, the subject is not accessible by permissions.
200
+ # It is not mandatory to use this, but you may test on this in yor permissions file if necessary.
201
+ #
202
+ # === Example:
203
+ #
204
+ # module Permissions
205
+ # class Account < Trust::Permissions
206
+ # role :admin, :accountant do
207
+ # can :create, :new, require: :account, permit: [:number, :amount, :comment], if: :preload?
208
+ # can :create, :new, require: :account, permit: [:number, :amount, :comment], if: :valid_amount?, unless: :preload?
209
+ # end
210
+ # end
211
+ # end
212
+ def preload?
213
+ @preload
214
+ end
215
+
216
+ private
158
217
  def eval_expr(options) #:nodoc:
159
- options.collect do |oper, expr|
218
+ params_handler = {}
219
+ found = options.collect do |oper, expr|
160
220
  res = case expr
161
- when Symbol then send(expr)
221
+ when Symbol
222
+ [:if, :unless].include?(oper) ? send(expr) : expr
162
223
  when Proc
163
224
  if expr.lambda?
164
225
  instance_exec &expr
@@ -172,13 +233,85 @@ module Trust
172
233
  case oper
173
234
  when :if then res
174
235
  when :unless then !res
236
+ when :require
237
+ params_handler[:require] = res
238
+ true
239
+ when :permit
240
+ params_handler[:permit] = Array.wrap(res)
241
+ true
175
242
  else
176
243
  raise UnsupportedCondition, expr.inspect
177
244
  end
178
245
  end.all?
246
+ found && params_handler
179
247
  end
180
-
248
+
249
+ def permission_by_role
250
+ auth = nil
251
+ trace 'authorize_by_role?', 0, "#{user.try(:name)}"
252
+ user.role_symbols.any? do |role|
253
+ trace 'authorize_by_role?', 1, "#{role}"
254
+ if p = permissions[role]
255
+ trace 'authorize_by_role?', 2, "permissions: #{p.inspect}"
256
+ auth = authorization(p)
257
+ end
258
+ end
259
+ auth
260
+ end
261
+
262
+ # Checks is a member is authorized
263
+ # You will need to implement members_role in permissions yourself
264
+ def permission_by_member_role
265
+ m = members_role
266
+ trace 'authorize_by_member_role?', 0, "#{user.try(:name)}:#{m}"
267
+ p = member_permissions[m]
268
+ trace 'authorize_by_role?', 1, "permissions: #{p.inspect}"
269
+ p && authorization(p)
270
+ end
271
+
272
+ def authorization(permissions = {})
273
+ auth = nil
274
+ permissions.any? do |act, opt|
275
+ auth = (opt.any? ? eval_expr(opt) : {}) if act == action
276
+ end
277
+ trace( 'authorization', 2, "got permission!") if auth
278
+ auth
279
+ end
280
+
281
+ # sets default values for params_handler if keys does not exist.
282
+ # note: if keys exists, they can be nil, and they will not be set to default
283
+ def params_handler_default(params_handler)
284
+ params_handler[:require] = (self.class.entity_required || route_key(@klass)) unless params_handler.has_key?(:require)
285
+ params_handler[:permit] = self.class.entity_attributes unless params_handler.has_key?(:permit)
286
+ params_handler
287
+ end
288
+
289
+ def route_key(klass)
290
+ klass.name.to_s.underscore.tr('/','_').to_sym
291
+ end
292
+
293
+ def trace(method, indent = 0, msg = nil)
294
+ return unless Trust.log_level == :trace
295
+ Rails.logger.debug "#{self.class.name}.#{method}: #{"\t" * indent}#{msg}"
296
+ end
297
+
181
298
  class << self
299
+ # Assign default requirement for whitelisting paremeters
300
+ #
301
+ # See {ActionController::Parameters.require} for how this works in Rails
302
+ #
303
+ def require(entity)
304
+ self.entity_required = entity
305
+ end
306
+
307
+ # Assign default permissions for whitelisting paremeter attributes
308
+ #
309
+ # See {ActionController::Parameters.permit} for how this works in Rails
310
+ #
311
+ def permit(*attrs)
312
+ self.entity_attributes = attrs.dup
313
+ end
314
+
182
315
  # Assign permissions to one or more roles.
183
316
  #
184
317
  # You may call role or roles, they are the same function like +role :admin+ or +roles :admin, :accountant+
@@ -206,6 +339,26 @@ module Trust
206
339
  # The above permits admin and accountant to read accounts.
207
340
  #
208
341
  def role(*roles, &block)
342
+ self.permissions = _role(self.permissions, *roles, &block)
343
+ end
344
+ alias :roles :role
345
+
346
+ # Assign permissions to one or more roles on a member role.
347
+ #
348
+ # You may call member_role or member_roles, they are the same function like
349
+ # +member_role :scrum_master+ or +member_roles :scrum_master, :product_owner+
350
+ #
351
+ # When using this feature, your permission class must respond to members_rols, and return only one role
352
+ #
353
+ # See {Trust::Permissions.role} for definition
354
+ # See {Trust::Permissions.members_role} for how to implement this method
355
+ #
356
+ def member_role(*roles, &block)
357
+ self.member_permissions = _role(self.member_permissions, *roles, &block)
358
+ end
359
+ alias :member_roles :member_role
360
+
361
+ def _role(existing_permissions, *roles, &block)
209
362
  if block_given?
210
363
  if @@can_expressions > 0
211
364
  @@can_expressions = 0
@@ -228,18 +381,18 @@ module Trust
228
381
  @@can_expressions = 0
229
382
  end
230
383
  roles.flatten.each do |role|
231
- self.permissions[role] ||= []
384
+ existing_permissions[role] ||= []
232
385
  if perms[:cannot] && perms[:cannot].size > 0
233
386
  perms[:cannot].each do |p|
234
- self.permissions[role].delete_if { |perm| perm[0] == p }
387
+ existing_permissions[role].delete_if { |perm| perm[0] == p }
235
388
  end
236
389
  end
237
390
  if perms[:can] && perms[:can].size > 0
238
- self.permissions[role] += perms[:can]
391
+ existing_permissions[role] += perms[:can]
239
392
  end
240
393
  end
394
+ existing_permissions
241
395
  end
242
- alias :roles :role
243
396
 
244
397
  # Defines permissions
245
398
  #
@@ -23,5 +23,5 @@
23
23
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
24
 
25
25
  module Trust
26
- VERSION = "0.8.3"
26
+ VERSION = "1.4.2"
27
27
  end
@@ -77,8 +77,8 @@ class AccountsController < ApplicationController
77
77
  # PUT /clients/1/accounts/1.json
78
78
  def update
79
79
  respond_to do |format|
80
- if @account.update_attributes(params[:account])
81
- format.html { redirect_to client_account_path(@account), notice: 'Account was successfully updated.' }
80
+ if @account.update_attributes(resource.strong_params)
81
+ format.html { redirect_to client_account_path(@account.client, @account), notice: 'Account was successfully updated.' }
82
82
  format.json { head :no_content }
83
83
  else
84
84
  format.html { render action: "edit" }
@@ -70,7 +70,7 @@ class ClientsController < ApplicationController
70
70
  # PUT /clients/1.json
71
71
  def update
72
72
  respond_to do |format|
73
- if @client.update_attributes(params[:client])
73
+ if @client.update_attributes(resource.strong_params)
74
74
  format.html { redirect_to @client, notice: 'Client was successfully updated.' }
75
75
  format.json { head :no_content }
76
76
  else
@@ -64,7 +64,7 @@ class MongoAccountsController < ApplicationController
64
64
  def create
65
65
  respond_to do |format|
66
66
  if @mongo_account.save
67
- format.html { redirect_to mongo_client_mongo_account_path(@mongo_account.mongo_client,@mongo_account), notice: 'Account was successfully created.' }
67
+ format.html { redirect_to mongo_account_path(@mongo_account), notice: 'Account was successfully created.' }
68
68
  format.json { render json: @mongo_account, status: :created, location: @mongo_account }
69
69
  else
70
70
  format.html { render action: "new" }
@@ -77,8 +77,8 @@ class MongoAccountsController < ApplicationController
77
77
  # PUT /clients/1/accounts/1.json
78
78
  def update
79
79
  respond_to do |format|
80
- if @mongo_account.update_attributes(params[:mongo_account])
81
- format.html { redirect_to mongo_client_mongo_account_path(@mongo_account), notice: 'Account was successfully updated.' }
80
+ if @mongo_account.update_attributes(resource.strong_params)
81
+ format.html { redirect_to mongo_account_path(@mongo_account), notice: 'Account was successfully updated.' }
82
82
  format.json { head :no_content }
83
83
  else
84
84
  format.html { render action: "edit" }
@@ -90,10 +90,11 @@ class MongoAccountsController < ApplicationController
90
90
  # DELETE /clients/1/accounts/1
91
91
  # DELETE /clients/1/accounts/1.json
92
92
  def destroy
93
+ client_id = @mongo_account.mongo_client
93
94
  @mongo_account.destroy
94
95
 
95
96
  respond_to do |format|
96
- format.html { redirect_to mongo_client_mongo_accounts_url }
97
+ format.html { redirect_to mongo_client_mongo_accounts_path(client_id) }
97
98
  format.json { head :no_content }
98
99
  end
99
100
  end
@@ -70,7 +70,7 @@ class MongoClientsController < ApplicationController
70
70
  # PUT /clients/1.json
71
71
  def update
72
72
  respond_to do |format|
73
- if @mongo_client.update_attributes(params[:mongo_client])
73
+ if @mongo_client.update_attributes(resource.strong_params)
74
74
  format.html { redirect_to @mongo_client, notice: 'Client was successfully updated.' }
75
75
  format.json { head :no_content }
76
76
  else
@@ -64,8 +64,6 @@ class UsersController < ApplicationController
64
64
  # POST /users
65
65
  # POST /users.json
66
66
  def create
67
- @user = User.new(params[:user])
68
-
69
67
  respond_to do |format|
70
68
  if @user.save
71
69
  format.html { redirect_to @user, notice: 'User was successfully created.' }
@@ -80,10 +78,8 @@ class UsersController < ApplicationController
80
78
  # PUT /users/1
81
79
  # PUT /users/1.json
82
80
  def update
83
- @user = User.find(params[:id])
84
-
85
81
  respond_to do |format|
86
- if @user.update_attributes(params[:user])
82
+ if @user.update_attributes(resource.strong_params)
87
83
  format.html { redirect_to @user, notice: 'User was successfully updated.' }
88
84
  format.json { head :no_content }
89
85
  else
@@ -23,7 +23,7 @@
23
23
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
24
 
25
25
  class Account < ActiveRecord::Base
26
- attr_accessible :name, :client_id
26
+ # attr_accessible :name, :client_id
27
27
  belongs_to :client
28
28
  belongs_to :created_by, :class_name => 'User'
29
29
 
@@ -23,7 +23,7 @@
23
23
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
24
 
25
25
  class Client < ActiveRecord::Base
26
- attr_accessible :name
26
+ # attr_accessible :name
27
27
  has_many :accounts
28
28
  belongs_to :accountant, :class_name => 'User'
29
29
 
@@ -23,9 +23,12 @@
23
23
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
24
 
25
25
  module Permissions
26
+ Trust::Permissions.action_aliases = {
27
+ update: [:update, :edit],
28
+ }
26
29
  class Default < Trust::Permissions
27
30
  role :system_admin do
28
- can :manage
31
+ can :index, :show, :create, :new, :update, :edit, :destroy
29
32
  can :audit
30
33
  end
31
34
 
@@ -39,20 +42,22 @@ module Permissions
39
42
  end
40
43
 
41
44
  class Client < Default
42
- role :accountant, can(:manage)
43
- role all, can(:read)
45
+ role :accountant, can(:index, :show, :create, :new, :update, :edit, :destroy)
46
+ role all, can(:index, :show)
44
47
  end
45
48
 
46
49
  class MongoClient < Client
47
50
  end
48
51
 
49
52
  class Account < Default
53
+ require :account
54
+ permit :name, :client_id
50
55
  role :accountant do
51
- can :create, :if => :associated_with_client?
52
- can :update, :if => :creator?
56
+ can :new, :create, if: :associated_with_client?
57
+ can :update, if: :creator?, permit: :name
53
58
  end
54
59
  role :department_manager, :accountant do
55
- can :create, :if => lambda { parent && parent.accountant == :superspecial }
60
+ can :new, :create, :if => lambda { parent && parent.accountant == :superspecial }
56
61
  end
57
62
 
58
63
  def associated_with_client?
@@ -62,11 +67,11 @@ module Permissions
62
67
 
63
68
  class MongoAccount < Default
64
69
  role :accountant do
65
- can :create, :if => :associated_with_client?
70
+ can :new, :create, :if => :associated_with_client?
66
71
  can :update, :if => :creator?
67
72
  end
68
73
  role :department_manager, :accountant do
69
- can :create, :if => lambda { parent && parent.accountant == :superspecial }
74
+ can :new, :create, :if => lambda { parent && parent.accountant == :superspecial }
70
75
  end
71
76
 
72
77
  def associated_with_client?
@@ -76,10 +81,12 @@ module Permissions
76
81
 
77
82
  class Account::Credit < Account
78
83
  role :guest do
79
- can :create, :if => lambda { user.name == 'wife'}
80
- end
81
-
84
+ can :new, :create, :if => lambda { user.name == 'wife'}
85
+ end
82
86
  end
83
87
 
88
+ class User < Default
89
+ permit :name
90
+ end
84
91
 
85
92
  end
@@ -23,7 +23,7 @@
23
23
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
24
 
25
25
  class User < ActiveRecord::Base
26
- attr_accessible :name
26
+ # attr_accessible :name
27
27
 
28
28
  def role_symbols
29
29
  [ name && name.to_sym]