summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorRobert Speicher <robert@gitlab.com>2017-05-10 18:26:02 +0000
committerRobert Speicher <robert@gitlab.com>2017-05-10 18:26:02 +0000
commit180ec7113e358a7f8388e1436dc0670a11ba68df (patch)
treefba74833a7e89d6c19160a0d7e02355c5215c8df /spec
parent09c4d27ae48ceb181f86657043af2a129c17dabf (diff)
parentebd8b7f60f41358df562625a4692f352b86b8c80 (diff)
downloadgitlab-ce-180ec7113e358a7f8388e1436dc0670a11ba68df.tar.gz
Merge branch 'bvl-security-patches' into 'master'
Security patches -> `master` See merge request !11230
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/groups_controller_spec.rb35
-rw-r--r--spec/controllers/snippets_controller_spec.rb34
-rw-r--r--spec/features/dashboard/snippets_spec.rb47
-rw-r--r--spec/features/projects/snippets_spec.rb24
-rw-r--r--spec/features/snippets/explore_spec.rb25
-rw-r--r--spec/features/snippets/internal_snippet_spec.rb23
-rw-r--r--spec/features/users/snippets_spec.rb46
-rw-r--r--spec/finders/groups_finder_spec.rb57
-rw-r--r--spec/finders/snippets_finder_spec.rb125
-rw-r--r--spec/helpers/submodule_helper_spec.rb12
-rw-r--r--spec/lib/banzai/filter/external_link_filter_spec.rb85
-rw-r--r--spec/lib/gitlab/asciidoc_spec.rb29
-rw-r--r--spec/lib/gitlab/other_markup_spec.rb2
-rw-r--r--spec/lib/gitlab/project_search_results_spec.rb75
-rw-r--r--spec/models/snippet_spec.rb40
-rw-r--r--spec/policies/project_snippet_policy_spec.rb80
-rw-r--r--spec/views/projects/imports/new.html.haml_spec.rb22
17 files changed, 608 insertions, 153 deletions
diff --git a/spec/controllers/groups_controller_spec.rb b/spec/controllers/groups_controller_spec.rb
index 073b87a1cb4..4c8d82a1677 100644
--- a/spec/controllers/groups_controller_spec.rb
+++ b/spec/controllers/groups_controller_spec.rb
@@ -26,6 +26,41 @@ describe GroupsController do
end
end
+ describe 'GET #subgroups' do
+ let!(:public_subgroup) { create(:group, :public, parent: group) }
+ let!(:private_subgroup) { create(:group, :private, parent: group) }
+
+ context 'as a user' do
+ before do
+ sign_in(user)
+ end
+
+ it 'shows the public subgroups' do
+ get :subgroups, id: group.to_param
+
+ expect(assigns(:nested_groups)).to contain_exactly(public_subgroup)
+ end
+
+ context 'being member' do
+ it 'shows public and private subgroups the user is member of' do
+ private_subgroup.add_guest(user)
+
+ get :subgroups, id: group.to_param
+
+ expect(assigns(:nested_groups)).to contain_exactly(public_subgroup, private_subgroup)
+ end
+ end
+ end
+
+ context 'as a guest' do
+ it 'shows the public subgroups' do
+ get :subgroups, id: group.to_param
+
+ expect(assigns(:nested_groups)).to contain_exactly(public_subgroup)
+ end
+ end
+ end
+
describe 'GET #issues' do
let(:issue_1) { create(:issue, project: project) }
let(:issue_2) { create(:issue, project: project) }
diff --git a/spec/controllers/snippets_controller_spec.rb b/spec/controllers/snippets_controller_spec.rb
index 41cd5bdcdd8..930415a4778 100644
--- a/spec/controllers/snippets_controller_spec.rb
+++ b/spec/controllers/snippets_controller_spec.rb
@@ -3,6 +3,34 @@ require 'spec_helper'
describe SnippetsController do
let(:user) { create(:user) }
+ describe 'GET #index' do
+ let(:user) { create(:user) }
+
+ context 'when username parameter is present' do
+ it 'renders snippets of a user when username is present' do
+ get :index, username: user.username
+
+ expect(response).to render_template(:index)
+ end
+ end
+
+ context 'when username parameter is not present' do
+ it 'redirects to explore snippets page when user is not logged in' do
+ get :index
+
+ expect(response).to redirect_to(explore_snippets_path)
+ end
+
+ it 'redirects to snippets dashboard page when user is logged in' do
+ sign_in(user)
+
+ get :index
+
+ expect(response).to redirect_to(dashboard_snippets_path)
+ end
+ end
+ end
+
describe 'GET #new' do
context 'when signed in' do
before do
@@ -132,7 +160,7 @@ describe SnippetsController do
it 'responds with status 404' do
get :show, id: 'doesntexist'
- expect(response).to have_http_status(404)
+ expect(response).to redirect_to(new_user_session_path)
end
end
end
@@ -478,10 +506,10 @@ describe SnippetsController do
end
context 'when not signed in' do
- it 'responds with status 404' do
+ it 'redirects to the sign in path' do
get :raw, id: 'doesntexist'
- expect(response).to have_http_status(404)
+ expect(response).to redirect_to(new_user_session_path)
end
end
end
diff --git a/spec/features/dashboard/snippets_spec.rb b/spec/features/dashboard/snippets_spec.rb
index 62937688c22..c6ba118220a 100644
--- a/spec/features/dashboard/snippets_spec.rb
+++ b/spec/features/dashboard/snippets_spec.rb
@@ -12,4 +12,51 @@ describe 'Dashboard snippets', feature: true do
it_behaves_like 'paginated snippets'
end
+
+ context 'filtering by visibility' do
+ let(:user) { create(:user) }
+ let!(:snippets) do
+ [
+ create(:personal_snippet, :public, author: user),
+ create(:personal_snippet, :internal, author: user),
+ create(:personal_snippet, :private, author: user),
+ create(:personal_snippet, :public)
+ ]
+ end
+
+ before do
+ login_as(user)
+
+ visit dashboard_snippets_path
+ end
+
+ it 'contains all snippets of logged user' do
+ expect(page).to have_selector('.snippet-row', count: 3)
+
+ expect(page).to have_content(snippets[0].title)
+ expect(page).to have_content(snippets[1].title)
+ expect(page).to have_content(snippets[2].title)
+ end
+
+ it 'contains all private snippets of logged user when clicking on private' do
+ click_link('Private')
+
+ expect(page).to have_selector('.snippet-row', count: 1)
+ expect(page).to have_content(snippets[2].title)
+ end
+
+ it 'contains all internal snippets of logged user when clicking on internal' do
+ click_link('Internal')
+
+ expect(page).to have_selector('.snippet-row', count: 1)
+ expect(page).to have_content(snippets[1].title)
+ end
+
+ it 'contains all public snippets of logged user when clicking on public' do
+ click_link('Public')
+
+ expect(page).to have_selector('.snippet-row', count: 1)
+ expect(page).to have_content(snippets[0].title)
+ end
+ end
end
diff --git a/spec/features/projects/snippets_spec.rb b/spec/features/projects/snippets_spec.rb
index d37e8ed4699..18689c17fe9 100644
--- a/spec/features/projects/snippets_spec.rb
+++ b/spec/features/projects/snippets_spec.rb
@@ -4,11 +4,27 @@ describe 'Project snippets', feature: true do
context 'when the project has snippets' do
let(:project) { create(:empty_project, :public) }
let!(:snippets) { create_list(:project_snippet, 2, :public, author: project.owner, project: project) }
- before do
- allow(Snippet).to receive(:default_per_page).and_return(1)
- visit namespace_project_snippets_path(project.namespace, project)
+ let!(:other_snippet) { create(:project_snippet) }
+
+ context 'pagination' do
+ before do
+ allow(Snippet).to receive(:default_per_page).and_return(1)
+
+ visit namespace_project_snippets_path(project.namespace, project)
+ end
+
+ it_behaves_like 'paginated snippets'
end
- it_behaves_like 'paginated snippets'
+ context 'list content' do
+ it 'contains all project snippets' do
+ visit namespace_project_snippets_path(project.namespace, project)
+
+ expect(page).to have_selector('.snippet-row', count: 2)
+
+ expect(page).to have_content(snippets[0].title)
+ expect(page).to have_content(snippets[1].title)
+ end
+ end
end
end
diff --git a/spec/features/snippets/explore_spec.rb b/spec/features/snippets/explore_spec.rb
index 10a4597e467..fd097fe2e74 100644
--- a/spec/features/snippets/explore_spec.rb
+++ b/spec/features/snippets/explore_spec.rb
@@ -1,11 +1,11 @@
require 'rails_helper'
feature 'Explore Snippets', feature: true do
- scenario 'User should see snippets that are not private' do
- public_snippet = create(:personal_snippet, :public)
- internal_snippet = create(:personal_snippet, :internal)
- private_snippet = create(:personal_snippet, :private)
+ let!(:public_snippet) { create(:personal_snippet, :public) }
+ let!(:internal_snippet) { create(:personal_snippet, :internal) }
+ let!(:private_snippet) { create(:personal_snippet, :private) }
+ scenario 'User should see snippets that are not private' do
login_as create(:user)
visit explore_snippets_path
@@ -13,4 +13,21 @@ feature 'Explore Snippets', feature: true do
expect(page).to have_content(internal_snippet.title)
expect(page).not_to have_content(private_snippet.title)
end
+
+ scenario 'External user should see only public snippets' do
+ login_as create(:user, :external)
+ visit explore_snippets_path
+
+ expect(page).to have_content(public_snippet.title)
+ expect(page).not_to have_content(internal_snippet.title)
+ expect(page).not_to have_content(private_snippet.title)
+ end
+
+ scenario 'Not authenticated user should see only public snippets' do
+ visit explore_snippets_path
+
+ expect(page).to have_content(public_snippet.title)
+ expect(page).not_to have_content(internal_snippet.title)
+ expect(page).not_to have_content(private_snippet.title)
+ end
end
diff --git a/spec/features/snippets/internal_snippet_spec.rb b/spec/features/snippets/internal_snippet_spec.rb
new file mode 100644
index 00000000000..93382f4c359
--- /dev/null
+++ b/spec/features/snippets/internal_snippet_spec.rb
@@ -0,0 +1,23 @@
+require 'rails_helper'
+
+feature 'Internal Snippets', feature: true, js: true do
+ let(:internal_snippet) { create(:personal_snippet, :internal) }
+
+ describe 'normal user' do
+ before do
+ login_as :user
+ end
+
+ scenario 'sees internal snippets' do
+ visit snippet_path(internal_snippet)
+
+ expect(page).to have_content(internal_snippet.content)
+ end
+
+ scenario 'sees raw internal snippets' do
+ visit raw_snippet_path(internal_snippet)
+
+ expect(page).to have_content(internal_snippet.content)
+ end
+ end
+end
diff --git a/spec/features/users/snippets_spec.rb b/spec/features/users/snippets_spec.rb
index 1546a06b80c..4efbd672322 100644
--- a/spec/features/users/snippets_spec.rb
+++ b/spec/features/users/snippets_spec.rb
@@ -3,14 +3,46 @@ require 'spec_helper'
describe 'Snippets tab on a user profile', feature: true, js: true do
context 'when the user has snippets' do
let(:user) { create(:user) }
- let!(:snippets) { create_list(:snippet, 2, :public, author: user) }
- before do
- allow(Snippet).to receive(:default_per_page).and_return(1)
- visit user_path(user)
- page.within('.user-profile-nav') { click_link 'Snippets' }
- wait_for_ajax
+
+ context 'pagination' do
+ let!(:snippets) { create_list(:snippet, 2, :public, author: user) }
+
+ before do
+ allow(Snippet).to receive(:default_per_page).and_return(1)
+ visit user_path(user)
+ page.within('.user-profile-nav') { click_link 'Snippets' }
+ wait_for_ajax
+ end
+
+ it_behaves_like 'paginated snippets', remote: true
end
- it_behaves_like 'paginated snippets', remote: true
+ context 'list content' do
+ let!(:public_snippet) { create(:snippet, :public, author: user) }
+ let!(:internal_snippet) { create(:snippet, :internal, author: user) }
+ let!(:private_snippet) { create(:snippet, :private, author: user) }
+ let!(:other_snippet) { create(:snippet, :public) }
+
+ it 'contains only internal and public snippets of a user when a user is logged in' do
+ login_as(:user)
+ visit user_path(user)
+ page.within('.user-profile-nav') { click_link 'Snippets' }
+ wait_for_ajax
+
+ expect(page).to have_selector('.snippet-row', count: 2)
+
+ expect(page).to have_content(public_snippet.title)
+ expect(page).to have_content(internal_snippet.title)
+ end
+
+ it 'contains only public snippets of a user when a user is not logged in' do
+ visit user_path(user)
+ page.within('.user-profile-nav') { click_link 'Snippets' }
+ wait_for_ajax
+
+ expect(page).to have_selector('.snippet-row', count: 1)
+ expect(page).to have_content(public_snippet.title)
+ end
+ end
end
end
diff --git a/spec/finders/groups_finder_spec.rb b/spec/finders/groups_finder_spec.rb
index d5d111e8d15..5b3591550c1 100644
--- a/spec/finders/groups_finder_spec.rb
+++ b/spec/finders/groups_finder_spec.rb
@@ -3,29 +3,64 @@ require 'spec_helper'
describe GroupsFinder do
describe '#execute' do
let(:user) { create(:user) }
- let!(:private_group) { create(:group, :private) }
- let!(:internal_group) { create(:group, :internal) }
- let!(:public_group) { create(:group, :public) }
- let(:finder) { described_class.new }
- describe 'execute' do
- describe 'without a user' do
- subject { finder.execute }
+ context 'root level groups' do
+ let!(:private_group) { create(:group, :private) }
+ let!(:internal_group) { create(:group, :internal) }
+ let!(:public_group) { create(:group, :public) }
+
+ context 'without a user' do
+ subject { described_class.new.execute }
it { is_expected.to eq([public_group]) }
end
- describe 'with a user' do
- subject { finder.execute(user) }
+ context 'with a user' do
+ subject { described_class.new(user).execute }
context 'normal user' do
- it { is_expected.to eq([public_group, internal_group]) }
+ it { is_expected.to contain_exactly(public_group, internal_group) }
end
context 'external user' do
let(:user) { create(:user, external: true) }
- it { is_expected.to eq([public_group]) }
+ it { is_expected.to contain_exactly(public_group) }
+ end
+
+ context 'user is member of the private group' do
+ before do
+ private_group.add_guest(user)
+ end
+
+ it { is_expected.to contain_exactly(public_group, internal_group, private_group) }
+ end
+ end
+ end
+
+ context 'subgroups' do
+ let!(:parent_group) { create(:group, :public) }
+ let!(:public_subgroup) { create(:group, :public, parent: parent_group) }
+ let!(:internal_subgroup) { create(:group, :internal, parent: parent_group) }
+ let!(:private_subgroup) { create(:group, :private, parent: parent_group) }
+
+ context 'without a user' do
+ it 'only returns public subgroups' do
+ expect(described_class.new(nil, parent: parent_group).execute).to contain_exactly(public_subgroup)
+ end
+ end
+
+ context 'with a user' do
+ it 'returns public and internal subgroups' do
+ expect(described_class.new(user, parent: parent_group).execute).to contain_exactly(public_subgroup, internal_subgroup)
+ end
+
+ context 'being member' do
+ it 'returns public subgroups, internal subgroups, and private subgroups user is member of' do
+ private_subgroup.add_guest(user)
+
+ expect(described_class.new(user, parent: parent_group).execute).to contain_exactly(public_subgroup, internal_subgroup, private_subgroup)
+ end
end
end
end
diff --git a/spec/finders/snippets_finder_spec.rb b/spec/finders/snippets_finder_spec.rb
index cb6c80d1bd0..35f1683eef9 100644
--- a/spec/finders/snippets_finder_spec.rb
+++ b/spec/finders/snippets_finder_spec.rb
@@ -8,79 +8,145 @@ describe SnippetsFinder do
let(:project1) { create(:empty_project, :public, group: group) }
let(:project2) { create(:empty_project, :private, group: group) }
- context ':all filter' do
+ context 'all snippets visible to a user' do
let!(:snippet1) { create(:personal_snippet, :private) }
let!(:snippet2) { create(:personal_snippet, :internal) }
let!(:snippet3) { create(:personal_snippet, :public) }
+ let!(:project_snippet1) { create(:project_snippet, :private) }
+ let!(:project_snippet2) { create(:project_snippet, :internal) }
+ let!(:project_snippet3) { create(:project_snippet, :public) }
it "returns all private and internal snippets" do
- snippets = described_class.new.execute(user, filter: :all)
- expect(snippets).to include(snippet2, snippet3)
- expect(snippets).not_to include(snippet1)
+ snippets = described_class.new(user, scope: :all).execute
+ expect(snippets).to include(snippet2, snippet3, project_snippet2, project_snippet3)
+ expect(snippets).not_to include(snippet1, project_snippet1)
end
it "returns all public snippets" do
- snippets = described_class.new.execute(nil, filter: :all)
- expect(snippets).to include(snippet3)
- expect(snippets).not_to include(snippet1, snippet2)
+ snippets = described_class.new(nil, scope: :all).execute
+ expect(snippets).to include(snippet3, project_snippet3)
+ expect(snippets).not_to include(snippet1, snippet2, project_snippet1, project_snippet2)
+ end
+
+ it "returns all public and internal snippets for normal user" do
+ snippets = described_class.new(user).execute
+
+ expect(snippets).to include(snippet2, snippet3, project_snippet2, project_snippet3)
+ expect(snippets).not_to include(snippet1, project_snippet1)
+ end
+
+ it "returns all public snippets for non authorized user" do
+ snippets = described_class.new(nil).execute
+
+ expect(snippets).to include(snippet3, project_snippet3)
+ expect(snippets).not_to include(snippet1, snippet2, project_snippet1, project_snippet2)
+ end
+
+ it "returns all public and authored snippets for external user" do
+ external_user = create(:user, :external)
+ authored_snippet = create(:personal_snippet, :internal, author: external_user)
+
+ snippets = described_class.new(external_user).execute
+
+ expect(snippets).to include(snippet3, project_snippet3, authored_snippet)
+ expect(snippets).not_to include(snippet1, snippet2, project_snippet1, project_snippet2)
end
end
- context ':public filter' do
+ context 'filter by visibility' do
let!(:snippet1) { create(:personal_snippet, :private) }
let!(:snippet2) { create(:personal_snippet, :internal) }
let!(:snippet3) { create(:personal_snippet, :public) }
- it "returns public public snippets" do
- snippets = described_class.new.execute(nil, filter: :public)
+ it "returns public snippets when visibility is PUBLIC" do
+ snippets = described_class.new(nil, visibility: Snippet::PUBLIC).execute
expect(snippets).to include(snippet3)
expect(snippets).not_to include(snippet1, snippet2)
end
end
- context ':by_user filter' do
+ context 'filter by scope' do
+ let!(:snippet1) { create(:personal_snippet, :private, author: user) }
+ let!(:snippet2) { create(:personal_snippet, :internal, author: user) }
+ let!(:snippet3) { create(:personal_snippet, :public, author: user) }
+
+ it "returns all snippets for 'all' scope" do
+ snippets = described_class.new(user, scope: :all).execute
+
+ expect(snippets).to include(snippet1, snippet2, snippet3)
+ end
+
+ it "returns all snippets for 'are_private' scope" do
+ snippets = described_class.new(user, scope: :are_private).execute
+
+ expect(snippets).to include(snippet1)
+ expect(snippets).not_to include(snippet2, snippet3)
+ end
+
+ it "returns all snippets for 'are_interna;' scope" do
+ snippets = described_class.new(user, scope: :are_internal).execute
+
+ expect(snippets).to include(snippet2)
+ expect(snippets).not_to include(snippet1, snippet3)
+ end
+
+ it "returns all snippets for 'are_private' scope" do
+ snippets = described_class.new(user, scope: :are_public).execute
+
+ expect(snippets).to include(snippet3)
+ expect(snippets).not_to include(snippet1, snippet2)
+ end
+ end
+
+ context 'filter by author' do
let!(:snippet1) { create(:personal_snippet, :private, author: user) }
let!(:snippet2) { create(:personal_snippet, :internal, author: user) }
let!(:snippet3) { create(:personal_snippet, :public, author: user) }
it "returns all public and internal snippets" do
- snippets = described_class.new.execute(user1, filter: :by_user, user: user)
+ snippets = described_class.new(user1, author: user).execute
+
expect(snippets).to include(snippet2, snippet3)
expect(snippets).not_to include(snippet1)
end
it "returns internal snippets" do
- snippets = described_class.new.execute(user, filter: :by_user, user: user, scope: "are_internal")
+ snippets = described_class.new(user, author: user, visibility: Snippet::INTERNAL).execute
+
expect(snippets).to include(snippet2)
expect(snippets).not_to include(snippet1, snippet3)
end
it "returns private snippets" do
- snippets = described_class.new.execute(user, filter: :by_user, user: user, scope: "are_private")
+ snippets = described_class.new(user, author: user, visibility: Snippet::PRIVATE).execute
+
expect(snippets).to include(snippet1)
expect(snippets).not_to include(snippet2, snippet3)
end
it "returns public snippets" do
- snippets = described_class.new.execute(user, filter: :by_user, user: user, scope: "are_public")
+ snippets = described_class.new(user, author: user, visibility: Snippet::PUBLIC).execute
+
expect(snippets).to include(snippet3)
expect(snippets).not_to include(snippet1, snippet2)
end
it "returns all snippets" do
- snippets = described_class.new.execute(user, filter: :by_user, user: user)
+ snippets = described_class.new(user, author: user).execute
+
expect(snippets).to include(snippet1, snippet2, snippet3)
end
it "returns only public snippets if unauthenticated user" do
- snippets = described_class.new.execute(nil, filter: :by_user, user: user)
+ snippets = described_class.new(nil, author: user).execute
+
expect(snippets).to include(snippet3)
expect(snippets).not_to include(snippet2, snippet1)
end
end
- context 'by_project filter' do
+ context 'filter by project' do
before do
@snippet1 = create(:project_snippet, :private, project: project1)
@snippet2 = create(:project_snippet, :internal, project: project1)
@@ -88,43 +154,52 @@ describe SnippetsFinder do
end
it "returns public snippets for unauthorized user" do
- snippets = described_class.new.execute(nil, filter: :by_project, project: project1)
+ snippets = described_class.new(nil, project: project1).execute
+
expect(snippets).to include(@snippet3)
expect(snippets).not_to include(@snippet1, @snippet2)
end
it "returns public and internal snippets for non project members" do
- snippets = described_class.new.execute(user, filter: :by_project, project: project1)
+ snippets = described_class.new(user, project: project1).execute
+
expect(snippets).to include(@snippet2, @snippet3)
expect(snippets).not_to include(@snippet1)
end
it "returns public snippets for non project members" do
- snippets = described_class.new.execute(user, filter: :by_project, project: project1, scope: "are_public")
+ snippets = described_class.new(user, project: project1, visibility: Snippet::PUBLIC).execute
+
expect(snippets).to include(@snippet3)
expect(snippets).not_to include(@snippet1, @snippet2)
end
it "returns internal snippets for non project members" do
- snippets = described_class.new.execute(user, filter: :by_project, project: project1, scope: "are_internal")
+ snippets = described_class.new(user, project: project1, visibility: Snippet::INTERNAL).execute
+
expect(snippets).to include(@snippet2)
expect(snippets).not_to include(@snippet1, @snippet3)
end
it "does not return private snippets for non project members" do
- snippets = described_class.new.execute(user, filter: :by_project, project: project1, scope: "are_private")
+ snippets = described_class.new(user, project: project1, visibility: Snippet::PRIVATE).execute
+
expect(snippets).not_to include(@snippet1, @snippet2, @snippet3)
end
it "returns all snippets for project members" do
project1.team << [user, :developer]
- snippets = described_class.new.execute(user, filter: :by_project, project: project1)
+
+ snippets = described_class.new(user, project: project1).execute
+
expect(snippets).to include(@snippet1, @snippet2, @snippet3)
end
it "returns private snippets for project members" do
project1.team << [user, :developer]
- snippets = described_class.new.execute(user, filter: :by_project, project: project1, scope: "are_private")
+
+ snippets = described_class.new(user, project: project1, visibility: Snippet::PRIVATE).execute
+
expect(snippets).to include(@snippet1)
end
end
diff --git a/spec/helpers/submodule_helper_spec.rb b/spec/helpers/submodule_helper_spec.rb
index 345bc33a67b..9da33792659 100644
--- a/spec/helpers/submodule_helper_spec.rb
+++ b/spec/helpers/submodule_helper_spec.rb
@@ -109,6 +109,18 @@ describe SubmoduleHelper do
end
context 'submodule on unsupported' do
+ it 'sanitizes unsupported protocols' do
+ stub_url('javascript:alert("XSS");')
+
+ expect(helper.submodule_links(submodule_item)).to eq([nil, nil])
+ end
+
+ it 'sanitizes unsupported protocols disguised as a repository URL' do
+ stub_url('javascript:alert("XSS");foo/bar.git')
+
+ expect(helper.submodule_links(submodule_item)).to eq([nil, nil])
+ end
+
it 'returns original' do
stub_url('http://mygitserver.com/gitlab-org/gitlab-ce')
expect(submodule_links(submodule_item)).to eq([repo.submodule_url_for, nil])
diff --git a/spec/lib/banzai/filter/external_link_filter_spec.rb b/spec/lib/banzai/filter/external_link_filter_spec.rb
index d9e4525cb28..6f6c215be87 100644
--- a/spec/lib/banzai/filter/external_link_filter_spec.rb
+++ b/spec/lib/banzai/filter/external_link_filter_spec.rb
@@ -1,5 +1,22 @@
require 'spec_helper'
+shared_examples 'an external link with rel attribute' do
+ it 'adds rel="nofollow" to external links' do
+ expect(doc.at_css('a')).to have_attribute('rel')
+ expect(doc.at_css('a')['rel']).to include 'nofollow'
+ end
+
+ it 'adds rel="noreferrer" to external links' do
+ expect(doc.at_css('a')).to have_attribute('rel')
+ expect(doc.at_css('a')['rel']).to include 'noreferrer'
+ end
+
+ it 'adds rel="noopener" to external links' do
+ expect(doc.at_css('a')).to have_attribute('rel')
+ expect(doc.at_css('a')['rel']).to include 'noopener'
+ end
+end
+
describe Banzai::Filter::ExternalLinkFilter, lib: true do
include FilterSpecHelper
@@ -22,49 +39,51 @@ describe Banzai::Filter::ExternalLinkFilter, lib: true do
context 'for root links on document' do
let(:doc) { filter %q(<a href="https://google.com/">Google</a>) }
- it 'adds rel="nofollow" to external links' do
- expect(doc.at_css('a')).to have_attribute('rel')
- expect(doc.at_css('a')['rel']).to include 'nofollow'
- end
-
- it 'adds rel="noreferrer" to external links' do
- expect(doc.at_css('a')).to have_attribute('rel')
- expect(doc.at_css('a')['rel']).to include 'noreferrer'
- end
+ it_behaves_like 'an external link with rel attribute'
end
context 'for nested links on document' do
let(:doc) { filter %q(<p><a href="https://google.com/">Google</a></p>) }
- it 'adds rel="nofollow" to external links' do
- expect(doc.at_css('a')).to have_attribute('rel')
- expect(doc.at_css('a')['rel']).to include 'nofollow'
+ it_behaves_like 'an external link with rel attribute'
+ end
+
+ context 'for invalid urls' do
+ it 'skips broken hrefs' do
+ doc = filter %q(<p><a href="don't crash on broken urls">Google</a></p>)
+ expected = %q(<p><a href="don't%20crash%20on%20broken%20urls">Google</a></p>)
+
+ expect(doc.to_html).to eq(expected)
end
+ end
+
+ context 'for links with a username' do
+ context 'with a valid username' do
+ let(:doc) { filter %q(<a href="https://user@google.com/">Google</a>) }
- it 'adds rel="noreferrer" to external links' do
- expect(doc.at_css('a')).to have_attribute('rel')
- expect(doc.at_css('a')['rel']).to include 'noreferrer'
+ it_behaves_like 'an external link with rel attribute'
+ end
+
+ context 'with an impersonated username' do
+ let(:internal) { Gitlab.config.gitlab.url }
+
+ let(:doc) { filter %Q(<a href="https://#{internal}@example.com" target="_blank">Reverse Tabnabbing</a>) }
+
+ it_behaves_like 'an external link with rel attribute'
end
end
context 'for non-lowercase scheme links' do
- let(:doc_with_http) { filter %q(<p><a href="httP://google.com/">Google</a></p>) }
- let(:doc_with_https) { filter %q(<p><a href="hTTpS://google.com/">Google</a></p>) }
-
- it 'adds rel="nofollow" to external links' do
- expect(doc_with_http.at_css('a')).to have_attribute('rel')
- expect(doc_with_https.at_css('a')).to have_attribute('rel')
+ context 'with http' do
+ let(:doc) { filter %q(<p><a href="httP://google.com/">Google</a></p>) }
- expect(doc_with_http.at_css('a')['rel']).to include 'nofollow'
- expect(doc_with_https.at_css('a')['rel']).to include 'nofollow'
+ it_behaves_like 'an external link with rel attribute'
end
- it 'adds rel="noreferrer" to external links' do
- expect(doc_with_http.at_css('a')).to have_attribute('rel')
- expect(doc_with_https.at_css('a')).to have_attribute('rel')
+ context 'with https' do
+ let(:doc) { filter %q(<p><a href="hTTpS://google.com/">Google</a></p>) }
- expect(doc_with_http.at_css('a')['rel']).to include 'noreferrer'
- expect(doc_with_https.at_css('a')['rel']).to include 'noreferrer'
+ it_behaves_like 'an external link with rel attribute'
end
it 'skips internal links' do
@@ -84,14 +103,6 @@ describe Banzai::Filter::ExternalLinkFilter, lib: true do
context 'for protocol-relative links' do
let(:doc) { filter %q(<p><a href="//google.com/">Google</a></p>) }
- it 'adds rel="nofollow" to external links' do
- expect(doc.at_css('a')).to have_attribute('rel')
- expect(doc.at_css('a')['rel']).to include 'nofollow'
- end
-
- it 'adds rel="noreferrer" to external links' do
- expect(doc.at_css('a')).to have_attribute('rel')
- expect(doc.at_css('a')['rel']).to include 'noreferrer'
- end
+ it_behaves_like 'an external link with rel attribute'
end
end
diff --git a/spec/lib/gitlab/asciidoc_spec.rb b/spec/lib/gitlab/asciidoc_spec.rb
index 0f47fb2fbd9..2c7ebb15fd7 100644
--- a/spec/lib/gitlab/asciidoc_spec.rb
+++ b/spec/lib/gitlab/asciidoc_spec.rb
@@ -22,7 +22,22 @@ module Gitlab
expect(Asciidoctor).to receive(:convert)
.with(input, expected_asciidoc_opts).and_return(html)
- expect(render(input)).to eq(html)
+ expect(render(input, context)).to eq(html)
+ end
+
+ context "with asciidoc_opts" do
+ it "merges the options with default ones" do
+ expected_asciidoc_opts = {
+ safe: :secure,
+ backend: :gitlab_html5,
+ attributes: described_class::DEFAULT_ADOC_ATTRS
+ }
+
+ expect(Asciidoctor).to receive(:convert)
+ .with(input, expected_asciidoc_opts).and_return(html)
+
+ render(input, context)
+ end
end
context "XSS" do
@@ -33,7 +48,7 @@ module Gitlab
},
'images' => {
input: 'image:https://localhost.com/image.png[Alt text" onerror="alert(7)]',
- output: "<div>\n<p><span><img src=\"https://localhost.com/image.png\" alt=\"Alt text\"></span></p>\n</div>"
+ output: "<img src=\"https://localhost.com/image.png\" alt=\"Alt text\">"
},
'pre' => {
input: '```mypre"><script>alert(3)</script>',
@@ -43,10 +58,18 @@ module Gitlab
links.each do |name, data|
it "does not convert dangerous #{name} into HTML" do
- expect(render(data[:input])).to eq(data[:output])
+ expect(render(data[:input], context)).to include(data[:output])
end
end
end
+
+ context 'external links' do
+ it 'adds the `rel` attribute to the link' do
+ output = render('link:https://google.com[Google]', context)
+
+ expect(output).to include('rel="nofollow noreferrer noopener"')
+ end
+ end
end
def render(*args)
diff --git a/spec/lib/gitlab/other_markup_spec.rb b/spec/lib/gitlab/other_markup_spec.rb
index d6d53e8586c..c0f5fa9dc1f 100644
--- a/spec/lib/gitlab/other_markup_spec.rb
+++ b/spec/lib/gitlab/other_markup_spec.rb
@@ -13,7 +13,7 @@ describe Gitlab::OtherMarkup, lib: true do
}
links.each do |name, data|
it "does not convert dangerous #{name} into HTML" do
- expect(render(data[:file], data[:input])).to eq(data[:output])
+ expect(render(data[:file], data[:input], context)).to eq(data[:output])
end
end
end
diff --git a/spec/lib/gitlab/project_search_results_spec.rb b/spec/lib/gitlab/project_search_results_spec.rb
index a7c8e7f1f57..6e0b1192706 100644
--- a/spec/lib/gitlab/project_search_results_spec.rb
+++ b/spec/lib/gitlab/project_search_results_spec.rb
@@ -22,8 +22,37 @@ describe Gitlab::ProjectSearchResults, lib: true do
end
describe 'blob search' do
- let(:project) { create(:project, :repository) }
- let(:results) { described_class.new(user, project, 'files').objects('blobs') }
+ let(:project) { create(:project, :public, :repository) }
+
+ subject(:results) { described_class.new(user, project, 'files').objects('blobs') }
+
+ context 'when repository is disabled' do
+ let(:project) { create(:project, :public, :repository, :repository_disabled) }
+
+ it 'hides blobs from members' do
+ project.add_reporter(user)
+
+ is_expected.to be_empty
+ end
+
+ it 'hides blobs from non-members' do
+ is_expected.to be_empty
+ end
+ end
+
+ context 'when repository is internal' do
+ let(:project) { create(:project, :public, :repository, :repository_private) }
+
+ it 'finds blobs for members' do
+ project.add_reporter(user)
+
+ is_expected.not_to be_empty
+ end
+
+ it 'hides blobs from non-members' do
+ is_expected.to be_empty
+ end
+ end
it 'finds by name' do
expect(results).to include(["files/images/wm.svg", nil])
@@ -70,6 +99,46 @@ describe Gitlab::ProjectSearchResults, lib: true do
end
end
+ describe 'wiki search' do
+ let(:project) { create(:project, :public) }
+ let(:wiki) { build(:project_wiki, project: project) }
+ let!(:wiki_page) { wiki.create_page('Title', 'Content') }
+
+ subject(:results) { described_class.new(user, project, 'Content').objects('wiki_blobs') }
+
+ context 'when wiki is disabled' do
+ let(:project) { create(:project, :public, :wiki_disabled) }
+
+ it 'hides wiki blobs from members' do
+ project.add_reporter(user)
+
+ is_expected.to be_empty
+ end
+
+ it 'hides wiki blobs from non-members' do
+ is_expected.to be_empty
+ end
+ end
+
+ context 'when wiki is internal' do
+ let(:project) { create(:project, :public, :wiki_private) }
+
+ it 'finds wiki blobs for members' do
+ project.add_reporter(user)
+
+ is_expected.not_to be_empty
+ end
+
+ it 'hides wiki blobs from non-members' do
+ is_expected.to be_empty
+ end
+ end
+
+ it 'finds by content' do
+ expect(results).to include("master:Title.md:1:Content\n")
+ end
+ end
+
it 'does not list issues on private projects' do
issue = create(:issue, project: project)
@@ -79,7 +148,6 @@ describe Gitlab::ProjectSearchResults, lib: true do
end
describe 'confidential issues' do
- let(:project) { create(:empty_project) }
let(:query) { 'issue' }
let(:author) { create(:user) }
let(:assignee) { create(:user) }
@@ -277,6 +345,7 @@ describe Gitlab::ProjectSearchResults, lib: true do
context 'by commit hash' do
let(:project) { create(:project, :public, :repository) }
let(:commit) { project.repository.commit('0b4bc9a') }
+
commit_hashes = { short: '0b4bc9a', full: '0b4bc9a49b562e85de7cc9e834518ea6828729b9' }
commit_hashes.each do |type, commit_hash|
diff --git a/spec/models/snippet_spec.rb b/spec/models/snippet_spec.rb
index 75b1fc7e216..1e5c96fe593 100644
--- a/spec/models/snippet_spec.rb
+++ b/spec/models/snippet_spec.rb
@@ -131,46 +131,6 @@ describe Snippet, models: true do
end
end
- describe '.accessible_to' do
- let(:author) { create(:author) }
- let(:project) { create(:empty_project) }
-
- let!(:public_snippet) { create(:snippet, :public) }
- let!(:internal_snippet) { create(:snippet, :internal) }
- let!(:private_snippet) { create(:snippet, :private, author: author) }
-
- let!(:project_public_snippet) { create(:snippet, :public, project: project) }
- let!(:project_internal_snippet) { create(:snippet, :internal, project: project) }
- let!(:project_private_snippet) { create(:snippet, :private, project: project) }
-
- it 'returns only public snippets when user is blank' do
- expect(described_class.accessible_to(nil)).to match_array [public_snippet, project_public_snippet]
- end
-
- it 'returns only public, and internal snippets for regular users' do
- user = create(:user)
-
- expect(described_class.accessible_to(user)).to match_array [public_snippet, internal_snippet, project_public_snippet, project_internal_snippet]
- end
-
- it 'returns public, internal snippets and project private snippets for project members' do
- member = create(:user)
- project.team << [member, :developer]
-
- expect(described_class.accessible_to(member)).to match_array [public_snippet, internal_snippet, project_public_snippet, project_internal_snippet, project_private_snippet]
- end
-
- it 'returns private snippets where the user is the author' do
- expect(described_class.accessible_to(author)).to match_array [public_snippet, internal_snippet, private_snippet, project_public_snippet, project_internal_snippet]
- end
-
- it 'returns all snippets when for admins' do
- admin = create(:admin)
-
- expect(described_class.accessible_to(admin)).to match_array [public_snippet, internal_snippet, private_snippet, project_public_snippet, project_internal_snippet, project_private_snippet]
- end
- end
-
describe '#participants' do
let(:project) { create(:empty_project, :public) }
let(:snippet) { create(:snippet, content: 'foo', project: project) }
diff --git a/spec/policies/project_snippet_policy_spec.rb b/spec/policies/project_snippet_policy_spec.rb
index d0758af57dd..e1771b636b8 100644
--- a/spec/policies/project_snippet_policy_spec.rb
+++ b/spec/policies/project_snippet_policy_spec.rb
@@ -1,7 +1,9 @@
require 'spec_helper'
describe ProjectSnippetPolicy, models: true do
- let(:current_user) { create(:user) }
+ let(:regular_user) { create(:user) }
+ let(:external_user) { create(:user, :external) }
+ let(:project) { create(:empty_project) }
let(:author_permissions) do
[
@@ -10,13 +12,15 @@ describe ProjectSnippetPolicy, models: true do
]
end
- subject { described_class.abilities(current_user, project_snippet).to_set }
+ def abilities(user, snippet_visibility)
+ snippet = create(:project_snippet, snippet_visibility, project: project)
- context 'public snippet' do
- let(:project_snippet) { create(:project_snippet, :public) }
+ described_class.abilities(user, snippet).to_set
+ end
+ context 'public snippet' do
context 'no user' do
- let(:current_user) { nil }
+ subject { abilities(nil, :public) }
it do
is_expected.to include(:read_project_snippet)
@@ -25,6 +29,17 @@ describe ProjectSnippetPolicy, models: true do
end
context 'regular user' do
+ subject { abilities(regular_user, :public) }
+
+ it do
+ is_expected.to include(:read_project_snippet)
+ is_expected.not_to include(*author_permissions)
+ end
+ end
+
+ context 'external user' do
+ subject { abilities(external_user, :public) }
+
it do
is_expected.to include(:read_project_snippet)
is_expected.not_to include(*author_permissions)
@@ -33,10 +48,8 @@ describe ProjectSnippetPolicy, models: true do
end
context 'internal snippet' do
- let(:project_snippet) { create(:project_snippet, :internal) }
-
context 'no user' do
- let(:current_user) { nil }
+ subject { abilities(nil, :internal) }
it do
is_expected.not_to include(:read_project_snippet)
@@ -45,6 +58,28 @@ describe ProjectSnippetPolicy, models: true do
end
context 'regular user' do
+ subject { abilities(regular_user, :internal) }
+
+ it do
+ is_expected.to include(:read_project_snippet)
+ is_expected.not_to include(*author_permissions)
+ end
+ end
+
+ context 'external user' do
+ subject { abilities(external_user, :internal) }
+
+ it do
+ is_expected.not_to include(:read_project_snippet)
+ is_expected.not_to include(*author_permissions)
+ end
+ end
+
+ context 'project team member external user' do
+ subject { abilities(external_user, :internal) }
+
+ before { project.team << [external_user, :developer] }
+
it do
is_expected.to include(:read_project_snippet)
is_expected.not_to include(*author_permissions)
@@ -53,10 +88,8 @@ describe ProjectSnippetPolicy, models: true do
end
context 'private snippet' do
- let(:project_snippet) { create(:project_snippet, :private) }
-
context 'no user' do
- let(:current_user) { nil }
+ subject { abilities(nil, :private) }
it do
is_expected.not_to include(:read_project_snippet)
@@ -65,6 +98,8 @@ describe ProjectSnippetPolicy, models: true do
end
context 'regular user' do
+ subject { abilities(regular_user, :private) }
+
it do
is_expected.not_to include(:read_project_snippet)
is_expected.not_to include(*author_permissions)
@@ -72,7 +107,9 @@ describe ProjectSnippetPolicy, models: true do
end
context 'snippet author' do
- let(:project_snippet) { create(:project_snippet, :private, author: current_user) }
+ let(:snippet) { create(:project_snippet, :private, author: regular_user) }
+
+ subject { described_class.abilities(regular_user, snippet).to_set }
it do
is_expected.to include(:read_project_snippet)
@@ -80,8 +117,21 @@ describe ProjectSnippetPolicy, models: true do
end
end
- context 'project team member' do
- before { project_snippet.project.team << [current_user, :developer] }
+ context 'project team member normal user' do
+ subject { abilities(regular_user, :private) }
+
+ before { project.team << [regular_user, :developer] }
+
+ it do
+ is_expected.to include(:read_project_snippet)
+ is_expected.not_to include(*author_permissions)
+ end
+ end
+
+ context 'project team member external user' do
+ subject { abilities(external_user, :private) }
+
+ before { project.team << [external_user, :developer] }
it do
is_expected.to include(:read_project_snippet)
@@ -90,7 +140,7 @@ describe ProjectSnippetPolicy, models: true do
end
context 'admin user' do
- let(:current_user) { create(:admin) }
+ subject { abilities(create(:admin), :private) }
it do
is_expected.to include(:read_project_snippet)
diff --git a/spec/views/projects/imports/new.html.haml_spec.rb b/spec/views/projects/imports/new.html.haml_spec.rb
new file mode 100644
index 00000000000..9b293065797
--- /dev/null
+++ b/spec/views/projects/imports/new.html.haml_spec.rb
@@ -0,0 +1,22 @@
+require "spec_helper"
+
+describe "projects/imports/new.html.haml" do
+ let(:user) { create(:user) }
+
+ context 'when import fails' do
+ let(:project) { create(:project_empty_repo, import_status: :failed, import_error: '<a href="http://googl.com">Foo</a>', import_type: :gitlab_project, import_source: '/var/opt/gitlab/gitlab-rails/shared/tmp/project_exports/uploads/t.tar.gz', import_url: nil) }
+
+ before do
+ sign_in(user)
+ project.team << [user, :master]
+ end
+
+ it "escapes HTML in import errors" do
+ assign(:project, project)
+
+ render
+
+ expect(rendered).not_to have_link('Foo', href: "http://googl.com")
+ end
+ end
+end