Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-12-01 00:09:16 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-12-01 00:09:16 +0300
commit2ddcd634fc74d894b243694582fdf58cf5fb3c2a (patch)
tree632d56475fca27be71f240dc54e82de1b2d55ce9 /spec
parentace0df53d3ed38344b470727d430484d24eeb798 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/config/settings_spec.rb16
-rw-r--r--spec/features/boards/add_issues_modal_spec.rb5
-rw-r--r--spec/features/projects/settings/service_desk_setting_spec.rb55
-rw-r--r--spec/frontend/clusters/components/__snapshots__/remove_cluster_confirmation_spec.js.snap4
-rw-r--r--spec/frontend/design_management/components/upload/__snapshots__/design_version_dropdown_spec.js.snap4
-rw-r--r--spec/frontend/incidents_settings/components/__snapshots__/alerts_form_spec.js.snap2
-rw-r--r--spec/frontend/jira_import/components/__snapshots__/jira_import_form_spec.js.snap4
-rw-r--r--spec/frontend/monitoring/components/__snapshots__/dashboard_template_spec.js.snap2
-rw-r--r--spec/frontend/pages/projects/graphs/__snapshots__/code_coverage_spec.js.snap2
-rw-r--r--spec/frontend/vue_shared/components/__snapshots__/split_button_spec.js.snap2
-rw-r--r--spec/initializers/secret_token_spec.rb27
-rw-r--r--spec/lib/gitlab/encrypted_configuration_spec.rb145
-rw-r--r--spec/models/project_spec.rb36
13 files changed, 284 insertions, 20 deletions
diff --git a/spec/config/settings_spec.rb b/spec/config/settings_spec.rb
index ed873478fc9..6525ae653c9 100644
--- a/spec/config/settings_spec.rb
+++ b/spec/config/settings_spec.rb
@@ -134,4 +134,20 @@ RSpec.describe Settings do
end
end
end
+
+ describe '.encrypted' do
+ before do
+ allow(Gitlab::Application.secrets).to receive(:encryped_settings_key_base).and_return(SecureRandom.hex(64))
+ end
+
+ it 'defaults to using the encrypted_settings_key_base for the key' do
+ expect(Gitlab::EncryptedConfiguration).to receive(:new).with(hash_including(base_key: Gitlab::Application.secrets.encrypted_settings_key_base))
+ Settings.encrypted('tmp/tests/test.enc')
+ end
+
+ it 'returns empty encrypted config when a key has not been set' do
+ allow(Gitlab::Application.secrets).to receive(:encrypted_settings_key_base).and_return(nil)
+ expect(Settings.encrypted('tmp/tests/test.enc').read).to be_empty
+ end
+ end
end
diff --git a/spec/features/boards/add_issues_modal_spec.rb b/spec/features/boards/add_issues_modal_spec.rb
index f941adca233..8d0fa3e023b 100644
--- a/spec/features/boards/add_issues_modal_spec.rb
+++ b/spec/features/boards/add_issues_modal_spec.rb
@@ -37,6 +37,10 @@ RSpec.describe 'Issue Boards add issue modal', :js do
end
context 'modal interaction' do
+ before do
+ stub_feature_flags(add_issues_button: true)
+ end
+
it 'opens modal' do
click_button('Add issues')
@@ -72,6 +76,7 @@ RSpec.describe 'Issue Boards add issue modal', :js do
context 'issues list' do
before do
+ stub_feature_flags(add_issues_button: true)
click_button('Add issues')
wait_for_requests
diff --git a/spec/features/projects/settings/service_desk_setting_spec.rb b/spec/features/projects/settings/service_desk_setting_spec.rb
index 59e6f54da2f..d31913d2dcf 100644
--- a/spec/features/projects/settings/service_desk_setting_spec.rb
+++ b/spec/features/projects/settings/service_desk_setting_spec.rb
@@ -14,20 +14,57 @@ RSpec.describe 'Service Desk Setting', :js do
allow_any_instance_of(Project).to receive(:present).with(current_user: user).and_return(presenter)
allow(::Gitlab::IncomingEmail).to receive(:enabled?) { true }
allow(::Gitlab::IncomingEmail).to receive(:supports_wildcard?) { true }
-
- visit edit_project_path(project)
end
it 'shows activation checkbox' do
+ visit edit_project_path(project)
+
expect(page).to have_selector("#service-desk-checkbox")
end
- it 'shows incoming email after activating' do
- find("#service-desk-checkbox").click
- wait_for_requests
- project.reload
- expect(project.service_desk_enabled).to be_truthy
- expect(project.service_desk_address).to be_present
- expect(find('[data-testid="incoming-email"]').value).to eq(project.service_desk_address)
+ context 'when service_desk_email is disabled' do
+ before do
+ allow(::Gitlab::ServiceDeskEmail).to receive(:enabled?).and_return(false)
+
+ visit edit_project_path(project)
+ end
+
+ it 'shows incoming email but not project name suffix after activating' do
+ find("#service-desk-checkbox").click
+
+ wait_for_requests
+
+ project.reload
+ expect(project.service_desk_enabled).to be_truthy
+ expect(project.service_desk_address).to be_present
+ expect(find('[data-testid="incoming-email"]').value).to eq(project.service_desk_incoming_address)
+ expect(page).not_to have_selector('#service-desk-project-suffix')
+ end
+ end
+
+ context 'when service_desk_email is enabled' do
+ before do
+ allow(::Gitlab::ServiceDeskEmail).to receive(:enabled?) { true }
+ allow(::Gitlab::ServiceDeskEmail).to receive(:address_for_key) { 'address-suffix@example.com' }
+
+ visit edit_project_path(project)
+ end
+
+ it 'allows setting of custom address suffix' do
+ find("#service-desk-checkbox").click
+ wait_for_requests
+
+ project.reload
+ expect(find('[data-testid="incoming-email"]').value).to eq(project.service_desk_incoming_address)
+
+ page.within '#js-service-desk' do
+ fill_in('service-desk-project-suffix', with: 'foo')
+ click_button 'Save changes'
+ end
+
+ wait_for_requests
+
+ expect(find('[data-testid="incoming-email"]').value).to eq('address-suffix@example.com')
+ end
end
end
diff --git a/spec/frontend/clusters/components/__snapshots__/remove_cluster_confirmation_spec.js.snap b/spec/frontend/clusters/components/__snapshots__/remove_cluster_confirmation_spec.js.snap
index 7471ef2c1b3..6f28573c808 100644
--- a/spec/frontend/clusters/components/__snapshots__/remove_cluster_confirmation_spec.js.snap
+++ b/spec/frontend/clusters/components/__snapshots__/remove_cluster_confirmation_spec.js.snap
@@ -9,7 +9,7 @@ exports[`Remove cluster confirmation modal renders splitbutton with modal includ
menu-class="dropdown-menu-large"
>
<button
- class="btn btn-danger btn-md gl-button split-content-button btn-danger-secondary"
+ class="btn btn-danger btn-md gl-button split-content-button"
type="button"
>
<!---->
@@ -27,7 +27,7 @@ exports[`Remove cluster confirmation modal renders splitbutton with modal includ
<button
aria-expanded="false"
aria-haspopup="true"
- class="btn dropdown-toggle btn-danger btn-md gl-button gl-dropdown-toggle btn-danger-secondary dropdown-toggle-split"
+ class="btn dropdown-toggle btn-danger btn-md gl-button gl-dropdown-toggle dropdown-toggle-split"
type="button"
>
<span
diff --git a/spec/frontend/design_management/components/upload/__snapshots__/design_version_dropdown_spec.js.snap b/spec/frontend/design_management/components/upload/__snapshots__/design_version_dropdown_spec.js.snap
index 812836e02b7..8c6b446794f 100644
--- a/spec/frontend/design_management/components/upload/__snapshots__/design_version_dropdown_spec.js.snap
+++ b/spec/frontend/design_management/components/upload/__snapshots__/design_version_dropdown_spec.js.snap
@@ -2,7 +2,7 @@
exports[`Design management design version dropdown component renders design version dropdown button 1`] = `
<gl-dropdown-stub
- category="tertiary"
+ category="primary"
headertext=""
issueiid=""
projectpath=""
@@ -42,7 +42,7 @@ exports[`Design management design version dropdown component renders design vers
exports[`Design management design version dropdown component renders design version list 1`] = `
<gl-dropdown-stub
- category="tertiary"
+ category="primary"
headertext=""
issueiid=""
projectpath=""
diff --git a/spec/frontend/incidents_settings/components/__snapshots__/alerts_form_spec.js.snap b/spec/frontend/incidents_settings/components/__snapshots__/alerts_form_spec.js.snap
index f9845c813e2..26ff4aa657b 100644
--- a/spec/frontend/incidents_settings/components/__snapshots__/alerts_form_spec.js.snap
+++ b/spec/frontend/incidents_settings/components/__snapshots__/alerts_form_spec.js.snap
@@ -47,7 +47,7 @@ exports[`Alert integration settings form default state should match the default
<gl-dropdown-stub
block="true"
- category="tertiary"
+ category="primary"
data-qa-selector="incident_templates_dropdown"
headertext=""
id="alert-integration-settings-issue-template"
diff --git a/spec/frontend/jira_import/components/__snapshots__/jira_import_form_spec.js.snap b/spec/frontend/jira_import/components/__snapshots__/jira_import_form_spec.js.snap
index 751ceb3c235..c40b7c90c72 100644
--- a/spec/frontend/jira_import/components/__snapshots__/jira_import_form_spec.js.snap
+++ b/spec/frontend/jira_import/components/__snapshots__/jira_import_form_spec.js.snap
@@ -86,7 +86,7 @@ exports[`JiraImportForm table body shows correct information in each cell 1`] =
<button
aria-expanded="false"
aria-haspopup="true"
- class="btn dropdown-toggle btn-default btn-md gl-button gl-dropdown-toggle btn-default-tertiary"
+ class="btn dropdown-toggle btn-default btn-md gl-button gl-dropdown-toggle"
type="button"
>
<!---->
@@ -201,7 +201,7 @@ exports[`JiraImportForm table body shows correct information in each cell 1`] =
<button
aria-expanded="false"
aria-haspopup="true"
- class="btn dropdown-toggle btn-default btn-md gl-button gl-dropdown-toggle btn-default-tertiary"
+ class="btn dropdown-toggle btn-default btn-md gl-button gl-dropdown-toggle"
type="button"
>
<!---->
diff --git a/spec/frontend/monitoring/components/__snapshots__/dashboard_template_spec.js.snap b/spec/frontend/monitoring/components/__snapshots__/dashboard_template_spec.js.snap
index 645aca0b157..17720aeb702 100644
--- a/spec/frontend/monitoring/components/__snapshots__/dashboard_template_spec.js.snap
+++ b/spec/frontend/monitoring/components/__snapshots__/dashboard_template_spec.js.snap
@@ -33,7 +33,7 @@ exports[`Dashboard template matches the default snapshot 1`] = `
class="mb-2 pr-2 d-flex d-sm-block"
>
<gl-dropdown-stub
- category="tertiary"
+ category="primary"
class="flex-grow-1"
data-qa-selector="environments_dropdown"
headertext=""
diff --git a/spec/frontend/pages/projects/graphs/__snapshots__/code_coverage_spec.js.snap b/spec/frontend/pages/projects/graphs/__snapshots__/code_coverage_spec.js.snap
index 30cc87242d0..324c9788309 100644
--- a/spec/frontend/pages/projects/graphs/__snapshots__/code_coverage_spec.js.snap
+++ b/spec/frontend/pages/projects/graphs/__snapshots__/code_coverage_spec.js.snap
@@ -10,7 +10,7 @@ exports[`Code Coverage when fetching data is successful matches the snapshot 1`]
<!---->
<gl-dropdown-stub
- category="tertiary"
+ category="primary"
headertext=""
size="medium"
text="rspec"
diff --git a/spec/frontend/vue_shared/components/__snapshots__/split_button_spec.js.snap b/spec/frontend/vue_shared/components/__snapshots__/split_button_spec.js.snap
index 9d160eb5ba4..dd88ba9a6fb 100644
--- a/spec/frontend/vue_shared/components/__snapshots__/split_button_spec.js.snap
+++ b/spec/frontend/vue_shared/components/__snapshots__/split_button_spec.js.snap
@@ -2,7 +2,7 @@
exports[`SplitButton renders actionItems 1`] = `
<gl-dropdown-stub
- category="tertiary"
+ category="primary"
headertext=""
menu-class=""
size="medium"
diff --git a/spec/initializers/secret_token_spec.rb b/spec/initializers/secret_token_spec.rb
index 51a14aca4ad..ab16dbad3fc 100644
--- a/spec/initializers/secret_token_spec.rb
+++ b/spec/initializers/secret_token_spec.rb
@@ -24,7 +24,7 @@ RSpec.describe 'create_tokens' do
describe 'ensure acknowledged secrets in any installations' do
let(:acknowledged_secrets) do
- %w[secret_key_base otp_key_base db_key_base openid_connect_signing_key]
+ %w[secret_key_base otp_key_base db_key_base openid_connect_signing_key encrypted_settings_key_base rotated_encrypted_settings_key_base]
end
it 'does not allow to add a new secret without a proper handling' do
@@ -90,6 +90,7 @@ RSpec.describe 'create_tokens' do
expect(new_secrets['otp_key_base']).to eq(secrets.otp_key_base)
expect(new_secrets['db_key_base']).to eq(secrets.db_key_base)
expect(new_secrets['openid_connect_signing_key']).to eq(secrets.openid_connect_signing_key)
+ expect(new_secrets['encrypted_settings_key_base']).to eq(secrets.encrypted_settings_key_base)
end
create_tokens
@@ -106,6 +107,7 @@ RSpec.describe 'create_tokens' do
before do
secrets.db_key_base = 'db_key_base'
secrets.openid_connect_signing_key = 'openid_connect_signing_key'
+ secrets.encrypted_settings_key_base = 'encrypted_settings_key_base'
allow(File).to receive(:exist?).with('.secret').and_return(true)
stub_file_read('.secret', content: 'file_key')
@@ -158,6 +160,7 @@ RSpec.describe 'create_tokens' do
expect(secrets.otp_key_base).to eq('otp_key_base')
expect(secrets.db_key_base).to eq('db_key_base')
expect(secrets.openid_connect_signing_key).to eq('openid_connect_signing_key')
+ expect(secrets.encrypted_settings_key_base).to eq('encrypted_settings_key_base')
end
it 'deletes the .secret file' do
@@ -208,12 +211,34 @@ RSpec.describe 'create_tokens' do
create_tokens
end
end
+
+ context 'when rotated_encrypted_settings_key_base does not exist' do
+ before do
+ secrets.secret_key_base = 'secret_key_base'
+ secrets.otp_key_base = 'otp_key_base'
+ secrets.openid_connect_signing_key = 'openid_connect_signing_key'
+ secrets.encrypted_settings_key_base = 'encrypted_settings_key_base'
+ end
+
+ it 'does not warn about the missing secrets' do
+ expect(self).not_to receive(:warn_missing_secret).with('rotated_encrypted_settings_key_base')
+
+ create_tokens
+ end
+
+ it 'does not update secrets.yml' do
+ expect(File).not_to receive(:write)
+
+ create_tokens
+ end
+ end
end
context 'when db_key_base is blank but exists in secrets.yml' do
before do
secrets.otp_key_base = 'otp_key_base'
secrets.secret_key_base = 'secret_key_base'
+ secrets.encrypted_settings_key_base = 'encrypted_settings_key_base'
yaml_secrets = secrets.to_h.stringify_keys.merge('db_key_base' => '<%= an_erb_expression %>')
allow(File).to receive(:exist?).with('.secret').and_return(false)
diff --git a/spec/lib/gitlab/encrypted_configuration_spec.rb b/spec/lib/gitlab/encrypted_configuration_spec.rb
new file mode 100644
index 00000000000..eadc2cf71a7
--- /dev/null
+++ b/spec/lib/gitlab/encrypted_configuration_spec.rb
@@ -0,0 +1,145 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+RSpec.describe Gitlab::EncryptedConfiguration do
+ subject(:configuration) { described_class.new }
+
+ let!(:config_tmp_dir) { Dir.mktmpdir('config-') }
+
+ after do
+ FileUtils.rm_f(config_tmp_dir)
+ end
+
+ describe '#initialize' do
+ it 'accepts all args as optional fields' do
+ expect { configuration }.not_to raise_exception
+
+ expect(configuration.key).to be_nil
+ expect(configuration.previous_keys).to be_empty
+ end
+
+ it 'generates 32 byte key when provided a larger base key' do
+ configuration = described_class.new(base_key: 'A' * 64)
+
+ expect(configuration.key.bytesize).to eq 32
+ end
+
+ it 'generates 32 byte key when provided a smaller base key' do
+ configuration = described_class.new(base_key: 'A' * 16)
+
+ expect(configuration.key.bytesize).to eq 32
+ end
+
+ it 'throws an error when the base key is too small' do
+ expect { described_class.new(base_key: 'A' * 12) }.to raise_error 'Base key too small'
+ end
+ end
+
+ context 'when provided a config file but no key' do
+ let(:config_path) { File.join(config_tmp_dir, 'credentials.yml.enc') }
+
+ it 'throws an error when writing without a key' do
+ expect { described_class.new(content_path: config_path).write('test') }.to raise_error Gitlab::EncryptedConfiguration::MissingKeyError
+ end
+
+ it 'throws an error when reading without a key' do
+ config = described_class.new(content_path: config_path)
+ File.write(config_path, 'test')
+ expect { config.read }.to raise_error Gitlab::EncryptedConfiguration::MissingKeyError
+ end
+ end
+
+ context 'when provided key and config file' do
+ let(:credentials_config_path) { File.join(config_tmp_dir, 'credentials.yml.enc') }
+ let(:credentials_key) { SecureRandom.hex(64) }
+
+ describe '#write' do
+ it 'encrypts the file using the provided key' do
+ encryptor = ActiveSupport::MessageEncryptor.new(Gitlab::EncryptedConfiguration.generate_key(credentials_key), cipher: 'aes-256-gcm')
+ config = described_class.new(content_path: credentials_config_path, base_key: credentials_key)
+
+ config.write('sample-content')
+ expect(encryptor.decrypt_and_verify(File.read(credentials_config_path))).to eq('sample-content')
+ end
+ end
+
+ describe '#read' do
+ it 'reads yaml configuration' do
+ config = described_class.new(content_path: credentials_config_path, base_key: credentials_key)
+
+ config.write({ foo: { bar: true } }.to_yaml)
+ expect(config[:foo][:bar]).to be true
+ end
+
+ it 'allows referencing top level keys via dot syntax' do
+ config = described_class.new(content_path: credentials_config_path, base_key: credentials_key)
+
+ config.write({ foo: { bar: true } }.to_yaml)
+ expect(config.foo[:bar]).to be true
+ end
+
+ it 'throws a custom error when referencing an invalid key map config' do
+ config = described_class.new(content_path: credentials_config_path, base_key: credentials_key)
+
+ config.write("stringcontent")
+ expect { config[:foo] }.to raise_error Gitlab::EncryptedConfiguration::InvalidConfigError
+ end
+ end
+
+ describe '#change' do
+ it 'changes yaml configuration' do
+ config = described_class.new(content_path: credentials_config_path, base_key: credentials_key)
+
+ config.write({ foo: { bar: true } }.to_yaml)
+ config.change do |unencrypted_contents|
+ contents = YAML.safe_load(unencrypted_contents, permitted_classes: [Symbol])
+ contents.merge(beef: "stew").to_yaml
+ end
+ expect(config.foo[:bar]).to be true
+ expect(config.beef).to eq('stew')
+ end
+ end
+
+ context 'when provided previous_keys for rotation' do
+ let(:credential_key_original) { SecureRandom.hex(64) }
+ let(:credential_key_latest) { SecureRandom.hex(64) }
+ let(:config_path_original) { File.join(config_tmp_dir, 'credentials-orig.yml.enc') }
+ let(:config_path_latest) { File.join(config_tmp_dir, 'credentials-latest.yml.enc') }
+
+ def encryptor(key)
+ ActiveSupport::MessageEncryptor.new(Gitlab::EncryptedConfiguration.generate_key(key), cipher: 'aes-256-gcm')
+ end
+
+ describe '#write' do
+ it 'rotates the key when provided a new key' do
+ config1 = described_class.new(content_path: config_path_original, base_key: credential_key_original)
+ config1.write('sample-content1')
+
+ config2 = described_class.new(content_path: config_path_latest, base_key: credential_key_latest, previous_keys: [credential_key_original])
+ config2.write('sample-content2')
+
+ original_key_encryptor = encryptor(credential_key_original) # can read with the initial key
+ latest_key_encryptor = encryptor(credential_key_latest) # can read with the new key
+ both_key_encryptor = encryptor(credential_key_latest) # can read with either key
+ both_key_encryptor.rotate(Gitlab::EncryptedConfiguration.generate_key(credential_key_original))
+
+ expect(original_key_encryptor.decrypt_and_verify(File.read(config_path_original))).to eq('sample-content1')
+ expect(both_key_encryptor.decrypt_and_verify(File.read(config_path_original))).to eq('sample-content1')
+ expect(latest_key_encryptor.decrypt_and_verify(File.read(config_path_latest))).to eq('sample-content2')
+ expect(both_key_encryptor.decrypt_and_verify(File.read(config_path_latest))).to eq('sample-content2')
+ expect { original_key_encryptor.decrypt_and_verify(File.read(config_path_latest)) }.to raise_error(ActiveSupport::MessageEncryptor::InvalidMessage)
+ end
+ end
+
+ describe '#read' do
+ it 'supports reading using rotated config' do
+ described_class.new(content_path: config_path_original, base_key: credential_key_original).write({ foo: { bar: true } }.to_yaml)
+
+ config = described_class.new(content_path: config_path_original, base_key: credential_key_latest, previous_keys: [credential_key_original])
+ expect(config[:foo][:bar]).to be true
+ end
+ end
+ end
+ end
+end
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index f9c06b20d9c..0ca35476233 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -1535,6 +1535,42 @@ RSpec.describe Project, factory_default: :keep do
end
end
+ describe '.service_desk_custom_address_enabled?' do
+ let_it_be(:project) { create(:project, service_desk_enabled: true) }
+
+ subject(:address_enabled) { project.service_desk_custom_address_enabled? }
+
+ context 'when service_desk_email is enabled' do
+ before do
+ allow(::Gitlab::ServiceDeskEmail).to receive(:enabled?).and_return(true)
+ end
+
+ it 'returns true' do
+ expect(address_enabled).to be_truthy
+ end
+
+ context 'when service_desk_custom_address flag is disabled' do
+ before do
+ stub_feature_flags(service_desk_custom_address: false)
+ end
+
+ it 'returns false' do
+ expect(address_enabled).to be_falsey
+ end
+ end
+ end
+
+ context 'when service_desk_email is disabled' do
+ before do
+ allow(::Gitlab::ServiceDeskEmail).to receive(:enabled?).and_return(false)
+ end
+
+ it 'returns false when service_desk_email is disabled' do
+ expect(address_enabled).to be_falsey
+ end
+ end
+ end
+
describe '.find_by_service_desk_project_key' do
it 'returns the correct project' do
project1 = create(:project)