diff -ur redmine-1.0.2/app/controllers/issues_controller.rb redmine/app/controllers/issues_controller.rb --- redmine-1.0.2/app/controllers/issues_controller.rb 2010-09-27 02:33:17.000000000 +0400 +++ redmine/app/controllers/issues_controller.rb 2010-10-08 12:16:20.337725004 +0400 @@ -97,6 +97,7 @@ end def show + return render_403 if !@issue.visible? @journals = @issue.journals.find(:all, :include => [:user, :details], :order => "#{Journal.table_name}.created_on ASC") @journals.each_with_index {|j,i| j.indice = i+1} @journals.reverse! if User.current.wants_comments_in_reverse_order? diff -ur redmine-1.0.2/app/models/issue.rb redmine/app/models/issue.rb --- redmine-1.0.2/app/models/issue.rb 2010-09-27 02:33:39.000000000 +0400 +++ redmine/app/models/issue.rb 2010-10-08 12:16:20.339725020 +0400 @@ -74,8 +74,8 @@ after_destroy :update_parent_attributes # Returns true if usr or current user is allowed to view the issue - def visible?(usr=nil) - (usr || User.current).allowed_to?(:view_issues, self.project) + def visible?(user=User.current) + user.allowed_to?(:view_issues, self.project) || user.allowed_to?(:add_issues, self.project) && (author == user || assigned_to == user || watched_by?(user)) end def after_initialize diff -ur redmine-1.0.2/app/models/query.rb redmine/app/models/query.rb --- redmine-1.0.2/app/models/query.rb 2010-08-19 08:32:25.000000000 +0400 +++ redmine/app/models/query.rb 2010-10-08 12:16:20.340724583 +0400 @@ -379,7 +379,7 @@ group_by_column.groupable end - def project_statement + def project_statement(own=nil) project_clauses = [] if project && !@project.descendants.active.empty? ids = [project.id] @@ -401,7 +401,16 @@ elsif project project_clauses << "#{Project.table_name}.id = %d" % project.id end - project_clauses << Project.allowed_to_condition(User.current, :view_issues) + if own + wt = Watcher.table_name + uc = User.current.id.to_s + project_clauses << '('+Project.allowed_to_condition(User.current, :view_issues)+' OR '+Project.allowed_to_condition(User.current, :add_issues)+ + " AND (#{Issue.table_name}.author_id=#{uc} OR "+ + "#{Issue.table_name}.assigned_to_id=#{uc} OR "+ + "#{Issue.table_name}.id IN (SELECT #{wt}.watchable_id FROM #{wt} WHERE #{wt}.watchable_type='Issue' AND user_id=#{uc}))"+")" + else + project_clauses << Project.allowed_to_condition(User.current, :view_issues) + end project_clauses.join(' AND ') end @@ -442,7 +451,7 @@ end if filters and valid? - (filters_clauses << project_statement).join(' AND ') + (filters_clauses << project_statement(true)).join(' AND ') end # Returns the issue count diff -ur redmine-1.0.2/app/models/user.rb redmine/app/models/user.rb --- redmine-1.0.2/app/models/user.rb 2010-09-27 02:32:21.000000000 +0400 +++ redmine/app/models/user.rb 2010-10-08 12:16:20.341724431 +0400 @@ -339,7 +339,7 @@ roles = roles_for_project(project) return false unless roles - roles.detect {|role| (project.is_public? || role.member?) && role.allowed_to?(action)} + roles.any? {|role| (project.is_public? || role.member?) && role.allowed_to?(action)} elsif options[:global] # Admin users are always authorized @@ -347,7 +347,7 @@ # authorize if user has at least one role that has this permission roles = memberships.collect {|m| m.roles}.flatten.uniq - roles.detect {|r| r.allowed_to?(action)} || (self.logged? ? Role.non_member.allowed_to?(action) : Role.anonymous.allowed_to?(action)) + roles.any? {|r| r.allowed_to?(action)} || (self.logged? ? Role.non_member.allowed_to?(action) : Role.anonymous.allowed_to?(action)) else false end diff -ur redmine-1.0.2/lib/redmine.rb redmine/lib/redmine.rb --- redmine-1.0.2/lib/redmine.rb 2010-09-20 08:06:08.000000000 +0400 +++ redmine/lib/redmine.rb 2010-10-08 23:39:23.033627739 +0400 @@ -44,7 +44,7 @@ # Permissions Redmine::AccessControl.map do |map| - map.permission :view_project, {:projects => [:show], :activities => [:index]}, :public => true + map.permission :view_project, {:projects => [:show]}, :public => true map.permission :search_project, {:search => :index}, :public => true map.permission :add_project, {:projects => [:new, :create]}, :require => :loggedin map.permission :edit_project, {:projects => [:settings, :edit, :update]}, :require => :member @@ -58,13 +58,14 @@ map.permission :manage_categories, {:projects => :settings, :issue_categories => [:new, :edit, :destroy]}, :require => :member # Issues map.permission :view_issues, {:issues => [:index, :show], + :activities => [:index], :auto_complete => [:issues], :context_menus => [:issues], :versions => [:index, :show, :status_by], :journals => :index, :queries => :index, :reports => [:issue_report, :issue_report_details]} - map.permission :add_issues, {:issues => [:new, :create, :update_form]} + map.permission :add_issues, {:issues => [:new, :create, :update_form, :index, :show]} map.permission :edit_issues, {:issues => [:edit, :update, :bulk_edit, :bulk_update, :update_form], :journals => [:new]} map.permission :manage_issue_relations, {:issue_relations => [:new, :destroy]} map.permission :manage_subtasks, {} @@ -93,7 +94,7 @@ map.project_module :news do |map| map.permission :manage_news, {:news => [:new, :edit, :destroy, :destroy_comment]}, :require => :member map.permission :view_news, {:news => [:index, :show]}, :public => true - map.permission :comment_news, {:news => :add_comment} + map.permission :comment_news, {:activities => [:index], :news => :add_comment} end map.project_module :documents do |map| @@ -120,15 +121,15 @@ map.project_module :repository do |map| map.permission :manage_repository, {:repositories => [:edit, :committers, :destroy]}, :require => :member - map.permission :browse_repository, :repositories => [:show, :browse, :entry, :annotate, :changes, :diff, :stats, :graph] - map.permission :view_changesets, :repositories => [:show, :revisions, :revision] + map.permission :browse_repository, {:activities => [:index], :repositories => [:show, :browse, :entry, :annotate, :changes, :diff, :stats, :graph]} + map.permission :view_changesets, {:activities => [:index], :repositories => [:show, :revisions, :revision]} map.permission :commit_access, {} end map.project_module :boards do |map| map.permission :manage_boards, {:boards => [:new, :edit, :destroy]}, :require => :member map.permission :view_messages, {:boards => [:index, :show], :messages => [:show]}, :public => true - map.permission :add_messages, {:messages => [:new, :reply, :quote]} + map.permission :add_messages, {:activities => [:index], :messages => [:new, :reply, :quote]} map.permission :edit_messages, {:messages => :edit}, :require => :member map.permission :edit_own_messages, {:messages => :edit}, :require => :loggedin map.permission :delete_messages, {:messages => :destroy}, :require => :member diff -ur redmine-1.0.2/test/fixtures/issues.yml redmine/test/fixtures/issues.yml --- redmine-1.0.2/test/fixtures/issues.yml 2010-09-27 02:33:39.000000000 +0400 +++ redmine/test/fixtures/issues.yml 2010-10-08 12:16:20.343723937 +0400 @@ -103,11 +103,10 @@ category_id: description: This is an issue of a private subproject of cookbook tracker_id: 1 - assigned_to_id: + assigned_to_id: 12 author_id: 2 status_id: 1 start_date: <%= Date.today.to_s(:db) %> - due_date: <%= 1.days.from_now.to_date.to_s(:db) %> root_id: 6 lft: 1 rgt: 2 @@ -244,3 +243,20 @@ root_id: 13 lft: 1 rgt: 2 +issues_014: + created_on: <%= 5.days.ago.to_date.to_s(:db) %> + project_id: 5 + updated_on: <%= 2.days.ago.to_date.to_s(:db) %> + priority_id: 5 + subject: Test own message + id: 14 + fixed_version_id: + category_id: + description: Test own message + tracker_id: 1 + assigned_to_id: + author_id: 12 + status_id: 1 + root_id: 14 + lft: 1 + rgt: 2 diff -ur redmine-1.0.2/test/fixtures/member_roles.yml redmine/test/fixtures/member_roles.yml --- redmine-1.0.2/test/fixtures/member_roles.yml 2009-12-26 19:14:55.000000000 +0300 +++ redmine/test/fixtures/member_roles.yml 2010-10-08 12:16:20.343723937 +0400 @@ -47,3 +47,8 @@ role_id: 2 member_id: 10 inherited_from: 10 +member_roles_012: + id: 12 + role_id: 6 + member_id: 11 + inherited_from: 11 diff -ur redmine-1.0.2/test/fixtures/members.yml redmine/test/fixtures/members.yml --- redmine-1.0.2/test/fixtures/members.yml 2009-12-26 19:14:55.000000000 +0300 +++ redmine/test/fixtures/members.yml 2010-10-08 12:16:20.344723729 +0400 @@ -60,3 +60,9 @@ project_id: 2 user_id: 8 mail_notification: false +members_011: + id: 11 + created_on: 2006-07-19 19:35:33 +02:00 + project_id: 5 + user_id: 12 + mail_notification: false diff -ur redmine-1.0.2/test/fixtures/roles.yml redmine/test/fixtures/roles.yml --- redmine-1.0.2/test/fixtures/roles.yml 2010-03-13 17:56:49.000000000 +0300 +++ redmine/test/fixtures/roles.yml 2010-10-08 12:16:20.344723729 +0400 @@ -184,4 +184,13 @@ - :view_changesets position: 5 +roles_006: + name: Reporter2 + id: 6 + builtin: 0 + permissions: | + --- + - :add_issues + + position: 6 diff -ur redmine-1.0.2/test/fixtures/users.yml redmine/test/fixtures/users.yml --- redmine-1.0.2/test/fixtures/users.yml 2009-11-11 13:48:54.000000000 +0300 +++ redmine/test/fixtures/users.yml 2010-10-08 12:16:20.345723365 +0400 @@ -152,5 +152,21 @@ id: 11 lastname: B Team type: Group +users_012: + id: 12 + created_on: 2006-07-19 19:33:19 +02:00 + status: 1 + last_login_on: + language: 'ru' + hashed_password: 1 + updated_on: 2006-07-19 19:33:19 +02:00 + admin: false + mail: vasia@foo.bar + lastname: Vasia + firstname: Pupkin + auth_source_id: + mail_notification: false + login: vasia + type: User \ No newline at end of file diff -ur redmine-1.0.2/test/fixtures/watchers.yml redmine/test/fixtures/watchers.yml --- redmine-1.0.2/test/fixtures/watchers.yml 2009-02-12 20:35:57.000000000 +0300 +++ redmine/test/fixtures/watchers.yml 2010-10-08 12:16:20.345723365 +0400 @@ -11,4 +11,8 @@ watchable_type: Issue watchable_id: 2 user_id: 1 +watchers_004: + watchable_type: Issue + watchable_id: 9 + user_id: 12 \ No newline at end of file diff -ur redmine-1.0.2/test/functional/issues_controller_test.rb redmine/test/functional/issues_controller_test.rb --- redmine-1.0.2/test/functional/issues_controller_test.rb 2010-09-20 08:05:38.000000000 +0400 +++ redmine/test/functional/issues_controller_test.rb 2010-10-08 12:16:20.347723839 +0400 @@ -277,6 +277,7 @@ def test_show_should_deny_member_access_without_permission Role.find(1).remove_permission!(:view_issues) + Role.find(1).remove_permission!(:add_issues) @request.session[:user_id] = 2 get :show, :id => 1 assert_response 403 @@ -313,6 +314,30 @@ assert_not_nil assigns(:issue) end + def test_show_own_issue_by_author + @request.session[:user_id] = 12 + get :show, :id => 14 + assert_response :success + end + + def test_show_own_issue_by_assigned + @request.session[:user_id] = 12 + get :show, :id => 6 + assert_response :success + end + + def test_show_own_issue_by_watcher + @request.session[:user_id] = 12 + get :show, :id => 9 + assert_response :success + end + + def test_show_should_deny_access_without_permission + @request.session[:user_id] = 12 + get :show, :id => 10 + assert_response 403 + end + def test_get_new @request.session[:user_id] = 2 get :new, :project_id => 1, :tracker_id => 1 diff -ur redmine-1.0.2/test/unit/attachment_test.rb redmine/test/unit/attachment_test.rb --- redmine-1.0.2/test/unit/attachment_test.rb 2010-06-19 07:54:23.000000000 +0400 +++ redmine/test/unit/attachment_test.rb 2010-10-08 12:16:20.348723236 +0400 @@ -20,7 +20,7 @@ require File.dirname(__FILE__) + '/../test_helper' class AttachmentTest < ActiveSupport::TestCase - fixtures :issues, :users + fixtures :issues, :users, :watchers def setup end @@ -82,4 +82,26 @@ end end end + + def test_visible_file_for_issue + # Set "Add issue", unset "View issue" on default for user #12 + # author + a = Attachment.new(:container => Issue.find(14), :file => uploaded_test_file("testfile.txt", ""), :author => User.find(2)) + assert a.save + assert_equal true, a.visible?(User.find(12)) + # assigned to + a = Attachment.new(:container => Issue.find(6), :file => uploaded_test_file("testfile.txt", ""), :author => User.find(2)) + assert a.save + assert_equal true, a.visible?(User.find(12)) + # watcher + a = Attachment.new(:container => Issue.find(9), :file => uploaded_test_file("testfile.txt", ""), :author => User.find(2)) + assert a.save + assert_equal true, a.visible?(User.find(12)) + # other + a = Attachment.new(:container => Issue.find(10), :file => uploaded_test_file("testfile.txt", ""), :author => User.find(2)) + assert a.save + assert_equal false, a.visible?(User.find(12)) + Role.find(6).add_permission!(:view_issues) + assert_equal true, a.visible?(User.find(12)) + end end diff -ur redmine-1.0.2/test/unit/issue_test.rb redmine/test/unit/issue_test.rb --- redmine-1.0.2/test/unit/issue_test.rb 2010-09-27 02:33:39.000000000 +0400 +++ redmine/test/unit/issue_test.rb 2010-10-08 12:16:20.349723183 +0400 @@ -106,6 +106,29 @@ assert issues.detect {|issue| !issue.project.is_public?} end + def test_visible + user=User.find(12) + issue = Issue.new(:project_id => 5, :tracker_id => 1, :author_id => 2, :status_id => 1, :priority => IssuePriority.all.first, :subject => 'test_own', :description => 'IssueTest#test_own', :estimated_hours => '5:30') + assert issue.save + issue.reload + # Test for user, with "View_issue" + assert_equal true, issue.visible?(User.find(8)) + # Test for user, without "View issue", but with "Add issue" + assert_equal false, issue.visible?(user) + # Test for assinged user + issue.assigned_to=user + assert_equal true, issue.visible?(user) + # Test for watcher + issue.assigned_to=nil + issue.add_watcher(user) + assert_equal true, issue.visible?(user) + # Test for author + issue = Issue.new(:project_id => 5, :tracker_id => 1, :author_id => 12, :status_id => 1, :priority => IssuePriority.all.first, :subject => 'test_own', :description => 'IssueTest#test_own', :estimated_hours => '5:30') + assert issue.save + issue.reload + assert_equal true, issue.visible?(user) + end + def test_errors_full_messages_should_include_custom_fields_errors field = IssueCustomField.find_by_name('Database') @@ -677,7 +700,7 @@ test "#by_subproject" do groups = Issue.by_subproject(Project.find(1)) assert_equal 2, groups.size - assert_equal 5, groups.inject(0) {|sum, group| sum + group['total'].to_i} + assert_equal 6, groups.inject(0) {|sum, group| sum + group['total'].to_i} end diff -ur redmine-1.0.2/test/unit/mailer_test.rb redmine/test/unit/mailer_test.rb --- redmine-1.0.2/test/unit/mailer_test.rb 2010-09-27 02:32:38.000000000 +0400 +++ redmine/test/unit/mailer_test.rb 2010-10-08 12:16:20.350722465 +0400 @@ -235,6 +235,7 @@ user = User.find(9) Watcher.create!(:watchable => @issue, :user => user) Role.non_member.remove_permission!(:view_issues) + Role.non_member.remove_permission!(:add_issues) assert Mailer.deliver_issue_add(@issue) assert !last_email.bcc.include?(user.mail) end diff -ur redmine-1.0.2/vendor/plugins/acts_as_attachable/lib/acts_as_attachable.rb redmine/vendor/plugins/acts_as_attachable/lib/acts_as_attachable.rb --- redmine-1.0.2/vendor/plugins/acts_as_attachable/lib/acts_as_attachable.rb 2010-03-03 20:05:00.000000000 +0300 +++ redmine/vendor/plugins/acts_as_attachable/lib/acts_as_attachable.rb 2010-10-08 12:16:20.365738902 +0400 @@ -44,7 +44,7 @@ end def attachments_visible?(user=User.current) - user.allowed_to?(self.class.attachable_options[:view_permission], self.project) + user.allowed_to?(self.class.attachable_options[:view_permission], self.project) || is_a?(Issue) && self.visible?(user) end def attachments_deletable?(user=User.current)