Mercurial > hg > soundsoftware-site
diff app/models/user.rb @ 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 | bbb139d5ca95 af80e5618e9b 8661b858af72 |
line wrap: on
line diff
--- a/app/models/user.rb Fri Sep 24 14:06:04 2010 +0100 +++ b/app/models/user.rb Fri Nov 19 13:24:41 2010 +0000 @@ -33,6 +33,15 @@ :username => '#{login}' } + MAIL_NOTIFICATION_OPTIONS = [ + [:all, :label_user_mail_option_all], + [:selected, :label_user_mail_option_selected], + [:none, :label_user_mail_option_none], + [:only_my_events, :label_user_mail_option_only_my_events], + [:only_assigned, :label_user_mail_option_only_assigned], + [:only_owner, :label_user_mail_option_only_owner] + ] + has_and_belongs_to_many :groups, :after_add => Proc.new {|user, group| group.user_added(user)}, :after_remove => Proc.new {|user, group| group.user_removed(user)} has_many :issue_categories, :foreign_key => 'assigned_to_id', :dependent => :nullify @@ -65,7 +74,7 @@ validates_confirmation_of :password, :allow_nil => true def before_create - self.mail_notification = false + self.mail_notification = Setting.default_notification_option if self.mail_notification.blank? true end @@ -250,6 +259,17 @@ notified_projects_ids end + # Only users that belong to more than 1 project can select projects for which they are notified + def valid_notification_options + # Note that @user.membership.size would fail since AR ignores + # :include association option when doing a count + if memberships.length < 1 + MAIL_NOTIFICATION_OPTIONS.delete_if {|option| option.first == :selected} + else + MAIL_NOTIFICATION_OPTIONS + end + end + # Find a user account by matching the exact login and then a case-insensitive # version. Exact matches will be given priority. def self.find_by_login(login) @@ -324,23 +344,35 @@ !roles_for_project(project).detect {|role| role.member?}.nil? end - # Return true if the user is allowed to do the specified action on project - # action can be: + # Return true if the user is allowed to do the specified action on a specific context + # Action can be: # * a parameter-like Hash (eg. :controller => 'projects', :action => 'edit') # * a permission Symbol (eg. :edit_project) - def allowed_to?(action, project, options={}) - if project + # Context can be: + # * a project : returns true if user is allowed to do the specified action on this project + # * a group of projects : returns true if user is allowed on every project + # * nil with options[:global] set : check if user has at least one role allowed for this action, + # or falls back to Non Member / Anonymous permissions depending if the user is logged + def allowed_to?(action, context, options={}) + if context && context.is_a?(Project) # No action allowed on archived projects - return false unless project.active? + return false unless context.active? # No action allowed on disabled modules - return false unless project.allows_to?(action) + return false unless context.allows_to?(action) # Admin users are authorized for anything else return true if admin? - roles = roles_for_project(project) + roles = roles_for_project(context) return false unless roles - roles.detect {|role| (project.is_public? || role.member?) && role.allowed_to?(action)} + roles.detect {|role| (context.is_public? || role.member?) && role.allowed_to?(action)} + elsif context && context.is_a?(Array) + # Authorize if user is authorized on every element of the array + context.map do |project| + allowed_to?(action,project,options) + end.inject do |memo,allowed| + memo && allowed + end elsif options[:global] # Admin users are always authorized return true if admin? @@ -359,6 +391,41 @@ allowed_to?(action, nil, options.reverse_merge(:global => true)) end + # Utility method to help check if a user should be notified about an + # event. + # + # TODO: only supports Issue events currently + def notify_about?(object) + case mail_notification.to_sym + when :all + true + when :selected + # Handled by the Project + when :none + false + when :only_my_events + if object.is_a?(Issue) && (object.author == self || object.assigned_to == self) + true + else + false + end + when :only_assigned + if object.is_a?(Issue) && object.assigned_to == self + true + else + false + end + when :only_owner + if object.is_a?(Issue) && object.author == self + true + else + false + end + else + false + end + end + def self.current=(user) @current_user = user end