From: Jean-Philippe Lang Date: Tue, 5 Apr 2011 12:50:19 +0000 (+0000) Subject: Makes visible scopes accept projects option and deprecate Project.visible_by. X-Git-Tag: 1.2.0~524 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=405fc07e90730c550f1e690a446eda872fd8732d;p=redmine.git Makes visible scopes accept projects option and deprecate Project.visible_by. git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@5324 e93f8b46-1217-0410-a6f0-8f06a7374b81 --- diff --git a/app/models/changeset.rb b/app/models/changeset.rb index 719540823..59b2302ac 100644 --- a/app/models/changeset.rb +++ b/app/models/changeset.rb @@ -42,7 +42,7 @@ class Changeset < ActiveRecord::Base validates_uniqueness_of :scmid, :scope => :repository_id, :allow_nil => true named_scope :visible, lambda {|*args| { :include => {:repository => :project}, - :conditions => Project.allowed_to_condition(args.first || User.current, :view_changesets) } } + :conditions => Project.allowed_to_condition(args.shift || User.current, :view_changesets, *args) } } def revision=(r) write_attribute :revision, (r.nil? ? nil : r.to_s) diff --git a/app/models/document.rb b/app/models/document.rb index 21232a2d9..d51f2d328 100644 --- a/app/models/document.rb +++ b/app/models/document.rb @@ -30,7 +30,7 @@ class Document < ActiveRecord::Base validates_length_of :title, :maximum => 60 named_scope :visible, lambda {|*args| { :include => :project, - :conditions => Project.allowed_to_condition(args.first || User.current, :view_documents) } } + :conditions => Project.allowed_to_condition(args.shift || User.current, :view_documents, *args) } } def visible?(user=User.current) !user.nil? && user.allowed_to?(:view_documents, project) diff --git a/app/models/issue.rb b/app/models/issue.rb index 24258b424..943626686 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -60,7 +60,7 @@ class Issue < ActiveRecord::Base validates_numericality_of :estimated_hours, :allow_nil => true named_scope :visible, lambda {|*args| { :include => :project, - :conditions => Issue.visible_condition(args.first || User.current) } } + :conditions => Issue.visible_condition(args.shift || User.current, *args) } } named_scope :open, :conditions => ["#{IssueStatus.table_name}.is_closed = ?", false], :include => :status diff --git a/app/models/journal.rb b/app/models/journal.rb index 7a36b12f1..39eb338d8 100644 --- a/app/models/journal.rb +++ b/app/models/journal.rb @@ -40,7 +40,7 @@ class Journal < ActiveRecord::Base named_scope :visible, lambda {|*args| { :include => {:issue => :project}, - :conditions => Issue.visible_condition(args.first || User.current) + :conditions => Issue.visible_condition(args.shift || User.current, *args) }} def save(*args) diff --git a/app/models/message.rb b/app/models/message.rb index 77c9ff550..776af6e4a 100644 --- a/app/models/message.rb +++ b/app/models/message.rb @@ -24,7 +24,7 @@ class Message < ActiveRecord::Base acts_as_searchable :columns => ['subject', 'content'], :include => {:board => :project}, - :project_key => 'project_id', + :project_key => "#{Board.table_name}.project_id", :date_column => "#{table_name}.created_on" acts_as_event :title => Proc.new {|o| "#{o.board.name}: #{o.subject}"}, :description => :content, @@ -43,7 +43,7 @@ class Message < ActiveRecord::Base after_create :add_author_as_watcher named_scope :visible, lambda {|*args| { :include => {:board => :project}, - :conditions => Project.allowed_to_condition(args.first || User.current, :view_messages) } } + :conditions => Project.allowed_to_condition(args.shift || User.current, :view_messages, *args) } } def visible?(user=User.current) !user.nil? && user.allowed_to?(:view_messages, project) diff --git a/app/models/news.rb b/app/models/news.rb index 7f8c73107..9e7cb1e19 100644 --- a/app/models/news.rb +++ b/app/models/news.rb @@ -34,7 +34,7 @@ class News < ActiveRecord::Base named_scope :visible, lambda {|*args| { :include => :project, - :conditions => Project.allowed_to_condition(args.first || User.current, :view_news) + :conditions => Project.allowed_to_condition(args.shift || User.current, :view_news, *args) }} def visible?(user=User.current) diff --git a/app/models/project.rb b/app/models/project.rb index 58839a6fe..2d6e2ef0e 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -84,7 +84,7 @@ class Project < ActiveRecord::Base named_scope :has_module, lambda { |mod| { :conditions => ["#{Project.table_name}.id IN (SELECT em.project_id FROM #{EnabledModule.table_name} em WHERE em.name=?)", mod.to_s] } } named_scope :active, { :conditions => "#{Project.table_name}.status = #{STATUS_ACTIVE}"} named_scope :all_public, { :conditions => { :is_public => true } } - named_scope :visible, lambda { { :conditions => Project.visible_by(User.current) } } + named_scope :visible, lambda {|*args| {:conditions => Project.visible_condition(args.shift || User.current, *args) }} def initialize(attributes = nil) super @@ -115,25 +115,30 @@ class Project < ActiveRecord::Base # returns latest created projects # non public projects will be returned only if user is a member of those def self.latest(user=nil, count=5) - find(:all, :limit => count, :conditions => visible_by(user), :order => "created_on DESC") + visible(user).find(:all, :limit => count, :order => "created_on DESC") end - # Returns a SQL :conditions string used to find all active projects for the specified user. + def self.visible_by(user=nil) + ActiveSupport::Deprecation.warn "Project.visible_by is deprecated and will be removed in Redmine 1.3.0. Use Project.visible_condition instead." + visible_condition(user || User.current) + end + + # Returns a SQL conditions string used to find all projects visible by the specified user. # # Examples: - # Projects.visible_by(admin) => "projects.status = 1" - # Projects.visible_by(normal_user) => "projects.status = 1 AND projects.is_public = 1" - def self.visible_by(user=nil) - user ||= User.current - if user && user.admin? - return "#{Project.table_name}.status=#{Project::STATUS_ACTIVE}" - elsif user && user.memberships.any? - return "#{Project.table_name}.status=#{Project::STATUS_ACTIVE} AND (#{Project.table_name}.is_public = #{connection.quoted_true} or #{Project.table_name}.id IN (#{user.memberships.collect{|m| m.project_id}.join(',')}))" - else - return "#{Project.table_name}.status=#{Project::STATUS_ACTIVE} AND #{Project.table_name}.is_public = #{connection.quoted_true}" - end + # Project.visible_condition(admin) => "projects.status = 1" + # Project.visible_condition(normal_user) => "((projects.status = 1) AND (projects.is_public = 1 OR projects.id IN (1,3,4)))" + # Project.visible_condition(anonymous) => "((projects.status = 1) AND (projects.is_public = 1))" + def self.visible_condition(user, options={}) + allowed_to_condition(user, :view_project, options) end + # Returns a SQL conditions string used to find all projects for which +user+ has the given +permission+ + # + # Valid options: + # * :project => limit the condition to project + # * :with_subprojects => limit the condition to project and its subprojects + # * :member => limit the condition to the user projects def self.allowed_to_condition(user, permission, options={}) base_statement = "#{Project.table_name}.status=#{Project::STATUS_ACTIVE}" if perm = Redmine::AccessControl.permission(permission) diff --git a/app/models/time_entry.rb b/app/models/time_entry.rb index c89ead322..a5139998a 100644 --- a/app/models/time_entry.rb +++ b/app/models/time_entry.rb @@ -41,7 +41,7 @@ class TimeEntry < ActiveRecord::Base named_scope :visible, lambda {|*args| { :include => :project, - :conditions => Project.allowed_to_condition(args.first || User.current, :view_time_entries) + :conditions => Project.allowed_to_condition(args.shift || User.current, :view_time_entries, *args) }} def after_initialize diff --git a/test/unit/issue_test.rb b/test/unit/issue_test.rb index f4dcf6625..5f61d61a5 100644 --- a/test/unit/issue_test.rb +++ b/test/unit/issue_test.rb @@ -106,6 +106,22 @@ class IssueTest < ActiveSupport::TestCase assert issues.detect {|issue| !issue.project.is_public?} end + def test_visible_scope_with_project + project = Project.find(1) + issues = Issue.visible(User.find(2), :project => project).all + projects = issues.collect(&:project).uniq + assert_equal 1, projects.size + assert_equal project, projects.first + end + + def test_visible_scope_with_project_and_subprojects + project = Project.find(1) + issues = Issue.visible(User.find(2), :project => project, :with_subprojects => true).all + projects = issues.collect(&:project).uniq + assert projects.size > 1 + assert_equal [], projects.select {|p| !p.is_or_is_descendant_of?(project)} + end + def test_errors_full_messages_should_include_custom_fields_errors field = IssueCustomField.find_by_name('Database')