diff options
author | Jean-Philippe Lang <jp_lang@yahoo.fr> | 2014-11-11 13:08:52 +0000 |
---|---|---|
committer | Jean-Philippe Lang <jp_lang@yahoo.fr> | 2014-11-11 13:08:52 +0000 |
commit | bdd3ccf8e52c69d2b6e16e7230a1b8f9a6c69e60 (patch) | |
tree | 1571b147765d42bccab602cdd9a79499829de612 /app/models | |
parent | 140ca9532c1c12b7ff710c076c6985dce18500e4 (diff) | |
download | redmine-bdd3ccf8e52c69d2b6e16e7230a1b8f9a6c69e60.tar.gz redmine-bdd3ccf8e52c69d2b6e16e7230a1b8f9a6c69e60.zip |
Adds a role setting for controlling visibility of users: all or members of visible projects (#11724).
git-svn-id: http://svn.redmine.org/redmine/trunk@13584 e93f8b46-1217-0410-a6f0-8f06a7374b81
Diffstat (limited to 'app/models')
-rw-r--r-- | app/models/issue_query.rb | 8 | ||||
-rw-r--r-- | app/models/principal.rb | 28 | ||||
-rw-r--r-- | app/models/role.rb | 8 | ||||
-rw-r--r-- | app/models/time_entry_query.rb | 6 | ||||
-rw-r--r-- | app/models/user.rb | 6 |
5 files changed, 49 insertions, 7 deletions
diff --git a/app/models/issue_query.rb b/app/models/issue_query.rb index 15c49c5d6..8140163d8 100644 --- a/app/models/issue_query.rb +++ b/app/models/issue_query.rb @@ -131,17 +131,17 @@ class IssueQuery < Query issue_custom_fields = [] if project - principals += project.principals.sort + principals += project.principals.visible unless project.leaf? subprojects = project.descendants.visible.to_a - principals += Principal.member_of(subprojects) + principals += Principal.member_of(subprojects).visible end versions = project.shared_versions.to_a categories = project.issue_categories.to_a issue_custom_fields = project.all_issue_custom_fields else if all_projects.any? - principals += Principal.member_of(all_projects) + principals += Principal.member_of(all_projects).visible end versions = Version.visible.where(:sharing => 'system').to_a issue_custom_fields = IssueCustomField.where(:is_for_all => true) @@ -185,7 +185,7 @@ class IssueQuery < Query :type => :list_optional, :values => assigned_to_values ) unless assigned_to_values.empty? - group_values = Group.givable.collect {|g| [g.name, g.id.to_s] } + group_values = Group.givable.visible.collect {|g| [g.name, g.id.to_s] } add_available_filter("member_of_group", :type => :list_optional, :values => group_values ) unless group_values.empty? diff --git a/app/models/principal.rb b/app/models/principal.rb index e6e6ea78e..d98531dca 100644 --- a/app/models/principal.rb +++ b/app/models/principal.rb @@ -38,6 +38,30 @@ class Principal < ActiveRecord::Base # Groups and active users scope :active, lambda { where(:status => STATUS_ACTIVE) } + scope :visible, lambda {|*args| + user = args.first || User.current + + if user.admin? + all + else + view_all_active = false + if user.memberships.to_a.any? + view_all_active = user.memberships.any? {|m| m.roles.any? {|r| r.users_visibility == 'all'}} + else + view_all_active = user.builtin_role.users_visibility == 'all' + end + + if view_all_active + active + else + # self and members of visible projects + active.where("#{table_name}.id = ? OR #{table_name}.id IN (SELECT user_id FROM #{Member.table_name} WHERE project_id IN (?))", + user.id, user.visible_project_ids + ) + end + end + } + scope :like, lambda {|q| q = q.to_s if q.blank? @@ -84,6 +108,10 @@ class Principal < ActiveRecord::Base to_s end + def visible?(user=User.current) + Principal.visible(user).where(:id => id).first == self + end + # Return true if the principal is a member of project def member_of?(project) projects.to_a.include?(project) diff --git a/app/models/role.rb b/app/models/role.rb index 31dbf75a1..c6a6b4979 100644 --- a/app/models/role.rb +++ b/app/models/role.rb @@ -39,6 +39,11 @@ class Role < ActiveRecord::Base ['own', :label_issues_visibility_own] ] + USERS_VISIBILITY_OPTIONS = [ + ['all', :label_users_visibility_all], + ['members_of_visible_projects', :label_users_visibility_members_of_visible_projects] + ] + scope :sorted, lambda { order(:builtin, :position) } scope :givable, lambda { order(:position).where(:builtin => 0) } scope :builtin, lambda { |*args| @@ -67,6 +72,9 @@ class Role < ActiveRecord::Base validates_inclusion_of :issues_visibility, :in => ISSUES_VISIBILITY_OPTIONS.collect(&:first), :if => lambda {|role| role.respond_to?(:issues_visibility)} + validates_inclusion_of :users_visibility, + :in => USERS_VISIBILITY_OPTIONS.collect(&:first), + :if => lambda {|role| role.respond_to?(:users_visibility)} # Copies attributes from another role, arg can be an id or a Role def copy_from(arg, options={}) diff --git a/app/models/time_entry_query.rb b/app/models/time_entry_query.rb index 05c39f55e..13ef60c20 100644 --- a/app/models/time_entry_query.rb +++ b/app/models/time_entry_query.rb @@ -40,20 +40,20 @@ class TimeEntryQuery < Query principals = [] if project - principals += project.principals.sort + principals += project.principals.visible.sort unless project.leaf? subprojects = project.descendants.visible.to_a if subprojects.any? add_available_filter "subproject_id", :type => :list_subprojects, :values => subprojects.collect{|s| [s.name, s.id.to_s] } - principals += Principal.member_of(subprojects) + principals += Principal.member_of(subprojects).visible end end else if all_projects.any? # members of visible projects - principals += Principal.member_of(all_projects) + principals += Principal.member_of(all_projects).visible # project filter project_values = [] if User.current.logged? && User.current.memberships.any? diff --git a/app/models/user.rb b/app/models/user.rb index a0a703700..b5bb6ae1e 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -148,6 +148,7 @@ class User < Principal @notified_projects_ids = nil @notified_projects_ids_changed = false @builtin_role = nil + @visible_project_ids = nil base_reload(*args) end @@ -528,6 +529,11 @@ class User < Principal @projects_by_role = hash end + # Returns the ids of visible projects + def visible_project_ids + @visible_project_ids ||= Project.visible(self).pluck(:id) + end + # Returns true if user is arg or belongs to arg def is_or_belongs_to?(arg) if arg.is_a?(User) |