Commit 727a2a86 authored by Jarka Košanová's avatar Jarka Košanová

Display only informaton visible to current user

Display only labels and assignees of issues
visible by the currently logged user
Display only issues visible to user in the burndown chart
parent 3132550d
......@@ -53,6 +53,18 @@ module Milestoneish
end
end
def issue_participants_visible_by_user(user)
User.joins(:issue_assignees)
.where('issue_assignees.issue_id' => issues_visible_to_user(user).select(:id))
.distinct
end
def issue_labels_visible_by_user(user)
Label.joins(:label_links)
.where('label_links.target_id' => issues_visible_to_user(user).select(:id), 'label_links.target_type' => 'Issue')
.distinct
end
def sorted_issues(user)
issues_visible_to_user(user).preload_associations.sort_by_attribute('label_priority')
end
......
......@@ -21,11 +21,11 @@
%li.nav-item
= link_to '#tab-participants', class: 'nav-link', 'data-toggle' => 'tab', 'data-endpoint': milestone_participants_tab_path(milestone) do
Participants
%span.badge.badge-pill= milestone.participants.count
%span.badge.badge-pill= milestone.issue_participants_visible_by_user(current_user).count
%li.nav-item
= link_to '#tab-labels', class: 'nav-link', 'data-toggle' => 'tab', 'data-endpoint': milestone_labels_tab_path(milestone) do
Labels
%span.badge.badge-pill= milestone.labels.count
%span.badge.badge-pill= milestone.issue_labels_visible_by_user(current_user).count
- issues = milestone.sorted_issues(current_user)
- show_project_name = local_assigns.fetch(:show_project_name, false)
......
---
title: Display only information visible to current user on the Milestone page
merge_request:
author:
type: security
......@@ -3,7 +3,7 @@
module EE
module MilestonesHelper
def burndown_chart(milestone)
Burndown.new(milestone) if milestone.supports_burndown_charts?
Burndown.new(milestone, current_user) if milestone.supports_burndown_charts?
end
def can_generate_chart?(milestone, burndown)
......
......@@ -17,12 +17,13 @@ class Burndown
end
end
attr_reader :start_date, :due_date, :end_date, :accurate, :legacy_data, :milestone
attr_reader :start_date, :due_date, :end_date, :accurate, :legacy_data, :milestone, :current_user
alias_method :accurate?, :accurate
alias_method :empty?, :legacy_data
def initialize(milestone)
def initialize(milestone, current_user)
@milestone = milestone
@current_user = current_user
@start_date = @milestone.start_date
@due_date = @milestone.due_date
@end_date = @milestone.due_date
......@@ -89,10 +90,10 @@ class Burndown
strong_memoize(:opened_issues_grouped_by_date) do
issues =
@milestone
.issues
.where('created_at <= ?', end_date)
.issues_visible_to_user(current_user)
.where('issues.created_at <= ?', end_date)
.reorder(nil)
.order(:created_at).to_a
.order('issues.created_at').to_a
issues.group_by do |issue|
issue.created_at.to_date
......@@ -124,9 +125,8 @@ class Burndown
# `issues.closed_at` can't be used once it's nullified if the issue is
# reopened.
internal_clause =
::Issue
@milestone.issues_visible_to_user(current_user)
.joins("LEFT OUTER JOIN events e ON issues.id = e.target_id AND e.target_type = 'Issue' AND e.action = #{Event::CLOSED}")
.where(milestone: @milestone)
.where("state = 'closed' OR (state = 'opened' AND e.action = #{Event::CLOSED})") # rubocop:disable GitlabSecurity/SqlInjection
rel =
......
......@@ -2,6 +2,7 @@ require 'spec_helper'
describe Burndown do
set(:user) { create(:user) }
set(:non_member) { create(:user) }
let(:start_date) { "2017-03-01" }
let(:due_date) { "2017-03-03" }
......@@ -16,13 +17,13 @@ describe Burndown do
end
end
subject { described_class.new(milestone).to_json }
subject { described_class.new(milestone, user).to_json }
it "generates an array with date, issue count and weight" do
expect(subject).to eq([
["2017-03-01", 3, 6],
["2017-03-02", 4, 8],
["2017-03-03", 2, 4]
["2017-03-01", 4, 8],
["2017-03-02", 5, 10],
["2017-03-03", 3, 6]
].to_json)
end
......@@ -45,7 +46,7 @@ describe Burndown do
end
it "sets attribute accurate to true" do
burndown = described_class.new(milestone)
burndown = described_class.new(milestone, user)
expect(burndown).to be_accurate
end
......@@ -57,14 +58,14 @@ describe Burndown do
it "considers closed_at as milestone start date" do
expect(subject).to eq([
["2017-03-01", 3, 6],
["2017-03-02", 3, 6],
["2017-03-03", 3, 6]
["2017-03-01", 4, 8],
["2017-03-02", 4, 8],
["2017-03-03", 4, 8]
].to_json)
end
it "sets attribute empty to true" do
burndown = described_class.new(milestone)
burndown = described_class.new(milestone, user)
expect(burndown).to be_empty
end
......@@ -76,7 +77,7 @@ describe Burndown do
end
it "sets attribute accurate to false" do
burndown = described_class.new(milestone)
burndown = described_class.new(milestone, user)
expect(burndown).not_to be_accurate
end
......@@ -92,12 +93,26 @@ describe Burndown do
create(:issue, milestone: milestone, project: project, created_at: creation_date, weight: 3)
expect(subject).to eq([
['2017-03-01', 3, 6],
['2017-03-02', 6, 13],
['2017-03-03', 4, 9]
['2017-03-01', 4, 8],
['2017-03-02', 7, 15],
['2017-03-03', 5, 11]
].to_json)
end
end
context 'when issues belong to a public project' do
it 'does not include confidential issues for users who are not project members' do
project.update(visibility_level: Gitlab::VisibilityLevel::PUBLIC)
expected_result = [
["2017-03-01", 3, 6],
["2017-03-02", 4, 8],
["2017-03-03", 2, 4]
].to_json
expect(described_class.new(milestone, non_member).to_json).to eq(expected_result)
end
end
end
describe 'project milestone burndown' do
......@@ -126,6 +141,10 @@ describe Burndown do
let(:nested_group_milestone) { create(:milestone, group: nested_group, start_date: start_date, due_date: due_date) }
context 'when nested group milestone', :nested_groups do
before do
group.add_developer(user)
end
it_behaves_like 'burndown for milestone' do
let(:milestone) { nested_group_milestone }
let(:project) { nested_group_project }
......@@ -194,6 +213,9 @@ describe Burndown do
issue_closed_twice = reopened_issues.last
close_issue(issue_closed_twice)
reopen_issue(issue_closed_twice)
# create one confidential issue
create(:issue, :confidential, issue_params) if Date.today == milestone.start_date
end
end
end
......
......@@ -9,8 +9,10 @@ describe Milestone, 'Milestoneish' do
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(:label1) { create(:label, project: project) }
let(:label2) { create(:label, project: project) }
let!(:issue) { create(:issue, project: project, milestone: milestone, assignees: [member], labels: [label1]) }
let!(:security_issue_1) { create(:issue, :confidential, project: project, author: author, milestone: milestone, labels: [label2]) }
let!(:security_issue_2) { create(:issue, :confidential, project: project, assignees: [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) }
......@@ -42,6 +44,95 @@ describe Milestone, 'Milestoneish' do
end
end
context 'attributes visibility' do
using RSpec::Parameterized::TableSyntax
let(:users) do
{
anonymous: nil,
non_member: non_member,
guest: guest,
member: member,
assignee: assignee
}
end
let(:project_visibility_levels) do
{
public: Gitlab::VisibilityLevel::PUBLIC,
internal: Gitlab::VisibilityLevel::INTERNAL,
private: Gitlab::VisibilityLevel::PRIVATE
}
end
describe '#issue_participants_visible_by_user' do
where(:visibility, :user_role, :result) do
:public | nil | [:member]
:public | :non_member | [:member]
:public | :guest | [:member]
:public | :member | [:member, :assignee]
:internal | nil | []
:internal | :non_member | [:member]
:internal | :guest | [:member]
:internal | :member | [:member, :assignee]
:private | nil | []
:private | :non_member | []
:private | :guest | [:member]
:private | :member | [:member, :assignee]
end
with_them do
before do
project.update(visibility_level: project_visibility_levels[visibility])
end
it 'returns the proper participants' do
user = users[user_role]
participants = result.map { |role| users[role] }
expect(milestone.issue_participants_visible_by_user(user)).to match_array(participants)
end
end
end
describe '#issue_labels_visible_by_user' do
let(:labels) do
{
label1: label1,
label2: label2
}
end
where(:visibility, :user_role, :result) do
:public | nil | [:label1]
:public | :non_member | [:label1]
:public | :guest | [:label1]
:public | :member | [:label1, :label2]
:internal | nil | []
:internal | :non_member | [:label1]
:internal | :guest | [:label1]
:internal | :member | [:label1, :label2]
:private | nil | []
:private | :non_member | []
:private | :guest | [:label1]
:private | :member | [:label1, :label2]
end
with_them do
before do
project.update(visibility_level: project_visibility_levels[visibility])
end
it 'returns the proper participants' do
user = users[user_role]
expected_labels = result.map { |label| labels[label] }
expect(milestone.issue_labels_visible_by_user(user)).to match_array(expected_labels)
end
end
end
end
describe '#sorted_merge_requests' do
it 'sorts merge requests by label priority' do
merge_request_1 = create(:labeled_merge_request, labels: [label_2], source_project: project, source_branch: 'branch_1', milestone: milestone)
......
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