summaryrefslogtreecommitdiffstats
path: root/app/models
diff options
context:
space:
mode:
authorJean-Philippe Lang <jp_lang@yahoo.fr>2014-11-11 13:08:52 +0000
committerJean-Philippe Lang <jp_lang@yahoo.fr>2014-11-11 13:08:52 +0000
commitbdd3ccf8e52c69d2b6e16e7230a1b8f9a6c69e60 (patch)
tree1571b147765d42bccab602cdd9a79499829de612 /app/models
parent140ca9532c1c12b7ff710c076c6985dce18500e4 (diff)
downloadredmine-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.rb8
-rw-r--r--app/models/principal.rb28
-rw-r--r--app/models/role.rb8
-rw-r--r--app/models/time_entry_query.rb6
-rw-r--r--app/models/user.rb6
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)