Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
45465a1f21
commit
0088061332
|
|
@ -34,7 +34,6 @@ export default {
|
|||
:key="`${currentKey}-${field.name}`"
|
||||
v-bind="field"
|
||||
:is-validated="isValidated"
|
||||
:data-qa-selector="`${field.name}_div`"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -117,11 +117,7 @@ export default {
|
|||
</template>
|
||||
|
||||
<template #cell(title)="{ item }">
|
||||
<gl-avatar-link
|
||||
:href="item.edit_path"
|
||||
:title="item.title"
|
||||
:data-qa-selector="`${item.name}_link`"
|
||||
>
|
||||
<gl-avatar-link :href="item.edit_path" :title="item.title" :data-testid="`${item.name}-link`">
|
||||
<gl-avatar-labeled
|
||||
:label="item.title"
|
||||
:sub-label="item.description"
|
||||
|
|
|
|||
|
|
@ -52,10 +52,7 @@ export default {
|
|||
@select="onLanguageSelected"
|
||||
>
|
||||
<template #list-item="{ item: locale }">
|
||||
<span
|
||||
:data-testid="itemTestSelector(locale.value)"
|
||||
:data-qa-selector="itemTestSelector(locale.value)"
|
||||
>
|
||||
<span :data-testid="itemTestSelector(locale.value)">
|
||||
{{ locale.text }}
|
||||
</span>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -27,11 +27,15 @@ class ReleasesFinder
|
|||
private
|
||||
|
||||
def get_releases
|
||||
Release.where(project_id: authorized_projects).where.not(tag: nil) # rubocop: disable CodeReuse/ActiveRecord
|
||||
Release
|
||||
.where(project_id: authorized_projects) # rubocop: disable CodeReuse/ActiveRecord
|
||||
.tagged
|
||||
end
|
||||
|
||||
def get_latest_releases
|
||||
Release.latest_for_projects(authorized_projects, order_by: params[:order_by_for_latest]).where.not(tag: nil) # rubocop: disable CodeReuse/ActiveRecord
|
||||
Release
|
||||
.latest_for_projects(authorized_projects, order_by: params[:order_by_for_latest])
|
||||
.tagged
|
||||
end
|
||||
|
||||
def authorized_projects
|
||||
|
|
|
|||
|
|
@ -38,6 +38,10 @@ class Release < ApplicationRecord
|
|||
validates_associated :milestone_releases, message: -> (_, obj) { obj[:value].map(&:errors).map(&:full_messages).join(",") }
|
||||
validates :links, nested_attributes_duplicates: { scope: :release, child_attributes: %i[name url filepath] }
|
||||
|
||||
# All releases should have tags, but because of existing invalid data, we need a work around so that presenters don't
|
||||
# fail to generate URLs on release related pages
|
||||
scope :tagged, -> { where.not(tag: [nil, '']) }
|
||||
|
||||
scope :sorted, -> { order(released_at: :desc) }
|
||||
scope :preloaded, -> {
|
||||
includes(
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
- show_group_events = local_assigns.fetch(:show_group_events, false)
|
||||
|
||||
.scrolling-tabs-container.inner-page-scroll-tabs.is-smaller.flex-fill
|
||||
.scrolling-tabs-container.inner-page-scroll-tabs.gl-flex-grow-1.gl-min-w-0.gl-w-full
|
||||
%button.fade-left{ type: 'button', title: _('Scroll left'), 'aria-label': _('Scroll left') }
|
||||
= sprite_icon('chevron-lg-left', size: 12)
|
||||
%button.fade-right{ type: 'button', title: _('Scroll right'), 'aria-label': _('Scroll right') }
|
||||
|
|
|
|||
|
|
@ -217,10 +217,6 @@ deployment_clusters:
|
|||
- table: clusters
|
||||
column: cluster_id
|
||||
on_delete: async_delete
|
||||
deployments:
|
||||
- table: clusters
|
||||
column: cluster_id
|
||||
on_delete: async_nullify
|
||||
events:
|
||||
- table: users
|
||||
column: author_id
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RemoveDeploymentsClusterId < Gitlab::Database::Migration[2.2]
|
||||
disable_ddl_transaction!
|
||||
milestone '16.7'
|
||||
|
||||
def up
|
||||
with_lock_retries do
|
||||
remove_column :deployments, :cluster_id, if_exists: true
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
with_lock_retries do
|
||||
add_column :deployments, :cluster_id, :integer, if_not_exists: true
|
||||
end
|
||||
|
||||
add_concurrent_index(:deployments, [:cluster_id, :status])
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1 @@
|
|||
6a6904e4d238188de896f31d18ed970c1784cbd831506f48ad186d3ca0f1a2af
|
||||
|
|
@ -15997,7 +15997,6 @@ CREATE TABLE deployments (
|
|||
on_stop character varying,
|
||||
status smallint NOT NULL,
|
||||
finished_at timestamp with time zone,
|
||||
cluster_id integer,
|
||||
deployable_id bigint,
|
||||
archived boolean DEFAULT false NOT NULL
|
||||
);
|
||||
|
|
@ -32705,8 +32704,6 @@ CREATE INDEX index_deployments_for_visible_scope ON deployments USING btree (env
|
|||
|
||||
CREATE INDEX index_deployments_on_archived_project_id_iid ON deployments USING btree (archived, project_id, iid);
|
||||
|
||||
CREATE INDEX index_deployments_on_cluster_id_and_status ON deployments USING btree (cluster_id, status);
|
||||
|
||||
CREATE INDEX index_deployments_on_created_at ON deployments USING btree (created_at);
|
||||
|
||||
CREATE INDEX index_deployments_on_deployable_type_and_deployable_id ON deployments USING btree (deployable_type, deployable_id);
|
||||
|
|
|
|||
|
|
@ -1136,7 +1136,7 @@ To find objects to display in a field, we can add resolvers to
|
|||
`app/graphql/resolvers`.
|
||||
|
||||
Arguments can be defined in the resolver in the same way as in a mutation.
|
||||
See the [Mutation arguments](#object-identifier-arguments) section.
|
||||
See the [Arguments](#arguments) section.
|
||||
|
||||
To limit the amount of queries performed, we can use [BatchLoader](graphql_guide/batchloader.md).
|
||||
|
||||
|
|
@ -1420,7 +1420,7 @@ We can use `#ready?` to perform set-up, validation, or early-return without invo
|
|||
|
||||
Good reasons to use `#ready?` include:
|
||||
|
||||
- Validating mutually exclusive arguments (see [validating arguments](#validating-arguments)).
|
||||
- Validating mutually exclusive arguments.
|
||||
- Returning `Relation.none` if we know before-hand that no results are possible.
|
||||
- Performing setup such as initializing instance variables (although consider lazily initialized methods for this).
|
||||
|
||||
|
|
@ -1625,85 +1625,6 @@ Examples:
|
|||
|
||||
If you need advice for mutation naming, canvass the Slack `#graphql` channel for feedback.
|
||||
|
||||
### Arguments
|
||||
|
||||
Arguments for a mutation are defined using `argument`.
|
||||
|
||||
Example:
|
||||
|
||||
```ruby
|
||||
argument :my_arg, GraphQL::Types::String,
|
||||
required: true,
|
||||
description: "A description of the argument."
|
||||
```
|
||||
|
||||
#### Nullability
|
||||
|
||||
Arguments can be marked as `required: true` which means the value must be present and not `null`.
|
||||
If a required argument's value can be `null`, use the `required: :nullable` declaration.
|
||||
|
||||
Example:
|
||||
|
||||
```ruby
|
||||
argument :due_date,
|
||||
Types::TimeType,
|
||||
required: :nullable,
|
||||
description: 'The desired due date for the issue. Due date is removed if null.'
|
||||
```
|
||||
|
||||
In the above example, the `due_date` argument must be given, but unlike the GraphQL spec, the value can be `null`.
|
||||
This allows 'unsetting' the due date in a single mutation rather than creating a new mutation for removing the due date.
|
||||
|
||||
```ruby
|
||||
{ due_date: null } # => OK
|
||||
{ due_date: "2025-01-10" } # => OK
|
||||
{ } # => invalid (not given)
|
||||
```
|
||||
|
||||
#### Keywords
|
||||
|
||||
Each GraphQL `argument` defined is passed to the `#resolve` method
|
||||
of a mutation as keyword arguments.
|
||||
|
||||
Example:
|
||||
|
||||
```ruby
|
||||
def resolve(my_arg:)
|
||||
# Perform mutation ...
|
||||
end
|
||||
```
|
||||
|
||||
#### Input Types
|
||||
|
||||
`graphql-ruby` wraps up arguments into an
|
||||
[input type](https://graphql.org/learn/schema/#input-types).
|
||||
|
||||
For example, the
|
||||
[`mergeRequestSetDraft` mutation](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/graphql/mutations/merge_requests/set_draft.rb)
|
||||
defines these arguments (some
|
||||
[through inheritance](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/graphql/mutations/merge_requests/base.rb)):
|
||||
|
||||
```ruby
|
||||
argument :project_path, GraphQL::Types::ID,
|
||||
required: true,
|
||||
description: "The project the merge request to mutate is in."
|
||||
|
||||
argument :iid, GraphQL::Types::String,
|
||||
required: true,
|
||||
description: "The IID of the merge request to mutate."
|
||||
|
||||
argument :draft,
|
||||
GraphQL::Types::Boolean,
|
||||
required: false,
|
||||
description: <<~DESC
|
||||
Whether or not to set the merge request as a draft.
|
||||
DESC
|
||||
```
|
||||
|
||||
These arguments automatically generate an input type called
|
||||
`MergeRequestSetDraftInput` with the 3 arguments we specified and the
|
||||
`clientMutationId`.
|
||||
|
||||
### Object identifier arguments
|
||||
|
||||
In keeping with the GitLab use of [Global IDs](#global-ids), mutation
|
||||
|
|
@ -2017,36 +1938,110 @@ code so that we have a single source of truth and we do not trigger a subscripti
|
|||
|
||||
For more information, see [GraphQL pagination](graphql_guide/pagination.md).
|
||||
|
||||
## Validating arguments
|
||||
## Arguments
|
||||
|
||||
For validations of single arguments, use the
|
||||
[`prepare` option](https://github.com/rmosolgo/graphql-ruby/blob/master/guides/fields/arguments.md)
|
||||
as usual.
|
||||
|
||||
Sometimes a mutation or resolver may accept a number of optional
|
||||
arguments, but we still want to validate that at least one of the optional
|
||||
arguments is provided. In this situation, consider using the `#ready?`
|
||||
method in your mutation or resolver to provide the validation. The
|
||||
`#ready?` method is called before any work is done in the
|
||||
`#resolve` method.
|
||||
[Arguments](https://graphql-ruby.org/fields/arguments.html) for a resolver or mutation are defined using `argument`.
|
||||
|
||||
Example:
|
||||
|
||||
```ruby
|
||||
def ready?(**args)
|
||||
if args.values_at(:body, :position).compact.blank?
|
||||
raise Gitlab::Graphql::Errors::ArgumentError,
|
||||
'body or position arguments are required'
|
||||
end
|
||||
argument :my_arg, GraphQL::Types::String,
|
||||
required: true,
|
||||
description: "A description of the argument."
|
||||
```
|
||||
|
||||
# Always remember to call `#super`
|
||||
super
|
||||
### Nullability
|
||||
|
||||
Arguments can be marked as `required: true` which means the value must be present and not `null`.
|
||||
If a required argument's value can be `null`, use the `required: :nullable` declaration.
|
||||
|
||||
Example:
|
||||
|
||||
```ruby
|
||||
argument :due_date,
|
||||
Types::TimeType,
|
||||
required: :nullable,
|
||||
description: 'The desired due date for the issue. Due date is removed if null.'
|
||||
```
|
||||
|
||||
In the above example, the `due_date` argument must be given, but unlike the GraphQL spec, the value can be `null`.
|
||||
This allows 'unsetting' the due date in a single mutation rather than creating a new mutation for removing the due date.
|
||||
|
||||
```ruby
|
||||
{ due_date: null } # => OK
|
||||
{ due_date: "2025-01-10" } # => OK
|
||||
{ } # => invalid (not given)
|
||||
```
|
||||
|
||||
#### Nullability and required: false
|
||||
|
||||
If an argument is marked `required: false` the client is permitted to send `null` as a value.
|
||||
Often this is undesirable.
|
||||
|
||||
If an argument is optional but `null` is not an allowed value, use validation to ensure that passing `null` returns an error:
|
||||
|
||||
```ruby
|
||||
argument :name, GraphQL::Types::String,
|
||||
required: false,
|
||||
validates: { allow_null: false }
|
||||
```
|
||||
|
||||
Alternatively, if you wish to allow `null` when it is not an allowed value, you can replace it with a default value:
|
||||
|
||||
```ruby
|
||||
argument :name, GraphQL::Types::String,
|
||||
required: false,
|
||||
default_value: "No Name Provided",
|
||||
replace_null_with_default: true
|
||||
```
|
||||
|
||||
See [Validation](https://graphql-ruby.org/fields/validation.html),
|
||||
[Nullability](https://graphql-ruby.org/fields/arguments.html#nullability) and
|
||||
[Default Values](https://graphql-ruby.org/fields/arguments.html#default-values) for more details.
|
||||
|
||||
### Keywords
|
||||
|
||||
Each GraphQL `argument` defined is passed to the `#resolve` method
|
||||
of a mutation as keyword arguments.
|
||||
|
||||
Example:
|
||||
|
||||
```ruby
|
||||
def resolve(my_arg:)
|
||||
# Perform mutation ...
|
||||
end
|
||||
```
|
||||
|
||||
In the future this may be able to be done using `OneOf Input Objects` if
|
||||
[this RFC](https://github.com/graphql/graphql-spec/pull/825)
|
||||
is merged.
|
||||
### Input Types
|
||||
|
||||
`graphql-ruby` wraps up arguments into an
|
||||
[input type](https://graphql.org/learn/schema/#input-types).
|
||||
|
||||
For example, the
|
||||
[`mergeRequestSetDraft` mutation](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/graphql/mutations/merge_requests/set_draft.rb)
|
||||
defines these arguments (some
|
||||
[through inheritance](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/graphql/mutations/merge_requests/base.rb)):
|
||||
|
||||
```ruby
|
||||
argument :project_path, GraphQL::Types::ID,
|
||||
required: true,
|
||||
description: "The project the merge request to mutate is in."
|
||||
|
||||
argument :iid, GraphQL::Types::String,
|
||||
required: true,
|
||||
description: "The IID of the merge request to mutate."
|
||||
|
||||
argument :draft,
|
||||
GraphQL::Types::Boolean,
|
||||
required: false,
|
||||
description: <<~DESC
|
||||
Whether or not to set the merge request as a draft.
|
||||
DESC
|
||||
```
|
||||
|
||||
These arguments automatically generate an input type called
|
||||
`MergeRequestSetDraftInput` with the 3 arguments we specified and the
|
||||
`clientMutationId`.
|
||||
|
||||
## GitLab custom scalars
|
||||
|
||||
|
|
@ -2133,7 +2128,7 @@ additional items:
|
|||
Integration tests can also verify the following items, because they invoke the
|
||||
full stack:
|
||||
|
||||
- An argument or scalar's [`prepare`](#validating-arguments) applies correctly.
|
||||
- An argument or scalar's validations apply correctly.
|
||||
- Logic in a resolver or mutation's [`#ready?` method](#correct-use-of-resolverready) applies correctly.
|
||||
- An [argument's `default_value`](https://graphql-ruby.org/fields/arguments.html) applies correctly.
|
||||
- Objects resolve successfully, and there are no N+1 issues.
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ GraphQL is a framework with many moving parts. It's important that the framework
|
|||
- Do not manually invoke framework bits. For example, do not instantiate resolvers during execution and instead let the framework do that.
|
||||
- You can subclass resolvers, as in `MyResolver.single` (see [deriving resolvers](../api_graphql_styleguide.md#deriving-resolvers)).
|
||||
- Use the `ready?` method for more complex argument logic (see [correct use of resolver#ready](../api_graphql_styleguide.md#correct-use-of-resolverready)).
|
||||
- Use the `prepare` method for more complex argument validation (see [validating arguments](../api_graphql_styleguide.md#validating-arguments)).
|
||||
- Use the `prepare` method for more complex argument validation (see [Preprocessing](https://graphql-ruby.org/fields/arguments.html#preprocessing)).
|
||||
|
||||
For details, see [resolver guide](../api_graphql_styleguide.md#writing-resolvers).
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ title = "gitleaks config"
|
|||
[[rules]]
|
||||
id = "gitlab_personal_access_token"
|
||||
description = "GitLab Personal Access Token"
|
||||
regex = '''glpat-[0-9a-zA-Z_\-]{20}'''
|
||||
regex = '''\bglpat-[0-9a-zA-Z_\-]{20}\b'''
|
||||
tags = ["gitlab", "revocation_type"]
|
||||
keywords = [
|
||||
"glpat",
|
||||
|
|
@ -15,7 +15,7 @@ keywords = [
|
|||
[[rules]]
|
||||
id = "gitlab_pipeline_trigger_token"
|
||||
description = "GitLab Pipeline Trigger Token"
|
||||
regex = '''glptt-[0-9a-zA-Z_\-]{20}'''
|
||||
regex = '''\bglptt-[0-9a-zA-Z_\-]{40}\b'''
|
||||
tags = ["gitlab"]
|
||||
keywords = [
|
||||
"glptt",
|
||||
|
|
@ -24,7 +24,7 @@ keywords = [
|
|||
[[rules]]
|
||||
id = "gitlab_runner_registration_token"
|
||||
description = "GitLab Runner Registration Token"
|
||||
regex = '''GR1348941[0-9a-zA-Z_\-]{20}'''
|
||||
regex = '''\bGR1348941[0-9a-zA-Z_\-]{20}\b'''
|
||||
tags = ["gitlab"]
|
||||
keywords = [
|
||||
"GR1348941",
|
||||
|
|
@ -33,17 +33,275 @@ keywords = [
|
|||
[[rules]]
|
||||
id = "gitlab_runner_auth_token"
|
||||
description = "GitLab Runner Authentication Token"
|
||||
regex = '''glrt-[0-9a-zA-Z_\-]{20}'''
|
||||
regex = '''\bglrt-[0-9a-zA-Z_\-]{20}\b'''
|
||||
tags = ["gitlab"]
|
||||
keywords = [
|
||||
"glrt",
|
||||
]
|
||||
|
||||
[[rules]]
|
||||
id = "gitlab_feed_token"
|
||||
id = "gitlab_oauth_app_secret"
|
||||
description = "GitLab OAuth Application Secrets"
|
||||
regex = '''\bgloas-[0-9a-zA-Z_\-]{64}\b'''
|
||||
tags = ["gitlab"]
|
||||
keywords = [
|
||||
"gloas",
|
||||
]
|
||||
|
||||
[[rules]]
|
||||
id = "gitlab_feed_token_v2"
|
||||
description = "GitLab Feed Token"
|
||||
regex = '''glft-[0-9a-zA-Z_\-]{20}'''
|
||||
regex = '''\bglft-[0-9a-zA-Z_\-]{20}\b'''
|
||||
tags = ["gitlab"]
|
||||
keywords = [
|
||||
"glft",
|
||||
]
|
||||
|
||||
[[rules]]
|
||||
id = "gitlab_kubernetes_agent_token"
|
||||
description = "GitLab Agent for Kubernetes token"
|
||||
regex = '''\bglagent-[0-9a-zA-Z_\-]{50}\b'''
|
||||
tags = ["gitlab"]
|
||||
keywords = [
|
||||
"glagent",
|
||||
]
|
||||
|
||||
[[rules]]
|
||||
id = "gitlab_incoming_email_token"
|
||||
description = "GitLab Incoming email token"
|
||||
regex = '''\bglimt-[0-9a-zA-Z_\-]{25}\b'''
|
||||
tags = ["gitlab"]
|
||||
keywords = [
|
||||
"glimt",
|
||||
]
|
||||
|
||||
[[rules]]
|
||||
id = "AWS"
|
||||
description = "AWS Access Token"
|
||||
regex = '''\bAKIA[0-9A-Z]{16}\b'''
|
||||
tags = ["aws", "revocation_type"]
|
||||
keywords = [
|
||||
"AKIA",
|
||||
]
|
||||
|
||||
[[rules]]
|
||||
id = "Github Personal Access Token"
|
||||
description = "Github Personal Access Token"
|
||||
regex = '''ghp_[0-9a-zA-Z]{36}'''
|
||||
keywords = [
|
||||
"ghp_",
|
||||
]
|
||||
|
||||
[[rules]]
|
||||
id = "Github OAuth Access Token"
|
||||
description = "Github OAuth Access Token"
|
||||
regex = '''gho_[0-9a-zA-Z]{36}'''
|
||||
keywords = [
|
||||
"gho_",
|
||||
]
|
||||
|
||||
[[rules]]
|
||||
id = "Github App Token"
|
||||
description = "Github App Token"
|
||||
regex = '''(ghu|ghs)_[0-9a-zA-Z]{36}'''
|
||||
keywords = [
|
||||
"ghu_",
|
||||
"ghs_"
|
||||
]
|
||||
|
||||
[[rules]]
|
||||
id = "Github Refresh Token"
|
||||
description = "Github Refresh Token"
|
||||
regex = '''ghr_[0-9a-zA-Z]{76}'''
|
||||
keywords = [
|
||||
"ghr_"
|
||||
]
|
||||
|
||||
[[rules]]
|
||||
id = "Shopify shared secret"
|
||||
description = "Shopify shared secret"
|
||||
regex = '''shpss_[a-fA-F0-9]{32}'''
|
||||
keywords = [
|
||||
"shpss_"
|
||||
]
|
||||
|
||||
[[rules]]
|
||||
id = "Shopify access token"
|
||||
description = "Shopify access token"
|
||||
regex = '''shpat_[a-fA-F0-9]{32}'''
|
||||
keywords = [
|
||||
"shpat_"
|
||||
]
|
||||
|
||||
[[rules]]
|
||||
id = "Shopify custom app access token"
|
||||
description = "Shopify custom app access token"
|
||||
regex = '''shpca_[a-fA-F0-9]{32}'''
|
||||
keywords = [
|
||||
"shpca_"
|
||||
]
|
||||
|
||||
[[rules]]
|
||||
id = "Shopify private app access token"
|
||||
description = "Shopify private app access token"
|
||||
regex = '''shppa_[a-fA-F0-9]{32}'''
|
||||
keywords = [
|
||||
"shppa_"
|
||||
]
|
||||
|
||||
[[rules]]
|
||||
id = "Slack token"
|
||||
description = "Slack token"
|
||||
regex = '''xox[baprs]-([0-9a-zA-Z]{10,48})'''
|
||||
keywords = [
|
||||
"xoxb","xoxa","xoxp","xoxr","xoxs",
|
||||
]
|
||||
|
||||
[[rules]]
|
||||
id = "Stripe"
|
||||
description = "Stripe"
|
||||
regex = '''(?i)(sk|pk)_(test|live)_[0-9a-z]{10,32}'''
|
||||
keywords = [
|
||||
"sk_test","pk_test","sk_live","pk_live",
|
||||
]
|
||||
|
||||
[[rules]]
|
||||
id = "PyPI upload token"
|
||||
description = "PyPI upload token"
|
||||
regex = '''pypi-AgEIcHlwaS5vcmc[A-Za-z0-9-_]{50,1000}'''
|
||||
tags = ["pypi", "revocation_type"]
|
||||
keywords = [
|
||||
"pypi-AgEIcHlwaS5vcmc",
|
||||
]
|
||||
|
||||
[[rules]]
|
||||
id = "Google (GCP) Service-account"
|
||||
description = "Google (GCP) Service-account"
|
||||
tags = ["gitlab_partner_token", "revocation_type"]
|
||||
regex = '''\"private_key\":\s*\"-{5}BEGIN PRIVATE KEY-{5}[\s\S]*?",'''
|
||||
keywords = [
|
||||
"service_account",
|
||||
]
|
||||
|
||||
[[rules]]
|
||||
id = "GCP API key"
|
||||
description = "GCP API keys can be misused to gain API quota from billed projects"
|
||||
tags = ["gitlab_partner_token", "revocation_type"]
|
||||
regex = '''(?i)\b(AIza[0-9A-Za-z-_]{35})(?:['|\"|\n|\r|\s|\x60|;]|$)'''
|
||||
secretGroup = 1
|
||||
keywords = [
|
||||
"AIza",
|
||||
]
|
||||
|
||||
[[rules]]
|
||||
id = "GCP OAuth client secret"
|
||||
description = "GCP OAuth client secrets can be misused to spoof your application"
|
||||
tags = ["gitlab_partner_token", "revocation_type"]
|
||||
regex = '''GOCSPX-[a-zA-Z0-9_-]{28}'''
|
||||
keywords = [
|
||||
"GOCSPX-",
|
||||
]
|
||||
|
||||
[[rules]]
|
||||
id = "Grafana API token"
|
||||
description = "Grafana API token"
|
||||
regex = '''['\"]eyJrIjoi(?i)[a-z0-9-_=]{72,92}['\"]'''
|
||||
keywords = [
|
||||
"grafana",
|
||||
]
|
||||
|
||||
[[rules]]
|
||||
id = "Hashicorp Terraform user/org API token"
|
||||
description = "Hashicorp Terraform user/org API token"
|
||||
regex = '''['\"](?i)[a-z0-9]{14}\.atlasv1\.[a-z0-9-_=]{60,70}['\"]'''
|
||||
keywords = [
|
||||
"atlasv1",
|
||||
"hashicorp",
|
||||
"terraform"
|
||||
]
|
||||
|
||||
[[rules]]
|
||||
id = "Hashicorp Vault batch token"
|
||||
description = "Hashicorp Vault batch token"
|
||||
regex = '''b\.AAAAAQ[0-9a-zA-Z_-]{156}'''
|
||||
keywords = [
|
||||
"hashicorp",
|
||||
"AAAAAQ",
|
||||
"vault"
|
||||
]
|
||||
|
||||
[[rules]]
|
||||
id = "Mailchimp API key"
|
||||
description = "Mailchimp API key"
|
||||
regex = '''(?i)(mailchimp[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-f0-9]{32}-us20)['\"]'''
|
||||
secretGroup = 3
|
||||
keywords = [
|
||||
"mailchimp",
|
||||
]
|
||||
|
||||
[[rules]]
|
||||
id = "Mailgun private API token"
|
||||
description = "Mailgun private API token"
|
||||
regex = '''(?i)(mailgun[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"](key-[a-f0-9]{32})['\"]'''
|
||||
secretGroup = 3
|
||||
keywords = [
|
||||
"mailgun",
|
||||
]
|
||||
|
||||
[[rules]]
|
||||
id = "Mailgun webhook signing key"
|
||||
description = "Mailgun webhook signing key"
|
||||
regex = '''(?i)(mailgun[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([a-h0-9]{32}-[a-h0-9]{8}-[a-h0-9]{8})['\"]'''
|
||||
secretGroup = 3
|
||||
keywords = [
|
||||
"mailgun",
|
||||
]
|
||||
|
||||
[[rules]]
|
||||
id = "New Relic user API Key"
|
||||
description = "New Relic user API Key"
|
||||
regex = '''['\"](NRAK-[A-Z0-9]{27})['\"]'''
|
||||
keywords = [
|
||||
"NRAK",
|
||||
]
|
||||
|
||||
[[rules]]
|
||||
id = "New Relic user API ID"
|
||||
description = "New Relic user API ID"
|
||||
regex = '''(?i)(newrelic[a-z0-9_ .\-,]{0,25})(=|>|:=|\|\|:|<=|=>|:).{0,5}['\"]([A-Z0-9]{64})['\"]'''
|
||||
secretGroup = 3
|
||||
keywords = [
|
||||
"newrelic",
|
||||
]
|
||||
|
||||
[[rules]]
|
||||
id = "npm access token"
|
||||
description = "npm access token"
|
||||
regex = '''['\"](npm_(?i)[a-z0-9]{36})['\"]'''
|
||||
keywords = [
|
||||
"npm_",
|
||||
]
|
||||
|
||||
[[rules]]
|
||||
id = "Rubygem API token"
|
||||
description = "Rubygem API token"
|
||||
regex = '''rubygems_[a-f0-9]{48}'''
|
||||
keywords = [
|
||||
"rubygems_",
|
||||
]
|
||||
|
||||
[[rules]]
|
||||
id = "Segment Public API token"
|
||||
description = "Segment Public API token"
|
||||
regex = '''sgp_[a-zA-Z0-9]{64}'''
|
||||
keywords = [
|
||||
"sgp_",
|
||||
]
|
||||
|
||||
[[rules]]
|
||||
id = "Sendgrid API token"
|
||||
description = "Sendgrid API token"
|
||||
regex = '''SG\.(?i)[a-z0-9_\-\.]{66}'''
|
||||
keywords = [
|
||||
"sendgrid",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ RSpec.describe Gitlab::SecretDetection::Scan, feature_category: :secret_detectio
|
|||
{
|
||||
"id" => "gitlab_pipeline_trigger_token",
|
||||
"description" => "GitLab Pipeline Trigger Token",
|
||||
"regex" => "glptt-[0-9a-zA-Z_\\-]{20}",
|
||||
"regex" => "glptt-[0-9a-zA-Z_\\-]{40}",
|
||||
"tags" => ["gitlab"],
|
||||
"keywords" => ["glptt"]
|
||||
},
|
||||
|
|
@ -35,7 +35,7 @@ RSpec.describe Gitlab::SecretDetection::Scan, feature_category: :secret_detectio
|
|||
"keywords" => ["GR1348941"]
|
||||
},
|
||||
{
|
||||
"id" => "gitlab_feed_token",
|
||||
"id" => "gitlab_feed_token_v2",
|
||||
"description" => "GitLab Feed Token",
|
||||
"regex" => "glft-[0-9a-zA-Z_-]{20}",
|
||||
"tags" => ["gitlab"],
|
||||
|
|
@ -96,7 +96,7 @@ RSpec.describe Gitlab::SecretDetection::Scan, feature_category: :secret_detectio
|
|||
let(:blobs) do
|
||||
[
|
||||
new_blob(id: 111, data: "glpat-12312312312312312312"), # gitleaks:allow
|
||||
new_blob(id: 222, data: "\n\nglptt-12312312312312312312"), # gitleaks:allow
|
||||
new_blob(id: 222, data: "\n\nglptt-1231231231231231231212312312312312312312"), # gitleaks:allow
|
||||
new_blob(id: 333, data: "data with no secret"),
|
||||
new_blob(id: 444, data: "GR134894112312312312312312312\nglft-12312312312312312312") # gitleaks:allow
|
||||
]
|
||||
|
|
|
|||
|
|
@ -6,31 +6,31 @@ module QA
|
|||
module Settings
|
||||
class Integrations < QA::Page::Base
|
||||
view 'app/assets/javascripts/integrations/index/components/integrations_table.vue' do
|
||||
element :jenkins_link, %q(:data-qa-selector="`${item.name}_link`") # rubocop:disable QA/ElementWithPattern
|
||||
element :prometheus_link, %q(:data-qa-selector="`${item.name}_link`") # rubocop:disable QA/ElementWithPattern
|
||||
element :jira_link, %q(:data-qa-selector="`${item.name}_link`") # rubocop:disable QA/ElementWithPattern
|
||||
element :pipelines_email_link, %q(:data-qa-selector="`${item.name}_link`") # rubocop:disable QA/ElementWithPattern
|
||||
element :gitlab_slack_application_link, %q(:data-qa-selector="`${item.name}_link`") # rubocop:disable QA/ElementWithPattern
|
||||
element 'jenkins-link', %q(:data-testid="`${item.name}-link`") # rubocop:disable QA/ElementWithPattern -- required for qa:selectors job to pass
|
||||
element 'prometheus-link', %q(:data-testid="`${item.name}-link`") # rubocop:disable QA/ElementWithPattern -- required for qa:selectors job to pass
|
||||
element 'jira-link', %q(:data-testid="`${item.name}-link`") # rubocop:disable QA/ElementWithPattern -- required for qa:selectors job to pass
|
||||
element 'pipelines_email-link', %q(:data-testid="`${item.name}-link`") # rubocop:disable QA/ElementWithPattern -- required for qa:selectors job to pass
|
||||
element 'gitlab_slack_application-link', %q(:data-testid="`${item.name}-link`") # rubocop:disable QA/ElementWithPattern -- required for qa:selectors job to pass
|
||||
end
|
||||
|
||||
def click_on_prometheus_integration
|
||||
click_element :prometheus_link
|
||||
click_element('prometheus-link')
|
||||
end
|
||||
|
||||
def click_pipelines_email_link
|
||||
click_element :pipelines_email_link
|
||||
click_element('pipelines_email-link')
|
||||
end
|
||||
|
||||
def click_jira_link
|
||||
click_element :jira_link
|
||||
click_element('jira-link')
|
||||
end
|
||||
|
||||
def click_jenkins_ci_link
|
||||
click_element :jenkins_link
|
||||
click_element('jenkins-link')
|
||||
end
|
||||
|
||||
def click_slack_application_link
|
||||
click_element :gitlab_slack_application_link
|
||||
click_element('gitlab_slack_application-link')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -26,6 +26,18 @@ RSpec.describe ReleasesFinder, feature_category: :release_orchestration do
|
|||
end
|
||||
end
|
||||
|
||||
shared_examples_for 'when a release is tagless' do
|
||||
# There shouldn't be tags in this state, but because some exist in production and cause page loading errors, this
|
||||
# test exists. We can test empty string but not the nil value since there is a not null constraint at the database
|
||||
# level.
|
||||
it 'does not return the tagless release' do
|
||||
empty_string_tag = create(:release, project: project, tag: 'v99.0.0')
|
||||
empty_string_tag.update_column(:tag, '')
|
||||
|
||||
expect(subject).not_to include(empty_string_tag)
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples_for 'preload' do
|
||||
it 'preloads associations' do
|
||||
expect(Release).to receive(:preloaded).once.and_call_original
|
||||
|
|
@ -89,6 +101,7 @@ RSpec.describe ReleasesFinder, feature_category: :release_orchestration do
|
|||
|
||||
it_behaves_like 'preload'
|
||||
it_behaves_like 'when a tag parameter is passed'
|
||||
it_behaves_like 'when a release is tagless'
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -132,6 +145,7 @@ RSpec.describe ReleasesFinder, feature_category: :release_orchestration do
|
|||
|
||||
it_behaves_like 'preload'
|
||||
it_behaves_like 'when a tag parameter is passed'
|
||||
it_behaves_like 'when a release is tagless'
|
||||
|
||||
context 'with sorting parameters' do
|
||||
it 'sorted by released_at in descending order by default' do
|
||||
|
|
@ -223,6 +237,7 @@ RSpec.describe ReleasesFinder, feature_category: :release_orchestration do
|
|||
end
|
||||
|
||||
it_behaves_like 'preload'
|
||||
it_behaves_like 'when a release is tagless'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -122,6 +122,20 @@ RSpec.describe Release, feature_category: :release_orchestration do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'tagged' do
|
||||
# We only test for empty string since there's a not null constraint at the database level
|
||||
it 'does not return the tagless release' do
|
||||
empty_string_tag = create(:release, tag: 'v99.0.0')
|
||||
empty_string_tag.update_column(:tag, '')
|
||||
|
||||
expect(described_class.tagged).not_to include(empty_string_tag)
|
||||
end
|
||||
|
||||
it 'does return the tagged releases' do
|
||||
expect(described_class.tagged).to include(release)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'latest releases' do
|
||||
let_it_be(:yesterday) { Time.zone.now - 1.day }
|
||||
let_it_be(:tomorrow) { Time.zone.now + 1.day }
|
||||
|
|
|
|||
Loading…
Reference in New Issue