comparison app/models/.svn/text-base/user.rb.svn-base @ 37:94944d00e43c

* Update to SVN trunk rev 4411
author Chris Cannam <chris.cannam@soundsoftware.ac.uk>
date Fri, 19 Nov 2010 13:24:41 +0000
parents 40f7cfd4df19
children af80e5618e9b 8661b858af72
comparison
equal deleted inserted replaced
22:40f7cfd4df19 37:94944d00e43c
31 :lastname_firstname => '#{lastname} #{firstname}', 31 :lastname_firstname => '#{lastname} #{firstname}',
32 :lastname_coma_firstname => '#{lastname}, #{firstname}', 32 :lastname_coma_firstname => '#{lastname}, #{firstname}',
33 :username => '#{login}' 33 :username => '#{login}'
34 } 34 }
35 35
36 MAIL_NOTIFICATION_OPTIONS = [
37 [:all, :label_user_mail_option_all],
38 [:selected, :label_user_mail_option_selected],
39 [:none, :label_user_mail_option_none],
40 [:only_my_events, :label_user_mail_option_only_my_events],
41 [:only_assigned, :label_user_mail_option_only_assigned],
42 [:only_owner, :label_user_mail_option_only_owner]
43 ]
44
36 has_and_belongs_to_many :groups, :after_add => Proc.new {|user, group| group.user_added(user)}, 45 has_and_belongs_to_many :groups, :after_add => Proc.new {|user, group| group.user_added(user)},
37 :after_remove => Proc.new {|user, group| group.user_removed(user)} 46 :after_remove => Proc.new {|user, group| group.user_removed(user)}
38 has_many :issue_categories, :foreign_key => 'assigned_to_id', :dependent => :nullify 47 has_many :issue_categories, :foreign_key => 'assigned_to_id', :dependent => :nullify
39 has_many :changesets, :dependent => :nullify 48 has_many :changesets, :dependent => :nullify
40 has_one :preference, :dependent => :destroy, :class_name => 'UserPreference' 49 has_one :preference, :dependent => :destroy, :class_name => 'UserPreference'
63 validates_format_of :mail, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i, :allow_nil => true 72 validates_format_of :mail, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i, :allow_nil => true
64 validates_length_of :mail, :maximum => 60, :allow_nil => true 73 validates_length_of :mail, :maximum => 60, :allow_nil => true
65 validates_confirmation_of :password, :allow_nil => true 74 validates_confirmation_of :password, :allow_nil => true
66 75
67 def before_create 76 def before_create
68 self.mail_notification = false 77 self.mail_notification = Setting.default_notification_option if self.mail_notification.blank?
69 true 78 true
70 end 79 end
71 80
72 def before_save 81 def before_save
73 # update hashed_password if password was set 82 # update hashed_password if password was set
248 Member.update_all("mail_notification = #{connection.quoted_true}", ['user_id = ? AND project_id IN (?)', id, ids]) if ids && !ids.empty? 257 Member.update_all("mail_notification = #{connection.quoted_true}", ['user_id = ? AND project_id IN (?)', id, ids]) if ids && !ids.empty?
249 @notified_projects_ids = nil 258 @notified_projects_ids = nil
250 notified_projects_ids 259 notified_projects_ids
251 end 260 end
252 261
262 # Only users that belong to more than 1 project can select projects for which they are notified
263 def valid_notification_options
264 # Note that @user.membership.size would fail since AR ignores
265 # :include association option when doing a count
266 if memberships.length < 1
267 MAIL_NOTIFICATION_OPTIONS.delete_if {|option| option.first == :selected}
268 else
269 MAIL_NOTIFICATION_OPTIONS
270 end
271 end
272
253 # Find a user account by matching the exact login and then a case-insensitive 273 # Find a user account by matching the exact login and then a case-insensitive
254 # version. Exact matches will be given priority. 274 # version. Exact matches will be given priority.
255 def self.find_by_login(login) 275 def self.find_by_login(login)
256 # force string comparison to be case sensitive on MySQL 276 # force string comparison to be case sensitive on MySQL
257 type_cast = (ActiveRecord::Base.connection.adapter_name == 'MySQL') ? 'BINARY' : '' 277 type_cast = (ActiveRecord::Base.connection.adapter_name == 'MySQL') ? 'BINARY' : ''
322 # Return true if the user is a member of project 342 # Return true if the user is a member of project
323 def member_of?(project) 343 def member_of?(project)
324 !roles_for_project(project).detect {|role| role.member?}.nil? 344 !roles_for_project(project).detect {|role| role.member?}.nil?
325 end 345 end
326 346
327 # Return true if the user is allowed to do the specified action on project 347 # Return true if the user is allowed to do the specified action on a specific context
328 # action can be: 348 # Action can be:
329 # * a parameter-like Hash (eg. :controller => 'projects', :action => 'edit') 349 # * a parameter-like Hash (eg. :controller => 'projects', :action => 'edit')
330 # * a permission Symbol (eg. :edit_project) 350 # * a permission Symbol (eg. :edit_project)
331 def allowed_to?(action, project, options={}) 351 # Context can be:
332 if project 352 # * a project : returns true if user is allowed to do the specified action on this project
353 # * a group of projects : returns true if user is allowed on every project
354 # * nil with options[:global] set : check if user has at least one role allowed for this action,
355 # or falls back to Non Member / Anonymous permissions depending if the user is logged
356 def allowed_to?(action, context, options={})
357 if context && context.is_a?(Project)
333 # No action allowed on archived projects 358 # No action allowed on archived projects
334 return false unless project.active? 359 return false unless context.active?
335 # No action allowed on disabled modules 360 # No action allowed on disabled modules
336 return false unless project.allows_to?(action) 361 return false unless context.allows_to?(action)
337 # Admin users are authorized for anything else 362 # Admin users are authorized for anything else
338 return true if admin? 363 return true if admin?
339 364
340 roles = roles_for_project(project) 365 roles = roles_for_project(context)
341 return false unless roles 366 return false unless roles
342 roles.detect {|role| (project.is_public? || role.member?) && role.allowed_to?(action)} 367 roles.detect {|role| (context.is_public? || role.member?) && role.allowed_to?(action)}
343 368
369 elsif context && context.is_a?(Array)
370 # Authorize if user is authorized on every element of the array
371 context.map do |project|
372 allowed_to?(action,project,options)
373 end.inject do |memo,allowed|
374 memo && allowed
375 end
344 elsif options[:global] 376 elsif options[:global]
345 # Admin users are always authorized 377 # Admin users are always authorized
346 return true if admin? 378 return true if admin?
347 379
348 # authorize if user has at least one role that has this permission 380 # authorize if user has at least one role that has this permission
355 387
356 # Is the user allowed to do the specified action on any project? 388 # Is the user allowed to do the specified action on any project?
357 # See allowed_to? for the actions and valid options. 389 # See allowed_to? for the actions and valid options.
358 def allowed_to_globally?(action, options) 390 def allowed_to_globally?(action, options)
359 allowed_to?(action, nil, options.reverse_merge(:global => true)) 391 allowed_to?(action, nil, options.reverse_merge(:global => true))
392 end
393
394 # Utility method to help check if a user should be notified about an
395 # event.
396 #
397 # TODO: only supports Issue events currently
398 def notify_about?(object)
399 case mail_notification.to_sym
400 when :all
401 true
402 when :selected
403 # Handled by the Project
404 when :none
405 false
406 when :only_my_events
407 if object.is_a?(Issue) && (object.author == self || object.assigned_to == self)
408 true
409 else
410 false
411 end
412 when :only_assigned
413 if object.is_a?(Issue) && object.assigned_to == self
414 true
415 else
416 false
417 end
418 when :only_owner
419 if object.is_a?(Issue) && object.author == self
420 true
421 else
422 false
423 end
424 else
425 false
426 end
360 end 427 end
361 428
362 def self.current=(user) 429 def self.current=(user)
363 @current_user = user 430 @current_user = user
364 end 431 end