Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2021-04-16 09:09:16 +00:00
parent 1b668e02bd
commit f079dd371c
29 changed files with 442 additions and 61 deletions

View file

@ -592,12 +592,6 @@ RSpec/EmptyLineAfterFinalLetItBe:
- ee/spec/services/requirements_management/update_requirement_service_spec.rb
- ee/spec/services/resource_access_tokens/create_service_spec.rb
- ee/spec/services/resource_access_tokens/revoke_service_spec.rb
- ee/spec/services/status_page/publish_attachments_service_spec.rb
- ee/spec/services/status_page/publish_details_service_spec.rb
- ee/spec/services/status_page/publish_list_service_spec.rb
- ee/spec/services/status_page/publish_service_spec.rb
- ee/spec/services/status_page/trigger_publish_service_spec.rb
- ee/spec/services/status_page/unpublish_details_service_spec.rb
- ee/spec/services/todo_service_spec.rb
- ee/spec/support/shared_examples/graphql/geo/geo_registries_resolver_shared_examples.rb
- ee/spec/support/shared_examples/graphql/mutations/set_multiple_assignees_shared_examples.rb

View file

@ -46,6 +46,7 @@ export default {
:loading-text="groupedSummaryText"
:error-text="groupedSummaryText"
:has-issues="shouldRenderIssuesList"
track-action="users_expanding_testing_accessibility_report"
class="mr-widget-section grouped-security-reports mr-report"
>
<template #body>

View file

@ -87,6 +87,7 @@ export default {
:component="$options.componentNames.CodequalityIssueBody"
:popover-options="codequalityPopover"
:show-report-section-status-icon="false"
track-action="users_expanding_testing_code_quality_report"
class="js-codequality-widget mr-widget-border-top mr-report"
>
<template v-if="hasError" #sub-heading>{{ statusReason }}</template>

View file

@ -1,8 +1,10 @@
<script>
import { GlButton } from '@gitlab/ui';
import api from '~/api';
import { __ } from '~/locale';
import StatusIcon from '~/vue_merge_request_widget/components/mr_widget_status_icon.vue';
import Popover from '~/vue_shared/components/help_popover.vue';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { status, SLOT_SUCCESS, SLOT_LOADING, SLOT_ERROR } from '../constants';
import IssuesList from './issues_list.vue';
@ -14,6 +16,7 @@ export default {
Popover,
StatusIcon,
},
mixins: [glFeatureFlagsMixin()],
props: {
alwaysOpen: {
type: Boolean,
@ -98,6 +101,11 @@ export default {
required: false,
default: false,
},
trackAction: {
type: String,
required: false,
default: null,
},
},
data() {
@ -164,6 +172,10 @@ export default {
},
methods: {
toggleCollapsed() {
if (this.trackAction && this.glFeatures.usersExpandingWidgetsUsageData) {
api.trackRedisHllUserEvent(this.trackAction);
}
if (this.shouldEmitToggleEvent) {
this.$emit('toggleEvent');
}

View file

@ -184,6 +184,7 @@ export default {
:has-issues="false"
class="mr-widget-border-top mr-report"
data-testid="security-mr-widget"
track-action="users_expanding_secure_security_report"
>
<template v-for="slot in $options.summarySlots" #[slot]>
<span :key="slot">
@ -212,6 +213,7 @@ export default {
:has-issues="false"
class="mr-widget-border-top mr-report"
data-testid="security-mr-widget"
track-action="users_expanding_secure_security_report"
>
<template #error>
{{ $options.i18n.scansHaveRun }}

View file

@ -43,6 +43,9 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
push_frontend_feature_flag(:usage_data_i_testing_summary_widget_total, @project, default_enabled: :yaml)
push_frontend_feature_flag(:improved_emoji_picker, project, default_enabled: :yaml)
# Usage data feature flags
push_frontend_feature_flag(:users_expanding_widgets_usage_data, @project, default_enabled: :yaml)
record_experiment_user(:invite_members_version_b)
experiment(:invite_members_in_comment, namespace: @project.root_ancestor) do |experiment_instance|

View file

@ -42,14 +42,14 @@ module TokenAuthenticatableStrategies
return insecure_strategy.get_token(instance) if migrating?
encrypted_token = instance.read_attribute(encrypted_field)
token = Gitlab::CryptoHelper.aes256_gcm_decrypt(encrypted_token)
token = EncryptionHelper.decrypt_token(encrypted_token)
token || (insecure_strategy.get_token(instance) if optional?)
end
def set_token(instance, token)
raise ArgumentError unless token.present?
instance[encrypted_field] = Gitlab::CryptoHelper.aes256_gcm_encrypt(token)
instance[encrypted_field] = EncryptionHelper.encrypt_token(token)
instance[token_field] = token if migrating?
instance[token_field] = nil if optional?
token
@ -85,10 +85,9 @@ module TokenAuthenticatableStrategies
end
def find_by_encrypted_token(token, unscoped)
nonce = Gitlab::CryptoHelper::AES256_GCM_IV_STATIC
encrypted_value = Gitlab::CryptoHelper.aes256_gcm_encrypt(token, nonce: nonce)
relation(unscoped).find_by(encrypted_field => encrypted_value)
encrypted_value = EncryptionHelper.encrypt_token(token)
token_encrypted_with_static_iv = Gitlab::CryptoHelper.aes256_gcm_encrypt(token)
relation(unscoped).find_by(encrypted_field => [encrypted_value, token_encrypted_with_static_iv])
end
def insecure_strategy

View file

@ -0,0 +1,26 @@
# frozen_string_literal: true
module TokenAuthenticatableStrategies
class EncryptionHelper
DYNAMIC_NONCE_IDENTIFIER = "|"
NONCE_SIZE = 12
def self.encrypt_token(plaintext_token)
Gitlab::CryptoHelper.aes256_gcm_encrypt(plaintext_token)
end
def self.decrypt_token(token)
return unless token
# The pattern of the token is "#{DYNAMIC_NONCE_IDENTIFIER}#{token}#{iv_of_12_characters}"
if token.start_with?(DYNAMIC_NONCE_IDENTIFIER) && token.size > NONCE_SIZE + DYNAMIC_NONCE_IDENTIFIER.size
token_to_decrypt = token[1...-NONCE_SIZE]
iv = token[-NONCE_SIZE..-1]
Gitlab::CryptoHelper.aes256_gcm_decrypt(token_to_decrypt, nonce: iv)
else
Gitlab::CryptoHelper.aes256_gcm_decrypt(token)
end
end
end
end

View file

@ -4,18 +4,26 @@ module Issuable
class DestroyService < IssuableBaseService
def execute(issuable)
if issuable.destroy
delete_todos(issuable)
issuable.update_project_counter_caches
issuable.assignees.each(&:invalidate_cache_counts)
after_destroy(issuable)
end
end
private
def delete_todos(issuable)
actor = issuable.is_a?(Epic) ? issuable.resource_parent : issuable.resource_parent.group
def after_destroy(issuable)
delete_todos(issuable)
issuable.update_project_counter_caches
issuable.assignees.each(&:invalidate_cache_counts)
end
if Feature.enabled?(:destroy_issuable_todos_async, actor, default_enabled: :yaml)
def group_for(issuable)
issuable.resource_parent
end
def delete_todos(issuable)
group = group_for(issuable)
if Feature.enabled?(:destroy_issuable_todos_async, group, default_enabled: :yaml)
TodosDestroyer::DestroyedIssuableWorker
.perform_async(issuable.id, issuable.class.name)
else
@ -26,3 +34,5 @@ module Issuable
end
end
end
Issuable::DestroyService.prepend_if_ee('EE::Issuable::DestroyService')

View file

@ -0,0 +1,8 @@
---
name: users_expanding_widgets_usage_data
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57133
rollout_issue_url:
milestone: '13.11'
type: development
group: group::code review
default_enabled: true

View file

@ -0,0 +1,20 @@
---
key_path: redis_hll_counters.secure.users_expanding_secure_security_report_monthly
description: Count of expanding the security report widget
product_section: sec
product_stage: secure
product_group: group::static analysis
product_category: dependency_scanning
value_type: number
status: implemented
milestone: '13.11'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57133
time_frame: 28d
data_source: redis_hll
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate

View file

@ -0,0 +1,20 @@
---
key_path: redis_hll_counters.testing.users_expanding_testing_code_quality_report_monthly
description: Count of expanding the code quality widget
product_section: ops
product_stage: verify
product_group: group::testing
product_category: code_quality
value_type: number
status: implemented
milestone: '13.11'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57133
time_frame: 28d
data_source: redis_hll
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate

View file

@ -0,0 +1,20 @@
---
key_path: redis_hll_counters.testing.users_expanding_testing_accessibility_report_monthly
description: Count of expanding the accessibility report widget
product_section: ops
product_stage: verify
product_group: group::testing
product_category: accessibility_testing
value_type: number
status: implemented
milestone: '13.11'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57133
time_frame: 28d
data_source: redis_hll
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate

View file

@ -0,0 +1,20 @@
---
key_path: redis_hll_counters.secure.users_expanding_secure_security_report_weekly
description: Count of expanding the security report widget
product_section: sec
product_stage: secure
product_group: group::static analysis
product_category: dependency_scanning
value_type: number
status: implemented
milestone: '13.11'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57133
time_frame: 7d
data_source: redis_hll
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate

View file

@ -0,0 +1,20 @@
---
key_path: redis_hll_counters.testing.users_expanding_testing_code_quality_report_weekly
description: Count of expanding the code quality widget
product_section: ops
product_stage: verify
product_group: group::testing
product_category: code_quality
value_type: number
status: implemented
milestone: '13.11'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57133
time_frame: 7d
data_source: redis_hll
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate

View file

@ -0,0 +1,20 @@
---
key_path: redis_hll_counters.testing.users_expanding_testing_accessibility_report_weekly
description: Count of expanding the accessibility report widget
product_section: ops
product_stage: verify
product_group: group::testing
product_category: accessibility_testing
value_type: number
status: implemented
milestone: '13.11'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57133
time_frame: 7d
data_source: redis_hll
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate

View file

@ -9872,6 +9872,30 @@ Status: `data_available`
Tiers: `premium`, `ultimate`
### `redis_hll_counters.epics_usage.g_project_management_epic_destroyed_monthly`
Count of MAU destroying epics
[YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/config/metrics/counts_28d/20210413174710_g_project_management_epic_destroyed_monthly.yml)
Group: `group::product planning`
Status: `implemented`
Tiers: `premium`, `ultimate`
### `redis_hll_counters.epics_usage.g_project_management_epic_destroyed_weekly`
Count of WAU destroying epics
[YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/config/metrics/counts_7d/20210413174449_g_project_management_epic_destroyed_weekly.yml)
Group: `group::product planning`
Status: `implemented`
Tiers: `premium`, `ultimate`
### `redis_hll_counters.epics_usage.g_project_management_epic_issue_added_monthly`
Count of MAU adding issues to epics
@ -13448,6 +13472,30 @@ Status: `data_available`
Tiers: `free`, `premium`, `ultimate`
### `redis_hll_counters.secure.users_expanding_secure_security_report_monthly`
Count of expanding the security report widget
[YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/counts_28d/20210409095855_users_expanding_secure_security_report_monthly.yml)
Group: `group::static analysis`
Status: `implemented`
Tiers: `free`, `premium`, `ultimate`
### `redis_hll_counters.secure.users_expanding_secure_security_report_weekly`
Count of expanding the security report widget
[YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/counts_7d/20210409095855_users_expanding_secure_security_report_weekly.yml)
Group: `group::static analysis`
Status: `implemented`
Tiers: `free`, `premium`, `ultimate`
### `redis_hll_counters.snippets.i_snippets_show_monthly`
Missing description
@ -13880,6 +13928,54 @@ Status: `removed`
Tiers: `premium`, `ultimate`
### `redis_hll_counters.testing.users_expanding_testing_accessibility_report_monthly`
Count of expanding the accessibility report widget
[YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/counts_28d/20210409100628_users_expanding_testing_accessibility_report_monthly.yml)
Group: `group::testing`
Status: `implemented`
Tiers: `free`, `premium`, `ultimate`
### `redis_hll_counters.testing.users_expanding_testing_accessibility_report_weekly`
Count of expanding the accessibility report widget
[YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/counts_7d/20210409100628_users_expanding_testing_accessibility_report_weekly.yml)
Group: `group::testing`
Status: `implemented`
Tiers: `free`, `premium`, `ultimate`
### `redis_hll_counters.testing.users_expanding_testing_code_quality_report_monthly`
Count of expanding the code quality widget
[YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/counts_28d/20210409100451_users_expanding_testing_code_quality_report_monthly.yml)
Group: `group::testing`
Status: `implemented`
Tiers: `free`, `premium`, `ultimate`
### `redis_hll_counters.testing.users_expanding_testing_code_quality_report_weekly`
Count of expanding the code quality widget
[YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/counts_7d/20210409100451_users_expanding_testing_code_quality_report_weekly.yml)
Group: `group::testing`
Status: `implemented`
Tiers: `free`, `premium`, `ultimate`
### `redis_hll_counters.user_packages.i_package_composer_user_monthly`
Missing description

View file

@ -16,30 +16,17 @@ module Gitlab
::Digest::SHA256.base64digest("#{value}#{salt}")
end
def aes256_gcm_encrypt(value, nonce: nil)
aes256_gcm_encrypt_using_static_nonce(value)
def aes256_gcm_encrypt(value, nonce: AES256_GCM_IV_STATIC)
encrypted_token = Encryptor.encrypt(AES256_GCM_OPTIONS.merge(value: value, iv: nonce))
Base64.strict_encode64(encrypted_token)
end
def aes256_gcm_decrypt(value)
def aes256_gcm_decrypt(value, nonce: AES256_GCM_IV_STATIC)
return unless value
nonce = AES256_GCM_IV_STATIC
encrypted_token = Base64.decode64(value)
decrypted_token = Encryptor.decrypt(AES256_GCM_OPTIONS.merge(value: encrypted_token, iv: nonce))
decrypted_token
end
def aes256_gcm_encrypt_using_static_nonce(value)
create_encrypted_token(value, AES256_GCM_IV_STATIC)
end
def read_only?
Gitlab::Database.read_only?
end
def create_encrypted_token(value, iv)
encrypted_token = Encryptor.encrypt(AES256_GCM_OPTIONS.merge(value: value, iv: iv))
Base64.strict_encode64(encrypted_token)
end
end
end

View file

@ -460,3 +460,19 @@
redis_slot: pipeline_authoring
aggregation: weekly
feature_flag: usage_data_o_pipeline_authoring_unique_users_pushing_mr_ciconfigfile
# Merge request widgets
- name: users_expanding_secure_security_report
redis_slot: secure
category: secure
aggregation: weekly
feature_flag: users_expanding_widgets_usage_data
- name: users_expanding_testing_code_quality_report
redis_slot: testing
category: testing
aggregation: weekly
feature_flag: users_expanding_widgets_usage_data
- name: users_expanding_testing_accessibility_report
redis_slot: testing
category: testing
aggregation: weekly
feature_flag: users_expanding_widgets_usage_data

View file

@ -134,3 +134,9 @@
redis_slot: project_management
aggregation: daily
feature_flag: track_epics_activity
- name: g_project_management_epic_destroyed
category: epics_usage
redis_slot: project_management
aggregation: daily
feature_flag: track_epics_activity

View file

@ -51,7 +51,7 @@
"@gitlab/favicon-overlay": "2.0.0",
"@gitlab/svgs": "1.189.0",
"@gitlab/tributejs": "1.0.0",
"@gitlab/ui": "29.5.0",
"@gitlab/ui": "29.6.0",
"@gitlab/visual-review-tools": "1.6.1",
"@rails/actioncable": "^6.0.3-4",
"@rails/ujs": "^6.0.3-4",

View file

@ -57,7 +57,6 @@ module DeprecationToolkitEnv
%w[
activerecord-6.0.3.6/lib/active_record/migration.rb
activesupport-6.0.3.6/lib/active_support/cache.rb
batch-loader-1.4.0/lib/batch_loader/graphql.rb
carrierwave-1.3.1/lib/carrierwave/sanitized_file.rb
activerecord-6.0.3.6/lib/active_record/relation.rb
selenium-webdriver-3.142.7/lib/selenium/webdriver/firefox/driver.rb

View file

@ -20,15 +20,21 @@ RSpec.describe Gitlab::CryptoHelper do
expect(encrypted).not_to include "\n"
end
it 'does not save hashed token with iv value in database' do
expect { described_class.aes256_gcm_encrypt('some-value') }.not_to change { TokenWithIv.count }
end
it 'encrypts using static iv' do
expect(Encryptor).to receive(:encrypt).with(described_class::AES256_GCM_OPTIONS.merge(value: 'some-value', iv: described_class::AES256_GCM_IV_STATIC)).and_return('hashed_value')
described_class.aes256_gcm_encrypt('some-value')
end
context 'with provided iv' do
let(:iv) { create_nonce }
it 'encrypts using provided iv' do
expect(Encryptor).to receive(:encrypt).with(described_class::AES256_GCM_OPTIONS.merge(value: 'some-value', iv: iv)).and_return('hashed_value')
described_class.aes256_gcm_encrypt('some-value', nonce: iv)
end
end
end
describe '.aes256_gcm_decrypt' do
@ -46,10 +52,22 @@ RSpec.describe Gitlab::CryptoHelper do
expect(decrypted).to eq 'some-value'
end
end
it 'does not save hashed token with iv value in database' do
expect { described_class.aes256_gcm_decrypt(encrypted) }.not_to change { TokenWithIv.count }
context 'when token was encrypted using random nonce' do
let(:value) { 'random-value' }
let(:iv) { create_nonce }
let(:encrypted) { described_class.aes256_gcm_encrypt(value, nonce: iv) }
it 'correctly decrypts encrypted string' do
decrypted = described_class.aes256_gcm_decrypt(encrypted, nonce: iv)
expect(decrypted).to eq value
end
end
end
def create_nonce
::Digest::SHA256.hexdigest('my-value').bytes.take(TokenAuthenticatableStrategies::EncryptionHelper::NONCE_SIZE).pack('c*')
end
end

View file

@ -44,7 +44,8 @@ RSpec.describe Gitlab::UsageDataCounters::HLLRedisCounter, :clean_gitlab_redis_s
'ci_templates',
'quickactions',
'pipeline_authoring',
'epics_usage'
'epics_usage',
'secure'
)
end
end

View file

@ -1362,7 +1362,7 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
let(:categories) { ::Gitlab::UsageDataCounters::HLLRedisCounter.categories }
let(:ineligible_total_categories) do
%w[source_code ci_secrets_management incident_management_alerts snippets terraform incident_management_oncall]
%w[source_code ci_secrets_management incident_management_alerts snippets terraform incident_management_oncall secure]
end
context 'with redis_hll_tracking feature enabled' do

View file

@ -54,7 +54,7 @@ RSpec.describe ApplicationSetting, 'TokenAuthenticatable' do
it 'persists new token as an encrypted string' do
expect(subject).to eq settings.reload.runners_registration_token
expect(settings.read_attribute('runners_registration_token_encrypted'))
.to eq Gitlab::CryptoHelper.aes256_gcm_encrypt(subject, nonce: Gitlab::CryptoHelper::AES256_GCM_IV_STATIC)
.to eq TokenAuthenticatableStrategies::EncryptionHelper.encrypt_token(subject)
expect(settings).to be_persisted
end
@ -243,7 +243,7 @@ RSpec.describe Ci::Build, 'TokenAuthenticatable' do
it 'persists new token as an encrypted string' do
build.ensure_token!
encrypted = Gitlab::CryptoHelper.aes256_gcm_encrypt(build.token, nonce: Gitlab::CryptoHelper::AES256_GCM_IV_STATIC)
encrypted = TokenAuthenticatableStrategies::EncryptionHelper.encrypt_token(build.token)
expect(build.read_attribute('token_encrypted')).to eq encrypted
end

View file

@ -7,6 +7,10 @@ RSpec.describe TokenAuthenticatableStrategies::Encrypted do
let(:instance) { double(:instance) }
let(:encrypted) do
TokenAuthenticatableStrategies::EncryptionHelper.encrypt_token('my-value')
end
let(:encrypted_with_static_iv) do
Gitlab::CryptoHelper.aes256_gcm_encrypt('my-value')
end
@ -15,12 +19,25 @@ RSpec.describe TokenAuthenticatableStrategies::Encrypted do
end
describe '#find_token_authenticatable' do
context 'when using optional strategy' do
context 'when encryption is required' do
let(:options) { { encrypted: :required } }
it 'finds the encrypted resource by cleartext' do
allow(model).to receive(:find_by)
.with('some_field_encrypted' => [encrypted, encrypted_with_static_iv])
.and_return('encrypted resource')
expect(subject.find_token_authenticatable('my-value'))
.to eq 'encrypted resource'
end
end
context 'when encryption is optional' do
let(:options) { { encrypted: :optional } }
it 'finds the encrypted resource by cleartext' do
allow(model).to receive(:find_by)
.with('some_field_encrypted' => encrypted)
.with('some_field_encrypted' => [encrypted, encrypted_with_static_iv])
.and_return('encrypted resource')
expect(subject.find_token_authenticatable('my-value'))
@ -33,7 +50,7 @@ RSpec.describe TokenAuthenticatableStrategies::Encrypted do
.and_return('plaintext resource')
allow(model).to receive(:find_by)
.with('some_field_encrypted' => encrypted)
.with('some_field_encrypted' => [encrypted, encrypted_with_static_iv])
.and_return(nil)
expect(subject.find_token_authenticatable('my-value'))
@ -41,7 +58,7 @@ RSpec.describe TokenAuthenticatableStrategies::Encrypted do
end
end
context 'when using migration strategy' do
context 'when encryption is migrating' do
let(:options) { { encrypted: :migrating } }
it 'finds the cleartext resource by cleartext' do
@ -65,7 +82,27 @@ RSpec.describe TokenAuthenticatableStrategies::Encrypted do
end
describe '#get_token' do
context 'when using optional strategy' do
context 'when encryption is required' do
let(:options) { { encrypted: :required } }
it 'returns decrypted token when an encrypted with static iv token is present' do
allow(instance).to receive(:read_attribute)
.with('some_field_encrypted')
.and_return(Gitlab::CryptoHelper.aes256_gcm_encrypt('my-test-value'))
expect(subject.get_token(instance)).to eq 'my-test-value'
end
it 'returns decrypted token when an encrypted token is present' do
allow(instance).to receive(:read_attribute)
.with('some_field_encrypted')
.and_return(encrypted)
expect(subject.get_token(instance)).to eq 'my-value'
end
end
context 'when encryption is optional' do
let(:options) { { encrypted: :optional } }
it 'returns decrypted token when an encrypted token is present' do
@ -76,6 +113,14 @@ RSpec.describe TokenAuthenticatableStrategies::Encrypted do
expect(subject.get_token(instance)).to eq 'my-value'
end
it 'returns decrypted token when an encrypted with static iv token is present' do
allow(instance).to receive(:read_attribute)
.with('some_field_encrypted')
.and_return(Gitlab::CryptoHelper.aes256_gcm_encrypt('my-test-value'))
expect(subject.get_token(instance)).to eq 'my-test-value'
end
it 'returns the plaintext token when encrypted token is not present' do
allow(instance).to receive(:read_attribute)
.with('some_field_encrypted')
@ -89,7 +134,7 @@ RSpec.describe TokenAuthenticatableStrategies::Encrypted do
end
end
context 'when using migration strategy' do
context 'when encryption is migrating' do
let(:options) { { encrypted: :migrating } }
it 'returns cleartext token when an encrypted token is present' do
@ -119,12 +164,22 @@ RSpec.describe TokenAuthenticatableStrategies::Encrypted do
end
describe '#set_token' do
context 'when using optional strategy' do
context 'when encryption is required' do
let(:options) { { encrypted: :required } }
it 'writes encrypted token and returns it' do
expect(instance).to receive(:[]=)
.with('some_field_encrypted', encrypted)
expect(subject.set_token(instance, 'my-value')).to eq 'my-value'
end
end
context 'when encryption is optional' do
let(:options) { { encrypted: :optional } }
it 'writes encrypted token and removes plaintext token and returns it' do
expect(instance).to receive(:[]=)
.with('some_field_encrypted', any_args)
.with('some_field_encrypted', encrypted)
expect(instance).to receive(:[]=)
.with('some_field', nil)
@ -132,12 +187,12 @@ RSpec.describe TokenAuthenticatableStrategies::Encrypted do
end
end
context 'when using migration strategy' do
context 'when encryption is migrating' do
let(:options) { { encrypted: :migrating } }
it 'writes encrypted token and writes plaintext token' do
expect(instance).to receive(:[]=)
.with('some_field_encrypted', any_args)
.with('some_field_encrypted', encrypted)
expect(instance).to receive(:[]=)
.with('some_field', 'my-value')

View file

@ -0,0 +1,27 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe TokenAuthenticatableStrategies::EncryptionHelper do
let(:encrypted_token) { described_class.encrypt_token('my-value') }
describe '.encrypt_token' do
it 'encrypts token' do
expect(encrypted_token).not_to eq('my-value')
end
end
describe '.decrypt_token' do
it 'decrypts token with static iv' do
expect(described_class.decrypt_token(encrypted_token)).to eq('my-value')
end
it 'decrypts token with dynamic iv' do
iv = ::Digest::SHA256.hexdigest('my-value').bytes.take(described_class::NONCE_SIZE).pack('c*')
token = Gitlab::CryptoHelper.aes256_gcm_encrypt('my-value', nonce: iv)
encrypted_token = "#{described_class::DYNAMIC_NONCE_IDENTIFIER}#{token}#{iv}"
expect(described_class.decrypt_token(encrypted_token)).to eq('my-value')
end
end
end

View file

@ -907,10 +907,10 @@
resolved "https://registry.yarnpkg.com/@gitlab/tributejs/-/tributejs-1.0.0.tgz#672befa222aeffc83e7d799b0500a7a4418e59b8"
integrity sha512-nmKw1+hB6MHvlmPz63yPwVs1qQkycHwsKgxpEbzmky16Y6mL4EJMk3w1b8QlOAF/AIAzjCERPhe/R4MJiohbZw==
"@gitlab/ui@29.5.0":
version "29.5.0"
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-29.5.0.tgz#5f8cdf062ef69800c5a6f4a4871b7283f59de34a"
integrity sha512-ebNNKZORRIoqQRF+tCaiS17pyt9qI46ULgyUYJkXHmwQKMUL0sqXRoPMPVK6T2snzMUnyNeKBMoMxTy5BiTnNA==
"@gitlab/ui@29.6.0":
version "29.6.0"
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-29.6.0.tgz#5e8369d7aeab56edab570ef148dbc289b51901fc"
integrity sha512-bomMDBzS/S+ztFgAC23oDjMEK3cFZ3UcKJGs3iKXtCTKIxtzXKrL0LWYxkidywIwWm9L+1udgsx/GTKoVW0ItQ==
dependencies:
"@babel/standalone" "^7.0.0"
"@gitlab/vue-toasted" "^1.3.0"