Skip to content
Snippets Groups Projects
Commit f2ba4e3d authored by Douglas Barbosa Alexandre's avatar Douglas Barbosa Alexandre
Browse files

Restrict access to confidential issues on search results

parent e4f1c001
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -11,7 +11,7 @@ module Search
projects = ProjectsFinder.new.execute(current_user)
projects = projects.in_namespace(group.id) if group
 
Gitlab::SearchResults.new(projects, params[:search])
Gitlab::SearchResults.new(current_user, projects, params[:search])
end
end
end
Loading
Loading
@@ -7,7 +7,8 @@ module Search
end
 
def execute
Gitlab::ProjectSearchResults.new(project,
Gitlab::ProjectSearchResults.new(current_user,
project,
params[:search],
params[:repository_ref])
end
Loading
Loading
Loading
Loading
@@ -2,7 +2,8 @@ module Gitlab
class ProjectSearchResults < SearchResults
attr_reader :project, :repository_ref
 
def initialize(project, query, repository_ref = nil)
def initialize(current_user, project, query, repository_ref = nil)
@current_user = current_user
@project = project
@repository_ref = if repository_ref.present?
repository_ref
Loading
Loading
module Gitlab
class SearchResults
attr_reader :query
attr_reader :current_user, :query
 
# Limit search results by passed projects
# It allows us to search only for projects user has access to
attr_reader :limit_projects
 
def initialize(limit_projects, query)
def initialize(current_user, limit_projects, query)
@current_user = current_user
@limit_projects = limit_projects || Project.all
@query = Shellwords.shellescape(query) if query.present?
end
Loading
Loading
@@ -58,7 +59,7 @@ module Gitlab
end
 
def issues
issues = Issue.where(project_id: project_ids_relation)
issues = Issue.visible_to_user(current_user).where(project_id: project_ids_relation)
 
if query =~ /#(\d+)\z/
issues = issues.where(iid: $1)
Loading
Loading
require 'spec_helper'
 
describe Gitlab::ProjectSearchResults, lib: true do
let(:user) { create(:user) }
let(:project) { create(:project) }
let(:query) { 'hello world' }
 
describe 'initialize with empty ref' do
let(:results) { Gitlab::ProjectSearchResults.new(project, query, '') }
let(:results) { Gitlab::ProjectSearchResults.new(user, project, query, '') }
 
it { expect(results.project).to eq(project) }
it { expect(results.repository_ref).to be_nil }
Loading
Loading
@@ -14,10 +15,74 @@ describe Gitlab::ProjectSearchResults, lib: true do
 
describe 'initialize with ref' do
let(:ref) { 'refs/heads/test' }
let(:results) { Gitlab::ProjectSearchResults.new(project, query, ref) }
let(:results) { Gitlab::ProjectSearchResults.new(user, project, query, ref) }
 
it { expect(results.project).to eq(project) }
it { expect(results.repository_ref).to eq(ref) }
it { expect(results.query).to eq('hello world') }
end
describe 'confidential issues' do
let(:query) { 'issue' }
let(:author) { create(:user) }
let(:assignee) { create(:user) }
let(:non_member) { create(:user) }
let(:member) { create(:user) }
let(:admin) { create(:admin) }
let!(:issue) { create(:issue, project: project, title: 'Issue 1') }
let!(:security_issue_1) { create(:issue, :confidential, project: project, title: 'Security issue 1', author: author) }
let!(:security_issue_2) { create(:issue, :confidential, title: 'Security issue 2', project: project, assignee: assignee) }
it 'should not list project confidential issues for non project members' do
results = described_class.new(non_member, project, query)
issues = results.objects('issues')
expect(issues).to include issue
expect(issues).not_to include security_issue_1
expect(issues).not_to include security_issue_2
expect(results.issues_count).to eq 1
end
it 'should list project confidential issues for author' do
results = described_class.new(author, project, query)
issues = results.objects('issues')
expect(issues).to include issue
expect(issues).to include security_issue_1
expect(issues).not_to include security_issue_2
expect(results.issues_count).to eq 2
end
it 'should list project confidential issues for assignee' do
results = described_class.new(assignee, project.id, query)
issues = results.objects('issues')
expect(issues).to include issue
expect(issues).not_to include security_issue_1
expect(issues).to include security_issue_2
expect(results.issues_count).to eq 2
end
it 'should list project confidential issues for project members' do
project.team << [member, :developer]
results = described_class.new(member, project, query)
issues = results.objects('issues')
expect(issues).to include issue
expect(issues).to include security_issue_1
expect(issues).to include security_issue_2
expect(results.issues_count).to eq 3
end
it 'should list all project issues for admin' do
results = described_class.new(admin, project, query)
issues = results.objects('issues')
expect(issues).to include issue
expect(issues).to include security_issue_1
expect(issues).to include security_issue_2
expect(results.issues_count).to eq 3
end
end
end
require 'spec_helper'
 
describe Gitlab::SearchResults do
let(:user) { create(:user) }
let!(:project) { create(:project, name: 'foo') }
let!(:issue) { create(:issue, project: project, title: 'foo') }
 
Loading
Loading
@@ -9,7 +10,7 @@ describe Gitlab::SearchResults do
end
 
let!(:milestone) { create(:milestone, project: project, title: 'foo') }
let(:results) { described_class.new(Project.all, 'foo') }
let(:results) { described_class.new(user, Project.all, 'foo') }
 
describe '#total_count' do
it 'returns the total amount of search hits' do
Loading
Loading
@@ -52,4 +53,92 @@ describe Gitlab::SearchResults do
expect(results.empty?).to eq(false)
end
end
describe 'confidential issues' do
let(:project_1) { create(:empty_project) }
let(:project_2) { create(:empty_project) }
let(:project_3) { create(:empty_project) }
let(:project_4) { create(:empty_project) }
let(:query) { 'issue' }
let(:limit_projects) { Project.where(id: [project_1.id, project_2.id, project_3.id]) }
let(:author) { create(:user) }
let(:assignee) { create(:user) }
let(:non_member) { create(:user) }
let(:member) { create(:user) }
let(:admin) { create(:admin) }
let!(:issue) { create(:issue, project: project_1, title: 'Issue 1') }
let!(:security_issue_1) { create(:issue, :confidential, project: project_1, title: 'Security issue 1', author: author) }
let!(:security_issue_2) { create(:issue, :confidential, title: 'Security issue 2', project: project_1, assignee: assignee) }
let!(:security_issue_3) { create(:issue, :confidential, project: project_2, title: 'Security issue 3', author: author) }
let!(:security_issue_4) { create(:issue, :confidential, project: project_3, title: 'Security issue 4', assignee: assignee) }
let!(:security_issue_5) { create(:issue, :confidential, project: project_4, title: 'Security issue 5') }
it 'should not list confidential issues for non project members' do
results = described_class.new(non_member, limit_projects, query)
issues = results.objects('issues')
expect(issues).to include issue
expect(issues).not_to include security_issue_1
expect(issues).not_to include security_issue_2
expect(issues).not_to include security_issue_3
expect(issues).not_to include security_issue_4
expect(issues).not_to include security_issue_5
expect(results.issues_count).to eq 1
end
it 'should list confidential issues for author' do
results = described_class.new(author, limit_projects, query)
issues = results.objects('issues')
expect(issues).to include issue
expect(issues).to include security_issue_1
expect(issues).not_to include security_issue_2
expect(issues).to include security_issue_3
expect(issues).not_to include security_issue_4
expect(issues).not_to include security_issue_5
expect(results.issues_count).to eq 3
end
it 'should list confidential issues for assignee' do
results = described_class.new(assignee, limit_projects, query)
issues = results.objects('issues')
expect(issues).to include issue
expect(issues).not_to include security_issue_1
expect(issues).to include security_issue_2
expect(issues).not_to include security_issue_3
expect(issues).to include security_issue_4
expect(issues).not_to include security_issue_5
expect(results.issues_count).to eq 3
end
it 'should list confidential issues for project members' do
project_1.team << [member, :developer]
project_2.team << [member, :developer]
results = described_class.new(member, limit_projects, query)
issues = results.objects('issues')
expect(issues).to include issue
expect(issues).to include security_issue_1
expect(issues).to include security_issue_2
expect(issues).to include security_issue_3
expect(issues).not_to include security_issue_4
expect(issues).not_to include security_issue_5
expect(results.issues_count).to eq 4
end
it 'should list all issues for admin' do
results = described_class.new(admin, limit_projects, query)
issues = results.objects('issues')
expect(issues).to include issue
expect(issues).to include security_issue_1
expect(issues).to include security_issue_2
expect(issues).to include security_issue_3
expect(issues).to include security_issue_4
expect(issues).not_to include security_issue_5
expect(results.issues_count).to eq 5
end
end
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment