diff options
author | Tuomo Ala-Vannesluoma <tuomoav@gmail.com> | 2018-10-05 16:41:11 +0300 |
---|---|---|
committer | Nick Thomas <nick@gitlab.com> | 2018-10-05 16:41:11 +0300 |
commit | c84b60b1645950a30fdbc37c9065a200dc750d90 (patch) | |
tree | 76d523f37481fa1422f63e96e2a1777d48060b9c /spec | |
parent | c972f2e459a6b45852a3d4e76566cdf772a6764a (diff) |
Make GitLab pages support access control
Diffstat (limited to 'spec')
-rw-r--r-- | spec/factories/projects.rb | 18 | ||||
-rw-r--r-- | spec/graphql/types/permission_types/project_spec.rb | 2 | ||||
-rw-r--r-- | spec/lib/gitlab/import_export/safe_model_attributes.yml | 1 | ||||
-rw-r--r-- | spec/migrations/add_pages_access_level_to_project_feature_spec.rb | 30 | ||||
-rw-r--r-- | spec/models/internal_id_spec.rb | 3 | ||||
-rw-r--r-- | spec/models/project_feature_spec.rb | 15 | ||||
-rw-r--r-- | spec/requests/api/pages/internal_access_spec.rb | 88 | ||||
-rw-r--r-- | spec/requests/api/pages/private_access_spec.rb | 88 | ||||
-rw-r--r-- | spec/requests/api/pages/public_access_spec.rb | 88 | ||||
-rw-r--r-- | spec/services/projects/update_service_spec.rb | 21 |
10 files changed, 349 insertions, 5 deletions
diff --git a/spec/factories/projects.rb b/spec/factories/projects.rb index 80801eb1082..e4823a5adf1 100644 --- a/spec/factories/projects.rb +++ b/spec/factories/projects.rb @@ -1,6 +1,8 @@ require_relative '../support/helpers/test_env' FactoryBot.define do + PAGES_ACCESS_LEVEL_SCHEMA_VERSION = 20180423204600 + # Project without repository # # Project does not have bare repository. @@ -23,6 +25,7 @@ FactoryBot.define do issues_access_level ProjectFeature::ENABLED merge_requests_access_level ProjectFeature::ENABLED repository_access_level ProjectFeature::ENABLED + pages_access_level ProjectFeature::ENABLED # we can't assign the delegated `#ci_cd_settings` attributes directly, as the # `#ci_cd_settings` relation needs to be created first @@ -34,13 +37,20 @@ FactoryBot.define do builds_access_level = [evaluator.builds_access_level, evaluator.repository_access_level].min merge_requests_access_level = [evaluator.merge_requests_access_level, evaluator.repository_access_level].min - project.project_feature.update( + hash = { wiki_access_level: evaluator.wiki_access_level, builds_access_level: builds_access_level, snippets_access_level: evaluator.snippets_access_level, issues_access_level: evaluator.issues_access_level, merge_requests_access_level: merge_requests_access_level, - repository_access_level: evaluator.repository_access_level) + repository_access_level: evaluator.repository_access_level + } + + if ActiveRecord::Migrator.current_version >= PAGES_ACCESS_LEVEL_SCHEMA_VERSION + hash.store("pages_access_level", evaluator.pages_access_level) + end + + project.project_feature.update(hash) # Normally the class Projects::CreateService is used for creating # projects, and this class takes care of making sure the owner and current @@ -244,6 +254,10 @@ FactoryBot.define do trait(:repository_enabled) { repository_access_level ProjectFeature::ENABLED } trait(:repository_disabled) { repository_access_level ProjectFeature::DISABLED } trait(:repository_private) { repository_access_level ProjectFeature::PRIVATE } + trait(:pages_public) { pages_access_level ProjectFeature::PUBLIC } + trait(:pages_enabled) { pages_access_level ProjectFeature::ENABLED } + trait(:pages_disabled) { pages_access_level ProjectFeature::DISABLED } + trait(:pages_private) { pages_access_level ProjectFeature::PRIVATE } trait :auto_devops do association :auto_devops, factory: :project_auto_devops diff --git a/spec/graphql/types/permission_types/project_spec.rb b/spec/graphql/types/permission_types/project_spec.rb index 89eecef096e..927153adc5b 100644 --- a/spec/graphql/types/permission_types/project_spec.rb +++ b/spec/graphql/types/permission_types/project_spec.rb @@ -10,7 +10,7 @@ describe Types::PermissionTypes::Project do :read_commit_status, :request_access, :create_pipeline, :create_pipeline_schedule, :create_merge_request_from, :create_wiki, :push_code, :create_deployment, :push_to_delete_protected_branch, :admin_wiki, :admin_project, :update_pages, :admin_remote_mirror, :create_label, - :update_wiki, :destroy_wiki, :create_pages, :destroy_pages + :update_wiki, :destroy_wiki, :create_pages, :destroy_pages, :read_pages_content ] expect(described_class).to have_graphql_fields(expected_permissions) diff --git a/spec/lib/gitlab/import_export/safe_model_attributes.yml b/spec/lib/gitlab/import_export/safe_model_attributes.yml index e9f1be172b0..7be1bf6e0bf 100644 --- a/spec/lib/gitlab/import_export/safe_model_attributes.yml +++ b/spec/lib/gitlab/import_export/safe_model_attributes.yml @@ -492,6 +492,7 @@ ProjectFeature: - snippets_access_level - builds_access_level - repository_access_level +- pages_access_level - created_at - updated_at ProtectedBranch::MergeAccessLevel: diff --git a/spec/migrations/add_pages_access_level_to_project_feature_spec.rb b/spec/migrations/add_pages_access_level_to_project_feature_spec.rb new file mode 100644 index 00000000000..3946602c5be --- /dev/null +++ b/spec/migrations/add_pages_access_level_to_project_feature_spec.rb @@ -0,0 +1,30 @@ +require 'spec_helper' +require Rails.root.join('db', 'migrate', '20180423204600_add_pages_access_level_to_project_feature.rb') + +describe AddPagesAccessLevelToProjectFeature, :migration do + let(:namespaces) { table(:namespaces) } + let(:projects) { table(:projects) } + let(:features) { table(:project_features) } + let!(:namespace) { namespaces.create(name: 'gitlab', path: 'gitlab') } + let!(:first_project) { projects.create(name: 'gitlab1', path: 'gitlab1', namespace_id: namespace.id) } + let!(:first_project_features) { features.create(project_id: first_project.id) } + let!(:second_project) { projects.create(name: 'gitlab2', path: 'gitlab2', namespace_id: namespace.id) } + let!(:second_project_features) { features.create(project_id: second_project.id) } + + it 'correctly migrate pages for old projects to be public' do + migrate! + + # For old projects pages should be public + expect(first_project_features.reload.pages_access_level).to eq ProjectFeature::PUBLIC + expect(second_project_features.reload.pages_access_level).to eq ProjectFeature::PUBLIC + end + + it 'after migration pages are enabled as default' do + migrate! + + # For new project default is enabled + third_project = projects.create(name: 'gitlab3', path: 'gitlab3', namespace_id: namespace.id) + third_project_features = features.create(project_id: third_project.id) + expect(third_project_features.reload.pages_access_level).to eq ProjectFeature::ENABLED + end +end diff --git a/spec/models/internal_id_spec.rb b/spec/models/internal_id_spec.rb index f2aad455d5f..52c00a74b4b 100644 --- a/spec/models/internal_id_spec.rb +++ b/spec/models/internal_id_spec.rb @@ -65,7 +65,8 @@ describe InternalId do context 'with an insufficient schema version' do before do described_class.reset_column_information - expect(ActiveRecord::Migrator).to receive(:current_version).and_return(InternalId::REQUIRED_SCHEMA_VERSION - 1) + # Project factory will also call the current_version + expect(ActiveRecord::Migrator).to receive(:current_version).twice.and_return(InternalId::REQUIRED_SCHEMA_VERSION - 1) end let(:init) { double('block') } diff --git a/spec/models/project_feature_spec.rb b/spec/models/project_feature_spec.rb index 2a193864e46..fee7d65c217 100644 --- a/spec/models/project_feature_spec.rb +++ b/spec/models/project_feature_spec.rb @@ -17,7 +17,7 @@ describe ProjectFeature do end describe '#feature_available?' do - let(:features) { %w(issues wiki builds merge_requests snippets repository) } + let(:features) { %w(issues wiki builds merge_requests snippets repository pages) } context 'when features are disabled' do it "returns false" do @@ -112,6 +112,19 @@ describe ProjectFeature do end end + context 'public features' do + it "does not allow public for other than pages" do + features = %w(issues wiki builds merge_requests snippets repository) + project_feature = project.project_feature + + features.each do |feature| + field = "#{feature}_access_level".to_sym + project_feature.update_attribute(field, ProjectFeature::PUBLIC) + expect(project_feature.valid?).to be_falsy + end + end + end + describe '#*_enabled?' do let(:features) { %w(wiki builds merge_requests) } diff --git a/spec/requests/api/pages/internal_access_spec.rb b/spec/requests/api/pages/internal_access_spec.rb new file mode 100644 index 00000000000..c41eabe0a48 --- /dev/null +++ b/spec/requests/api/pages/internal_access_spec.rb @@ -0,0 +1,88 @@ +require 'spec_helper' + +describe "Internal Project Pages Access" do + using RSpec::Parameterized::TableSyntax + include AccessMatchers + + set(:group) { create(:group) } + set(:project) { create(:project, :internal, pages_access_level: ProjectFeature::ENABLED, namespace: group) } + + set(:admin) { create(:admin) } + set(:owner) { create(:user) } + set(:master) { create(:user) } + set(:developer) { create(:user) } + set(:reporter) { create(:user) } + set(:guest) { create(:user) } + set(:user) { create(:user) } + + before do + allow(Gitlab.config.pages).to receive(:access_control).and_return(true) + group.add_owner(owner) + project.add_master(master) + project.add_developer(developer) + project.add_reporter(reporter) + project.add_guest(guest) + end + + describe "Project should be internal" do + describe '#internal?' do + subject { project.internal? } + it { is_expected.to be_truthy } + end + end + + describe "GET /projects/:id/pages_access" do + context 'access depends on the level' do + where(:pages_access_level, :with_user, :expected_result) do + ProjectFeature::DISABLED | "admin" | 403 + ProjectFeature::DISABLED | "owner" | 403 + ProjectFeature::DISABLED | "master" | 403 + ProjectFeature::DISABLED | "developer" | 403 + ProjectFeature::DISABLED | "reporter" | 403 + ProjectFeature::DISABLED | "guest" | 403 + ProjectFeature::DISABLED | "user" | 403 + ProjectFeature::DISABLED | nil | 404 + ProjectFeature::PUBLIC | "admin" | 200 + ProjectFeature::PUBLIC | "owner" | 200 + ProjectFeature::PUBLIC | "master" | 200 + ProjectFeature::PUBLIC | "developer" | 200 + ProjectFeature::PUBLIC | "reporter" | 200 + ProjectFeature::PUBLIC | "guest" | 200 + ProjectFeature::PUBLIC | "user" | 200 + ProjectFeature::PUBLIC | nil | 404 + ProjectFeature::ENABLED | "admin" | 200 + ProjectFeature::ENABLED | "owner" | 200 + ProjectFeature::ENABLED | "master" | 200 + ProjectFeature::ENABLED | "developer" | 200 + ProjectFeature::ENABLED | "reporter" | 200 + ProjectFeature::ENABLED | "guest" | 200 + ProjectFeature::ENABLED | "user" | 200 + ProjectFeature::ENABLED | nil | 404 + ProjectFeature::PRIVATE | "admin" | 200 + ProjectFeature::PRIVATE | "owner" | 200 + ProjectFeature::PRIVATE | "master" | 200 + ProjectFeature::PRIVATE | "developer" | 200 + ProjectFeature::PRIVATE | "reporter" | 200 + ProjectFeature::PRIVATE | "guest" | 200 + ProjectFeature::PRIVATE | "user" | 403 + ProjectFeature::PRIVATE | nil | 404 + end + + with_them do + before do + project.project_feature.update(pages_access_level: pages_access_level) + end + it "correct return value" do + if !with_user.nil? + user = public_send(with_user) + get api("/projects/#{project.id}/pages_access", user) + else + get api("/projects/#{project.id}/pages_access") + end + + expect(response).to have_gitlab_http_status(expected_result) + end + end + end + end +end diff --git a/spec/requests/api/pages/private_access_spec.rb b/spec/requests/api/pages/private_access_spec.rb new file mode 100644 index 00000000000..d69c15b0477 --- /dev/null +++ b/spec/requests/api/pages/private_access_spec.rb @@ -0,0 +1,88 @@ +require 'spec_helper' + +describe "Private Project Pages Access" do + using RSpec::Parameterized::TableSyntax + include AccessMatchers + + set(:group) { create(:group) } + set(:project) { create(:project, :private, pages_access_level: ProjectFeature::ENABLED, namespace: group) } + + set(:admin) { create(:admin) } + set(:owner) { create(:user) } + set(:master) { create(:user) } + set(:developer) { create(:user) } + set(:reporter) { create(:user) } + set(:guest) { create(:user) } + set(:user) { create(:user) } + + before do + allow(Gitlab.config.pages).to receive(:access_control).and_return(true) + group.add_owner(owner) + project.add_master(master) + project.add_developer(developer) + project.add_reporter(reporter) + project.add_guest(guest) + end + + describe "Project should be private" do + describe '#private?' do + subject { project.private? } + it { is_expected.to be_truthy } + end + end + + describe "GET /projects/:id/pages_access" do + context 'access depends on the level' do + where(:pages_access_level, :with_user, :expected_result) do + ProjectFeature::DISABLED | "admin" | 403 + ProjectFeature::DISABLED | "owner" | 403 + ProjectFeature::DISABLED | "master" | 403 + ProjectFeature::DISABLED | "developer" | 403 + ProjectFeature::DISABLED | "reporter" | 403 + ProjectFeature::DISABLED | "guest" | 403 + ProjectFeature::DISABLED | "user" | 404 + ProjectFeature::DISABLED | nil | 404 + ProjectFeature::PUBLIC | "admin" | 200 + ProjectFeature::PUBLIC | "owner" | 200 + ProjectFeature::PUBLIC | "master" | 200 + ProjectFeature::PUBLIC | "developer" | 200 + ProjectFeature::PUBLIC | "reporter" | 200 + ProjectFeature::PUBLIC | "guest" | 200 + ProjectFeature::PUBLIC | "user" | 404 + ProjectFeature::PUBLIC | nil | 404 + ProjectFeature::ENABLED | "admin" | 200 + ProjectFeature::ENABLED | "owner" | 200 + ProjectFeature::ENABLED | "master" | 200 + ProjectFeature::ENABLED | "developer" | 200 + ProjectFeature::ENABLED | "reporter" | 200 + ProjectFeature::ENABLED | "guest" | 200 + ProjectFeature::ENABLED | "user" | 404 + ProjectFeature::ENABLED | nil | 404 + ProjectFeature::PRIVATE | "admin" | 200 + ProjectFeature::PRIVATE | "owner" | 200 + ProjectFeature::PRIVATE | "master" | 200 + ProjectFeature::PRIVATE | "developer" | 200 + ProjectFeature::PRIVATE | "reporter" | 200 + ProjectFeature::PRIVATE | "guest" | 200 + ProjectFeature::PRIVATE | "user" | 404 + ProjectFeature::PRIVATE | nil | 404 + end + + with_them do + before do + project.project_feature.update(pages_access_level: pages_access_level) + end + it "correct return value" do + if !with_user.nil? + user = public_send(with_user) + get api("/projects/#{project.id}/pages_access", user) + else + get api("/projects/#{project.id}/pages_access") + end + + expect(response).to have_gitlab_http_status(expected_result) + end + end + end + end +end diff --git a/spec/requests/api/pages/public_access_spec.rb b/spec/requests/api/pages/public_access_spec.rb new file mode 100644 index 00000000000..882ca26ac51 --- /dev/null +++ b/spec/requests/api/pages/public_access_spec.rb @@ -0,0 +1,88 @@ +require 'spec_helper' + +describe "Public Project Pages Access" do + using RSpec::Parameterized::TableSyntax + include AccessMatchers + + set(:group) { create(:group) } + set(:project) { create(:project, :public, pages_access_level: ProjectFeature::ENABLED, namespace: group) } + + set(:admin) { create(:admin) } + set(:owner) { create(:user) } + set(:master) { create(:user) } + set(:developer) { create(:user) } + set(:reporter) { create(:user) } + set(:guest) { create(:user) } + set(:user) { create(:user) } + + before do + allow(Gitlab.config.pages).to receive(:access_control).and_return(true) + group.add_owner(owner) + project.add_master(master) + project.add_developer(developer) + project.add_reporter(reporter) + project.add_guest(guest) + end + + describe "Project should be public" do + describe '#public?' do + subject { project.public? } + it { is_expected.to be_truthy } + end + end + + describe "GET /projects/:id/pages_access" do + context 'access depends on the level' do + where(:pages_access_level, :with_user, :expected_result) do + ProjectFeature::DISABLED | "admin" | 403 + ProjectFeature::DISABLED | "owner" | 403 + ProjectFeature::DISABLED | "master" | 403 + ProjectFeature::DISABLED | "developer" | 403 + ProjectFeature::DISABLED | "reporter" | 403 + ProjectFeature::DISABLED | "guest" | 403 + ProjectFeature::DISABLED | "user" | 403 + ProjectFeature::DISABLED | nil | 403 + ProjectFeature::PUBLIC | "admin" | 200 + ProjectFeature::PUBLIC | "owner" | 200 + ProjectFeature::PUBLIC | "master" | 200 + ProjectFeature::PUBLIC | "developer" | 200 + ProjectFeature::PUBLIC | "reporter" | 200 + ProjectFeature::PUBLIC | "guest" | 200 + ProjectFeature::PUBLIC | "user" | 200 + ProjectFeature::PUBLIC | nil | 200 + ProjectFeature::ENABLED | "admin" | 200 + ProjectFeature::ENABLED | "owner" | 200 + ProjectFeature::ENABLED | "master" | 200 + ProjectFeature::ENABLED | "developer" | 200 + ProjectFeature::ENABLED | "reporter" | 200 + ProjectFeature::ENABLED | "guest" | 200 + ProjectFeature::ENABLED | "user" | 200 + ProjectFeature::ENABLED | nil | 200 + ProjectFeature::PRIVATE | "admin" | 200 + ProjectFeature::PRIVATE | "owner" | 200 + ProjectFeature::PRIVATE | "master" | 200 + ProjectFeature::PRIVATE | "developer" | 200 + ProjectFeature::PRIVATE | "reporter" | 200 + ProjectFeature::PRIVATE | "guest" | 200 + ProjectFeature::PRIVATE | "user" | 403 + ProjectFeature::PRIVATE | nil | 403 + end + + with_them do + before do + project.project_feature.update(pages_access_level: pages_access_level) + end + it "correct return value" do + if !with_user.nil? + user = public_send(with_user) + get api("/projects/#{project.id}/pages_access", user) + else + get api("/projects/#{project.id}/pages_access") + end + + expect(response).to have_gitlab_http_status(expected_result) + end + end + end + end +end diff --git a/spec/services/projects/update_service_spec.rb b/spec/services/projects/update_service_spec.rb index 695b9980548..d58ff2cedc0 100644 --- a/spec/services/projects/update_service_spec.rb +++ b/spec/services/projects/update_service_spec.rb @@ -340,6 +340,27 @@ describe Projects::UpdateService do call_service end end + + context 'when updating #pages_access_level' do + subject(:call_service) do + update_project(project, admin, project_feature_attributes: { pages_access_level: ProjectFeature::PRIVATE }) + end + + it 'updates the attribute' do + expect { call_service } + .to change { project.project_feature.pages_access_level } + .to(ProjectFeature::PRIVATE) + end + + it 'calls Projects::UpdatePagesConfigurationService' do + expect(Projects::UpdatePagesConfigurationService) + .to receive(:new) + .with(project) + .and_call_original + + call_service + end + end end describe '#run_auto_devops_pipeline?' do |