Restrict access for confidential issues on milestone view

parent 1029f410
......@@ -38,7 +38,7 @@ module MilestonesHelper
def milestone_progress_bar(milestone)
options = {
class: 'progress-bar progress-bar-success',
style: "width: #{milestone.percent_complete}%;"
style: "width: #{milestone.percent_complete(current_user)}%;"
}
content_tag :div, class: 'progress' do
......
module Milestoneish
def closed_items_count
issues.closed.size + merge_requests.closed_and_merged.size
def closed_items_count(user = nil)
issues_visible_to_user(user).closed.size + merge_requests.closed_and_merged.size
end
def total_items_count
issues.size + merge_requests.size
def total_items_count(user = nil)
issues_visible_to_user(user).size + merge_requests.size
end
def complete?
total_items_count == closed_items_count
def complete?(user = nil)
total_items_count(user) == closed_items_count(user)
end
def percent_complete
((closed_items_count * 100) / total_items_count).abs
def percent_complete(user = nil)
((closed_items_count(user) * 100) / total_items_count(user)).abs
rescue ZeroDivisionError
0
end
......@@ -22,4 +22,8 @@ module Milestoneish
(due_date - Date.today).to_i
end
def issues_visible_to_user(user = nil)
issues.visible_to_user(user)
end
end
......@@ -121,8 +121,8 @@ class Milestone < ActiveRecord::Base
active? && issues.opened.count.zero?
end
def is_empty?
total_items_count.zero?
def is_empty?(user = nil)
total_items_count(user).zero?
end
def author_id
......
......@@ -42,7 +42,7 @@
= preserve do
= markdown @milestone.description
- if @milestone.complete? && @milestone.active?
- if @milestone.complete?(current_user) && @milestone.active?
.alert.alert-success.prepend-top-default
%span All issues for this milestone are closed. You may close milestone now.
......
......@@ -6,10 +6,10 @@
.col-sm-6
%strong= link_to_gfm truncate(milestone.title, length: 100), milestone_path
.col-sm-6
.pull-right.light #{milestone.percent_complete}% complete
.pull-right.light #{milestone.percent_complete(current_user)}% complete
.row
.col-sm-6
= link_to pluralize(milestone.issues.size, 'Issue'), issues_path
= link_to pluralize(milestone.issues_visible_to_user(current_user).size, 'Issue'), issues_path
&middot;
= link_to pluralize(milestone.merge_requests.size, 'Merge Request'), merge_requests_path
.col-sm-6= milestone_progress_bar(milestone)
......
......@@ -3,15 +3,15 @@
.context.prepend-top-default
.milestone-summary
%h4 Progress
%strong= milestone.issues.size
%strong= milestone.issues_visible_to_user(current_user).size
issues:
%span.milestone-stat
%strong= milestone.issues.opened.size
%strong= milestone.issues_visible_to_user(current_user).opened.size
open and
%strong= milestone.issues.closed.size
%strong= milestone.issues_visible_to_user(current_user).closed.size
closed
%span.milestone-stat
%strong== #{milestone.percent_complete}%
%strong== #{milestone.percent_complete(current_user)}%
complete
%span.milestone-stat
......
......@@ -2,7 +2,7 @@
%li.active
= link_to '#tab-issues', 'data-toggle' => 'tab', 'data-show' => '.tab-issues-buttons' do
Issues
%span.badge= milestone.issues.size
%span.badge= milestone.issues_visible_to_user(current_user).size
%li
= link_to '#tab-merge-requests', 'data-toggle' => 'tab', 'data-show' => '.tab-merge-requests-buttons' do
Merge Requests
......@@ -21,7 +21,7 @@
.tab-content.milestone-content
.tab-pane.active#tab-issues
= render 'shared/milestones/issues_tab', issues: milestone.issues, show_project_name: show_project_name, show_full_project_name: show_full_project_name
= render 'shared/milestones/issues_tab', issues: milestone.issues_visible_to_user(current_user), show_project_name: show_project_name, show_full_project_name: show_full_project_name
.tab-pane#tab-merge-requests
= render 'shared/milestones/merge_requests_tab', merge_requests: milestone.merge_requests, show_project_name: show_project_name, show_full_project_name: show_full_project_name
.tab-pane#tab-participants
......
......@@ -28,7 +28,7 @@
%h2.title
= markdown escape_once(milestone.title), pipeline: :single_line
- if milestone.complete? && milestone.active?
- if milestone.complete?(current_user) && milestone.active?
.alert.alert-success.prepend-top-default
- close_msg = group ? 'You may close the milestone now.' : 'Navigate to the project to close the milestone.'
%span All issues for this milestone are closed. #{close_msg}
......@@ -47,7 +47,7 @@
- project_name = group ? ms.project.name : ms.project.name_with_namespace
= link_to project_name, namespace_project_milestone_path(ms.project.namespace, ms.project, ms)
%td
= ms.issues.opened.count
= ms.issues_visible_to_user(current_user).opened.count
%td
- if ms.closed?
Closed
......
require 'spec_helper'
describe Milestone, 'Milestoneish' do
let(:author) { create(:user) }
let(:assignee) { create(:user) }
let(:non_member) { create(:user) }
let(:member) { create(:user) }
let(:admin) { create(:admin) }
let(:project) { create(:project, :public) }
let(:milestone) { create(:milestone, project: project) }
let!(:issue) { create(:issue, project: project, milestone: milestone) }
let!(:security_issue_1) { create(:issue, :confidential, project: project, author: author, milestone: milestone) }
let!(:security_issue_2) { create(:issue, :confidential, project: project, assignee: assignee, milestone: milestone) }
let!(:closed_issue_1) { create(:issue, :closed, project: project, milestone: milestone) }
let!(:closed_issue_2) { create(:issue, :closed, project: project, milestone: milestone) }
let!(:closed_security_issue_1) { create(:issue, :confidential, :closed, project: project, author: author, milestone: milestone) }
let!(:closed_security_issue_2) { create(:issue, :confidential, :closed, project: project, assignee: assignee, milestone: milestone) }
let!(:closed_security_issue_3) { create(:issue, :confidential, :closed, project: project, author: author, milestone: milestone) }
let!(:closed_security_issue_4) { create(:issue, :confidential, :closed, project: project, assignee: assignee, milestone: milestone) }
let!(:merge_request) { create(:merge_request, source_project: project, target_project: project, milestone: milestone) }
before do
project.team << [member, :developer]
end
describe '#closed_items_count' do
it 'should not count confidential issues for non project members' do
expect(milestone.closed_items_count(non_member)).to eq 2
end
it 'should count confidential issues for author' do
expect(milestone.closed_items_count(author)).to eq 4
end
it 'should count confidential issues for assignee' do
expect(milestone.closed_items_count(assignee)).to eq 4
end
it 'should count confidential issues for project members' do
expect(milestone.closed_items_count(member)).to eq 6
end
it 'should count all issues for admin' do
expect(milestone.closed_items_count(admin)).to eq 6
end
end
describe '#total_items_count' do
it 'should not count confidential issues for non project members' do
expect(milestone.total_items_count(non_member)).to eq 4
end
it 'should count confidential issues for author' do
expect(milestone.total_items_count(author)).to eq 7
end
it 'should count confidential issues for assignee' do
expect(milestone.total_items_count(assignee)).to eq 7
end
it 'should count confidential issues for project members' do
expect(milestone.total_items_count(member)).to eq 10
end
it 'should count all issues for admin' do
expect(milestone.total_items_count(admin)).to eq 10
end
end
describe '#complete?' do
it 'returns false when has items opened' do
expect(milestone.complete?(non_member)).to eq false
end
it 'returns true when all items are closed' do
issue.close
merge_request.close
expect(milestone.complete?(non_member)).to eq true
end
end
describe '#percent_complete' do
it 'should not count confidential issues for non project members' do
expect(milestone.percent_complete(non_member)).to eq 50
end
it 'should count confidential issues for author' do
expect(milestone.percent_complete(author)).to eq 57
end
it 'should count confidential issues for assignee' do
expect(milestone.percent_complete(assignee)).to eq 57
end
it 'should count confidential issues for project members' do
expect(milestone.percent_complete(member)).to eq 60
end
it 'should count confidential issues for admin' do
expect(milestone.percent_complete(admin)).to eq 60
end
end
end
......@@ -32,6 +32,7 @@ describe Milestone, models: true do
let(:milestone) { create(:milestone) }
let(:issue) { create(:issue) }
let(:user) { create(:user) }
describe "unique milestone title per project" do
it "shouldn't accept the same title in a project twice" do
......@@ -50,18 +51,17 @@ describe Milestone, models: true do
describe "#percent_complete" do
it "should not count open issues" do
milestone.issues << issue
expect(milestone.percent_complete).to eq(0)
expect(milestone.percent_complete(user)).to eq(0)
end
it "should count closed issues" do
issue.close
milestone.issues << issue
expect(milestone.percent_complete).to eq(100)
expect(milestone.percent_complete(user)).to eq(100)
end
it "should recover from dividing by zero" do
expect(milestone.issues).to receive(:size).and_return(0)
expect(milestone.percent_complete).to eq(0)
expect(milestone.percent_complete(user)).to eq(0)
end
end
......@@ -103,7 +103,7 @@ describe Milestone, models: true do
)
end
it { expect(milestone.percent_complete).to eq(75) }
it { expect(milestone.percent_complete(user)).to eq(75) }
end
describe :items_count do
......@@ -113,23 +113,23 @@ describe Milestone, models: true do
milestone.merge_requests << create(:merge_request)
end
it { expect(milestone.closed_items_count).to eq(1) }
it { expect(milestone.total_items_count).to eq(3) }
it { expect(milestone.is_empty?).to be_falsey }
it { expect(milestone.closed_items_count(user)).to eq(1) }
it { expect(milestone.total_items_count(user)).to eq(3) }
it { expect(milestone.is_empty?(user)).to be_falsey }
end
describe :can_be_closed? do
it { expect(milestone.can_be_closed?).to be_truthy }
end
describe :is_empty? do
describe :total_items_count do
before do
create :closed_issue, milestone: milestone
create :merge_request, milestone: milestone
end
it 'Should return total count of issues and merge requests assigned to milestone' do
expect(milestone.total_items_count).to eq 2
expect(milestone.total_items_count(user)).to eq 2
end
end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment