Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2025-07-02 12:13:07 +00:00
parent 4743299a37
commit 36aae58f55
89 changed files with 639 additions and 275 deletions

View File

@ -2780,6 +2780,8 @@
.releases:rules:canonical-dot-com-security-gitlab-stable-branch-only:
rules:
# Run release environment related jobs for initial RC tag pipelines - https://gitlab.com/gitlab-com/gl-infra/delivery/-/issues/21267
- if: '$CI_SERVER_HOST == "gitlab.com" && $CI_PROJECT_PATH == "gitlab-org/security/gitlab" && $CI_COMMIT_REF_NAME =~ /^v?[\d.]+-rc42-ee$/'
- if: '$CI_COMMIT_MESSAGE =~ /\[merge-train skip\]/'
when: never
- if: '$CI_SERVER_HOST == "gitlab.com" && $CI_PROJECT_PATH == "gitlab-org/security/gitlab" && $CI_COMMIT_REF_NAME =~ /^[\d-]+-stable-ee$/'

View File

@ -3,26 +3,6 @@
InternalAffairs/NodeMatcherDirective:
Details: grace period
Exclude:
- 'rubocop/cop/gitlab/policy_rule_boolean.rb'
- 'rubocop/cop/gitlab/rails/safe_format.rb'
- 'rubocop/cop/gitlab/rails_logger.rb'
- 'rubocop/cop/gitlab/service_response.rb'
- 'rubocop/cop/gitlab/strong_memoize_attr.rb'
- 'rubocop/cop/gitlab/token_without_prefix.rb'
- 'rubocop/cop/gitlab/union.rb'
- 'rubocop/cop/graphql/authorize_types.rb'
- 'rubocop/cop/graphql/descriptions.rb'
- 'rubocop/cop/graphql/enum_names.rb'
- 'rubocop/cop/graphql/enum_values.rb'
- 'rubocop/cop/graphql/graphql_name_position.rb'
- 'rubocop/cop/graphql/id_type.rb'
- 'rubocop/cop/graphql/json_type.rb'
- 'rubocop/cop/graphql/old_types.rb'
- 'rubocop/cop/graphql/resolver_type.rb'
- 'rubocop/cop/graphql/resource_not_available_error.rb'
- 'rubocop/cop/group_public_or_visible_to_user.rb'
- 'rubocop/cop/ignored_columns.rb'
- 'rubocop/cop/include_sidekiq_worker.rb'
- 'rubocop/cop/migration/add_concurrent_foreign_key.rb'
- 'rubocop/cop/migration/add_limit_to_text_columns.rb'
- 'rubocop/cop/migration/background_migration_missing_active_concern.rb'

View File

@ -1 +1 @@
9a72666ea3a0a18d2f02d2821b880daee41d9767
02eb9160dd6a4825e892b22eb5543c5c1da5cc65

View File

@ -1 +1 @@
6c90dbb27ce3609304d71ffcd2b8113a08590f5c
70acd17ccd04ef784f793b1b00a84873e798b1dd

View File

@ -286,6 +286,14 @@ module Ci
end
end
def enqueue_immediately?
redis_state.enqueue_immediately?
end
def set_enqueue_immediately!
redis_state.enqueue_immediately = true
end
private
def dependencies

View File

@ -89,24 +89,6 @@ module Ci
ensure_metadata.id_tokens = value
end
def enqueue_immediately?
if Feature.enabled?(:ci_redis_enqueue_immediately, project)
redis_state.enqueue_immediately?
else
!!options[:enqueue_immediately]
end
end
def set_enqueue_immediately!
if Feature.enabled?(:ci_redis_enqueue_immediately, project)
redis_state.enqueue_immediately = true
else
# ensures that even if `config_options: nil` in the database we set the
# new value correctly.
self.options = options.merge(enqueue_immediately: true)
end
end
# TODO: Update this logic when column `p_ci_builds.debug_trace_enabled` is added.
# See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/194954#note_2574776849.
def debug_trace_enabled?

View File

@ -289,7 +289,7 @@ module MergeRequests
end
def trigger_user_merge_request_updated(merge_request)
[merge_request.assignees, merge_request.reviewers].flatten.uniq.each do |user|
[merge_request.author, *merge_request.assignees, *merge_request.reviewers].uniq.each do |user|
GraphqlTriggers.user_merge_request_updated(user, merge_request)
end
end

View File

@ -34,6 +34,7 @@ module MergeRequests
cleanup_refs(merge_request)
deactivate_pages_deployments(merge_request)
cancel_auto_merges_targeting_source_branch(merge_request)
trigger_user_merge_request_updated(merge_request)
execute_hooks(merge_request, 'merge')
end

View File

@ -43,7 +43,6 @@ module PersonalAccessTokens
def needs_update?
return false if ::Gitlab::Database.read_only?
return true unless Feature.enabled?(:pat_last_used_at_optimization, :request)
last_used_ip_needs_update? || last_used_at_needs_update?
end

View File

@ -5,4 +5,5 @@ class ExternalServiceReactiveCachingWorker # rubocop:disable Scalability/Idempot
worker_has_external_dependencies!
worker_resource_boundary :cpu
data_consistency :sticky
end

View File

@ -1,10 +0,0 @@
---
name: ci_redis_enqueue_immediately
description:
feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/work_items/549077
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/194746
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/550225
milestone: '18.2'
group: group::ci platform
type: gitlab_com_derisk
default_enabled: false

View File

@ -1,10 +0,0 @@
---
name: pat_last_used_at_optimization
description: PersonalAccessTokens::LastUsedService#execute will return early to check if the PAT needs update before obtaining exclusive lease. This reduces Redis SharedState load (from exclusive lease) but will increase DB queries (to check if PAT needs update based on last used IP).
feature_issue_url: https://gitlab.com/gitlab-com/gl-infra/data-access/durability/team/-/issues/198
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/193010
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/547121
milestone: '18.1'
group: group::authentication
type: gitlab_com_derisk
default_enabled: false

View File

@ -17,7 +17,11 @@ Doorkeeper.configure do
else
# Ensure user is redirected to redirect_uri after login
session[:user_return_to] = request.fullpath
redirect_to(new_user_session_url)
namespace_path = request.query_parameters['top_level_namespace_path']
resolver = Gitlab::Auth::OAuth::OauthResourceOwnerRedirectResolver.new(namespace_path)
redirect_to(resolver.resolve_redirect_url)
nil
end
end

View File

@ -3,6 +3,6 @@ migration_job_name: BackfillArchivedAndTraversalIdsToVulnerabilityStatistics
description: Backfill project.archived and project.namespace.traversal_ids values to the denormalized columns of the same name on vulnerability_statistics
feature_category: vulnerability_management
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/177993
milestone: '17.11'
queued_migration_version: 20250404035239
milestone: '18.2'
queued_migration_version: 20250630065826
finalized_by: 20250422130050

View File

@ -0,0 +1,9 @@
# frozen_string_literal: true
class AddNamespaceIdToDuoWorkflowsWorkflows < Gitlab::Database::Migration[2.3]
milestone '18.2'
def change
add_column :duo_workflows_workflows, :namespace_id, :bigint
end
end

View File

@ -0,0 +1,9 @@
# frozen_string_literal: true
class AddNamespaceIdToDuoWorkflowsCheckpoints < Gitlab::Database::Migration[2.3]
milestone '18.2'
def change
add_column :duo_workflows_checkpoints, :namespace_id, :bigint
end
end

View File

@ -0,0 +1,9 @@
# frozen_string_literal: true
class AddNamespaceIdToDuoWorkflowsEvents < Gitlab::Database::Migration[2.3]
milestone '18.2'
def change
add_column :duo_workflows_events, :namespace_id, :bigint
end
end

View File

@ -0,0 +1,9 @@
# frozen_string_literal: true
class AddNamespaceIdToDuoWorkflowsCheckpointWrites < Gitlab::Database::Migration[2.3]
milestone '18.2'
def change
add_column :duo_workflows_checkpoint_writes, :namespace_id, :bigint
end
end

View File

@ -0,0 +1,18 @@
# frozen_string_literal: true
class AddIndexToDuoWorkflowsWorkflowsOnNamespaceId < Gitlab::Database::Migration[2.3]
milestone '18.2'
disable_ddl_transaction!
TABLE_NAME = :duo_workflows_workflows
INDEX_NAME = "index_duo_workflows_workflows_on_namespace_id"
def up
add_concurrent_index TABLE_NAME, :namespace_id, name: INDEX_NAME
end
def down
remove_concurrent_index_by_name TABLE_NAME, INDEX_NAME
end
end

View File

@ -0,0 +1,18 @@
# frozen_string_literal: true
class AddIndexToDuoWorkflowsCheckpointsOnNamespaceId < Gitlab::Database::Migration[2.3]
milestone '18.2'
disable_ddl_transaction!
TABLE_NAME = :duo_workflows_checkpoints
INDEX_NAME = "index_duo_workflows_checkpoints_on_namespace_id"
def up
add_concurrent_index TABLE_NAME, :namespace_id, name: INDEX_NAME
end
def down
remove_concurrent_index_by_name TABLE_NAME, INDEX_NAME
end
end

View File

@ -0,0 +1,18 @@
# frozen_string_literal: true
class AddIndexToDuoWorkflowsEventsOnNamespaceId < Gitlab::Database::Migration[2.3]
milestone '18.2'
disable_ddl_transaction!
TABLE_NAME = :duo_workflows_events
INDEX_NAME = "index_duo_workflows_events_on_namespace_id"
def up
add_concurrent_index TABLE_NAME, :namespace_id, name: INDEX_NAME
end
def down
remove_concurrent_index_by_name TABLE_NAME, INDEX_NAME
end
end

View File

@ -0,0 +1,18 @@
# frozen_string_literal: true
class AddIndexToDuoWorkflowsCheckpointWritesOnNamespaceId < Gitlab::Database::Migration[2.3]
milestone '18.2'
disable_ddl_transaction!
TABLE_NAME = :duo_workflows_checkpoint_writes
INDEX_NAME = "index_duo_workflows_checkpoint_writes_on_namespace_id"
def up
add_concurrent_index TABLE_NAME, :namespace_id, name: INDEX_NAME
end
def down
remove_concurrent_index_by_name TABLE_NAME, INDEX_NAME
end
end

View File

@ -0,0 +1,17 @@
# frozen_string_literal: true
class AddNamespaceIdFkToDuoWorkflowsWorkflows < Gitlab::Database::Migration[2.3]
milestone '18.2'
disable_ddl_transaction!
def up
add_concurrent_foreign_key :duo_workflows_workflows, :namespaces, column: :namespace_id, on_delete: :cascade
end
def down
with_lock_retries do
remove_foreign_key_if_exists :duo_workflows_workflows, column: :namespace_id
end
end
end

View File

@ -0,0 +1,17 @@
# frozen_string_literal: true
class AddNamespaceIdFkToDuoWorkflowsCheckpoints < Gitlab::Database::Migration[2.3]
milestone '18.2'
disable_ddl_transaction!
def up
add_concurrent_foreign_key :duo_workflows_checkpoints, :namespaces, column: :namespace_id, on_delete: :cascade
end
def down
with_lock_retries do
remove_foreign_key_if_exists :duo_workflows_checkpoints, column: :namespace_id
end
end
end

View File

@ -0,0 +1,17 @@
# frozen_string_literal: true
class AddNamespaceIdFkToDuoWorkflowsEvents < Gitlab::Database::Migration[2.3]
milestone '18.2'
disable_ddl_transaction!
def up
add_concurrent_foreign_key :duo_workflows_events, :namespaces, column: :namespace_id, on_delete: :cascade
end
def down
with_lock_retries do
remove_foreign_key_if_exists :duo_workflows_events, column: :namespace_id
end
end
end

View File

@ -0,0 +1,17 @@
# frozen_string_literal: true
class AddNamespaceIdFkToDuoWorkflowsCheckpointWrites < Gitlab::Database::Migration[2.3]
milestone '18.2'
disable_ddl_transaction!
def up
add_concurrent_foreign_key :duo_workflows_checkpoint_writes, :namespaces, column: :namespace_id, on_delete: :cascade
end
def down
with_lock_retries do
remove_foreign_key_if_exists :duo_workflows_checkpoint_writes, column: :namespace_id
end
end
end

View File

@ -3,27 +3,15 @@
class RequeueBackfillArchivedAndTraversalIdsToVulnerabilityStatistics < Gitlab::Database::Migration[2.2]
milestone '17.11'
restrict_gitlab_migration gitlab_schema: :gitlab_sec
MIGRATION = "BackfillArchivedAndTraversalIdsToVulnerabilityStatistics"
DELAY_INTERVAL = 2.minutes
BATCH_SIZE = 1000
SUB_BATCH_SIZE = 100
def up
delete_batched_background_migration(MIGRATION, :vulnerability_statistics, :id, [])
queue_batched_background_migration(
MIGRATION,
:vulnerability_statistics,
:id,
job_interval: DELAY_INTERVAL,
batch_size: BATCH_SIZE,
sub_batch_size: SUB_BATCH_SIZE
)
# no-op
# requeue'ing once more to ensure that all vulnerability_statistics records have
# their traversal_ids and archived columns correctly set.
end
def down
delete_batched_background_migration(MIGRATION, :vulnerability_statistics, :id, [])
# no-op
end
end

View File

@ -0,0 +1,28 @@
# frozen_string_literal: true
class RequeueBackfillArchivedAndTraversalIdsToVulnerabilityStatisticsV2 < Gitlab::Database::Migration[2.3]
milestone '18.2'
restrict_gitlab_migration gitlab_schema: :gitlab_sec
MIGRATION = "BackfillArchivedAndTraversalIdsToVulnerabilityStatistics"
DELAY_INTERVAL = 2.minutes
BATCH_SIZE = 1000
SUB_BATCH_SIZE = 100
def up
delete_batched_background_migration(MIGRATION, :vulnerability_statistics, :id, [])
queue_batched_background_migration(
MIGRATION,
:vulnerability_statistics,
:id,
job_interval: DELAY_INTERVAL,
batch_size: BATCH_SIZE,
sub_batch_size: SUB_BATCH_SIZE
)
end
def down
delete_batched_background_migration(MIGRATION, :vulnerability_statistics, :id, [])
end
end

View File

@ -0,0 +1 @@
f85570e808e43874f01f101f4bab6acb7421ccd305095a3ae4e94ce70af95ff7

View File

@ -0,0 +1 @@
bb69920904fcdd5be8150ef281be7fa5b1c67e58c76ac2b267fd22b7d48efbe9

View File

@ -0,0 +1 @@
5b61ce406ec11414f67fe57b6443982cd657083e1b8631d136a522540d5a6e9e

View File

@ -0,0 +1 @@
289091a8d62edd23897e606bb631a987371b72fb388d2b56ab8697ccec185b45

View File

@ -0,0 +1 @@
415310ea40da54cb06ed2896b7290b27460a4b71b1e3ae13c9ecbc979401bd2f

View File

@ -0,0 +1 @@
4003d8a20a087f76e19a4738f6922378f4902082339b85a5816e04899a6c5504

View File

@ -0,0 +1 @@
9187c536cfc4c114bce915372ced7095a660d61e029d03b942f11ec9b02a0382

View File

@ -0,0 +1 @@
d1d552ae62ad5c130bc396006d46ae6fccb4bafbe4b432c88515e4acbdbfc40b

View File

@ -0,0 +1 @@
060b445192ea7b6d5aee6d3875544a1bac2507e1e614b2cb0380ed21705f8d43

View File

@ -0,0 +1 @@
6b3e68b7fb486214c1fa4fcab587768d3a17eee61a486884a2e90eab18727f8e

View File

@ -0,0 +1 @@
289af09f92d109553e6da339bc0b267537304c30e58dcd05d3e0b0ea53273b35

View File

@ -0,0 +1 @@
d7b4e73b4c3948a1aa4b1b43bb8c1261e39d729fa1e130f652773eb0d2031cf3

View File

@ -0,0 +1 @@
0ab861f394be58c6fd78c70ce08df162f2d3089808f7b1248a2198c97828b9ca

View File

@ -14245,6 +14245,7 @@ CREATE TABLE duo_workflows_checkpoint_writes (
channel text NOT NULL,
write_type text NOT NULL,
data text NOT NULL,
namespace_id bigint,
CONSTRAINT check_38dc205bb2 CHECK ((char_length(data) <= 10000)),
CONSTRAINT check_c64af76670 CHECK ((char_length(write_type) <= 255)),
CONSTRAINT check_d66d09c813 CHECK ((char_length(task) <= 255)),
@ -14271,6 +14272,7 @@ CREATE TABLE duo_workflows_checkpoints (
parent_ts text,
checkpoint jsonb NOT NULL,
metadata jsonb NOT NULL,
namespace_id bigint,
CONSTRAINT check_3dcc551d16 CHECK ((char_length(parent_ts) <= 255)),
CONSTRAINT check_5d3139b983 CHECK ((char_length(thread_ts) <= 255))
);
@ -14294,6 +14296,7 @@ CREATE TABLE duo_workflows_events (
event_status smallint NOT NULL,
message text,
correlation_id_value text,
namespace_id bigint,
CONSTRAINT check_125840165c CHECK ((char_length(message) <= 16384)),
CONSTRAINT check_5e35596b00 CHECK ((char_length(correlation_id_value) <= 128))
);
@ -14321,6 +14324,7 @@ CREATE TABLE duo_workflows_workflows (
pre_approved_agent_privileges smallint[] DEFAULT '{1,2}'::smallint[] NOT NULL,
image text,
environment smallint,
namespace_id bigint,
CONSTRAINT check_30ca07a4ef CHECK ((char_length(goal) <= 16384)),
CONSTRAINT check_3a9162f1ae CHECK ((char_length(image) <= 2048)),
CONSTRAINT check_ec723e2a1a CHECK ((char_length(workflow_definition) <= 255))
@ -35411,18 +35415,26 @@ CREATE INDEX index_draft_notes_on_merge_request_id ON draft_notes USING btree (m
CREATE INDEX index_draft_notes_on_project_id ON draft_notes USING btree (project_id);
CREATE INDEX index_duo_workflows_checkpoint_writes_on_namespace_id ON duo_workflows_checkpoint_writes USING btree (namespace_id);
CREATE INDEX index_duo_workflows_checkpoint_writes_on_project_id ON duo_workflows_checkpoint_writes USING btree (project_id);
CREATE INDEX index_duo_workflows_checkpoint_writes_thread_ts ON duo_workflows_checkpoint_writes USING btree (workflow_id, thread_ts);
CREATE INDEX index_duo_workflows_checkpoints_on_namespace_id ON duo_workflows_checkpoints USING btree (namespace_id);
CREATE INDEX index_duo_workflows_checkpoints_on_project_id ON duo_workflows_checkpoints USING btree (project_id);
CREATE INDEX index_duo_workflows_events_on_namespace_id ON duo_workflows_events USING btree (namespace_id);
CREATE INDEX index_duo_workflows_events_on_project_id ON duo_workflows_events USING btree (project_id);
CREATE INDEX index_duo_workflows_events_on_workflow_id ON duo_workflows_events USING btree (workflow_id);
CREATE UNIQUE INDEX index_duo_workflows_workflow_checkpoints_unique_thread ON duo_workflows_checkpoints USING btree (workflow_id, thread_ts);
CREATE INDEX index_duo_workflows_workflows_on_namespace_id ON duo_workflows_workflows USING btree (namespace_id);
CREATE INDEX index_duo_workflows_workflows_on_project_id ON duo_workflows_workflows USING btree (project_id);
CREATE INDEX index_duo_workflows_workflows_on_user_id ON duo_workflows_workflows USING btree (user_id);
@ -42879,6 +42891,9 @@ ALTER TABLE p_ci_builds
ALTER TABLE ONLY draft_notes
ADD CONSTRAINT fk_3ac2bcb746 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
ALTER TABLE ONLY duo_workflows_checkpoint_writes
ADD CONSTRAINT fk_3ad0964729 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
ALTER TABLE ONLY agent_activity_events
ADD CONSTRAINT fk_3af186389b FOREIGN KEY (merge_request_id) REFERENCES merge_requests(id) ON DELETE SET NULL;
@ -43233,6 +43248,9 @@ ALTER TABLE ONLY import_placeholder_memberships
ALTER TABLE p_ci_builds
ADD CONSTRAINT fk_6661f4f0e8 FOREIGN KEY (resource_group_id) REFERENCES ci_resource_groups(id) ON DELETE SET NULL;
ALTER TABLE ONLY duo_workflows_events
ADD CONSTRAINT fk_674e493798 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
ALTER TABLE ONLY routes
ADD CONSTRAINT fk_679ff8213d FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE NOT VALID;
@ -43368,6 +43386,9 @@ ALTER TABLE ONLY scan_result_policy_violations
ALTER TABLE ONLY approval_project_rules
ADD CONSTRAINT fk_773289d10b FOREIGN KEY (approval_policy_rule_id) REFERENCES approval_policy_rules(id) ON DELETE CASCADE;
ALTER TABLE ONLY duo_workflows_checkpoints
ADD CONSTRAINT fk_779e1a4594 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
ALTER TABLE ONLY agent_user_access_project_authorizations
ADD CONSTRAINT fk_78034b05d8 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
@ -43446,6 +43467,9 @@ ALTER TABLE ONLY namespaces
ALTER TABLE ONLY pages_domain_acme_orders
ADD CONSTRAINT fk_7fa123c002 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
ALTER TABLE ONLY duo_workflows_workflows
ADD CONSTRAINT fk_7fcf81369f FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
ALTER TABLE ONLY group_import_states
ADD CONSTRAINT fk_8053b3ebd6 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;

View File

@ -1,6 +1,6 @@
---
stage: Systems
group: Cloud Connector
stage: Developer Experience
group: Performance Enablement
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
gitlab_dedicated: yes
title: Performance bar

View File

@ -199,7 +199,7 @@ The following API resources are available outside of project and group contexts
| [Merge requests](merge_requests.md) | `/merge_requests` (also available for groups and projects) |
| [Namespaces](namespaces.md) | `/namespaces` |
| [Notification settings](notification_settings.md) | `/notification_settings` (also available for groups and projects) |
| [Policy settings](policy_settings.md) | `/admin/security/policy_settings` |
| [Compliance and Policy settings](compliance_policy_settings.md) | `/admin/security/compliance_policy_settings` |
| [Pages domains](pages_domains.md) | `/pages/domains` (also available for projects) |
| [Personal access tokens](personal_access_tokens.md) | `/personal_access_tokens` |
| [Plan limits](plan_limits.md) | `/application/plan_limits` |

View File

@ -0,0 +1,90 @@
---
stage: Security Risk Management
group: Security Policies
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
title: Compliance and policy settings API
---
{{< details >}}
- Tier: Ultimate
- Offering: GitLab Self-Managed
{{< /details >}}
{{< history >}}
- [Introduced](https://issue-link) in GitLab 18.2 [with a flag](../administration/feature_flags/_index.md) named `security_policies_csp`. Disabled by default.
{{< /history >}}
{{< alert type="flag" >}}
The availability of this feature is controlled by a feature flag. For more information, see the history.
{{< /alert >}}
Use this API to interact with the security policy settings for your GitLab instance.
Prerequisites:
- You must have administrator access to the instance.
- Your instance must have the Ultimate tier to use security policies.
## Get security policy settings
Gets the current security policy settings for this GitLab instance.
```plaintext
GET /admin/security/compliance_policy_settings
```
```shell
curl --request GET \
--header "PRIVATE-TOKEN: <your_access_token>" \
--url "https://gitlab.example.com/api/v4/admin/security/compliance_policy_settings"
```
Example response:
```json
{
"csp_namespace_id": 42
}
```
When no CSP namespace is configured:
```json
{
"csp_namespace_id": null
}
```
## Update security policy settings
Updates the security policy settings for this GitLab instance.
```plaintext
PUT /admin/security/compliance_policy_settings
```
| Attribute | Type | Required | Description |
|:------------------|:--------|:---------|:------------|
| `csp_namespace_id` | integer | yes | ID of the group designated to centrally manage security policies. Must be a top-level group. Set to `null` to clear the setting. |
```shell
curl --request PUT \
--header "PRIVATE-TOKEN: <your_access_token>" \
--header "Content-Type: application/json" \
--data '{"csp_namespace_id": 42}' \
--url "https://gitlab.example.com/api/v4/admin/security/compliance_policy_settings"
```
Example response:
```json
{
"csp_namespace_id": 42
}
```

View File

@ -16023,6 +16023,17 @@ The edge type for [`Dependency`](#dependency).
| <a id="dependencyedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
| <a id="dependencyedgenode"></a>`node` | [`Dependency`](#dependency) | The item at the end of the edge. |
#### `DependencyPathEdge`
The edge type for [`DependencyPath`](#dependencypath).
##### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="dependencypathedgecursor"></a>`cursor` | [`String!`](#string) | Cursor for use in pagination. |
| <a id="dependencypathedgenode"></a>`node` | [`DependencyPath`](#dependencypath) | Dependency path node. |
#### `DependencyProxyBlobConnection`
The connection type for [`DependencyProxyBlob`](#dependencyproxyblob).
@ -26303,9 +26314,31 @@ Ancestor path of a given dependency.
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="dependencypathiscyclic"></a>`isCyclic` | [`Boolean!`](#boolean) | Indicates if the path is cyclic. |
| <a id="dependencypathmaxdepthreached"></a>`maxDepthReached` | [`Boolean!`](#boolean) | Indicates if the path reached the maximum depth (8). |
| <a id="dependencypathpath"></a>`path` | [`[DependencyPathPartial!]!`](#dependencypathpartial) | Name of the dependency. |
### `DependencyPathPage`
Paginated dependency paths for SBOM occurrences.
#### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="dependencypathpageedges"></a>`edges` | [`[DependencyPathEdge!]!`](#dependencypathedge) | List of dependency path edges. |
| <a id="dependencypathpagenodes"></a>`nodes` | [`[DependencyPath!]!`](#dependencypath) | List of dependency paths. |
| <a id="dependencypathpagepageinfo"></a>`pageInfo` | [`DependencyPathPageInfo!`](#dependencypathpageinfo) | Pagination information for dependency paths. |
### `DependencyPathPageInfo`
#### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="dependencypathpageinfoendcursor"></a>`endCursor` | [`String`](#string) | When paginating forwards, the cursor to continue. |
| <a id="dependencypathpageinfohasnextpage"></a>`hasNextPage` | [`Boolean!`](#boolean) | When paginating forwards, are there more items?. |
| <a id="dependencypathpageinfohaspreviouspage"></a>`hasPreviousPage` | [`Boolean!`](#boolean) | When paginating backwards, are there more items?. |
| <a id="dependencypathpageinfostartcursor"></a>`startCursor` | [`String`](#string) | When paginating backwards, the cursor to continue. |
### `DependencyPathPartial`
Ancestor path partial of a given dependency.
@ -37008,12 +37041,15 @@ Ancestor dependency paths for a dependency used by the project. \
**Status**: Experiment.
{{< /details >}}
Returns [`[DependencyPath!]`](#dependencypath).
Returns [`DependencyPathPage`](#dependencypathpage).
###### Arguments
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="projectdependencypathsafter"></a>`after` | [`String`](#string) | Fetch paths after the cursor. |
| <a id="projectdependencypathsbefore"></a>`before` | [`String`](#string) | Fetch paths before the cursor. |
| <a id="projectdependencypathslimit"></a>`limit` | [`Int`](#int) | Number of paths to fetch. |
| <a id="projectdependencypathsoccurrence"></a>`occurrence` | [`SbomOccurrenceID!`](#sbomoccurrenceid) | Dependency path for occurrence. |
##### `Project.deployment`

View File

@ -49,13 +49,13 @@ Example response:
```json
{
"version": "15.2-pre",
"revision": "c401a659d0c",
"version": "18.1.1-ee",
"revision": "ceb07b24cb0",
"kas": {
"enabled": true,
"externalUrl": "grpc://gitlab.example.com:8150",
"externalK8sProxyUrl": "https://gitlab.example.com:8150/k8s-proxy",
"version": "15.0.0"
"version": "18.1.1"
},
"enterprise": true
}

View File

@ -1,90 +1,13 @@
---
stage: Security Risk Management
group: Security Policies
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
title: Policy settings API
redirect_to: 'compliance_policy_settings.md'
remove_date: '2025-10-01'
---
{{< details >}}
<!-- markdownlint-disable -->
- Tier: Ultimate
- Offering: GitLab Self-Managed
This document was moved to [another location](compliance_policy_settings.md).
{{< /details >}}
{{< history >}}
- [Introduced](https://issue-link) in GitLab 18.2 [with a flag](../administration/feature_flags/_index.md) named `security_policies_csp`. Disabled by default.
{{< /history >}}
{{< alert type="flag" >}}
The availability of this feature is controlled by a feature flag. For more information, see the history.
{{< /alert >}}
Use this API to interact with the security policy settings for your GitLab instance.
Prerequisites:
- You must have administrator access to the instance.
- Your instance must have the Ultimate tier to use security policies.
## Get security policy settings
Gets the current security policy settings for this GitLab instance.
```plaintext
GET /admin/security/policy_settings
```
```shell
curl --request GET \
--header "PRIVATE-TOKEN: <your_access_token>" \
--url "https://gitlab.example.com/api/v4/admin/security/policy_settings"
```
Example response:
```json
{
"csp_namespace_id": 42
}
```
When no CSP namespace is configured:
```json
{
"csp_namespace_id": null
}
```
## Update security policy settings
Updates the security policy settings for this GitLab instance.
```plaintext
PUT /admin/security/policy_settings
```
| Attribute | Type | Required | Description |
|:------------------|:--------|:---------|:------------|
| `csp_namespace_id` | integer | yes | ID of the group designated to centrally manage security policies. Must be a top-level group. Set to `null` to clear the setting. |
```shell
curl --request PUT \
--header "PRIVATE-TOKEN: <your_access_token>" \
--header "Content-Type: application/json" \
--data '{"csp_namespace_id": 42}' \
--url "https://gitlab.example.com/api/v4/admin/security/policy_settings"
```
Example response:
```json
{
"csp_namespace_id": 42
}
```
<!-- This redirect file can be deleted after <2025-10-01>. -->
<!-- Redirects that point to other docs in the same project expire in three months. -->
<!-- Redirects that point to docs in a different project or site (link is not relative and starts with `https:`) expire in one year. -->
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->

View File

@ -16,7 +16,7 @@ title: Version API
We recommend you use the [Metadata API](metadata.md) instead of the Version API.
It contains additional information and is aligned with the GraphQL metadata endpoint.
As of GitLab 15.5, the Version API is a mirror of the Metadata API.
The Version API is a mirror of the Metadata API.
{{< /alert >}}
@ -34,15 +34,4 @@ curl --header "PRIVATE-TOKEN: <your_access_token>" \
## Example responses
### GitLab 15.5 and later
See [Metadata API](metadata.md) for the response.
### GitLab 15.4 and earlier
```json
{
"version": "8.13.0-pre",
"revision": "4e963fe"
}
```

View File

@ -258,7 +258,7 @@ they prefer read replicas and wait for replicas to catch up:
| **Data consistency** | **Description** | **Guideline** |
|--------------|-----------------------------|----------|
| `:always` | The job is required to use the primary database for all queries. (Deprecated) | **Deprecated** Only needed for jobs that encounter edge cases around primary stickiness. |
| `:sticky` | The job prefers replicas, but switches to the primary for writes or when encountering replication lag. (Default) | This is the default option. It should be used for jobs that require to be executed as fast as possible. Replicas are guaranteed to be caught up to the point at which the job was enqueued in Sidekiq. |
| `:sticky` | The job prefers replicas, but switches to the primary for writes or when encountering replication lag. | This is the preferred option. It should be used for jobs that require to be executed as fast as possible. Replicas are guaranteed to be caught up to the point at which the job was enqueued in Sidekiq. |
| `:delayed` | The job prefers replicas, but switches to the primary for writes. When encountering replication lag before the job starts, the job is retried once. If the replica is still not up to date on the next retry, it switches to the primary. | It should be used for jobs where delaying execution further typically does not matter, such as cache expiration or web hooks execution. It should not be used for jobs where retry is disabled, such as cron jobs. |
In all cases workers read either from a replica that is fully caught up,

View File

@ -62,6 +62,16 @@ The following scopes are available for exact code search:
On GitLab Self-Managed, an administrator can enable global search
with the [`zoekt_cross_namespace_search`](exact_code_search.md#global-code-search) feature flag.
## Use exact code search
To use exact code search:
1. On the left sidebar, select **Search or go to**.
1. In the search box, enter your search term.
1. On the left sidebar, select **Code**.
You can also use exact code search in a project or group.
## Zoekt search API
{{< history >}}

View File

@ -0,0 +1,23 @@
# frozen_string_literal: true
module Gitlab
module Auth
module OAuth
class OauthResourceOwnerRedirectResolver
include ::Gitlab::Routing
attr_reader :top_level_namespace_path
def initialize(top_level_namespace_path)
@top_level_namespace_path = top_level_namespace_path
end
def resolve_redirect_url
new_user_session_url
end
end
end
end
end
Gitlab::Auth::OAuth::OauthResourceOwnerRedirectResolver.prepend_mod

View File

@ -267,7 +267,7 @@ gemnasium-python-dependency_scanning:
dependency-scanning:
variables:
ANALYZER_SUPPORTED_FILES: "packages.lock.json,conan.lock,conda-lock.yml,pubspec.lock,go.mod,go.graph,ivy-report.xml,maven.graph.json,dependencies.lock,package-lock.json,npm-shrinkwrap.json,pnpm-lock.yaml,yarn.lock,Podfile.lock,composer.lock,pipdeptree.json,requirements.txt,Pipfile.lock,pipenv.graph.json,poetry.lock,uv.lock,Gemfile.lock,gems.locked,Cargo.lock,dependencies-compile.dot,Package.resolved"
ADDITIONAL_SUPPORTED_FILES: "pom.xml,build.gradle,build.gradle.kts,build.sbt,requirements.pip,Pipfile,requires.txt,setup.py"
ADDITIONAL_SUPPORTED_FILES: "pom.xml,build.gradle,build.gradle.kts,build.sbt,requirements.pip,Pipfile,requires.txt,setup.py,*.csproj,*.vbproj"
SCA_TO_SARIF_MATCHER_VERSION: "v2.0.2"
stage: !reference [.ds-analyzer, stage]
image:

View File

@ -72,7 +72,7 @@ module Mattermost
end
def params
{ organization_id: Organizations::Organization::DEFAULT_ORGANIZATION_ID }
{ organization_id: @current_resource_owner.organizations.first.id }
.merge(Rack::Utils.parse_query(oauth_uri.query).symbolize_keys)
end

View File

@ -2394,10 +2394,19 @@ msgstr ""
msgid "AICatalog|Agents"
msgstr ""
msgid "AICatalog|Briefly describe what this agent is designed to do and its key capabilities."
msgstr ""
msgid "AICatalog|Choose a memorable name for your AI agent."
msgstr ""
msgid "AICatalog|Create agent"
msgstr ""
msgid "AICatalog|Description can't be blank."
msgid "AICatalog|Define the agent's personality, expertise, and behavioral guidelines. This shapes how the agent responds and approaches tasks."
msgstr ""
msgid "AICatalog|Description is required."
msgstr ""
msgid "AICatalog|Edit agent"
@ -2412,9 +2421,18 @@ msgstr ""
msgid "AICatalog|Modify the agent settings and configuration."
msgstr ""
msgid "AICatalog|Name is required."
msgstr ""
msgid "AICatalog|Please consider my background in... When explaining concepts, use... My preferred format for responses is... Always include..."
msgstr ""
msgid "AICatalog|Prompt"
msgstr ""
msgid "AICatalog|Provide default instructions or context that will be included with every user interaction."
msgstr ""
msgid "AICatalog|Released %{fullDate}"
msgstr ""
@ -2427,10 +2445,19 @@ msgstr ""
msgid "AICatalog|Save changes"
msgstr ""
msgid "AICatalog|System Prompt"
msgid "AICatalog|System Prompt (optional)"
msgstr ""
msgid "AICatalog|User Prompt"
msgid "AICatalog|This agent specializes in... It can help you with... Best suited for..."
msgstr ""
msgid "AICatalog|User Prompt (optional)"
msgstr ""
msgid "AICatalog|You are an expert in [domain]. Your communication style is [style]. When helping users, you should always... Your key strengths include... You approach problems by..."
msgstr ""
msgid "AICatalog|e.g., Research Assistant, Creative Writer, Code Helper"
msgstr ""
msgid "AISummary|Generates a summary of this issue"

View File

@ -23,14 +23,17 @@ module RuboCop
# rule { conducts_electricity & can?(:magnetize) }.enable :motor
# rule { ~conducts_electricity & batteries }.enable :motor
class PolicyRuleBoolean < RuboCop::Cop::Base
# @!method has_and_operator?(node)
def_node_search :has_and_operator?, <<~PATTERN
(and ...)
PATTERN
# @!method has_or_operator?(node)
def_node_search :has_or_operator?, <<~PATTERN
(or ...)
PATTERN
# @!method has_if?(node)
def_node_search :has_if?, <<~PATTERN
(if ...)
PATTERN

View File

@ -27,6 +27,7 @@ module RuboCop
RESTRICT_ON_SEND = %i[_ s_ N_ n_].freeze
# @!method wrapped_by?(node)
def_node_matcher :wrapped_by?, <<~PATTERN
^(send _ %method ...)
PATTERN

View File

@ -28,6 +28,7 @@ module RuboCop
LOG_METHODS = %i[debug error fatal info warn].freeze
LOG_METHODS_PATTERN = LOG_METHODS.map(&:inspect).join(' ').freeze
# @!method rails_logger_log?(node)
def_node_matcher :rails_logger_log?, <<~PATTERN
(send
(send (const nil? :Rails) :logger)

View File

@ -23,6 +23,7 @@ module RuboCop
RESTRICT_ON_SEND = %i[error success new].freeze
METHOD_NAMES = RESTRICT_ON_SEND.map(&:inspect).join(' ').freeze
# @!method service_response_with_http_status(node)
def_node_matcher :service_response_with_http_status, <<~PATTERN
(send
(const {nil? cbase} :ServiceResponse)

View File

@ -38,6 +38,7 @@ module RuboCop
STRONG_MEMOIZE_WITH_MSG =
'Use `strong_memoize_attr`, instead of using `strong_memoize_with` without parameters.'
# @!method strong_memoize?(node)
def_node_matcher :strong_memoize?, <<~PATTERN
(block
$(send nil? {:strong_memoize | :strong_memoize_with}

View File

@ -18,9 +18,12 @@ module RuboCop
MSG = 'Tokens should be prefixed. ' \
'See doc/development/secure_coding_guidelines.md#token-prefixes for more information.'
# @!method add_authentication_token_field?(node)
def_node_matcher :add_authentication_token_field?, <<~PATTERN
(send nil? :add_authentication_token_field ...)
PATTERN
# @!method format_with_prefix?(node)
def_node_matcher :format_with_prefix?, <<~PATTERN
(send nil? :add_authentication_token_field (sym $_)* (hash <$(pair (sym :format_with_prefix) _) ...>))
PATTERN

View File

@ -8,6 +8,7 @@ module RuboCop
class Union < RuboCop::Cop::Base
MSG = 'Use the `FromUnion` concern, instead of using `Gitlab::SQL::Union` directly'
# @!method raw_union?(node)
def_node_matcher :raw_union?, <<~PATTERN
(send (const (const (const nil? :Gitlab) :SQL) :Union) :new ...)
PATTERN

View File

@ -11,6 +11,7 @@ module RuboCop
ALLOWED_TYPES = %w[BaseEnum BaseEdge BaseScalar BasePermissionType MutationType SubscriptionType
QueryType GraphQL::Schema BaseUnion BaseInputObject].freeze
# @!method authorize?(node)
def_node_search :authorize?, <<~PATTERN
(send nil? :authorize sym+)
PATTERN

View File

@ -57,22 +57,27 @@ module RuboCop
MSG_CONTAINS_THIS = "`description` strings should not contain the demonstrative \"this\". "\
"#{MSG_STYLE_GUIDE_LINK}".freeze
# @!method graphql_describable?(node)
def_node_matcher :graphql_describable?, <<~PATTERN
(send nil? {:field :argument :value} ...)
PATTERN
# @!method enum?(node)
def_node_matcher :enum?, <<~PATTERN
(send nil? :value ...)
PATTERN
# @!method resolver_kwarg(node)
def_node_matcher :resolver_kwarg, <<~PATTERN
(... (hash <(pair (sym :resolver) $_) ...>))
PATTERN
# @!method description_kwarg(node)
def_node_matcher :description_kwarg, <<~PATTERN
(... (hash <(pair (sym :description) $_) ...>))
PATTERN
# @!method enum_style_description(node)
def_node_matcher :enum_style_description, <<~PATTERN
(send nil? :value _ $str ...)
PATTERN

View File

@ -37,14 +37,17 @@ module RuboCop
GRAPHQL_NAME_MISSING_MSG = "A `graphql_name` must be defined for a GraphQL enum. #{SEE_SG_MSG}".freeze
GRAPHQL_NAME_WITH_ENUM_MSG = "The `graphql_name` must not contain the string \"Enum\". #{SEE_SG_MSG}".freeze
# @!method enum_subclass(node)
def_node_matcher :enum_subclass, <<~PATTERN
(class $(const nil? _) (const {nil? cbase} /.*Enum$/) ...)
PATTERN
# @!method find_graphql_name(node)
def_node_search :find_graphql_name, <<~PATTERN
(... `(send nil? :graphql_name $(...)) ...)
PATTERN
# @!method declarative_enum?(node)
def_node_search :declarative_enum?, <<~PATTERN
(... (send nil? :declarative_enum ...) ...)
PATTERN

View File

@ -41,18 +41,22 @@ module RuboCop
MSG = "Enum values must either be an uppercase string literal or uppercased with the `upcase` method. " \
"See https://docs.gitlab.com/ee/development/api_graphql_styleguide.html#enums"
# @!method enum_value(node)
def_node_matcher :enum_value, <<~PATTERN
(send nil? :value $_ $...)
PATTERN
# @!method deprecated?(node)
def_node_search :deprecated?, <<~PATTERN
(hash <(pair (sym :deprecated) _) ...>)
PATTERN
# @!method upcase_literal?(node)
def_node_matcher :upcase_literal?, <<~PATTERN
(str #upcase?)
PATTERN
# @!method upcase_method?(node)
def_node_matcher :upcase_method?, <<~PATTERN
`(send _ :upcase)
PATTERN

View File

@ -23,6 +23,7 @@ module RuboCop
MSG = '`graphql_name` should be the first line of the class: '\
'https://docs.gitlab.com/ee/development/api_graphql_styleguide.html#naming-conventions'
# @!method graphql_name?(node)
def_node_search :graphql_name?, <<~PATTERN
(send nil? :graphql_name ...)
PATTERN

View File

@ -12,6 +12,7 @@ module RuboCop
context_namespace_path parent_path
].freeze
# @!method iid_with_id?(node)
def_node_matcher :iid_with_id?, <<~PATTERN
(send nil? {:field :argument}
(sym #iid?)
@ -19,6 +20,7 @@ module RuboCop
(...)?)
PATTERN
# @!method graphql_id_allowed?(node)
def_node_search :graphql_id_allowed?, <<~PATTERN
(send nil? :argument (_ #does_not_match?) (const (const (const nil? :GraphQL) :Types) :ID) ...)
PATTERN

View File

@ -21,6 +21,7 @@ module RuboCop
MSG = 'Avoid using GraphQL::Types::JSON. See: ' \
'https://docs.gitlab.com/ee/development/api_graphql_styleguide.html#json'
# @!method has_json_type?(node)
def_node_matcher :has_json_type?, <<~PATTERN
(send nil? {:field :argument}
(sym _)

View File

@ -25,6 +25,7 @@ module RuboCop
MSG_BOOLEAN = 'Avoid using GraphQL::BOOLEAN_TYPE. Use GraphQL::Types::Boolean instead'
MSG_FLOAT = 'Avoid using GraphQL::FLOAT_TYPE. Use GraphQL::Types::Float instead'
# @!method has_old_type?(node)
def_node_matcher :has_old_type?, <<~PATTERN
(send nil? {:field :argument}
(sym _)

View File

@ -26,6 +26,7 @@ module RuboCop
MSG = 'Missing type annotation: Please add `type` DSL method call. ' \
'e.g: type UserType.connection_type, null: true'
# @!method typed?(node)
def_node_matcher :typed?, <<~PATTERN
(... (begin <(send nil? :type ...) ...>))
PATTERN

View File

@ -25,8 +25,10 @@ module RuboCop
RESTRICT_ON_SEND = %i[raise].freeze
# @!method error(node)
def_node_matcher :error, const_pattern(EXCEPTION)
# @!method raise_error(node)
def_node_matcher :raise_error, <<~PATTERN
(send nil? :raise #error $...)
PATTERN

View File

@ -8,6 +8,7 @@ module RuboCop
'Please ensure that you are not using it on its own and that the amount ' \
'of rows being filtered is reasonable.'
# @!method public_or_visible_to_user?(node)
def_node_matcher :public_or_visible_to_user?, <<~PATTERN
(send (const nil? :Group) :public_or_visible_to_user ...)
PATTERN

View File

@ -26,14 +26,17 @@ module RuboCop
RESTRICT_ON_SEND = %i[ignored_columns ignored_columns= ignore_column ignore_columns].freeze
# @!method ignored_columns_add?(node)
def_node_matcher :ignored_columns_add?, <<~PATTERN
(send (self) :ignored_columns)
PATTERN
# @!method ignored_columns_set?(node)
def_node_matcher :ignored_columns_set?, <<~PATTERN
(send (self) :ignored_columns= ...)
PATTERN
# @!method using_ignore_columns?(node)
def_node_matcher :using_ignore_columns?, <<~PATTERN
(send nil? {:ignore_columns :ignore_column}...)
PATTERN

View File

@ -8,6 +8,7 @@ module RuboCop
MSG = 'Include `ApplicationWorker`, not `Sidekiq::Worker`.'
# @!method includes_sidekiq_worker?(node)
def_node_matcher :includes_sidekiq_worker?, <<~PATTERN
(send nil? :include (const (const nil? :Sidekiq) :Worker))
PATTERN

View File

@ -20,13 +20,29 @@ RSpec.describe Doorkeeper.configuration do
subject { controller.instance_exec(&Doorkeeper.configuration.authenticate_resource_owner) }
let(:controller) { double }
let(:base_request_params) { {} }
let(:mock_request) do
instance_double(ActionDispatch::Request,
'request',
fullpath: '/return-path',
query_parameters: base_request_params
)
end
let(:resolver) { instance_double(Gitlab::Auth::OAuth::OauthResourceOwnerRedirectResolver) }
before do
allow(controller).to receive(:current_user).and_return(current_user)
allow(controller).to receive(:session).and_return({})
allow(controller).to receive(:request).and_return(double('request', fullpath: '/return-path'))
allow(controller).to receive_messages(
current_user: current_user,
session: {},
request: mock_request
)
allow(controller).to receive(:redirect_to)
allow(controller).to receive(:new_user_session_url).and_return('/login')
allow(::Gitlab::Auth::OAuth::OauthResourceOwnerRedirectResolver)
.to receive(:new)
.with(nil)
.and_return(resolver)
allow(resolver).to receive(:resolve_redirect_url).and_return('/login')
end
context 'with a user present' do

View File

@ -0,0 +1,34 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::Auth::OAuth::OauthResourceOwnerRedirectResolver, feature_category: :system_access do
let(:resolver) { described_class.new(namespace_path) }
let(:namespace_path) { nil }
let(:group) { create(:group) }
describe '#resolve_redirect_url' do
subject(:resolve_redirect_url) { resolver.resolve_redirect_url }
before do
allow(resolver).to receive(:new_user_session_url).and_return('/login')
end
context 'with any namespace path' do
let(:namespace_path) { group.full_path }
it 'returns new_user_session_url' do
expect(resolver).to receive(:new_user_session_url)
expect(resolve_redirect_url).to eq('/login')
end
end
context 'with nil namespace path' do
let(:namespace_path) { nil }
it 'returns new_user_session_url' do
expect(resolve_redirect_url).to eq('/login')
end
end
end
end

View File

@ -6,7 +6,8 @@ RSpec.describe Mattermost::Session, type: :request do
include ExclusiveLeaseHelpers
include StubRequests
let(:user) { create(:user) }
let_it_be(:organization) { create(:organization) }
let(:user) { create(:user, organizations: [organization]) }
let(:gitlab_url) { "http://gitlab.com" }
let(:mattermost_url) { "http://mattermost.com" }
@ -24,8 +25,6 @@ RSpec.describe Mattermost::Session, type: :request do
it { is_expected.to respond_to(:strategy) }
describe '#with session' do
let_it_be(:organization) { create(:organization, :default) }
let(:location) { 'http://location.tld' }
let(:cookie_header) { 'MMOAUTH=taskik8az7rq8k6rkpuas7htia; Path=/;' }
let!(:stub) do
@ -110,6 +109,13 @@ RSpec.describe Mattermost::Session, type: :request do
expect(result).to eq("value")
end
it 'creates token in the same organization as the user' do
expect { subject.with_session {} }
.to change { OauthAccessToken.find_by(resource_owner: user)&.organization_id }
.from(nil)
.to(user.organizations.first.id)
end
end
end

View File

@ -13,14 +13,7 @@ RSpec.describe RequeueBackfillArchivedAndTraversalIdsToVulnerabilityStatistics,
}
migration.after -> {
expect(batched_migration).to have_scheduled_batched_migration(
gitlab_schema: :gitlab_sec,
table_name: :vulnerability_statistics,
column_name: :id,
interval: described_class::DELAY_INTERVAL,
batch_size: described_class::BATCH_SIZE,
sub_batch_size: described_class::SUB_BATCH_SIZE
)
expect(batched_migration).not_to have_scheduled_batched_migration
}
end
end

View File

@ -0,0 +1,27 @@
# frozen_string_literal: true
require 'spec_helper'
require_migration!
RSpec.describe RequeueBackfillArchivedAndTraversalIdsToVulnerabilityStatisticsV2, migration: :gitlab_sec, feature_category: :vulnerability_management do
let!(:batched_migration) { described_class::MIGRATION }
it 'schedules a new batched migration' do
reversible_migration do |migration|
migration.before -> {
expect(batched_migration).not_to have_scheduled_batched_migration
}
migration.after -> {
expect(batched_migration).to have_scheduled_batched_migration(
gitlab_schema: :gitlab_sec,
table_name: :vulnerability_statistics,
column_name: :id,
interval: described_class::DELAY_INTERVAL,
batch_size: described_class::BATCH_SIZE,
sub_batch_size: described_class::SUB_BATCH_SIZE
)
}
end
end
end

View File

@ -736,4 +736,27 @@ RSpec.describe Ci::Processable, feature_category: :continuous_integration do
expect(processable.strong_memoized?(:redis_state)).to be(true)
end
end
describe '#enqueue_immediately?', :clean_gitlab_redis_shared_state do
let(:processable) { build_stubbed(:ci_processable, pipeline: pipeline) }
[true, false].each do |value|
context "when enqueue_immediately is set to #{value}" do
before do
processable.redis_state.enqueue_immediately = value
end
it { expect(processable.enqueue_immediately?).to be(value) }
end
end
end
describe '#set_enqueue_immediately!', :clean_gitlab_redis_shared_state do
let(:processable) { build_stubbed(:ci_processable, pipeline: pipeline) }
it 'changes enqueue_immediately to true' do
expect { processable.set_enqueue_immediately! }
.to change { processable.enqueue_immediately? }.to(true)
end
end
end

View File

@ -553,37 +553,6 @@ RSpec.describe Ci::RetryJobService, :clean_gitlab_redis_shared_state, feature_ca
it_behaves_like 'checks enqueue_immediately?'
end
context 'with ci_redis_enqueue_immediately disabled' do
before do
stub_feature_flags(ci_redis_enqueue_immediately: false)
end
let!(:job) do
create(:ci_build, *[trait].compact, :failed, pipeline: pipeline, ci_stage: stage)
end
where(:trait, :enqueue_immediately) do
nil | false
:manual | true
:expired_scheduled | true
end
with_them do
it 'retries the given job but not the other manual/scheduled jobs' do
expect { subject }
.to change { Ci::Build.count }.by(1)
.and not_change { test_manual_build.reload.status }
.and not_change { subsequent_manual_build.reload.status }
.and not_change { test_scheduled_build.reload.status }
.and not_change { subsequent_scheduled_build.reload.status }
expect(new_job).to be_pending
end
it_behaves_like 'checks enqueue_immediately?'
end
end
end
end
end

View File

@ -133,6 +133,7 @@ RSpec.describe MergeRequests::ApprovalService, feature_category: :code_review_wo
it 'triggers GraphQL subscription userMergeRequestUpdated' do
expect(GraphqlTriggers).to receive(:user_merge_request_updated).with(user, merge_request)
expect(GraphqlTriggers).to receive(:user_merge_request_updated).with(merge_request.author, merge_request)
service.execute(merge_request)
end

View File

@ -121,6 +121,7 @@ RSpec.describe MergeRequests::HandleAssigneesChangeService, feature_category: :c
it 'triggers GraphQL subscription userMergeRequestUpdated' do
expect(GraphqlTriggers).to receive(:user_merge_request_updated).with(assignee, merge_request)
expect(GraphqlTriggers).to receive(:user_merge_request_updated).with(merge_request.author, merge_request)
execute
end

View File

@ -78,6 +78,13 @@ RSpec.describe MergeRequests::PostMergeService, feature_category: :code_review_w
subject
end
it 'triggers GraphQL subscription userMergeRequestUpdated' do
expect(GraphqlTriggers).to receive(:user_merge_request_updated).with(user, merge_request)
expect(GraphqlTriggers).to receive(:user_merge_request_updated).with(merge_request.author, merge_request)
subject
end
context 'when there are issues to be closed' do
let_it_be(:issue) { create(:issue, project: project) }

View File

@ -131,6 +131,7 @@ RSpec.describe MergeRequests::RemoveApprovalService, feature_category: :code_rev
it 'triggers GraphQL subscription userMergeRequestUpdated' do
expect(GraphqlTriggers).to receive(:user_merge_request_updated).with(user, merge_request)
expect(GraphqlTriggers).to receive(:user_merge_request_updated).with(merge_request.author, merge_request)
execute!
end

View File

@ -80,6 +80,7 @@ RSpec.describe MergeRequests::UpdateReviewerStateService, feature_category: :cod
it 'triggers GraphQL subscription userMergeRequestUpdated' do
expect(GraphqlTriggers).to receive(:user_merge_request_updated).with(current_user, merge_request)
expect(GraphqlTriggers).to receive(:user_merge_request_updated).with(merge_request.author, merge_request)
result
end

View File

@ -740,6 +740,7 @@ RSpec.describe MergeRequests::UpdateService, :mailer, feature_category: :code_re
end
it 'triggers GraphQL subscription userMergeRequestUpdated' do
expect(GraphqlTriggers).to receive(:user_merge_request_updated).with(merge_request.author, merge_request)
expect(GraphqlTriggers).to receive(:user_merge_request_updated).with(user3, merge_request)
expect(GraphqlTriggers).to receive(:user_merge_request_updated).with(user2, merge_request)

View File

@ -85,27 +85,6 @@ RSpec.describe PersonalAccessTokens::LastUsedService, feature_category: :system_
service_execution
end
context 'when pat_last_used_at_optimization FF is disabled' do
before do
stub_feature_flags(pat_last_used_at_optimization: false)
end
it "does not update the personal access token's last used ips" do
expect { service_execution }.not_to change { personal_access_token.last_used_ips.count }
expect(
Authn::PersonalAccessTokenLastUsedIp
.where(personal_access_token_id: personal_access_token.id, ip_address: Gitlab::IpAddressState.current)
.exists?
).to be_falsy
end
it "obtains exclusive lease" do
expect(service).to receive(:try_obtain_lease)
service_execution
end
end
end
context "when the current ip address is already saved" do
@ -230,22 +209,6 @@ RSpec.describe PersonalAccessTokens::LastUsedService, feature_category: :system_
service_execution
end
context 'when pat_last_used_at_optimization FF is disabled' do
before do
stub_feature_flags(pat_last_used_at_optimization: false)
end
it 'does not update the last_used_at timestamp' do
expect { service_execution }.not_to change { personal_access_token.last_used_at }
end
it "obtains exclusive lease" do
expect(service).to receive(:try_obtain_lease)
service_execution
end
end
end
context 'when the last_used_at timestamp is nil' do