Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
913af9b06e
commit
60e7627c99
|
|
@ -1228,7 +1228,7 @@ lib/gitlab/checks/** @proglottis @toon
|
|||
|
||||
[Verify] @gitlab-org/maintainers/cicd-verify
|
||||
# Verify Backend
|
||||
/**/app/**/ci/
|
||||
/**/app/**/ci/
|
||||
/**/lib/**/ci/
|
||||
/**/spec/**/ci/
|
||||
/**/app/**/merge_trains/
|
||||
|
|
@ -1347,7 +1347,7 @@ lib/gitlab/checks/** @proglottis @toon
|
|||
/**/javascripts/jobs/ @gitlab-org/ci-cd/verify/frontend
|
||||
/**/javascripts/token_access/ @gitlab-org/ci-cd/verify/frontend
|
||||
/**/javascripts/admin/application_settings/runner_token_expiration/ @gitlab-org/ci-cd/verify/frontend
|
||||
/**/javascripts/usage_quotas/pipelines/ @gitlab-org/ci-cd/verify/frontend @fulfillment-group/utilization-group/fe
|
||||
/**/javascripts/usage_quotas/pipelines/ @gitlab-org/ci-cd/verify/frontend @sheldonled @aalakkad @kpalchyk
|
||||
|
||||
[Manage::Workspace]
|
||||
lib/api/entities/basic_project_details.rb @gitlab-org/manage/manage-workspace/backend-approvers
|
||||
|
|
@ -1419,9 +1419,9 @@ ee/lib/ee/api/entities/project.rb @gitlab-org/manage/manage-workspace/backend-ap
|
|||
/lib/gitlab/audit_json_logger.rb @gitlab-org/govern/compliance
|
||||
|
||||
[Fulfillment::Utilization]
|
||||
/ee/app/assets/javascripts/usage_quotas/components/ @fulfillment-group/utilization-group/fe
|
||||
/ee/app/assets/javascripts/usage_quotas/seats/ @fulfillment-group/utilization-group/fe
|
||||
/ee/app/assets/javascripts/usage_quotas/storage/ @fulfillment-group/utilization-group/fe
|
||||
/ee/app/assets/javascripts/usage_quotas/components/ @sheldonled @aalakkad @kpalchyk
|
||||
/ee/app/assets/javascripts/usage_quotas/seats/ @sheldonled @aalakkad @kpalchyk
|
||||
/ee/app/assets/javascripts/usage_quotas/storage/ @sheldonled @aalakkad @kpalchyk
|
||||
|
||||
[Manage::Foundations]
|
||||
/lib/sidebars/ @gitlab-org/manage/foundations/engineering
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
a5d056f2e268a775f6742046e284f33bae43078b
|
||||
b8190668d147784e8be4a379b33f691363e08a0f
|
||||
|
|
|
|||
|
|
@ -132,7 +132,10 @@ export default {
|
|||
},
|
||||
watch: {
|
||||
descriptionHtml(newDescription, oldDescription) {
|
||||
if (!this.initialUpdate && newDescription !== oldDescription) {
|
||||
if (
|
||||
!this.initialUpdate &&
|
||||
this.stripClientState(newDescription) !== this.stripClientState(oldDescription)
|
||||
) {
|
||||
this.animateChange();
|
||||
} else {
|
||||
this.initialUpdate = false;
|
||||
|
|
@ -321,6 +324,9 @@ export default {
|
|||
listItem.append(element);
|
||||
}
|
||||
},
|
||||
stripClientState(description) {
|
||||
return description.replaceAll('<details open="true">', '<details>');
|
||||
},
|
||||
async createTask({ taskTitle, taskDescription, oldDescription }) {
|
||||
try {
|
||||
const { title, description } = extractTaskTitleAndDescription(taskTitle, taskDescription);
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import {
|
|||
REPORT_TYPE_SAST_IAC,
|
||||
REPORT_TYPE_DAST,
|
||||
REPORT_TYPE_DAST_PROFILES,
|
||||
REPORT_TYPE_BREACH_AND_ATTACK_SIMULATION,
|
||||
REPORT_TYPE_SECRET_DETECTION,
|
||||
REPORT_TYPE_DEPENDENCY_SCANNING,
|
||||
REPORT_TYPE_CONTAINER_SCANNING,
|
||||
|
|
@ -67,6 +68,30 @@ export const DAST_PROFILES_DESCRIPTION = s__(
|
|||
);
|
||||
export const DAST_PROFILES_CONFIG_TEXT = s__('SecurityConfiguration|Manage profiles');
|
||||
|
||||
export const BAS_BADGE_TEXT = s__('SecurityConfiguration|Incubating feature');
|
||||
export const BAS_BADGE_TOOLTIP = s__(
|
||||
'SecurityConfiguration|Breach and Attack Simulation is an incubating feature extending existing security testing by simulating adversary activity.',
|
||||
);
|
||||
export const BAS_DESCRIPTION = s__(
|
||||
'SecurityConfiguration|Simulate breach and attack scenarios against your running application by attempting to detect and exploit known vulnerabilities.',
|
||||
);
|
||||
export const BAS_HELP_PATH = helpPagePath(
|
||||
'user/application_security/breach_and_attack_simulation/index',
|
||||
);
|
||||
export const BAS_NAME = s__('SecurityConfiguration|Breach and Attack Simulation (BAS)');
|
||||
export const BAS_SHORT_NAME = s__('SecurityConfiguration|BAS');
|
||||
|
||||
export const BAS_DAST_FEATURE_FLAG_DESCRIPTION = s__(
|
||||
'SecurityConfiguration|Enable incubating Breach and Attack Simulation focused features such as callback attacks in your DAST scans.',
|
||||
);
|
||||
export const BAS_DAST_FEATURE_FLAG_HELP_PATH = helpPagePath(
|
||||
'user/application_security/breach_and_attack_simulation/index',
|
||||
{ anchor: 'extend-dynamic-application-security-testing-dast' },
|
||||
);
|
||||
export const BAS_DAST_FEATURE_FLAG_NAME = s__(
|
||||
'SecurityConfiguration|Out-of-Band Application Security Testing (OAST)',
|
||||
);
|
||||
|
||||
export const SECRET_DETECTION_NAME = __('Secret Detection');
|
||||
export const SECRET_DETECTION_DESCRIPTION = __(
|
||||
'Analyze your source code and git history for secrets.',
|
||||
|
|
@ -142,6 +167,7 @@ export const SCANNER_NAMES_MAP = {
|
|||
COVERAGE_FUZZING: COVERAGE_FUZZING_NAME,
|
||||
SECRET_DETECTION: SECRET_DETECTION_NAME,
|
||||
DEPENDENCY_SCANNING: DEPENDENCY_SCANNING_NAME,
|
||||
BAS: BAS_SHORT_NAME,
|
||||
GENERIC: s__('ciReport|Manually added'),
|
||||
};
|
||||
|
||||
|
|
@ -223,6 +249,25 @@ export const securityFeatures = [
|
|||
configurationText: CORPUS_MANAGEMENT_CONFIG_TEXT,
|
||||
},
|
||||
},
|
||||
{
|
||||
anchor: 'bas',
|
||||
badge: {
|
||||
alwaysDisplay: true,
|
||||
text: BAS_BADGE_TEXT,
|
||||
tooltipText: BAS_BADGE_TOOLTIP,
|
||||
variant: 'info',
|
||||
},
|
||||
description: BAS_DESCRIPTION,
|
||||
name: BAS_NAME,
|
||||
helpPath: BAS_HELP_PATH,
|
||||
secondary: {
|
||||
configurationHelpPath: BAS_DAST_FEATURE_FLAG_HELP_PATH,
|
||||
description: BAS_DAST_FEATURE_FLAG_DESCRIPTION,
|
||||
name: BAS_DAST_FEATURE_FLAG_NAME,
|
||||
},
|
||||
shortName: BAS_SHORT_NAME,
|
||||
type: REPORT_TYPE_BREACH_AND_ATTACK_SIMULATION,
|
||||
},
|
||||
];
|
||||
|
||||
export const complianceFeatures = [
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
<script>
|
||||
import { GlButton, GlCard, GlIcon, GlLink } from '@gitlab/ui';
|
||||
import { __, s__, sprintf } from '~/locale';
|
||||
import { REPORT_TYPE_SAST_IAC } from '~/vue_shared/security_reports/constants';
|
||||
import {
|
||||
REPORT_TYPE_BREACH_AND_ATTACK_SIMULATION,
|
||||
REPORT_TYPE_SAST_IAC,
|
||||
} from '~/vue_shared/security_reports/constants';
|
||||
import ManageViaMr from '~/vue_shared/security_configuration/components/manage_via_mr.vue';
|
||||
import FeatureCardBadge from './feature_card_badge.vue';
|
||||
|
||||
|
|
@ -68,8 +71,7 @@ export default {
|
|||
};
|
||||
},
|
||||
hasSecondary() {
|
||||
const { name, description, configurationText } = this.feature.secondary ?? {};
|
||||
return Boolean(name && description && configurationText);
|
||||
return Boolean(this.feature.secondary);
|
||||
},
|
||||
// This condition is a temporary hack to not display any wrong information
|
||||
// until this BE Bug is fixed: https://gitlab.com/gitlab-org/gitlab/-/issues/350307.
|
||||
|
|
@ -78,7 +80,17 @@ export default {
|
|||
return this.feature.type !== REPORT_TYPE_SAST_IAC;
|
||||
},
|
||||
hasBadge() {
|
||||
return Boolean(this.available && this.feature.badge?.text);
|
||||
const shouldDisplay = this.available || this.feature.badge?.alwaysDisplay;
|
||||
return Boolean(shouldDisplay && this.feature.badge?.text);
|
||||
},
|
||||
hasEnabledStatus() {
|
||||
return (
|
||||
this.isNotSastIACTemporaryHack &&
|
||||
this.feature.type !== REPORT_TYPE_BREACH_AND_ATTACK_SIMULATION
|
||||
);
|
||||
},
|
||||
showSecondaryConfigurationHelpPath() {
|
||||
return Boolean(this.available && this.feature.secondary?.configurationHelpPath);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
|
|
@ -118,19 +130,25 @@ export default {
|
|||
:badge-href="feature.badge.badgeHref"
|
||||
/>
|
||||
|
||||
<template v-if="enabled">
|
||||
<span>
|
||||
<gl-icon name="check-circle-filled" />
|
||||
<span class="gl-text-green-700">{{ $options.i18n.enabled }}</span>
|
||||
</span>
|
||||
<template v-if="hasEnabledStatus">
|
||||
<template v-if="enabled">
|
||||
<span>
|
||||
<gl-icon name="check-circle-filled" />
|
||||
<span class="gl-text-green-700">{{ $options.i18n.enabled }}</span>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<template v-else-if="available">
|
||||
<span>{{ $options.i18n.notEnabled }}</span>
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
{{ $options.i18n.availableWith }}
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<template v-else-if="available">
|
||||
<span>{{ $options.i18n.notEnabled }}</span>
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
{{ $options.i18n.availableWith }}
|
||||
<template v-else-if="!available">
|
||||
<span>{{ $options.i18n.availableWith }}</span>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -186,6 +204,16 @@ export default {
|
|||
>
|
||||
{{ feature.secondary.configurationText }}
|
||||
</gl-button>
|
||||
|
||||
<gl-button
|
||||
v-else-if="showSecondaryConfigurationHelpPath"
|
||||
icon="external-link"
|
||||
:href="feature.secondary.configurationHelpPath"
|
||||
category="secondary"
|
||||
class="gl-mt-5"
|
||||
>
|
||||
{{ $options.i18n.configurationGuide }}
|
||||
</gl-button>
|
||||
</div>
|
||||
</gl-card>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
export const SCOPED_LABEL_DELIMITER = '::';
|
||||
export const DEBOUNCE_DROPDOWN_DELAY = 200;
|
||||
export const DEFAULT_LABEL_COLOR = '#6699cc';
|
||||
|
||||
export const DropdownVariant = {
|
||||
Sidebar: 'sidebar',
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import { WORKSPACE_GROUP } from '~/issues/constants';
|
|||
import { __ } from '~/locale';
|
||||
import { workspaceLabelsQueries } from '../../../constants';
|
||||
import createLabelMutation from './graphql/create_label.mutation.graphql';
|
||||
import { DEFAULT_LABEL_COLOR } from './constants';
|
||||
|
||||
const errorMessage = __('Error creating label.');
|
||||
|
||||
|
|
@ -44,11 +45,16 @@ export default {
|
|||
type: String,
|
||||
required: true,
|
||||
},
|
||||
searchKey: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
labelTitle: '',
|
||||
selectedColor: '',
|
||||
labelTitle: this.searchKey,
|
||||
selectedColor: DEFAULT_LABEL_COLOR,
|
||||
labelCreateInProgress: false,
|
||||
error: undefined,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ export const REPORT_TYPE_SAST = 'sast';
|
|||
export const REPORT_TYPE_SAST_IAC = 'sast_iac';
|
||||
export const REPORT_TYPE_DAST = 'dast';
|
||||
export const REPORT_TYPE_DAST_PROFILES = 'dast_profiles';
|
||||
export const REPORT_TYPE_BREACH_AND_ATTACK_SIMULATION = 'breach_and_attack_simulation';
|
||||
export const REPORT_TYPE_SECRET_DETECTION = 'secret_detection';
|
||||
export const REPORT_TYPE_DEPENDENCY_SCANNING = 'dependency_scanning';
|
||||
export const REPORT_TYPE_CONTAINER_SCANNING = 'container_scanning';
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
module Security
|
||||
class SecurityJobsFinder < JobsFinder
|
||||
def self.allowed_job_types
|
||||
[:sast, :sast_iac, :dast, :dependency_scanning, :container_scanning, :secret_detection, :coverage_fuzzing, :api_fuzzing, :cluster_image_scanning]
|
||||
[:sast, :sast_iac, :breach_and_attack_simulation, :dast, :dependency_scanning, :container_scanning, :secret_detection, :coverage_fuzzing, :api_fuzzing, :cluster_image_scanning]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@ module Types
|
|||
graphql_name 'WorkItemPermissions'
|
||||
description 'Check permissions for the current user on a work item'
|
||||
|
||||
abilities :read_work_item, :update_work_item, :delete_work_item, :admin_work_item
|
||||
abilities :read_work_item, :update_work_item, :delete_work_item,
|
||||
:admin_work_item, :admin_parent_link
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -15,6 +15,14 @@ module Ci
|
|||
scope :for_projects, ->(project_ids) { where(project_id: project_ids) }
|
||||
|
||||
delegate :avatar_path, :description, :name, to: :project
|
||||
|
||||
def versions
|
||||
project.releases.order_released_desc
|
||||
end
|
||||
|
||||
def latest_version
|
||||
versions.first
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -6,6 +6,10 @@
|
|||
# See Ruby-lang issue https://bugs.ruby-lang.org/issues/17542
|
||||
# See issue on GitLab https://gitlab.com/gitlab-org/gitlab/-/issues/289836
|
||||
|
||||
# This file can be removed once Ruby 3.0 is no longer supported:
|
||||
# https://gitlab.com/gitlab-org/gitlab/-/issues/396223
|
||||
return if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new(3.1)
|
||||
|
||||
module Net
|
||||
class HTTP < Protocol
|
||||
def proxy_user
|
||||
|
|
|
|||
|
|
@ -163,6 +163,7 @@ InitializerConnections.raise_if_new_database_connection do
|
|||
draw :jira_connect
|
||||
|
||||
Gitlab.ee do
|
||||
draw :remote_development
|
||||
draw :security
|
||||
draw :smartcard
|
||||
draw :trial
|
||||
|
|
|
|||
|
|
@ -0,0 +1,83 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class SwapIssueUserMentionsNoteIdToBigintForGitlabDotCom < Gitlab::Database::Migration[2.1]
|
||||
include Gitlab::Database::MigrationHelpers::ConvertToBigint
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
TABLE_NAME = 'issue_user_mentions'
|
||||
|
||||
def up
|
||||
return unless should_run?
|
||||
|
||||
swap
|
||||
end
|
||||
|
||||
def down
|
||||
return unless should_run?
|
||||
|
||||
swap
|
||||
|
||||
add_concurrent_index TABLE_NAME, :note_id_convert_to_bigint, unique: true,
|
||||
name: 'index_issue_user_mentions_on_note_id_convert_to_bigint',
|
||||
where: 'note_id_convert_to_bigint IS NOT NULL'
|
||||
|
||||
add_concurrent_foreign_key TABLE_NAME, :notes, column: :note_id_convert_to_bigint,
|
||||
name: 'fk_issue_user_mentions_note_id_convert_to_bigint',
|
||||
on_delete: :cascade,
|
||||
validate: false
|
||||
end
|
||||
|
||||
def swap
|
||||
# This will replace the existing index_issue_user_mentions_on_note_id
|
||||
add_concurrent_index TABLE_NAME, :note_id_convert_to_bigint, unique: true,
|
||||
name: 'index_issue_user_mentions_on_note_id_convert_to_bigint',
|
||||
where: 'note_id_convert_to_bigint IS NOT NULL'
|
||||
|
||||
# This will replace the existing issue_user_mentions_on_issue_id_and_note_id_index
|
||||
add_concurrent_index TABLE_NAME, [:issue_id, :note_id_convert_to_bigint], unique: true,
|
||||
name: 'tmp_issue_user_mentions_on_issue_id_and_note_id_index'
|
||||
|
||||
# This will replace the existing issue_user_mentions_on_issue_id_index
|
||||
add_concurrent_index TABLE_NAME, :issue_id, unique: true,
|
||||
name: 'tmp_issue_user_mentions_on_issue_id_index',
|
||||
where: 'note_id_convert_to_bigint IS NULL'
|
||||
|
||||
# This will replace the existing fk_rails_3861d9fefa
|
||||
add_concurrent_foreign_key TABLE_NAME, :notes, column: :note_id_convert_to_bigint,
|
||||
name: 'fk_issue_user_mentions_note_id_convert_to_bigint',
|
||||
on_delete: :cascade
|
||||
|
||||
with_lock_retries(raise_on_exhaustion: true) do
|
||||
execute "LOCK TABLE notes, #{TABLE_NAME} IN ACCESS EXCLUSIVE MODE"
|
||||
|
||||
execute "ALTER TABLE #{TABLE_NAME} RENAME COLUMN note_id TO note_id_tmp"
|
||||
execute "ALTER TABLE #{TABLE_NAME} RENAME COLUMN note_id_convert_to_bigint TO note_id"
|
||||
execute "ALTER TABLE #{TABLE_NAME} RENAME COLUMN note_id_tmp TO note_id_convert_to_bigint"
|
||||
|
||||
function_name = Gitlab::Database::UnidirectionalCopyTrigger
|
||||
.on_table(TABLE_NAME, connection: connection)
|
||||
.name(:note_id, :note_id_convert_to_bigint)
|
||||
execute "ALTER FUNCTION #{quote_table_name(function_name)} RESET ALL"
|
||||
|
||||
execute 'DROP INDEX IF EXISTS index_issue_user_mentions_on_note_id'
|
||||
rename_index TABLE_NAME, 'index_issue_user_mentions_on_note_id_convert_to_bigint',
|
||||
'index_issue_user_mentions_on_note_id'
|
||||
|
||||
execute 'DROP INDEX IF EXISTS issue_user_mentions_on_issue_id_and_note_id_index'
|
||||
rename_index TABLE_NAME, 'tmp_issue_user_mentions_on_issue_id_and_note_id_index',
|
||||
'issue_user_mentions_on_issue_id_and_note_id_index'
|
||||
|
||||
execute 'DROP INDEX IF EXISTS issue_user_mentions_on_issue_id_index'
|
||||
rename_index TABLE_NAME, 'tmp_issue_user_mentions_on_issue_id_index',
|
||||
'issue_user_mentions_on_issue_id_index'
|
||||
|
||||
execute "ALTER TABLE #{TABLE_NAME} DROP CONSTRAINT IF EXISTS fk_rails_3861d9fefa"
|
||||
rename_constraint(TABLE_NAME, 'fk_issue_user_mentions_note_id_convert_to_bigint', 'fk_rails_3861d9fefa')
|
||||
end
|
||||
end
|
||||
|
||||
def should_run?
|
||||
com_or_dev_or_test_but_not_jh?
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AsyncValidateFkProjectsCreatorId < Gitlab::Database::Migration[2.1]
|
||||
TABLE_NAME = :projects
|
||||
COLUMN_NAME = :creator_id
|
||||
FK_NAME = :fk_03ec10b0d3
|
||||
|
||||
def up
|
||||
prepare_async_foreign_key_validation TABLE_NAME, COLUMN_NAME, name: FK_NAME
|
||||
end
|
||||
|
||||
def down
|
||||
unprepare_async_foreign_key_validation TABLE_NAME, COLUMN_NAME, name: FK_NAME
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1 @@
|
|||
3387abc29b2c499b8c1fafa8543f504d02cbca189b38f26a3776786416fa5820
|
||||
|
|
@ -0,0 +1 @@
|
|||
4955274e8f504af6e06432bd195e64eb6c520118a50f7da19af2fcf5872459cf
|
||||
|
|
@ -17365,11 +17365,11 @@ ALTER SEQUENCE issue_tracker_data_id_seq OWNED BY issue_tracker_data.id;
|
|||
CREATE TABLE issue_user_mentions (
|
||||
id bigint NOT NULL,
|
||||
issue_id integer NOT NULL,
|
||||
note_id integer,
|
||||
note_id_convert_to_bigint integer,
|
||||
mentioned_users_ids integer[],
|
||||
mentioned_projects_ids integer[],
|
||||
mentioned_groups_ids integer[],
|
||||
note_id_convert_to_bigint bigint
|
||||
note_id bigint
|
||||
);
|
||||
|
||||
CREATE SEQUENCE issue_user_mentions_id_seq
|
||||
|
|
@ -30802,8 +30802,6 @@ CREATE INDEX index_issue_tracker_data_on_integration_id ON issue_tracker_data US
|
|||
|
||||
CREATE UNIQUE INDEX index_issue_user_mentions_on_note_id ON issue_user_mentions USING btree (note_id) WHERE (note_id IS NOT NULL);
|
||||
|
||||
CREATE UNIQUE INDEX index_issue_user_mentions_on_note_id_convert_to_bigint ON issue_user_mentions USING btree (note_id_convert_to_bigint) WHERE (note_id_convert_to_bigint IS NOT NULL);
|
||||
|
||||
CREATE INDEX index_issues_on_author_id ON issues USING btree (author_id);
|
||||
|
||||
CREATE INDEX index_issues_on_author_id_and_id_and_created_at ON issues USING btree (author_id, id, created_at);
|
||||
|
|
@ -35269,9 +35267,6 @@ ALTER TABLE ONLY issues
|
|||
ALTER TABLE ONLY geo_event_log
|
||||
ADD CONSTRAINT fk_geo_event_log_on_geo_event_id FOREIGN KEY (geo_event_id) REFERENCES geo_events(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY issue_user_mentions
|
||||
ADD CONSTRAINT fk_issue_user_mentions_note_id_convert_to_bigint FOREIGN KEY (note_id_convert_to_bigint) REFERENCES notes(id) ON DELETE CASCADE NOT VALID;
|
||||
|
||||
ALTER TABLE ONLY ml_candidate_metrics
|
||||
ADD CONSTRAINT fk_ml_candidate_metrics_on_candidate_id FOREIGN KEY (candidate_id) REFERENCES ml_candidates(id) ON DELETE CASCADE;
|
||||
|
||||
|
|
|
|||
|
|
@ -216,6 +216,8 @@ The following actions on groups generate group audit events:
|
|||
[Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/377877) in GitLab 15.6.
|
||||
- An environment is protected or unprotected.
|
||||
[Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/216164) in GitLab 15.8.
|
||||
- Changes to Code Suggestions.
|
||||
[Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/405295) in GitLab 15.11.
|
||||
|
||||
### Project events
|
||||
|
||||
|
|
|
|||
|
|
@ -22517,6 +22517,7 @@ Check permissions for the current user on a work item.
|
|||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="workitempermissionsadminparentlink"></a>`adminParentLink` | [`Boolean!`](#boolean) | Indicates the user can perform `admin_parent_link` on this resource. |
|
||||
| <a id="workitempermissionsadminworkitem"></a>`adminWorkItem` | [`Boolean!`](#boolean) | Indicates the user can perform `admin_work_item` on this resource. |
|
||||
| <a id="workitempermissionsdeleteworkitem"></a>`deleteWorkItem` | [`Boolean!`](#boolean) | Indicates the user can perform `delete_work_item` on this resource. |
|
||||
| <a id="workitempermissionsreadworkitem"></a>`readWorkItem` | [`Boolean!`](#boolean) | Indicates the user can perform `read_work_item` on this resource. |
|
||||
|
|
@ -24529,6 +24530,7 @@ The status of the security scan.
|
|||
| Value | Description |
|
||||
| ----- | ----------- |
|
||||
| <a id="securityreporttypeenumapi_fuzzing"></a>`API_FUZZING` | API FUZZING scan report. |
|
||||
| <a id="securityreporttypeenumbreach_and_attack_simulation"></a>`BREACH_AND_ATTACK_SIMULATION` | BREACH AND ATTACK SIMULATION scan report. |
|
||||
| <a id="securityreporttypeenumcluster_image_scanning"></a>`CLUSTER_IMAGE_SCANNING` | CLUSTER IMAGE SCANNING scan report. |
|
||||
| <a id="securityreporttypeenumcontainer_scanning"></a>`CONTAINER_SCANNING` | CONTAINER SCANNING scan report. |
|
||||
| <a id="securityreporttypeenumcoverage_fuzzing"></a>`COVERAGE_FUZZING` | COVERAGE FUZZING scan report. |
|
||||
|
|
@ -24545,6 +24547,7 @@ The type of the security scanner.
|
|||
| Value | Description |
|
||||
| ----- | ----------- |
|
||||
| <a id="securityscannertypeapi_fuzzing"></a>`API_FUZZING` | API Fuzzing scanner. |
|
||||
| <a id="securityscannertypebreach_and_attack_simulation"></a>`BREACH_AND_ATTACK_SIMULATION` | Breach And Attack Simulation scanner. |
|
||||
| <a id="securityscannertypecluster_image_scanning"></a>`CLUSTER_IMAGE_SCANNING` | Cluster Image Scanning scanner. |
|
||||
| <a id="securityscannertypecontainer_scanning"></a>`CONTAINER_SCANNING` | Container Scanning scanner. |
|
||||
| <a id="securityscannertypecoverage_fuzzing"></a>`COVERAGE_FUZZING` | Coverage Fuzzing scanner. |
|
||||
|
|
|
|||
|
|
@ -216,12 +216,12 @@ sequence diagram.
|
|||
|
||||

|
||||
|
||||
On the diagrams above we see that currently a GitLab Runner Manager runs on a
|
||||
On the diagrams above we see that currently a runner manager runs on a
|
||||
machine that has access to a cloud provider's API. It is using Docker Machine
|
||||
to provision new Virtual Machines with Docker Engine installed and it
|
||||
configures the Docker daemon there to allow external authenticated requests. It
|
||||
stores credentials to such ephemeral Docker environments on disk. Once a
|
||||
machine has been provisioned and made available for GitLab Runner Manager to
|
||||
machine has been provisioned and made available for the runner manager to
|
||||
run builds, it is using one of the existing executors to run a user-provided
|
||||
script. In auto-scaling, this is typically done using the Docker executor.
|
||||
|
||||
|
|
@ -283,7 +283,7 @@ coupled with the VM lifecycle and job routing logic. Creating idle capacity
|
|||
happens as a side-effect of calling [`Acquire`](https://gitlab.com/gitlab-org/gitlab-runner/-/blob/267f40d871cd260dd063f7fbd36a921fedc62241/executors/docker/machine/provider.go#L449) on the `machineProvider` while binding a job to a VM.
|
||||
|
||||
There is also no current abstraction for in-VM job execution. VM-specific
|
||||
commands are generated by the Runner Manager using the [`GenerateShellScript`](https://gitlab.com/gitlab-org/gitlab-runner/-/blob/267f40d871cd260dd063f7fbd36a921fedc62241/common/build.go#L336)
|
||||
commands are generated by the runner manager using the [`GenerateShellScript`](https://gitlab.com/gitlab-org/gitlab-runner/-/blob/267f40d871cd260dd063f7fbd36a921fedc62241/common/build.go#L336)
|
||||
function and [injected](https://gitlab.com/gitlab-org/gitlab-runner/-/blob/267f40d871cd260dd063f7fbd36a921fedc62241/common/build.go#L373)
|
||||
into the VM as the manager drives the job execution stages.
|
||||
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ is used.
|
|||
To prevent artifacts from expiring, you can select **Keep** from the job details page.
|
||||
The option is not available when an artifact has no expiry set.
|
||||
|
||||
### With CI/CD variables to define the artifacts name
|
||||
### With a dynamically defined name
|
||||
|
||||
You can use [CI/CD variables](../variables/index.md) to dynamically define the
|
||||
artifacts file's name.
|
||||
|
|
@ -186,7 +186,7 @@ job:
|
|||
dependencies: []
|
||||
```
|
||||
|
||||
## View all job artifacts
|
||||
## View all job artifacts in a project
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/254938) in GitLab 15.11 [with a flag](../../administration/feature_flags.md) named `artifacts_management_page`. Disabled by default.
|
||||
|
||||
|
|
@ -202,21 +202,18 @@ You can download or delete individual artifacts from this list.
|
|||
|
||||
## Download job artifacts
|
||||
|
||||
You can download job artifacts by selecting **Download** (**{download}**) from:
|
||||
You can download job artifacts from:
|
||||
|
||||
- Any **Pipelines** list, to the right of the pipeline select **Download artifacts** (**{download}**).
|
||||
- Any **Jobs** list, to the right of the job select **Download artifacts** (**{download}**).
|
||||
- A job's detail page, on the right of the page select **Download**.
|
||||
- A merge request **Overview** page, to the right of the latest pipeline select **Artifacts** (**{download}**).
|
||||
- The [**Artifacts**](#view-all-job-artifacts) page, to the right of the job select **Download** (**{download}**).
|
||||
- If the **Browse** (**{folder-open}**) option is available, you can browse the contents of the artifacts
|
||||
from the UI without downloading the artifact. You can also select **Download artifacts archive**
|
||||
from the artifacts browser.
|
||||
- Any **Pipelines** list. On the right of the pipeline, select **Download artifacts** (**{download}**).
|
||||
- Any **Jobs** list. On the right of the job, select **Download artifacts** (**{download}**).
|
||||
- A job's detail page. On the right of the page, select **Download**.
|
||||
- A merge request **Overview** page. On the right of the latest pipeline, select **Artifacts** (**{download}**).
|
||||
- The [**Artifacts**](#view-all-job-artifacts-in-a-project) page. On the right of the job, select **Download** (**{download}**).
|
||||
- The [artifacts browser](#browse-the-contents-of-the-artifacts-archive). On the top of the page,
|
||||
select **Download artifacts archive** (**{download}**).
|
||||
|
||||
If [GitLab Pages](../../administration/pages/index.md) is enabled in the project, you can preview
|
||||
HTML files in the artifacts directly in your browser. If the project is internal or private, you must
|
||||
enable [GitLab Pages access control](../../administration/pages/index.md#access-control) to preview
|
||||
HTML files.
|
||||
[Report artifacts](../yaml/artifacts_reports.md) can only be downloaded from the **Pipelines** list
|
||||
or **Artifacts** page.
|
||||
|
||||
You can download job artifacts from the latest successful pipeline by using [the job artifacts API](../../api/job_artifacts.md).
|
||||
You cannot download [artifact reports](../yaml/artifacts_reports.md) with the job artifacts API,
|
||||
|
|
@ -245,7 +242,21 @@ Artifacts for [parent and child pipelines](../pipelines/downstream_pipelines.md#
|
|||
are searched in hierarchical order from parent to child. For example, if both parent and
|
||||
child pipelines have a job with the same name, the job artifacts from the parent pipeline are returned.
|
||||
|
||||
### From a URL with the artifacts browser
|
||||
## Browse the contents of the artifacts archive
|
||||
|
||||
You can browse the contents of the artifacts from the UI without downloading the artifact locally,
|
||||
from:
|
||||
|
||||
- Any **Jobs** list. On the right of the job, select **Browse** (**{folder-open}**).
|
||||
- A job's detail page. On the right of the page, select **Browse**.
|
||||
- The **Artifacts** page. On the right of the job, select **Browse** (**{folder-open}**).
|
||||
|
||||
If [GitLab Pages](../../administration/pages/index.md) is enabled in the project, you can preview
|
||||
HTML files in the artifacts directly in your browser. If the project is internal or private, you must
|
||||
enable [GitLab Pages access control](../../administration/pages/index.md#access-control) to preview
|
||||
HTML files.
|
||||
|
||||
### From a URL
|
||||
|
||||
You can browse the job artifacts of the latest successful pipeline for a specific job
|
||||
with a publicly accessible URL.
|
||||
|
|
|
|||
|
|
@ -803,7 +803,7 @@ variables:
|
|||
NOTE:
|
||||
Zip archives are the only supported artifact type. Follow [the issue for details](https://gitlab.com/gitlab-org/gitlab/-/issues/367203).
|
||||
|
||||
GitLab Runner can generate and produce attestation metadata for all build artifacts. To enable this feature, you must set the `RUNNER_GENERATE_ARTIFACTS_METADATA` environment variable to `true`. This variable can either be set globally or it can be set for individual jobs. The metadata is in rendered in a plain text `.json` file that's stored with the artifact. The filename is as follows: `{ARTIFACT_NAME}-metadata.json` where `ARTIFACT_NAME` is what was defined as the [name for the artifact](../jobs/job_artifacts.md#with-cicd-variables-to-define-the-artifacts-name) in the CI file. The filename, however, defaults to `artifacts-metadata.json` if no name was given to the build artifacts.
|
||||
GitLab Runner can generate and produce attestation metadata for all build artifacts. To enable this feature, you must set the `RUNNER_GENERATE_ARTIFACTS_METADATA` environment variable to `true`. This variable can either be set globally or it can be set for individual jobs. The metadata is in rendered in a plain text `.json` file that's stored with the artifact. The filename is as follows: `{ARTIFACT_NAME}-metadata.json` where `ARTIFACT_NAME` is what was defined as the [name for the artifact](../jobs/job_artifacts.md#with-a-dynamically-defined-name) in the CI file. The filename, however, defaults to `artifacts-metadata.json` if no name was given to the build artifacts.
|
||||
|
||||
### Attestation format
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ in your [subscription plan](https://about.gitlab.com/pricing/).
|
|||
|
||||
GitLab SaaS runners on Linux and Windows run on Google Compute Platform. The [Google Infrastructure Security Design Overview whitepaper](https://cloud.google.com/docs/security/infrastructure/design/resources/google_infrastructure_whitepaper_fa.pdf) provides an overview of how Google designs security into its technical infrastructure. The GitLab [Trust Center](https://about.gitlab.com/security/) and [GitLab Security Compliance Controls](https://about.staging.gitlab.com/handbook/engineering/security/security-assurance/security-compliance/sec-controls.html) pages provide an overview of the security and compliance controls that govern the GitLab SaaS runners.
|
||||
|
||||
The runner that serves as a Runner Manager automatically initiates the creation and deletion of the virtual machines (VMs) used for CI jobs. When the Runner Manager picks up a GitLab SaaS CI job, it automatically executes that job on a new VM. There is no human or manual intervention in this process. The following section provides an overview of the additional built-in layers that harden the security of the GitLab Runner SaaS CI build environment.
|
||||
The runner that serves as a runner manager automatically initiates the creation and deletion of the virtual machines (VMs) used for CI jobs. When the runner manager picks up a GitLab SaaS CI job, it automatically executes that job on a new VM. There is no human or manual intervention in this process. The following section provides an overview of the additional built-in layers that harden the security of the GitLab Runner SaaS CI build environment.
|
||||
|
||||
### Security of CI job execution on GitLab Runner SaaS (Linux, Windows)
|
||||
|
||||
|
|
@ -39,4 +39,4 @@ GitLab sends the command to remove the temporary runner VM to the Google Compute
|
|||
- Firewall rules only allow outbound communication from the temporary VM to the public internet.
|
||||
- Inbound communication from the public internet to the temporary VM is not allowed.
|
||||
- Firewall rules do not permit communication between VMs.
|
||||
- The only internal communication allowed to the temporary VMs is from the Runner Manager.
|
||||
- The only internal communication allowed to the temporary VMs is from the runner manager.
|
||||
|
|
|
|||
|
|
@ -958,7 +958,7 @@ job:
|
|||
|
||||
**Related topics**:
|
||||
|
||||
- [Use CI/CD variables to define the artifacts name](../jobs/job_artifacts.md#with-cicd-variables-to-define-the-artifacts-name).
|
||||
- [Use CI/CD variables to define the artifacts name](../jobs/job_artifacts.md#with-a-dynamically-defined-name).
|
||||
|
||||
#### `artifacts:public`
|
||||
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ The tool ensures that all aspects of swapping a foreign key are covered. This in
|
|||
|
||||
- Creating a migration to remove a foreign key.
|
||||
- Updating `db/structure.sql` with the new migration.
|
||||
- Updating `lib/gitlab/database/gitlab_loose_foreign_keys.yml` to add the new loose foreign key.
|
||||
- Updating `config/gitlab_loose_foreign_keys.yml` to add the new loose foreign key.
|
||||
- Creating or updating a model's specs to ensure that the loose foreign key is properly supported.
|
||||
|
||||
The tool is located at `scripts/decomposition/generate-loose-foreign-key`:
|
||||
|
|
|
|||
|
|
@ -135,6 +135,8 @@ To set up your self-managed instance for the GitLab for Jira Cloud app in GitLab
|
|||
|
||||
### Link your instance
|
||||
|
||||
See [prerequisites](#prerequisites).
|
||||
|
||||
To link your self-managed instance to the GitLab for Jira Cloud app:
|
||||
|
||||
1. Install the [GitLab for Jira Cloud app](https://marketplace.atlassian.com/apps/1221011/gitlab-com-for-jira-cloud?tab=overview&hosting=cloud).
|
||||
|
|
@ -320,3 +322,34 @@ To resolve this issue on GitLab self-managed, follow one of the solutions below,
|
|||
- Contact the [Jira Software Cloud support](https://support.atlassian.com/jira-software-cloud/) and ask to trigger a new installed lifecycle event for the GitLab for Jira Cloud app in your namespace.
|
||||
- In all GitLab versions:
|
||||
- Re-install the GitLab for Jira Cloud app. This might remove all already synced development panel data.
|
||||
|
||||
### `Failed to update GitLab version` error when setting up the GitLab for Jira Cloud app for self-managed instances
|
||||
|
||||
When you set up the GitLab for Jira Cloud app, you might get the following message after you enter your
|
||||
self-managed instance URL:
|
||||
|
||||
```plaintext
|
||||
Failed to update GitLab version. Please try again.
|
||||
```
|
||||
|
||||
To resolve this issue, ensure all prerequisites for your installation method have been met:
|
||||
|
||||
- [Prerequisites for connecting the GitLab for Jira Cloud app](#prerequisites)
|
||||
- [Prerequisites for installing the GitLab for Jira Cloud app manually](#prerequisites-1)
|
||||
|
||||
If you're using GitLab 15.8 and earlier and have previously enabled both the `jira_connect_oauth_self_managed`
|
||||
and the `jira_connect_oauth` feature flags, you must disable the `jira_connect_oauth_self_managed` flag
|
||||
due to a [known issue](https://gitlab.com/gitlab-org/gitlab/-/issues/388943). To check for these flags:
|
||||
|
||||
1. Open a [Rails console](../../administration/operations/rails_console.md#starting-a-rails-console-session).
|
||||
1. Execute the following code:
|
||||
|
||||
```ruby
|
||||
# Check if both feature flags are enabled.
|
||||
# If the flags are enabled, these commands return `true`.
|
||||
Feature.enabled?(:jira_connect_oauth)
|
||||
Feature.enabled?(:jira_connect_oauth_self_managed)
|
||||
|
||||
# If both flags are enabled, disable the `jira_connect_oauth_self_managed` flag.
|
||||
Feature.disable(:jira_connect_oauth_self_managed)
|
||||
```
|
||||
|
|
|
|||
|
|
@ -358,6 +358,16 @@ to a larger value in [the NGINX configuration](https://nginx.org/en/docs/http/ng
|
|||
|
||||
## Troubleshooting
|
||||
|
||||
### Using Google Chrome with Kerberos authentication against Windows AD
|
||||
|
||||
When you use Google Chrome to sign in to GitLab with Kerberos, you must enter your full username. For example, `username@domain.com`.
|
||||
|
||||
If you do not enter your full username, the sign-in fails. Check the logs to see the following event message as evidence of this sign-in failure:
|
||||
|
||||
```plain
|
||||
"message":"OmniauthKerberosController: failed to process Negotiate/Kerberos authentication: gss_accept_sec_context did not return GSS_S_COMPLETE: An unsupported mechanism was requested\nUnknown error"`.
|
||||
```
|
||||
|
||||
### Test connectivity between the GitLab and Kerberos servers
|
||||
|
||||
You can use utilities like [`kinit`](https://web.mit.edu/kerberos/krb5-1.12/doc/user/user_commands/kinit.html) and [`klist`](https://web.mit.edu/kerberos/krb5-1.12/doc/user/user_commands/klist.html) to test connectivity between the GitLab server
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ Different features are available in different [GitLab tiers](https://about.gitla
|
|||
| [Configure Secret Detection scanner](#enable-secret-detection) | **{check-circle}** Yes | **{check-circle}** Yes |
|
||||
| [Customize Secret Detection settings](#configure-scan-settings) | **{check-circle}** Yes | **{check-circle}** Yes |
|
||||
| Download [JSON Report](../sast/index.md#reports-json-format) | **{check-circle}** Yes | **{check-circle}** Yes |
|
||||
| [Check text for potential secrets](#warnings-for-potential-leaks-in-text-content) before it's posted | **{check-circle}** Yes | **{check-circle}** Yes |
|
||||
| See new findings in the merge request widget | **{dotted-circle}** No | **{check-circle}** Yes |
|
||||
| View identified secrets in the pipelines' **Security** tab | **{dotted-circle}** No | **{check-circle}** Yes |
|
||||
| [Manage vulnerabilities](../vulnerability_report/index.md) | **{dotted-circle}** No | **{check-circle}** Yes |
|
||||
|
|
@ -535,6 +536,26 @@ variable, or as a CI/CD variable.
|
|||
- If using a variable, set the value of `ADDITIONAL_CA_CERT_BUNDLE` to the text
|
||||
representation of the certificate.
|
||||
|
||||
## Warnings for potential leaks in text content
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/368434) in GitLab 15.11.
|
||||
|
||||
When you create an issue, propose a merge request, or write a comment, you might accidentally post a sensitive value.
|
||||
For example, you might paste in the details of an API request or an environment variable that contains an authentication token.
|
||||
|
||||
GitLab checks if the text of your issue description, merge request description, comment, or reply contains a sensitive token.
|
||||
If a token is found, a warning message is displayed. You can then edit your message before posting it.
|
||||
This check happens in your browser before the message is sent to the server.
|
||||
The check is always on; you don't have to set it up.
|
||||
|
||||
Your text is checked for the following secret types:
|
||||
|
||||
- GitLab [personal access tokens](../../../security/token_overview.md#personal-access-tokens)
|
||||
- GitLab [feed tokens](../../../security/token_overview.md#feed-token)
|
||||
|
||||
This feature is separate from Secret Detection scanning, which checks your Git repository for leaked secrets.
|
||||
[Issue 405147](https://gitlab.com/gitlab-org/gitlab/-/issues/405147) tracks efforts to align these two types of protection.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Set the logging level
|
||||
|
|
|
|||
|
|
@ -39,47 +39,18 @@ Credentials are only post-processed when Secret Detection finds them:
|
|||
- In public projects, because publicly exposed credentials pose an increased threat. Expansion to private projects is considered in [issue 391379](https://gitlab.com/gitlab-org/gitlab/-/issues/391379).
|
||||
- In projects with GitLab Ultimate, for technical reasons. Expansion to all tiers is tracked in [issue 391763](https://gitlab.com/gitlab-org/gitlab/-/issues/391763).
|
||||
|
||||
## High-level architecture
|
||||
## Partner program for leaked-credential notifications
|
||||
|
||||
This diagram describes how a post-processing hook revokes a secret within the GitLab application:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
GitLab Rails-->+GitLab Rails: gl-secret-detection-report.json
|
||||
GitLab Rails->>+Sidekiq: StoreScansService
|
||||
Sidekiq-->+Sidekiq: ScanSecurityReportSecretsWorker
|
||||
Sidekiq-->+Token Revocation API: GET revocable keys types
|
||||
Token Revocation API-->>-Sidekiq: OK
|
||||
Sidekiq->>+Token Revocation API: POST revoke revocable keys
|
||||
Token Revocation API-->>-Sidekiq: ACCEPTED
|
||||
Token Revocation API-->>+Receiver Service: revoke revocable keys
|
||||
Receiver Service-->>+Token Revocation API: ACCEPTED
|
||||
```
|
||||
|
||||
1. A pipeline with a Secret Detection job completes, producing a scan report (**1**).
|
||||
1. The report is processed (**2**) by a service class, which schedules an asychronous worker if token revocation is possible.
|
||||
1. The asynchronous worker (**3**) communicates with an externally deployed HTTP service
|
||||
(**4** and **5**) to determine which kinds of secrets can be automatically revoked.
|
||||
1. The worker sends (**6** and **7**) the list of detected secrets which the Token Revocation API is able to
|
||||
revoke.
|
||||
1. The Token Revocation API sends (**8** and **9**) each revocable token to their respective vendor's [receiver service](#integrate-your-cloud-provider-service-with-gitlabcom).
|
||||
|
||||
See the [Token Revocation API](../../../development/sec/token_revocation_api.md) documentation for more
|
||||
information.
|
||||
|
||||
## Integrate your cloud provider service with GitLab.com
|
||||
|
||||
Third-party cloud and SaaS vendors interested in automated token revocation can
|
||||
[express integration interest by filling out this form](https://forms.gle/wWpvrtLRK21Q2WJL9).
|
||||
Vendors must [implement a revocation receiver service](#implement-a-revocation-receiver-service)
|
||||
which will be called by the Token Revocation API.
|
||||
GitLab notifies partners when credentials they issue are leaked in public repositories on GitLab.com.
|
||||
If you operate a cloud or SaaS product and you're interested in receiving these notifications, learn more in [epic 4944](https://gitlab.com/groups/gitlab-org/-/epics/4944).
|
||||
Partners must [implement a revocation receiver service](#implement-a-revocation-receiver-service),
|
||||
which is called by the Token Revocation API.
|
||||
|
||||
### Implement a revocation receiver service
|
||||
|
||||
A revocation receiver service integrates with a GitLab instance's Token Revocation API to receive and respond
|
||||
to leaked token revocation requests. The service should be a publicly accessible HTTP API that is
|
||||
idempotent and rate-limited. Requests to your service from the Token Revocation API will follow the example
|
||||
idempotent and rate-limited. Requests to your service from the Token Revocation API look similar to the example
|
||||
below:
|
||||
|
||||
```plaintext
|
||||
|
|
@ -96,3 +67,32 @@ X-Gitlab-Token: MYSECRETTOKEN
|
|||
In this example, Secret Detection has determined that an instance of `my_api_token` has been leaked. The
|
||||
value of the token is provided to you, in addition to a publicly accessible URL to the raw content of the
|
||||
file containing the leaked token.
|
||||
|
||||
## High-level architecture
|
||||
|
||||
This diagram describes how a post-processing hook revokes a secret in the GitLab application:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
GitLab Rails-->+GitLab Rails: gl-secret-detection-report.json
|
||||
GitLab Rails->>+Sidekiq: StoreScansService
|
||||
Sidekiq-->+Sidekiq: ScanSecurityReportSecretsWorker
|
||||
Sidekiq-->+Token Revocation API: GET revocable keys types
|
||||
Token Revocation API-->>-Sidekiq: OK
|
||||
Sidekiq->>+Token Revocation API: POST revoke revocable keys
|
||||
Token Revocation API-->>-Sidekiq: ACCEPTED
|
||||
Token Revocation API-->>+Receiver Service: revoke revocable keys
|
||||
Receiver Service-->>+Token Revocation API: ACCEPTED
|
||||
```
|
||||
|
||||
1. A pipeline with a Secret Detection job completes, producing a scan report (**1**).
|
||||
1. The report is processed (**2**) by a service class, which schedules an asynchronous worker if token revocation is possible.
|
||||
1. The asynchronous worker (**3**) communicates with an externally deployed HTTP service
|
||||
(**4** and **5**) to determine which kinds of secrets can be automatically revoked.
|
||||
1. The worker sends (**6** and **7**) the list of detected secrets which the Token Revocation API is able to
|
||||
revoke.
|
||||
1. The Token Revocation API sends (**8** and **9**) each revocable token to their respective vendor's [receiver service](#implement-a-revocation-receiver-service).
|
||||
|
||||
See the [Token Revocation API](../../../development/sec/token_revocation_api.md) documentation for more
|
||||
information.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
---
|
||||
stage: Create
|
||||
group: Editor
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
type: reference
|
||||
---
|
||||
|
||||
> Introduced in GitLab 15.11 [with a flag](../../../administration/feature_flags.md) named `remote_development_feature_flag`. Disabled by default.
|
||||
|
||||
FLAG:
|
||||
On self-managed GitLab, by default this feature is not available. To make it available,
|
||||
ask an administrator to [enable the feature flag](../../../administration/feature_flags.md) named `remote_development_feature_flag`.
|
||||
On GitLab.com, this feature is not available.
|
||||
The feature is not ready for production use.
|
||||
|
||||
# Tutorial: Create and run your first GitLab Workspace **(ULTIMATE)**
|
||||
|
||||
This tutorial shows you how to configure and run your first Remote Development Workspace in GitLab.
|
||||
|
|
@ -6,6 +6,8 @@ module Gitlab
|
|||
class InstancePath
|
||||
include Gitlab::Utils::StrongMemoize
|
||||
|
||||
LATEST_VERSION_KEYWORD = '~latest'
|
||||
|
||||
def self.match?(address)
|
||||
address.include?('@') && address.start_with?(Settings.gitlab_ci['component_fqdn'])
|
||||
end
|
||||
|
|
@ -39,9 +41,9 @@ module Gitlab
|
|||
File.join(component_dir, @content_filename).delete_prefix('/')
|
||||
end
|
||||
|
||||
# TODO: Add support when version is a released tag and "~latest" moving target
|
||||
def sha
|
||||
return unless project
|
||||
return latest_version_sha if version == LATEST_VERSION_KEYWORD
|
||||
|
||||
project.commit(version)&.id
|
||||
end
|
||||
|
|
@ -69,6 +71,12 @@ module Gitlab
|
|||
|
||||
::Project.where_full_path_in(possible_paths).take # rubocop: disable CodeReuse/ActiveRecord
|
||||
end
|
||||
|
||||
def latest_version_sha
|
||||
return unless catalog_resource = project&.catalog_resource
|
||||
|
||||
catalog_resource.latest_version&.sha
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -39221,6 +39221,15 @@ msgstr ""
|
|||
msgid "SecurityConfiguration|Available with Ultimate"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityConfiguration|BAS"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityConfiguration|Breach and Attack Simulation (BAS)"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityConfiguration|Breach and Attack Simulation is an incubating feature extending existing security testing by simulating adversary activity."
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityConfiguration|By default, all analyzers are applied in order to cover all languages across your project, and only run if the language is detected in the merge request."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -39260,6 +39269,9 @@ msgstr ""
|
|||
msgid "SecurityConfiguration|Enable Auto DevOps"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityConfiguration|Enable incubating Breach and Attack Simulation focused features such as callback attacks in your DAST scans."
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityConfiguration|Enable security training to help your developers learn how to fix vulnerabilities. Developers can view security training from selected educational providers, relevant to the detected vulnerability."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -39272,6 +39284,9 @@ msgstr ""
|
|||
msgid "SecurityConfiguration|Immediately begin risk analysis and remediation with application security features. Start with SAST and Secret Detection, available to all plans. Upgrade to Ultimate to get all features, including:"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityConfiguration|Incubating feature"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityConfiguration|Learn more about vulnerability training"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -39296,6 +39311,9 @@ msgstr ""
|
|||
msgid "SecurityConfiguration|Once you've enabled a scan for the default branch, any subsequent feature branch you create will include the scan. An enabled scanner will not be reflected as such until the pipeline has been successfully executed and it has generated valid artifacts."
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityConfiguration|Out-of-Band Application Security Testing (OAST)"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityConfiguration|Quickly enable all continuous testing and compliance tools by enabling %{linkStart}Auto DevOps%{linkEnd}"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -39317,6 +39335,9 @@ msgstr ""
|
|||
msgid "SecurityConfiguration|Security training"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityConfiguration|Simulate breach and attack scenarios against your running application by attempting to detect and exploit known vulnerabilities."
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityConfiguration|Something went wrong. Please refresh the page, or try again later."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -50034,6 +50055,18 @@ msgstr ""
|
|||
msgid "WorkItem|You're only seeing %{boldStart}other activity%{boldEnd} in the feed. To add a comment, switch to one of the following options."
|
||||
msgstr ""
|
||||
|
||||
msgid "Workspaces"
|
||||
msgstr ""
|
||||
|
||||
msgid "Workspaces|Develop anywhere"
|
||||
msgstr ""
|
||||
|
||||
msgid "Workspaces|Get started with GitLab Workspaces"
|
||||
msgstr ""
|
||||
|
||||
msgid "Workspaces|GitLab Workspaces is a powerful collaborative platform that provides a comprehensive set of tools for software development teams to manage their entire development lifecycle."
|
||||
msgstr ""
|
||||
|
||||
msgid "Would you like to create a new branch?"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
{
|
||||
"version": "14.0.0",
|
||||
"version": "15.0.0",
|
||||
"vulnerabilities": [
|
||||
{
|
||||
"id": "1",
|
||||
"category": "sast",
|
||||
"name": "Predictable pseudorandom number generator",
|
||||
"message": "Predictable pseudorandom number generator",
|
||||
|
|
@ -29,6 +30,7 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"id": "2",
|
||||
"category": "sast",
|
||||
"name": "Predictable pseudorandom number generator",
|
||||
"message": "Predictable pseudorandom number generator",
|
||||
|
|
@ -56,6 +58,7 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"id": "3",
|
||||
"category": "sast",
|
||||
"name": "ECB mode is insecure",
|
||||
"message": "ECB mode is insecure",
|
||||
|
|
@ -90,6 +93,7 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"id": "4",
|
||||
"category": "sast",
|
||||
"name": "Hard coded key",
|
||||
"message": "Hard coded key",
|
||||
|
|
@ -124,6 +128,7 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"id": "5",
|
||||
"category": "sast",
|
||||
"name": "ECB mode is insecure",
|
||||
"message": "ECB mode is insecure",
|
||||
|
|
@ -158,8 +163,19 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"remediations": [],
|
||||
"remediations": [
|
||||
|
||||
],
|
||||
"scan": {
|
||||
"analyzer": {
|
||||
"id": "find_sec_bugs_analyzer",
|
||||
"name": "Find Security Bugs Analyzer",
|
||||
"url": "https://gitlab.com",
|
||||
"vendor": {
|
||||
"name": "GitLab"
|
||||
},
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"scanner": {
|
||||
"id": "find_sec_bugs",
|
||||
"name": "Find Security Bugs",
|
||||
|
|
@ -174,4 +190,4 @@
|
|||
"start_time": "2022-08-10T22:37:00",
|
||||
"end_time": "2022-08-10T22:38:00"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,33 @@
|
|||
{
|
||||
"version": "14.1.2",
|
||||
"vulnerabilities": [],
|
||||
"remediations": []
|
||||
}
|
||||
"version": "15.0.0",
|
||||
"vulnerabilities": [
|
||||
|
||||
],
|
||||
"remediations": [
|
||||
|
||||
],
|
||||
"scan": {
|
||||
"analyzer": {
|
||||
"id": "secret_detection_analyzer",
|
||||
"name": "Secret Detection Analyzer",
|
||||
"url": "https://gitlab.com",
|
||||
"vendor": {
|
||||
"name": "GitLab"
|
||||
},
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"scanner": {
|
||||
"id": "secret_detection",
|
||||
"name": "Secret Detection",
|
||||
"url": "https://gitlab.com",
|
||||
"vendor": {
|
||||
"name": "GitLab"
|
||||
},
|
||||
"version": "0.1.0"
|
||||
},
|
||||
"type": "sast",
|
||||
"start_time": "2022-03-11T18:48:16",
|
||||
"end_time": "2022-03-11T18:48:22",
|
||||
"status": "success"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,23 @@
|
|||
{
|
||||
"version": "14.1.2",
|
||||
"version": "15.0.0",
|
||||
"scan": {
|
||||
"analyzer": {
|
||||
"id": "sast_analyzer",
|
||||
"name": "SAST Analyzer",
|
||||
"url": "https://gitlab.com",
|
||||
"vendor": {
|
||||
"name": "GitLab"
|
||||
},
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"type": "sast",
|
||||
"start_time": "2022-03-11T18:48:16",
|
||||
"end_time": "2022-03-11T18:48:22",
|
||||
"status": "success"
|
||||
},
|
||||
"vulnerabilities": [
|
||||
{
|
||||
"id": "1",
|
||||
"category": "sast",
|
||||
"message": "Probable insecure usage of temp file/directory.",
|
||||
"cve": "python/hardcoded/hardcoded-tmp.py:52865813c884a507be1f152d654245af34aba8a391626d01f1ab6d3f52ec8779:B108",
|
||||
|
|
@ -26,6 +42,7 @@
|
|||
"url": "https://docs.openstack.org/bandit/latest/plugins/b108_hardcoded_tmp_directory.html"
|
||||
},
|
||||
{
|
||||
"id": "2",
|
||||
"category": "sast",
|
||||
"name": "Predictable pseudorandom number generator",
|
||||
"message": "Predictable pseudorandom number generator",
|
||||
|
|
@ -53,6 +70,7 @@
|
|||
"url": "https://find-sec-bugs.github.io/bugs.htm#PREDICTABLE_RANDOM"
|
||||
},
|
||||
{
|
||||
"id": "3",
|
||||
"category": "sast",
|
||||
"name": "Predictable pseudorandom number generator",
|
||||
"message": "Predictable pseudorandom number generator",
|
||||
|
|
@ -80,6 +98,7 @@
|
|||
"url": "https://find-sec-bugs.github.io/bugs.htm#PREDICTABLE_RANDOM"
|
||||
},
|
||||
{
|
||||
"id": "4",
|
||||
"category": "sast",
|
||||
"message": "Use of insecure MD2, MD4, or MD5 hash function.",
|
||||
"cve": "python/imports/imports-aliases.py:cb203b465dffb0cb3a8e8bd8910b84b93b0a5995a938e4b903dbb0cd6ffa1254:B303",
|
||||
|
|
@ -102,6 +121,7 @@
|
|||
"line": 11
|
||||
},
|
||||
{
|
||||
"id": "5",
|
||||
"category": "sast",
|
||||
"message": "Use of insecure MD2, MD4, or MD5 hash function.",
|
||||
"cve": "python/imports/imports-aliases.py:a7173c43ae66bd07466632d819d450e0071e02dbf782763640d1092981f9631b:B303",
|
||||
|
|
@ -124,6 +144,7 @@
|
|||
"line": 12
|
||||
},
|
||||
{
|
||||
"id": "6",
|
||||
"category": "sast",
|
||||
"message": "Use of insecure MD2, MD4, or MD5 hash function.",
|
||||
"cve": "python/imports/imports-aliases.py:017017b77deb0b8369b6065947833eeea752a92ec8a700db590fece3e934cf0d:B303",
|
||||
|
|
@ -146,6 +167,7 @@
|
|||
"line": 13
|
||||
},
|
||||
{
|
||||
"id": "6",
|
||||
"category": "sast",
|
||||
"message": "Use of insecure MD2, MD4, or MD5 hash function.",
|
||||
"cve": "python/imports/imports-aliases.py:45fc8c53aea7b84f06bc4e590cc667678d6073c4c8a1d471177ca2146fb22db2:B303",
|
||||
|
|
@ -168,6 +190,7 @@
|
|||
"line": 14
|
||||
},
|
||||
{
|
||||
"id": "7",
|
||||
"category": "sast",
|
||||
"message": "Pickle library appears to be in use, possible security issue.",
|
||||
"cve": "python/imports/imports-aliases.py:5f200d47291e7bbd8352db23019b85453ca048dd98ea0c291260fa7d009963a4:B301",
|
||||
|
|
@ -190,6 +213,7 @@
|
|||
"line": 15
|
||||
},
|
||||
{
|
||||
"id": "8",
|
||||
"category": "sast",
|
||||
"name": "ECB mode is insecure",
|
||||
"message": "ECB mode is insecure",
|
||||
|
|
@ -217,6 +241,7 @@
|
|||
"url": "https://find-sec-bugs.github.io/bugs.htm#ECB_MODE"
|
||||
},
|
||||
{
|
||||
"id": "9",
|
||||
"category": "sast",
|
||||
"name": "Cipher with no integrity",
|
||||
"message": "Cipher with no integrity",
|
||||
|
|
@ -244,6 +269,7 @@
|
|||
"url": "https://find-sec-bugs.github.io/bugs.htm#CIPHER_INTEGRITY"
|
||||
},
|
||||
{
|
||||
"id": "10",
|
||||
"category": "sast",
|
||||
"message": "Probable insecure usage of temp file/directory.",
|
||||
"cve": "python/hardcoded/hardcoded-tmp.py:63dd4d626855555b816985d82c4614a790462a0a3ada89dc58eb97f9c50f3077:B108",
|
||||
|
|
@ -268,6 +294,7 @@
|
|||
"url": "https://docs.openstack.org/bandit/latest/plugins/b108_hardcoded_tmp_directory.html"
|
||||
},
|
||||
{
|
||||
"id": "11",
|
||||
"category": "sast",
|
||||
"message": "Probable insecure usage of temp file/directory.",
|
||||
"cve": "python/hardcoded/hardcoded-tmp.py:4ad6d4c40a8c263fc265f3384724014e0a4f8dd6200af83e51ff120420038031:B108",
|
||||
|
|
@ -292,6 +319,7 @@
|
|||
"url": "https://docs.openstack.org/bandit/latest/plugins/b108_hardcoded_tmp_directory.html"
|
||||
},
|
||||
{
|
||||
"id": "12",
|
||||
"category": "sast",
|
||||
"message": "Consider possible security implications associated with Popen module.",
|
||||
"cve": "python/imports/imports-aliases.py:2c3e1fa1e54c3c6646e8bcfaee2518153c6799b77587ff8d9a7b0631f6d34785:B404",
|
||||
|
|
@ -314,6 +342,7 @@
|
|||
"line": 1
|
||||
},
|
||||
{
|
||||
"id": "13",
|
||||
"category": "sast",
|
||||
"message": "Consider possible security implications associated with pickle module.",
|
||||
"cve": "python/imports/imports.py:af58d07f6ad519ef5287fcae65bf1a6999448a1a3a8bc1ac2a11daa80d0b96bf:B403",
|
||||
|
|
@ -336,6 +365,7 @@
|
|||
"line": 2
|
||||
},
|
||||
{
|
||||
"id": "14",
|
||||
"category": "sast",
|
||||
"message": "Consider possible security implications associated with subprocess module.",
|
||||
"cve": "python/imports/imports.py:8de9bc98029d212db530785a5f6780cfa663548746ff228ab8fa96c5bb82f089:B404",
|
||||
|
|
@ -358,6 +388,7 @@
|
|||
"line": 4
|
||||
},
|
||||
{
|
||||
"id": "15",
|
||||
"category": "sast",
|
||||
"message": "Possible hardcoded password: 'blerg'",
|
||||
"cve": "python/hardcoded/hardcoded-passwords.py:97c30f1d76d2a88913e3ce9ae74087874d740f87de8af697a9c455f01119f633:B106",
|
||||
|
|
@ -382,6 +413,7 @@
|
|||
"url": "https://docs.openstack.org/bandit/latest/plugins/b106_hardcoded_password_funcarg.html"
|
||||
},
|
||||
{
|
||||
"id": "16",
|
||||
"category": "sast",
|
||||
"message": "Possible hardcoded password: 'root'",
|
||||
"cve": "python/hardcoded/hardcoded-passwords.py:7431c73a0bc16d94ece2a2e75ef38f302574d42c37ac0c3c38ad0b3bf8a59f10:B105",
|
||||
|
|
@ -406,6 +438,7 @@
|
|||
"url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html"
|
||||
},
|
||||
{
|
||||
"id": "17",
|
||||
"category": "sast",
|
||||
"message": "Possible hardcoded password: ''",
|
||||
"cve": "python/hardcoded/hardcoded-passwords.py:d2d1857c27caedd49c57bfbcdc23afcc92bd66a22701fcdc632869aab4ca73ee:B105",
|
||||
|
|
@ -430,6 +463,7 @@
|
|||
"url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html"
|
||||
},
|
||||
{
|
||||
"id": "18",
|
||||
"category": "sast",
|
||||
"message": "Possible hardcoded password: 'ajklawejrkl42348swfgkg'",
|
||||
"cve": "python/hardcoded/hardcoded-passwords.py:fb3866215a61393a5c9c32a3b60e2058171a23219c353f722cbd3567acab21d2:B105",
|
||||
|
|
@ -454,6 +488,7 @@
|
|||
"url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html"
|
||||
},
|
||||
{
|
||||
"id": "19",
|
||||
"category": "sast",
|
||||
"message": "Possible hardcoded password: 'blerg'",
|
||||
"cve": "python/hardcoded/hardcoded-passwords.py:63c62a8b7e1e5224439bd26b28030585ac48741e28ca64561a6071080c560a5f:B105",
|
||||
|
|
@ -478,6 +513,7 @@
|
|||
"url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html"
|
||||
},
|
||||
{
|
||||
"id": "20",
|
||||
"category": "sast",
|
||||
"message": "Possible hardcoded password: 'blerg'",
|
||||
"cve": "python/hardcoded/hardcoded-passwords.py:4311b06d08df8fa58229b341c531da8e1a31ec4520597bdff920cd5c098d86f9:B105",
|
||||
|
|
@ -502,6 +538,7 @@
|
|||
"url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html"
|
||||
},
|
||||
{
|
||||
"id": "21",
|
||||
"category": "sast",
|
||||
"message": "Consider possible security implications associated with subprocess module.",
|
||||
"cve": "python/imports/imports-function.py:5858400c2f39047787702de44d03361ef8d954c9d14bd54ee1c2bef9e6a7df93:B404",
|
||||
|
|
@ -524,6 +561,7 @@
|
|||
"line": 4
|
||||
},
|
||||
{
|
||||
"id": "22",
|
||||
"category": "sast",
|
||||
"message": "Consider possible security implications associated with pickle module.",
|
||||
"cve": "python/imports/imports-function.py:dbda3cf4190279d30e0aad7dd137eca11272b0b225e8af4e8bf39682da67d956:B403",
|
||||
|
|
@ -546,6 +584,7 @@
|
|||
"line": 2
|
||||
},
|
||||
{
|
||||
"id": "23",
|
||||
"category": "sast",
|
||||
"message": "Consider possible security implications associated with Popen module.",
|
||||
"cve": "python/imports/imports-from.py:eb8a0db9cd1a8c1ab39a77e6025021b1261cc2a0b026b2f4a11fca4e0636d8dd:B404",
|
||||
|
|
@ -568,6 +607,7 @@
|
|||
"line": 7
|
||||
},
|
||||
{
|
||||
"id": "24",
|
||||
"category": "sast",
|
||||
"message": "subprocess call with shell=True seems safe, but may be changed in the future, consider rewriting without shell",
|
||||
"cve": "python/imports/imports-aliases.py:f99f9721e27537fbcb6699a4cf39c6740d6234d2c6f06cfc2d9ea977313c483d:B602",
|
||||
|
|
@ -592,6 +632,7 @@
|
|||
"url": "https://docs.openstack.org/bandit/latest/plugins/b602_subprocess_popen_with_shell_equals_true.html"
|
||||
},
|
||||
{
|
||||
"id": "25",
|
||||
"category": "sast",
|
||||
"message": "Consider possible security implications associated with subprocess module.",
|
||||
"cve": "python/imports/imports-from.py:332a12ab1146698f614a905ce6a6a5401497a12281aef200e80522711c69dcf4:B404",
|
||||
|
|
@ -614,6 +655,7 @@
|
|||
"line": 6
|
||||
},
|
||||
{
|
||||
"id": "26",
|
||||
"category": "sast",
|
||||
"message": "Consider possible security implications associated with Popen module.",
|
||||
"cve": "python/imports/imports-from.py:0a48de4a3d5348853a03666cb574697e3982998355e7a095a798bd02a5947276:B404",
|
||||
|
|
@ -636,6 +678,7 @@
|
|||
"line": 1
|
||||
},
|
||||
{
|
||||
"id": "27",
|
||||
"category": "sast",
|
||||
"message": "Consider possible security implications associated with pickle module.",
|
||||
"cve": "python/imports/imports-aliases.py:51b71661dff994bde3529639a727a678c8f5c4c96f00d300913f6d5be1bbdf26:B403",
|
||||
|
|
@ -658,6 +701,7 @@
|
|||
"line": 7
|
||||
},
|
||||
{
|
||||
"id": "28",
|
||||
"category": "sast",
|
||||
"message": "Consider possible security implications associated with loads module.",
|
||||
"cve": "python/imports/imports-aliases.py:6ff02aeb3149c01ab68484d794a94f58d5d3e3bb0d58557ef4153644ea68ea54:B403",
|
||||
|
|
@ -680,6 +724,7 @@
|
|||
"line": 6
|
||||
},
|
||||
{
|
||||
"id": "29",
|
||||
"category": "sast",
|
||||
"message": "Statically-sized arrays can be improperly restricted, leading to potential overflows or other issues (CWE-119!/CWE-120)",
|
||||
"cve": "c/subdir/utils.c:b466873101951fe96e1332f6728eb7010acbbd5dfc3b65d7d53571d091a06d9e:CWE-119!/CWE-120",
|
||||
|
|
@ -713,6 +758,7 @@
|
|||
"url": "https://cwe.mitre.org/data/definitions/119.html"
|
||||
},
|
||||
{
|
||||
"id": "30",
|
||||
"category": "sast",
|
||||
"message": "Check when opening files - can an attacker redirect it (via symlinks), force the opening of special file type (e.g., device files), move things around to create a race condition, control its ancestors, or change its contents? (CWE-362)",
|
||||
"cve": "c/subdir/utils.c:bab681140fcc8fc3085b6bba74081b44ea145c1c98b5e70cf19ace2417d30770:CWE-362",
|
||||
|
|
@ -739,6 +785,7 @@
|
|||
"url": "https://cwe.mitre.org/data/definitions/362.html"
|
||||
},
|
||||
{
|
||||
"id": "31",
|
||||
"category": "sast",
|
||||
"message": "Statically-sized arrays can be improperly restricted, leading to potential overflows or other issues (CWE-119!/CWE-120)",
|
||||
"cve": "cplusplus/src/hello.cpp:c8c6dd0afdae6814194cf0930b719f757ab7b379cf8f261e7f4f9f2f323a818a:CWE-119!/CWE-120",
|
||||
|
|
@ -772,6 +819,7 @@
|
|||
"url": "https://cwe.mitre.org/data/definitions/119.html"
|
||||
},
|
||||
{
|
||||
"id": "32",
|
||||
"category": "sast",
|
||||
"message": "Does not check for buffer overflows when copying to destination [MS-banned] (CWE-120)",
|
||||
"cve": "cplusplus/src/hello.cpp:331c04062c4fe0c7c486f66f59e82ad146ab33cdd76ae757ca41f392d568cbd0:CWE-120",
|
||||
|
|
@ -799,4 +847,4 @@
|
|||
"url": "https://cwe.mitre.org/data/definitions/120.html"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"version": "14.0.4",
|
||||
"version": "15.0.4",
|
||||
"vulnerabilities": [
|
||||
{
|
||||
"id": "985a5666dcae22adef5ac12f8a8a2dacf9b9b481ae5d87cd0ac1712b0fd64864",
|
||||
|
|
@ -26,6 +26,15 @@
|
|||
}
|
||||
],
|
||||
"scan": {
|
||||
"analyzer": {
|
||||
"id": "find_sec_bugs_analyzer",
|
||||
"name": "Find Security Bugs Analyzer",
|
||||
"url": "https://gitlab.com",
|
||||
"vendor": {
|
||||
"name": "GitLab"
|
||||
},
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"scanner": {
|
||||
"id": "bandit",
|
||||
"name": "Bandit",
|
||||
|
|
@ -40,4 +49,4 @@
|
|||
"end_time": "2022-03-11T00:21:50",
|
||||
"status": "success"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"version": "14.0.4",
|
||||
"version": "15.0.4",
|
||||
"vulnerabilities": [
|
||||
{
|
||||
"id": "2e5656ff30e2e7cc93c36b4845c8a689ddc47fdbccf45d834c67442fbaa89be0",
|
||||
|
|
@ -51,6 +51,15 @@
|
|||
}
|
||||
],
|
||||
"scan": {
|
||||
"analyzer": {
|
||||
"id": "find_sec_bugs_analyzer",
|
||||
"name": "Find Security Bugs Analyzer",
|
||||
"url": "https://gitlab.com",
|
||||
"vendor": {
|
||||
"name": "GitLab"
|
||||
},
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"scanner": {
|
||||
"id": "gosec",
|
||||
"name": "Gosec",
|
||||
|
|
@ -65,4 +74,4 @@
|
|||
"end_time": "2022-03-15T20:33:17",
|
||||
"status": "success"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
{
|
||||
"version": "14.0.0",
|
||||
"version": "15.0.0",
|
||||
"vulnerabilities": [
|
||||
{
|
||||
"id": "1",
|
||||
"category": "sast",
|
||||
"name": "Cipher with no integrity",
|
||||
"message": "Cipher with no integrity",
|
||||
|
|
@ -49,8 +50,19 @@
|
|||
}
|
||||
}
|
||||
],
|
||||
"remediations": [],
|
||||
"remediations": [
|
||||
|
||||
],
|
||||
"scan": {
|
||||
"analyzer": {
|
||||
"id": "find_sec_bugs_analyzer",
|
||||
"name": "Find Security Bugs Analyzer",
|
||||
"url": "https://gitlab.com",
|
||||
"vendor": {
|
||||
"name": "GitLab"
|
||||
},
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"scanner": {
|
||||
"id": "find_sec_bugs",
|
||||
"name": "Find Security Bugs",
|
||||
|
|
@ -65,4 +77,4 @@
|
|||
"start_time": "2022-08-10T21:37:00",
|
||||
"end_time": "2022-08-10T21:38:00"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"version": "14.0.4",
|
||||
"version": "15.0.4",
|
||||
"vulnerabilities": [
|
||||
{
|
||||
"id": "985a5666dcae22adef5ac12f8a8a2dacf9b9b481ae5d87cd0ac1712b0fd64864",
|
||||
|
|
@ -54,6 +54,15 @@
|
|||
}
|
||||
],
|
||||
"scan": {
|
||||
"analyzer": {
|
||||
"id": "find_sec_bugs_analyzer",
|
||||
"name": "Find Security Bugs Analyzer",
|
||||
"url": "https://gitlab.com",
|
||||
"vendor": {
|
||||
"name": "GitLab"
|
||||
},
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"scanner": {
|
||||
"id": "semgrep",
|
||||
"name": "Semgrep",
|
||||
|
|
@ -68,4 +77,4 @@
|
|||
"end_time": "2022-03-11T18:48:22",
|
||||
"status": "success"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"version": "14.0.4",
|
||||
"version": "15.0.4",
|
||||
"vulnerabilities": [
|
||||
{
|
||||
"id": "79f6537b7ec83c7717f5bd1a4f12645916caafefe2e4359148d889855505aa67",
|
||||
|
|
@ -53,6 +53,15 @@
|
|||
}
|
||||
],
|
||||
"scan": {
|
||||
"analyzer": {
|
||||
"id": "find_sec_bugs_analyzer",
|
||||
"name": "Find Security Bugs Analyzer",
|
||||
"url": "https://gitlab.com",
|
||||
"vendor": {
|
||||
"name": "GitLab"
|
||||
},
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"scanner": {
|
||||
"id": "semgrep",
|
||||
"name": "Semgrep",
|
||||
|
|
@ -74,4 +83,4 @@
|
|||
"end_time": "2022-03-15T20:37:05",
|
||||
"status": "success"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"version": "14.0.4",
|
||||
"version": "15.0.4",
|
||||
"vulnerabilities": [
|
||||
{
|
||||
"id": "985a5666dcae22adef5ac12f8a8a2dacf9b9b481ae5d87cd0ac1712b0fd64864",
|
||||
|
|
@ -104,6 +104,15 @@
|
|||
}
|
||||
],
|
||||
"scan": {
|
||||
"analyzer": {
|
||||
"id": "semgrep_analyzer",
|
||||
"name": "Semgrep Analyzer",
|
||||
"url": "https://gitlab.com/",
|
||||
"vendor": {
|
||||
"name": "GitLab"
|
||||
},
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"scanner": {
|
||||
"id": "semgrep",
|
||||
"name": "Semgrep",
|
||||
|
|
@ -131,4 +140,4 @@
|
|||
"end_time": "2022-03-15T20:37:05",
|
||||
"status": "success"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
{
|
||||
"version": "14.0.0",
|
||||
"version": "15.0.0",
|
||||
"vulnerabilities": [
|
||||
{
|
||||
"id": "1_481ae5d87cd0ac1712b0fd64864",
|
||||
"category": "sast",
|
||||
"name": "Predictable pseudorandom number generator",
|
||||
"message": "Predictable pseudorandom number generator",
|
||||
|
|
@ -39,6 +40,7 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"id": "2_481ae5d87cd0ac1712b0fd64864",
|
||||
"category": "sast",
|
||||
"name": "Predictable pseudorandom number generator",
|
||||
"message": "Predictable pseudorandom number generator",
|
||||
|
|
@ -66,6 +68,7 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"id": "3_481ae5d87cd0ac1712b0fd64864",
|
||||
"category": "sast",
|
||||
"name": "ECB mode is insecure",
|
||||
"message": "ECB mode is insecure",
|
||||
|
|
@ -100,6 +103,7 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"id": "4_481ae5d87cd0ac1712b0fd64864",
|
||||
"category": "sast",
|
||||
"name": "Hard coded key",
|
||||
"message": "Hard coded key",
|
||||
|
|
@ -134,6 +138,7 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"id": "5_481ae5d87cd0ac1712b0fd64864",
|
||||
"category": "sast",
|
||||
"name": "Cipher with no integrity",
|
||||
"message": "Cipher with no integrity",
|
||||
|
|
@ -181,8 +186,19 @@
|
|||
}
|
||||
}
|
||||
],
|
||||
"remediations": [],
|
||||
"remediations": [
|
||||
|
||||
],
|
||||
"scan": {
|
||||
"analyzer": {
|
||||
"id": "find_sec_bugs_analyzer",
|
||||
"name": "Find Security Bugs Analyzer",
|
||||
"url": "https://gitlab.com",
|
||||
"vendor": {
|
||||
"name": "GitLab"
|
||||
},
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"scanner": {
|
||||
"id": "find_sec_bugs",
|
||||
"name": "Find Security Bugs",
|
||||
|
|
@ -197,4 +213,4 @@
|
|||
"start_time": "2022-08-10T21:37:00",
|
||||
"end_time": "2022-08-10T21:38:00"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,29 @@
|
|||
{
|
||||
"version": "14.1.2",
|
||||
"version": "15.0.0",
|
||||
"scan": {
|
||||
"analyzer": {
|
||||
"id": "secret_detection_analyzer",
|
||||
"name": "Secret Detection Analyzer",
|
||||
"url": "https://gitlab.com",
|
||||
"vendor": {
|
||||
"name": "GitLab"
|
||||
},
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"scanner": {
|
||||
"id": "secret_detection",
|
||||
"name": "Secret Detection",
|
||||
"url": "https://gitlab.com",
|
||||
"vendor": {
|
||||
"name": "GitLab"
|
||||
},
|
||||
"version": "0.1.0"
|
||||
},
|
||||
"type": "sast",
|
||||
"start_time": "2022-03-11T18:48:16",
|
||||
"end_time": "2022-03-11T18:48:22",
|
||||
"status": "success"
|
||||
},
|
||||
"vulnerabilities": [
|
||||
{
|
||||
"id": "27d2322d519c94f803ffed1cf6d14e455df97e5a0668e229eb853fdb0d277d2c",
|
||||
|
|
@ -17,7 +41,8 @@
|
|||
"location": {
|
||||
"file": "aws-key.py",
|
||||
"dependency": {
|
||||
"package": {}
|
||||
"package": {
|
||||
}
|
||||
},
|
||||
"commit": {
|
||||
"sha": "e9c3a56590d5bed4155c0d128f1552d52fdcc7ae"
|
||||
|
|
@ -32,5 +57,7 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"remediations": []
|
||||
}
|
||||
"remediations": [
|
||||
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,11 @@ import {
|
|||
getIssueDetailsResponse,
|
||||
projectWorkItemTypesQueryResponse,
|
||||
} from 'jest/work_items/mock_data';
|
||||
import { descriptionProps as initialProps, descriptionHtmlWithList } from '../mock_data/mock_data';
|
||||
import {
|
||||
descriptionProps as initialProps,
|
||||
descriptionHtmlWithList,
|
||||
descriptionHtmlWithDetailsTag,
|
||||
} from '../mock_data/mock_data';
|
||||
|
||||
jest.mock('~/alert');
|
||||
jest.mock('~/task_list');
|
||||
|
|
@ -111,6 +115,19 @@ describe('Description component', () => {
|
|||
expect(findGfmContent().classes()).toContain('issue-realtime-trigger-pulse');
|
||||
});
|
||||
|
||||
it('doesnt animate expand/collapse of details elements', async () => {
|
||||
createComponent();
|
||||
|
||||
await wrapper.setProps({ descriptionHtml: descriptionHtmlWithDetailsTag.collapsed });
|
||||
expect(findGfmContent().classes()).not.toContain('issue-realtime-pre-pulse');
|
||||
|
||||
await wrapper.setProps({ descriptionHtml: descriptionHtmlWithDetailsTag.expanded });
|
||||
expect(findGfmContent().classes()).not.toContain('issue-realtime-pre-pulse');
|
||||
|
||||
await wrapper.setProps({ descriptionHtml: descriptionHtmlWithDetailsTag.collapsed });
|
||||
expect(findGfmContent().classes()).not.toContain('issue-realtime-pre-pulse');
|
||||
});
|
||||
|
||||
it('applies syntax highlighting and math when description changed', async () => {
|
||||
createComponent();
|
||||
|
||||
|
|
|
|||
|
|
@ -79,3 +79,16 @@ export const descriptionHtmlWithList = `
|
|||
<li data-sourcepos="3:1-3:8">todo 3</li>
|
||||
</ul>
|
||||
`;
|
||||
|
||||
export const descriptionHtmlWithDetailsTag = {
|
||||
expanded: `
|
||||
<details open="true">
|
||||
<summary>Section 1</summary>
|
||||
<p>Data</p>
|
||||
</details>'`,
|
||||
collapsed: `
|
||||
<details>
|
||||
<summary>Section 1</summary>
|
||||
<p>Data</p>
|
||||
</details>'`,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,10 +1,15 @@
|
|||
import { GlIcon } from '@gitlab/ui';
|
||||
import { mount } from '@vue/test-utils';
|
||||
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
|
||||
import { securityFeatures } from '~/security_configuration/components/constants';
|
||||
import FeatureCard from '~/security_configuration/components/feature_card.vue';
|
||||
import FeatureCardBadge from '~/security_configuration/components/feature_card_badge.vue';
|
||||
import ManageViaMr from '~/vue_shared/security_configuration/components/manage_via_mr.vue';
|
||||
import { REPORT_TYPE_SAST } from '~/vue_shared/security_reports/constants';
|
||||
import {
|
||||
REPORT_TYPE_BREACH_AND_ATTACK_SIMULATION,
|
||||
REPORT_TYPE_SAST,
|
||||
REPORT_TYPE_SAST_IAC,
|
||||
} from '~/vue_shared/security_reports/constants';
|
||||
import { manageViaMRErrorMessage } from '../constants';
|
||||
import { makeFeature } from './utils';
|
||||
|
||||
|
|
@ -265,6 +270,56 @@ describe('FeatureCard component', () => {
|
|||
expect(links.exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('given an available secondary with a configuration guide', () => {
|
||||
beforeEach(() => {
|
||||
feature = makeFeature({
|
||||
available: true,
|
||||
configurationHelpPath: null,
|
||||
secondary: {
|
||||
name: 'secondary name',
|
||||
description: 'secondary description',
|
||||
configurationHelpPath: '/secondary',
|
||||
configurationText: null,
|
||||
},
|
||||
});
|
||||
createComponent({ feature });
|
||||
});
|
||||
|
||||
it('shows the secondary action', () => {
|
||||
const links = findLinks({
|
||||
text: 'Configuration guide',
|
||||
href: feature.secondary.configurationHelpPath,
|
||||
});
|
||||
expect(links.exists()).toBe(true);
|
||||
expect(links).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('given an unavailable secondary with a configuration guide', () => {
|
||||
beforeEach(() => {
|
||||
feature = makeFeature({
|
||||
available: false,
|
||||
configurationHelpPath: null,
|
||||
secondary: {
|
||||
name: 'secondary name',
|
||||
description: 'secondary description',
|
||||
configurationHelpPath: '/secondary',
|
||||
configurationText: null,
|
||||
},
|
||||
});
|
||||
createComponent({ feature });
|
||||
});
|
||||
|
||||
it('does not show the secondary action', () => {
|
||||
const links = findLinks({
|
||||
text: 'Configuration guide',
|
||||
href: feature.secondary.configurationHelpPath,
|
||||
});
|
||||
expect(links.exists()).toBe(false);
|
||||
expect(links).toHaveLength(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('information badge', () => {
|
||||
|
|
@ -290,4 +345,48 @@ describe('FeatureCard component', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('status and badge', () => {
|
||||
describe.each`
|
||||
context | available | configured | expectedStatus
|
||||
${'configured BAS feature'} | ${true} | ${true} | ${null}
|
||||
${'unavailable BAS feature'} | ${false} | ${false} | ${'Available with Ultimate'}
|
||||
${'unconfigured BAS feature'} | ${true} | ${false} | ${null}
|
||||
`('given $context', ({ available, configured, expectedStatus }) => {
|
||||
beforeEach(() => {
|
||||
const securityFeature = securityFeatures.find(
|
||||
({ type }) => REPORT_TYPE_BREACH_AND_ATTACK_SIMULATION === type,
|
||||
);
|
||||
feature = { ...securityFeature, available, configured };
|
||||
createComponent({ feature });
|
||||
});
|
||||
|
||||
it('should show an incubating feature badge', () => {
|
||||
expect(findBadge().exists()).toBe(true);
|
||||
});
|
||||
|
||||
if (expectedStatus) {
|
||||
it(`should show the status "${expectedStatus}"`, () => {
|
||||
expect(wrapper.findByTestId('feature-status').text()).toBe(expectedStatus);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe.each`
|
||||
context | available | configured
|
||||
${'configured SAST IaC feature'} | ${true} | ${true}
|
||||
${'unavailable SAST IaC feature'} | ${false} | ${false}
|
||||
${'unconfigured SAST IaC feature'} | ${true} | ${false}
|
||||
`('given $context', ({ available, configured }) => {
|
||||
beforeEach(() => {
|
||||
const securityFeature = securityFeatures.find(({ type }) => REPORT_TYPE_SAST_IAC === type);
|
||||
feature = { ...securityFeature, available, configured };
|
||||
createComponent({ feature });
|
||||
});
|
||||
|
||||
it(`should not show a status`, () => {
|
||||
expect(wrapper.findByTestId('feature-status').exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -8,11 +8,13 @@ import { createAlert } from '~/alert';
|
|||
import { workspaceLabelsQueries } from '~/sidebar/constants';
|
||||
import DropdownContentsCreateView from '~/sidebar/components/labels/labels_select_widget/dropdown_contents_create_view.vue';
|
||||
import createLabelMutation from '~/sidebar/components/labels/labels_select_widget/graphql/create_label.mutation.graphql';
|
||||
import { DEFAULT_LABEL_COLOR } from '~/sidebar/components/labels/labels_select_widget/constants';
|
||||
import {
|
||||
mockRegularLabel,
|
||||
mockSuggestedColors,
|
||||
createLabelSuccessfulResponse,
|
||||
workspaceLabelsQueryResponse,
|
||||
workspaceLabelsQueryEmptyResponse,
|
||||
} from './mock_data';
|
||||
|
||||
jest.mock('~/alert');
|
||||
|
|
@ -61,14 +63,16 @@ describe('DropdownContentsCreateView', () => {
|
|||
mutationHandler = createLabelSuccessHandler,
|
||||
labelCreateType = 'project',
|
||||
workspaceType = 'project',
|
||||
labelsResponse = workspaceLabelsQueryResponse,
|
||||
searchTerm = '',
|
||||
} = {}) => {
|
||||
const mockApollo = createMockApollo([[createLabelMutation, mutationHandler]]);
|
||||
mockApollo.clients.defaultClient.cache.writeQuery({
|
||||
query: workspaceLabelsQueries[workspaceType].query,
|
||||
data: workspaceLabelsQueryResponse.data,
|
||||
data: labelsResponse.data,
|
||||
variables: {
|
||||
fullPath: '',
|
||||
searchTerm: '',
|
||||
searchTerm,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -94,7 +98,7 @@ describe('DropdownContentsCreateView', () => {
|
|||
|
||||
it('selects a color after clicking on colored block', async () => {
|
||||
createComponent();
|
||||
expect(findSelectedColor().attributes('style')).toBeUndefined();
|
||||
expect(findSelectedColorText().attributes('value')).toBe(DEFAULT_LABEL_COLOR);
|
||||
|
||||
findAllColors().at(0).vm.$emit('click', new Event('mouseclick'));
|
||||
await nextTick();
|
||||
|
|
@ -104,7 +108,7 @@ describe('DropdownContentsCreateView', () => {
|
|||
|
||||
it('shows correct color hex code after selecting a color', async () => {
|
||||
createComponent();
|
||||
expect(findSelectedColorText().attributes('value')).toBe('');
|
||||
expect(findSelectedColorText().attributes('value')).toBe(DEFAULT_LABEL_COLOR);
|
||||
|
||||
findAllColors().at(0).vm.$emit('click', new Event('mouseclick'));
|
||||
await nextTick();
|
||||
|
|
@ -123,6 +127,7 @@ describe('DropdownContentsCreateView', () => {
|
|||
it('disables a Create button if color is not set', async () => {
|
||||
createComponent();
|
||||
findLabelTitleInput().vm.$emit('input', 'Test title');
|
||||
findSelectedColorText().vm.$emit('input', '');
|
||||
await nextTick();
|
||||
|
||||
expect(findCreateButton().props('disabled')).toBe(true);
|
||||
|
|
@ -232,4 +237,21 @@ describe('DropdownContentsCreateView', () => {
|
|||
titleTakenError.data.labelCreate.errors[0],
|
||||
);
|
||||
});
|
||||
|
||||
describe('when empty labels response', () => {
|
||||
it('is able to create label with searched text when empty response', async () => {
|
||||
createComponent({ searchTerm: '', labelsResponse: workspaceLabelsQueryEmptyResponse });
|
||||
|
||||
findLabelTitleInput().vm.$emit('input', 'random');
|
||||
|
||||
findCreateButton().vm.$emit('click');
|
||||
await waitForPromises();
|
||||
|
||||
expect(createLabelSuccessHandler).toHaveBeenCalledWith({
|
||||
color: DEFAULT_LABEL_COLOR,
|
||||
projectPath: '',
|
||||
title: 'random',
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -117,6 +117,17 @@ export const workspaceLabelsQueryResponse = {
|
|||
},
|
||||
};
|
||||
|
||||
export const workspaceLabelsQueryEmptyResponse = {
|
||||
data: {
|
||||
workspace: {
|
||||
id: 'gid://gitlab/Project/126',
|
||||
labels: {
|
||||
nodes: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const issuableLabelsQueryResponse = {
|
||||
data: {
|
||||
workspace: {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@ require 'spec_helper'
|
|||
RSpec.describe Types::PermissionTypes::WorkItem do
|
||||
it do
|
||||
expected_permissions = [
|
||||
:read_work_item, :update_work_item, :delete_work_item, :admin_work_item
|
||||
:read_work_item, :update_work_item, :delete_work_item, :admin_work_item,
|
||||
:admin_parent_link
|
||||
]
|
||||
|
||||
expected_permissions.each do |permission|
|
||||
|
|
|
|||
|
|
@ -8,6 +8,12 @@ require_relative '../../config/initializers/net_http_patch'
|
|||
RSpec.describe 'Net::HTTP patch proxy user and password encoding' do
|
||||
let(:net_http) { Net::HTTP.new('hostname.example') }
|
||||
|
||||
before do
|
||||
# This file can be removed once Ruby 3.0 is no longer supported:
|
||||
# https://gitlab.com/gitlab-org/gitlab/-/issues/396223
|
||||
skip if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new(3.1)
|
||||
end
|
||||
|
||||
describe '#proxy_user' do
|
||||
subject { net_http.proxy_user }
|
||||
|
||||
|
|
|
|||
|
|
@ -98,6 +98,37 @@ RSpec.describe Gitlab::Ci::Components::InstancePath, feature_category: :pipeline
|
|||
end
|
||||
end
|
||||
|
||||
context 'when version is `~latest`' do
|
||||
let(:version) { '~latest' }
|
||||
|
||||
context 'when project is a catalog resource' do
|
||||
before do
|
||||
create(:catalog_resource, project: existing_project)
|
||||
end
|
||||
|
||||
context 'when project has releases' do
|
||||
let_it_be(:releases) do
|
||||
[
|
||||
create(:release, project: existing_project, sha: 'sha-1', released_at: Time.zone.now - 1.day),
|
||||
create(:release, project: existing_project, sha: 'sha-2', released_at: Time.zone.now)
|
||||
]
|
||||
end
|
||||
|
||||
it 'returns the sha of the latest release' do
|
||||
expect(path.sha).to eq(releases.last.sha)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when project does not have releases' do
|
||||
it { expect(path.sha).to be_nil }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when project is not a catalog resource' do
|
||||
it { expect(path.sha).to be_nil }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when project does not exist' do
|
||||
let(:project_path) { 'non-existent/project' }
|
||||
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Sast do
|
|||
context "when passing valid report" do
|
||||
# rubocop: disable Layout/LineLength
|
||||
where(:report_format, :report_version, :scanner_length, :finding_length, :identifier_length, :file_path, :start_line, :end_line, :primary_identifiers_length) do
|
||||
:sast | '14.0.0' | 1 | 5 | 6 | 'groovy/src/main/java/com/gitlab/security_products/tests/App.groovy' | 47 | 47 | nil
|
||||
:sast_semgrep_for_multiple_findings | '14.0.4' | 1 | 2 | 6 | 'app/app.py' | 39 | nil | 2
|
||||
:sast | '15.0.0' | 1 | 5 | 6 | 'groovy/src/main/java/com/gitlab/security_products/tests/App.groovy' | 47 | 47 | nil
|
||||
:sast_semgrep_for_multiple_findings | '15.0.4' | 1 | 2 | 6 | 'app/app.py' | 39 | nil | 2
|
||||
end
|
||||
# rubocop: enable Layout/LineLength
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::SecretDetection do
|
|||
end
|
||||
|
||||
it "generates expected metadata_version" do
|
||||
expect(report.findings.first.metadata_version).to eq('14.1.2')
|
||||
expect(report.findings.first.metadata_version).to eq('15.0.0')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,66 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
require_migration!
|
||||
|
||||
RSpec.describe SwapIssueUserMentionsNoteIdToBigintForGitlabDotCom, feature_category: :database do
|
||||
describe '#up' do
|
||||
before do
|
||||
# A we call `schema_migrate_down!` before each example, and for this migration
|
||||
# `#down` is same as `#up`, we need to ensure we start from the expected state.
|
||||
connection = described_class.new.connection
|
||||
connection.execute('ALTER TABLE issue_user_mentions ALTER COLUMN note_id TYPE integer')
|
||||
connection.execute('ALTER TABLE issue_user_mentions ALTER COLUMN note_id_convert_to_bigint TYPE bigint')
|
||||
end
|
||||
|
||||
# rubocop: disable RSpec/AnyInstanceOf
|
||||
it 'swaps the integer and bigint columns for GitLab.com, dev, or test' do
|
||||
allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(true)
|
||||
|
||||
user_mentions = table(:issue_user_mentions)
|
||||
|
||||
disable_migrations_output do
|
||||
reversible_migration do |migration|
|
||||
migration.before -> {
|
||||
user_mentions.reset_column_information
|
||||
|
||||
expect(user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
|
||||
expect(user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('bigint')
|
||||
}
|
||||
|
||||
migration.after -> {
|
||||
user_mentions.reset_column_information
|
||||
|
||||
expect(user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('bigint')
|
||||
expect(user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('integer')
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it 'is a no-op for other instances' do
|
||||
allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(false)
|
||||
|
||||
user_mentions = table(:issue_user_mentions)
|
||||
|
||||
disable_migrations_output do
|
||||
reversible_migration do |migration|
|
||||
migration.before -> {
|
||||
user_mentions.reset_column_information
|
||||
|
||||
expect(user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
|
||||
expect(user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('bigint')
|
||||
}
|
||||
|
||||
migration.after -> {
|
||||
user_mentions.reset_column_information
|
||||
|
||||
expect(user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
|
||||
expect(user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('bigint')
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
# rubocop: enable RSpec/AnyInstanceOf
|
||||
end
|
||||
end
|
||||
|
|
@ -3,6 +3,17 @@
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Ci::Catalog::Resource, feature_category: :pipeline_composition do
|
||||
let_it_be(:project) { create(:project) }
|
||||
let_it_be(:resource) { create(:catalog_resource, project: project) }
|
||||
|
||||
let_it_be(:releases) do
|
||||
[
|
||||
create(:release, project: project, released_at: Time.zone.now - 2.days),
|
||||
create(:release, project: project, released_at: Time.zone.now - 1.day),
|
||||
create(:release, project: project, released_at: Time.zone.now)
|
||||
]
|
||||
end
|
||||
|
||||
it { is_expected.to belong_to(:project) }
|
||||
|
||||
it { is_expected.to delegate_method(:avatar_path).to(:project) }
|
||||
|
|
@ -11,12 +22,21 @@ RSpec.describe Ci::Catalog::Resource, feature_category: :pipeline_composition do
|
|||
|
||||
describe '.for_projects' do
|
||||
it 'returns catalog resources for the given project IDs' do
|
||||
project = create(:project)
|
||||
resource = create(:catalog_resource, project: project)
|
||||
|
||||
resources_for_projects = described_class.for_projects(project.id)
|
||||
|
||||
expect(resources_for_projects).to contain_exactly(resource)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#versions' do
|
||||
it 'returns releases ordered by released date descending' do
|
||||
expect(resource.versions).to eq(releases.reverse)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#latest_version' do
|
||||
it 'returns the latest release' do
|
||||
expect(resource.latest_version).to eq(releases.last)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -59,7 +59,8 @@ RSpec.describe 'Query.work_item(id)', feature_category: :team_planning do
|
|||
'readWorkItem' => true,
|
||||
'updateWorkItem' => true,
|
||||
'deleteWorkItem' => false,
|
||||
'adminWorkItem' => true
|
||||
'adminWorkItem' => true,
|
||||
'adminParentLink' => true
|
||||
},
|
||||
'project' => hash_including('id' => project.to_gid.to_s, 'fullPath' => project.full_path)
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in New Issue