Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
a8b811acdf
commit
65952e598a
51 changed files with 343 additions and 157 deletions
|
@ -4,6 +4,8 @@ class Admin::IntegrationsController < Admin::ApplicationController
|
|||
include IntegrationsActions
|
||||
include ServicesHelper
|
||||
|
||||
before_action :not_found, unless: -> { instance_level_integrations? }
|
||||
|
||||
feature_category :integrations
|
||||
|
||||
private
|
||||
|
@ -12,10 +14,6 @@ class Admin::IntegrationsController < Admin::ApplicationController
|
|||
Service.find_or_initialize_non_project_specific_integration(name, instance: true)
|
||||
end
|
||||
|
||||
def integrations_enabled?
|
||||
instance_level_integrations?
|
||||
end
|
||||
|
||||
def scoped_edit_integration_path(integration)
|
||||
edit_admin_application_settings_integration_path(integration)
|
||||
end
|
||||
|
|
|
@ -6,7 +6,6 @@ module IntegrationsActions
|
|||
included do
|
||||
include ServiceParams
|
||||
|
||||
before_action :not_found, unless: :integrations_enabled?
|
||||
before_action :integration, only: [:edit, :update, :test]
|
||||
end
|
||||
|
||||
|
@ -51,10 +50,6 @@ module IntegrationsActions
|
|||
|
||||
private
|
||||
|
||||
def integrations_enabled?
|
||||
false
|
||||
end
|
||||
|
||||
def integration
|
||||
# Using instance variable `@service` still required as it's used in ServiceParams.
|
||||
# Should be removed once that is refactored to use `@integration`.
|
||||
|
|
|
@ -25,10 +25,6 @@ module Groups
|
|||
Service.find_or_initialize_non_project_specific_integration(name, group_id: group.id)
|
||||
end
|
||||
|
||||
def integrations_enabled?
|
||||
Feature.enabled?(:group_level_integrations, group, default_enabled: true)
|
||||
end
|
||||
|
||||
def scoped_edit_integration_path(integration)
|
||||
edit_group_settings_integration_path(group, integration)
|
||||
end
|
||||
|
|
|
@ -122,10 +122,6 @@ module ServicesHelper
|
|||
false
|
||||
end
|
||||
|
||||
def group_level_integrations?
|
||||
@group.present? && Feature.enabled?(:group_level_integrations, @group, default_enabled: true)
|
||||
end
|
||||
|
||||
def instance_level_integrations?
|
||||
!Gitlab.com?
|
||||
end
|
||||
|
|
|
@ -7,7 +7,7 @@ module Admin
|
|||
def propagate
|
||||
if integration.instance?
|
||||
update_inherited_integrations
|
||||
create_integration_for_groups_without_integration if Feature.enabled?(:group_level_integrations, default_enabled: true)
|
||||
create_integration_for_groups_without_integration
|
||||
create_integration_for_projects_without_integration
|
||||
else
|
||||
update_inherited_descendant_integrations
|
||||
|
|
|
@ -34,7 +34,7 @@ module Groups
|
|||
if @group.save
|
||||
@group.add_owner(current_user)
|
||||
@group.create_namespace_settings
|
||||
Service.create_from_active_default_integrations(@group, :group_id) if Feature.enabled?(:group_level_integrations, default_enabled: true)
|
||||
Service.create_from_active_default_integrations(@group, :group_id)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -159,11 +159,10 @@
|
|||
%span
|
||||
= _('General')
|
||||
|
||||
- if group_level_integrations?
|
||||
= nav_link(controller: :integrations) do
|
||||
= link_to group_settings_integrations_path(@group), title: _('Integrations') do
|
||||
%span
|
||||
= _('Integrations')
|
||||
= nav_link(controller: :integrations) do
|
||||
= link_to group_settings_integrations_path(@group), title: _('Integrations') do
|
||||
%span
|
||||
= _('Integrations')
|
||||
|
||||
= nav_link(path: 'groups#projects') do
|
||||
= link_to projects_group_path(@group), title: _('Projects') do
|
||||
|
|
|
@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/224168
|
|||
milestone: '13.4'
|
||||
type: development
|
||||
group: group::geo
|
||||
default_enabled: false
|
||||
default_enabled: true
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
---
|
||||
name: group_level_integrations
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27557
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/238575
|
||||
milestone: '12.10'
|
||||
type: development
|
||||
group: group::ecosystem
|
||||
default_enabled: true
|
|
@ -8,7 +8,6 @@ allowlists
|
|||
anonymized
|
||||
Ansible
|
||||
Anthos
|
||||
API
|
||||
approvers
|
||||
architected
|
||||
Artifactory
|
||||
|
@ -63,7 +62,6 @@ bundlers
|
|||
burndown
|
||||
burnup
|
||||
cacheable
|
||||
CAS
|
||||
CentOS
|
||||
Certbot
|
||||
chai
|
||||
|
@ -234,7 +232,6 @@ kubectl
|
|||
Kubernetes
|
||||
Kubesec
|
||||
Laravel
|
||||
LDAP
|
||||
ldapsearch
|
||||
Lefthook
|
||||
Leiningen
|
||||
|
@ -299,7 +296,6 @@ namespacing
|
|||
namespacings
|
||||
Nanoc
|
||||
Netlify
|
||||
NGINX
|
||||
Nokogiri
|
||||
npm
|
||||
Nurtch
|
||||
|
@ -407,7 +403,6 @@ reusability
|
|||
reverified
|
||||
reverifies
|
||||
reverify
|
||||
RHEL
|
||||
rollout
|
||||
rollouts
|
||||
rsync
|
||||
|
@ -424,7 +419,6 @@ runit
|
|||
runtime
|
||||
runtimes
|
||||
Salesforce
|
||||
SAML
|
||||
sandboxing
|
||||
sanitization
|
||||
sbt
|
||||
|
@ -447,7 +441,6 @@ Slack
|
|||
Slony
|
||||
smartcard
|
||||
smartcards
|
||||
SMTP
|
||||
Sobelow
|
||||
Solarized
|
||||
Sourcegraph
|
||||
|
@ -456,7 +449,6 @@ sparklines
|
|||
spidering
|
||||
Splunk
|
||||
SpotBugs
|
||||
SSH
|
||||
Stackdriver
|
||||
storable
|
||||
storages
|
||||
|
|
|
@ -776,7 +776,7 @@ are generated:
|
|||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/15442) in GitLab 12.3.
|
||||
|
||||
Contains details of GitLab's [Database Load Balancing](database_load_balancing.md).
|
||||
Contains details of GitLab [Database Load Balancing](database_load_balancing.md).
|
||||
It's stored at:
|
||||
|
||||
- `/var/log/gitlab/gitlab-rails/database_load_balancing.log` for Omnibus GitLab packages.
|
||||
|
|
|
@ -13,7 +13,7 @@ Explore our features to monitor your GitLab instance:
|
|||
take action on alerts.
|
||||
- [Performance monitoring](performance/index.md): GitLab Performance Monitoring makes it possible to measure a wide variety of statistics of your instance.
|
||||
- [Prometheus](prometheus/index.md): Prometheus is a powerful time-series monitoring service, providing a flexible platform for monitoring GitLab and other software products.
|
||||
- [GitHub imports](github_imports.md): Monitor the health and progress of GitLab's GitHub importer with various Prometheus metrics.
|
||||
- [GitHub imports](github_imports.md): Monitor the health and progress of the GitHub importer with various Prometheus metrics.
|
||||
- [Monitoring uptime](../../user/admin_area/monitoring/health_check.md): Check the server status using the health check endpoint.
|
||||
- [IP whitelists](ip_whitelist.md): Configure GitLab for monitoring endpoints that provide health check information when probed.
|
||||
- [`nginx_status`](https://docs.gitlab.com/omnibus/settings/nginx.html#enablingdisabling-nginx_status): Monitor your NGINX server status
|
||||
|
|
|
@ -310,7 +310,7 @@ instance (`cache`, `shared_state` etc.).
|
|||
|
||||
## Metrics shared directory
|
||||
|
||||
GitLab's Prometheus client requires a directory to store metrics data shared between multi-process services.
|
||||
The GitLab Prometheus client requires a directory to store metrics data shared between multi-process services.
|
||||
Those files are shared among all instances running under Unicorn server.
|
||||
The directory must be accessible to all running Unicorn's processes, or
|
||||
metrics can't function correctly.
|
||||
|
|
|
@ -8,11 +8,11 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
Every API call to epic_issues must be authenticated.
|
||||
|
||||
If a user is not a member of a group and the group is private, a `GET` request on that group will
|
||||
result in a `404` status code.
|
||||
If a user is not a member of a group and the group is private, a `GET` request on that group
|
||||
results in a `404` status code.
|
||||
|
||||
Epics are available only in GitLab [Premium and higher](https://about.gitlab.com/pricing/).
|
||||
If the Epics feature is not available, a `403` status code will be returned.
|
||||
If the Epics feature is not available, a `403` status code is returned.
|
||||
|
||||
## List issues for an epic
|
||||
|
||||
|
|
|
@ -8959,8 +8959,7 @@ type GeoNode {
|
|||
selectiveSyncType: String
|
||||
|
||||
"""
|
||||
Find snippet repository registries on this Geo node. Available only when
|
||||
feature flag `geo_snippet_repository_replication` is enabled
|
||||
Find snippet repository registries on this Geo node
|
||||
"""
|
||||
snippetRepositoryRegistries(
|
||||
"""
|
||||
|
@ -24606,6 +24605,11 @@ type VulnerabilitiesCountByDayEdge {
|
|||
Represents a vulnerability
|
||||
"""
|
||||
type Vulnerability implements Noteable {
|
||||
"""
|
||||
Timestamp of when the vulnerability state was changed to confirmed
|
||||
"""
|
||||
confirmedAt: Time
|
||||
|
||||
"""
|
||||
Description of the vulnerability
|
||||
"""
|
||||
|
|
|
@ -25082,7 +25082,7 @@
|
|||
},
|
||||
{
|
||||
"name": "snippetRepositoryRegistries",
|
||||
"description": "Find snippet repository registries on this Geo node. Available only when feature flag `geo_snippet_repository_replication` is enabled",
|
||||
"description": "Find snippet repository registries on this Geo node",
|
||||
"args": [
|
||||
{
|
||||
"name": "ids",
|
||||
|
@ -71715,6 +71715,20 @@
|
|||
"name": "Vulnerability",
|
||||
"description": "Represents a vulnerability",
|
||||
"fields": [
|
||||
{
|
||||
"name": "confirmedAt",
|
||||
"description": "Timestamp of when the vulnerability state was changed to confirmed",
|
||||
"args": [
|
||||
|
||||
],
|
||||
"type": {
|
||||
"kind": "SCALAR",
|
||||
"name": "Time",
|
||||
"ofType": null
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "description",
|
||||
"description": "Description of the vulnerability",
|
||||
|
|
|
@ -1513,7 +1513,7 @@ Autogenerated return type of EpicTreeReorder.
|
|||
| `selectiveSyncNamespaces` | NamespaceConnection | The namespaces that should be synced, if `selective_sync_type` == `namespaces` |
|
||||
| `selectiveSyncShards` | String! => Array | The repository storages whose projects should be synced, if `selective_sync_type` == `shards` |
|
||||
| `selectiveSyncType` | String | Indicates if syncing is limited to only specific groups, or shards |
|
||||
| `snippetRepositoryRegistries` | SnippetRepositoryRegistryConnection | Find snippet repository registries on this Geo node. Available only when feature flag `geo_snippet_repository_replication` is enabled |
|
||||
| `snippetRepositoryRegistries` | SnippetRepositoryRegistryConnection | Find snippet repository registries on this Geo node |
|
||||
| `syncObjectStorage` | Boolean | Indicates if this secondary node will replicate blobs in Object Storage |
|
||||
| `terraformStateVersionRegistries` | TerraformStateVersionRegistryConnection | Find terraform state version registries on this Geo node |
|
||||
| `url` | String | The user-facing URL for this Geo node |
|
||||
|
@ -3716,6 +3716,7 @@ Represents a vulnerability.
|
|||
|
||||
| Field | Type | Description |
|
||||
| ----- | ---- | ----------- |
|
||||
| `confirmedAt` | Time | Timestamp of when the vulnerability state was changed to confirmed |
|
||||
| `description` | String | Description of the vulnerability |
|
||||
| `detectedAt` | Time! | Timestamp of when the vulnerability was first detected |
|
||||
| `discussions` | DiscussionConnection! | All discussions on this noteable |
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 237 KiB |
|
@ -105,10 +105,10 @@ External monitoring tools can poll the API and verify pipeline health or collect
|
|||
metrics for long term SLA analytics.
|
||||
|
||||
For example, the [GitLab CI Pipelines Exporter](https://github.com/mvisonneau/gitlab-ci-pipelines-exporter)
|
||||
for Prometheus fetches metrics from the API. It can check branches in projects automatically
|
||||
for Prometheus fetches metrics from the API and pipeline events. It can check branches in projects automatically
|
||||
and get the pipeline status and duration. In combination with a Grafana dashboard,
|
||||
this helps build an actionable view for your operations team. Metric graphs can also
|
||||
be embedded into incidents making problem resolving easier.
|
||||
be embedded into incidents making problem resolving easier. Additionally, it can also export metrics about jobs and environments.
|
||||
|
||||
![Grafana Dashboard for GitLab CI Pipelines Prometheus Exporter](img/ci_efficiency_pipeline_health_grafana_dashboard.png)
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ all subsystems at GitLab:
|
|||
- Correlation IDs should never be used to pass context (for example, a username or an IP address).
|
||||
- Correlation IDs should never be _parsed_, or manipulated in other ways (for example, split).
|
||||
|
||||
The [LabKit library](https://gitlab.com/gitlab-org/labkit) provides a standardized interface for working with GitLab's
|
||||
The [LabKit library](https://gitlab.com/gitlab-org/labkit) provides a standardized interface for working with GitLab
|
||||
correlation IDs in the Go programming language. LabKit can be used as a
|
||||
reference implementation for developers working with tracing and correlation IDs
|
||||
on non-Go GitLab subsystems.
|
||||
|
|
|
@ -7,7 +7,7 @@ description: Learn how to contribute to GitLab Documentation.
|
|||
|
||||
# GitLab Documentation guidelines
|
||||
|
||||
GitLab's documentation is [intended as the single source of truth (SSOT)](https://about.gitlab.com/handbook/documentation/) for information about how to configure, use, and troubleshoot GitLab. The documentation contains use cases and usage instructions for every GitLab feature, organized by product area and subject. This includes topics and workflows that span multiple GitLab features, and the use of GitLab with other applications.
|
||||
The GitLab documentation is [intended as the single source of truth (SSOT)](https://about.gitlab.com/handbook/documentation/) for information about how to configure, use, and troubleshoot GitLab. The documentation contains use cases and usage instructions for every GitLab feature, organized by product area and subject. This includes topics and workflows that span multiple GitLab features, and the use of GitLab with other applications.
|
||||
|
||||
In addition to this page, the following resources can help you craft and contribute to documentation:
|
||||
|
||||
|
@ -230,7 +230,7 @@ Things to note:
|
|||
and prints the file and the line where this file is mentioned.
|
||||
You may ask why the two greps. Since [we use relative paths to link to
|
||||
documentation](styleguide/index.md#links), sometimes it might be useful to search a path deeper.
|
||||
- The `*.md` extension is not used when a document is linked to GitLab's
|
||||
- The `*.md` extension is not used when a document is linked to the GitLab
|
||||
built-in help page, which is why we omit it in `git grep`.
|
||||
- Use the checklist on the "Change documentation location" MR description template.
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ In either case, an outcome of the experiment should be posted to the issue with
|
|||
Experiments' code quality can fail our standards for several reasons. These
|
||||
reasons can include not being added to the codebase for a long time, or because
|
||||
of fast iteration to retrieve data. However, having the experiment run (or not
|
||||
run) shouldn't impact GitLab's availability. To avoid or identify issues,
|
||||
run) shouldn't impact GitLab availability. To avoid or identify issues,
|
||||
experiments are initially deployed to a small number of users. Regardless,
|
||||
experiments still need tests.
|
||||
|
||||
|
@ -326,11 +326,11 @@ For visibility, please also share any commands run against production in the `#s
|
|||
|
||||
### Manually force the current user to be in the experiment group
|
||||
|
||||
You may force the application to put your current user in the experiment group. To do so
|
||||
add a query string parameter to the path where the experiment runs. If you do so,
|
||||
You may force the application to put your current user in the experiment group. To do so
|
||||
add a query string parameter to the path where the experiment runs. If you do so,
|
||||
the experiment will work only for this request and won't work after following links or submitting forms.
|
||||
|
||||
For example, to forcibly enable the `EXPERIMENT_KEY` experiment, add `force_experiment=EXPERIMENT_KEY`
|
||||
For example, to forcibly enable the `EXPERIMENT_KEY` experiment, add `force_experiment=EXPERIMENT_KEY`
|
||||
to the URL:
|
||||
|
||||
```shell
|
||||
|
|
|
@ -619,7 +619,7 @@ alt_usage_data(999)
|
|||
### Prometheus Queries
|
||||
|
||||
In those cases where operational metrics should be part of Usage Ping, a database or Redis query is unlikely
|
||||
to provide useful data. Instead, Prometheus might be more appropriate, since most of GitLab's architectural
|
||||
to provide useful data. Instead, Prometheus might be more appropriate, since most GitLab architectural
|
||||
components publish metrics to it that can be queried back, aggregated, and included as usage data.
|
||||
|
||||
NOTE:
|
||||
|
|
|
@ -81,7 +81,7 @@ infrastructure.
|
|||
GitLab stores and executes your infrastructure as code, whether it's
|
||||
defined in Ansible, Puppet or Chef. We also offer native integration with
|
||||
[Terraform](https://www.terraform.io/), uniting your GitOps and
|
||||
Infrastructure-as-Code (IaC) workflows with GitLab's authentication, authorization,
|
||||
Infrastructure-as-Code (IaC) workflows with the GitLab authentication, authorization,
|
||||
and user interface. By lowering the barrier to entry for adopting Terraform, you
|
||||
can manage and provision infrastructure through machine-readable definition files,
|
||||
rather than physical hardware configuration or interactive configuration tools.
|
||||
|
|
|
@ -23,7 +23,7 @@ For this embed to display correctly, the
|
|||
Copy the link and add an image tag as [inline HTML](../../user/markdown.md#inline-html)
|
||||
in your Markdown. You can tweak the query parameters to meet your needs, such as
|
||||
removing the `&from=` and `&to=` parameters to display a live chart. Here is example
|
||||
markup for a live chart from GitLab's public dashboard:
|
||||
markup for a live chart from a GitLab public dashboard:
|
||||
|
||||
```html
|
||||
<img src="https://dashboards.gitlab.com/d/RZmbBr7mk/gitlab-triage?orgId=1&refresh=30s&var-env=gprd&var-environment=gprd&var-prometheus=prometheus-01-inf-gprd&var-prometheus_app=prometheus-app-01-inf-gprd&var-backend=All&var-type=All&var-stage=main&from=1580444107655&to=1580465707655"/>
|
||||
|
|
|
@ -109,3 +109,43 @@ questions that you know someone might ask.
|
|||
Each scenario can be a third-level heading, e.g. `### Getting error message X`.
|
||||
If you have none to add when creating a doc, leave this section in place
|
||||
but commented out to help encourage others to add to it in the future. -->
|
||||
|
||||
## Two-factor Authentication (2FA) for Git over SSH operations
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/270554) in GitLab 13.7.
|
||||
> - It's [deployed behind a feature flag](<replace with path to>/user/feature_flags.md), disabled by default.
|
||||
> - It's disabled on GitLab.com.
|
||||
> - It's not recommended for production use.
|
||||
> - To use it in GitLab self-managed instances, ask a GitLab administrator to [enable it](#enable-or-disable-two-factor-authentication-2fa-for-git-operations).
|
||||
|
||||
WARNING:
|
||||
This feature might not be available to you. Check the **version history** note above for details.
|
||||
|
||||
Two-factor authentication can be enforced for Git over SSH operations. The OTP
|
||||
verification can be done via a GitLab Shell command:
|
||||
|
||||
```shell
|
||||
ssh git@<hostname> 2fa_verify
|
||||
```
|
||||
|
||||
Once the OTP is verified, Git over SSH operations can be used for 15 minutes
|
||||
with the associated SSH key.
|
||||
|
||||
### Enable or disable Two-factor Authentication (2FA) for Git operations
|
||||
|
||||
Two-factor Authentication (2FA) for Git operations is under development and not
|
||||
ready for production use. It is deployed behind a feature flag that is
|
||||
**disabled by default**. [GitLab administrators with access to the GitLab Rails console](<replace with path to>/administration/feature_flags.md)
|
||||
can enable it.
|
||||
|
||||
To enable it:
|
||||
|
||||
```ruby
|
||||
Feature.enable(:two_factor_for_cli)
|
||||
```
|
||||
|
||||
To disable it:
|
||||
|
||||
```ruby
|
||||
Feature.disable(:two_factor_for_cli)
|
||||
```
|
||||
|
|
|
@ -26,7 +26,7 @@ to the server's IP address. This better ensures a stable target for our certs' C
|
|||
and makes long-term resolution simpler.
|
||||
|
||||
```shell
|
||||
sudo EXTERNAL_URL="http://my-host.internal" install gitlab-ee
|
||||
sudo EXTERNAL_URL="http://my-host.internal" apt-get install gitlab-ee
|
||||
```
|
||||
|
||||
## Enabling SSL
|
||||
|
|
|
@ -4,7 +4,7 @@ group: Project Management
|
|||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# Award emoji
|
||||
# Award emoji **(CORE)**
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/1825) in GitLab 8.2.
|
||||
> - GitLab 9.0 [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/9570) the usage of native emoji if the platform
|
||||
|
@ -46,7 +46,7 @@ celebrate an accomplishment or agree with an opinion.
|
|||
To:
|
||||
|
||||
- Add an award emoji, click the smile in the top right of the comment and pick an emoji from the dropdown.
|
||||
- Remove an award emoji, click the emoji again and the vote will be removed.
|
||||
- Remove an award emoji, click the emoji again.
|
||||
|
||||
![Picking an emoji for a comment](img/award_emoji_comment_picker.png)
|
||||
|
||||
|
|
|
@ -149,12 +149,11 @@ Shared runners provided by GitLab are **not** configurable. Consider [installing
|
|||
|
||||
### Linux shared runners
|
||||
|
||||
Linux shared runners on GitLab.com run in [autoscale mode](https://docs.gitlab.com/runner/configuration/autoscale.html) and are powered by Google Cloud Platform.
|
||||
Autoscaling means reduced waiting times to spin up CI/CD jobs, and isolated VMs for each project,
|
||||
thus maximizing security. They're free to use for public open source projects and limited
|
||||
to 400 CI minutes per month per group for private projects. More minutes
|
||||
[can be purchased](../../subscriptions/gitlab_com/index.md#purchase-additional-ci-minutes), if
|
||||
needed. Read about all [GitLab.com plans](https://about.gitlab.com/pricing/).
|
||||
Linux shared runners on GitLab.com run in autoscale mode and are powered by Google Cloud Platform.
|
||||
|
||||
Autoscaling means reduced queue times to spin up CI/CD jobs, and isolated VMs for each project, thus maximizing security. These shared runners are available for users and customers on GitLab.com.
|
||||
|
||||
GitLab offers Gold tier capabilities and included CI/CD minutes per group per month for our [Open Source](https://about.gitlab.com/solutions/open-source/join/), [Education](https://about.gitlab.com/solutions/education/), and [Startups](https://about.gitlab.com/solutions/startups/) programs. For private projects, GitLab offers various [plans](https://about.gitlab.com/pricing/), starting with a Free tier.
|
||||
|
||||
All your CI/CD jobs run on [n1-standard-1 instances](https://cloud.google.com/compute/docs/machine-types) with 3.75GB of RAM, CoreOS and the latest Docker Engine
|
||||
installed. Instances provide 1 vCPU and 25GB of HDD disk space. The default
|
||||
|
|
|
@ -66,7 +66,7 @@ See [Adding and removing Kubernetes clusters](add_remove_clusters.md) for detail
|
|||
to:
|
||||
|
||||
- Create a cluster in Google Cloud Platform (GCP) or Amazon Elastic Kubernetes Service
|
||||
(EKS) using GitLab's UI.
|
||||
(EKS) using the GitLab UI.
|
||||
- Add an integration to an existing cluster from any Kubernetes platform.
|
||||
|
||||
### Multiple Kubernetes clusters
|
||||
|
@ -237,7 +237,7 @@ A Kubernetes cluster can be the destination for a deployment job. If
|
|||
[deployment variables](#deployment-variables) are made available to your job
|
||||
and configuration is not required. You can immediately begin interacting with
|
||||
the cluster from your jobs using tools such as `kubectl` or `helm`.
|
||||
- You don't use GitLab's cluster integration you can still deploy to your
|
||||
- You don't use the GitLab cluster integration, you can still deploy to your
|
||||
cluster. However, you must configure Kubernetes tools yourself
|
||||
using [environment variables](../../../ci/variables/README.md#custom-environment-variables)
|
||||
before you can interact with the cluster from your jobs.
|
||||
|
@ -318,7 +318,7 @@ the need to leave GitLab.
|
|||
|
||||
#### Deploy Boards
|
||||
|
||||
GitLab's Deploy Boards offer a consolidated view of the current health and
|
||||
GitLab Deploy Boards offer a consolidated view of the current health and
|
||||
status of each CI [environment](../../../ci/environments/index.md) running on Kubernetes,
|
||||
displaying the status of the pods in the deployment. Developers and other
|
||||
teammates can view the progress and status of a rollout, pod by pod, in the
|
||||
|
|
|
@ -27,7 +27,7 @@ NGINX Ingress versions prior to 0.16.0 offer an included [VTS Prometheus metrics
|
|||
|
||||
## Configuring NGINX Ingress monitoring
|
||||
|
||||
If you have deployed NGINX Ingress using GitLab's [Kubernetes cluster integration](../../clusters/index.md#installing-applications), Prometheus [automatically monitors it](#about-managed-nginx-ingress-deployments).
|
||||
If you have deployed NGINX Ingress using the GitLab [Kubernetes cluster integration](../../clusters/index.md#installing-applications), Prometheus [automatically monitors it](#about-managed-nginx-ingress-deployments).
|
||||
|
||||
For other deployments, there is [some configuration](#manually-setting-up-nginx-ingress-for-prometheus-monitoring) required depending on your installation:
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ GitLab has support for automatically detecting and monitoring the Kubernetes NGI
|
|||
|
||||
## Configuring NGINX Ingress monitoring
|
||||
|
||||
If you have deployed NGINX Ingress using GitLab's [Kubernetes cluster integration](../../clusters/index.md#installing-applications), Prometheus [automatically monitors](#about-managed-nginx-ingress-deployments) it.
|
||||
If you have deployed NGINX Ingress using the GitLab [Kubernetes cluster integration](../../clusters/index.md#installing-applications), Prometheus [automatically monitors](#about-managed-nginx-ingress-deployments) it.
|
||||
|
||||
For other deployments, there is [some configuration](#manually-setting-up-nginx-ingress-for-prometheus-monitoring) required depending on your installation:
|
||||
|
||||
|
|
|
@ -300,7 +300,7 @@ module API
|
|||
post '/two_factor_otp_check', feature_category: :authentication_and_authorization do
|
||||
status 200
|
||||
|
||||
break { success: false } unless Feature.enabled?(:two_factor_for_cli)
|
||||
break { success: false, message: 'Feature flag is disabled' } unless Feature.enabled?(:two_factor_for_cli)
|
||||
|
||||
actor.update_last_used_at!
|
||||
user = actor.user
|
||||
|
@ -316,6 +316,8 @@ module API
|
|||
otp_validation_result = ::Users::ValidateOtpService.new(user).execute(params.fetch(:otp_attempt))
|
||||
|
||||
if otp_validation_result[:status] == :success
|
||||
::Gitlab::Auth::Otp::SessionEnforcer.new(actor.key).update_session
|
||||
|
||||
{ success: true }
|
||||
else
|
||||
{ success: false, message: 'Invalid OTP' }
|
||||
|
|
36
lib/gitlab/auth/otp/session_enforcer.rb
Normal file
36
lib/gitlab/auth/otp/session_enforcer.rb
Normal file
|
@ -0,0 +1,36 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Auth
|
||||
module Otp
|
||||
class SessionEnforcer
|
||||
OTP_SESSIONS_NAMESPACE = 'session:otp'
|
||||
DEFAULT_EXPIRATION = 15.minutes.to_i
|
||||
|
||||
def initialize(key)
|
||||
@key = key
|
||||
end
|
||||
|
||||
def update_session
|
||||
Gitlab::Redis::SharedState.with do |redis|
|
||||
redis.setex(key_name, DEFAULT_EXPIRATION, true)
|
||||
end
|
||||
end
|
||||
|
||||
def access_restricted?
|
||||
Gitlab::Redis::SharedState.with do |redis|
|
||||
!redis.get(key_name)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :key
|
||||
|
||||
def key_name
|
||||
@key_name ||= "#{OTP_SESSIONS_NAMESPACE}:#{key.id}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -77,6 +77,7 @@ module Gitlab
|
|||
check_authentication_abilities!
|
||||
check_command_disabled!
|
||||
check_command_existence!
|
||||
check_otp_session!
|
||||
|
||||
custom_action = check_custom_action
|
||||
return custom_action if custom_action
|
||||
|
@ -254,6 +255,31 @@ module Gitlab
|
|||
end
|
||||
end
|
||||
|
||||
def check_otp_session!
|
||||
return unless ssh?
|
||||
return if !key? || deploy_key?
|
||||
return unless Feature.enabled?(:two_factor_for_cli)
|
||||
return unless user.two_factor_enabled?
|
||||
|
||||
if ::Gitlab::Auth::Otp::SessionEnforcer.new(actor).access_restricted?
|
||||
message = "OTP verification is required to access the repository.\n\n"\
|
||||
" Use: #{build_ssh_otp_verify_command}"
|
||||
|
||||
raise ForbiddenError, message
|
||||
end
|
||||
end
|
||||
|
||||
def build_ssh_otp_verify_command
|
||||
user = "#{Gitlab.config.gitlab_shell.ssh_user}@" unless Gitlab.config.gitlab_shell.ssh_user.empty?
|
||||
user_host = "#{user}#{Gitlab.config.gitlab_shell.ssh_host}"
|
||||
|
||||
if Gitlab.config.gitlab_shell.ssh_port != 22
|
||||
"ssh #{user_host} -p #{Gitlab.config.gitlab_shell.ssh_port} 2fa_verify"
|
||||
else
|
||||
"ssh #{user_host} 2fa_verify"
|
||||
end
|
||||
end
|
||||
|
||||
def check_db_accessibility!
|
||||
return unless receive_pack?
|
||||
|
||||
|
@ -399,6 +425,10 @@ module Gitlab
|
|||
protocol == 'http'
|
||||
end
|
||||
|
||||
def ssh?
|
||||
protocol == 'ssh'
|
||||
end
|
||||
|
||||
def upload_pack?
|
||||
cmd == 'git-upload-pack'
|
||||
end
|
||||
|
|
|
@ -6,12 +6,17 @@ module QA
|
|||
module_function
|
||||
|
||||
# In some cases we don't need to wait for anything, blocked, running or pending is acceptable
|
||||
# Some cases only need pipeline to finish with different condition (completion, success or replication)
|
||||
# Some cases only we do need pipeline to finish with expected condition (completed, succeeded or replicated)
|
||||
def visit_latest_pipeline(pipeline_condition: nil)
|
||||
Page::Project::Menu.perform(&:click_ci_cd_pipelines)
|
||||
Page::Project::Pipeline::Index.perform(&:"wait_for_latest_pipeline_#{pipeline_condition}") if pipeline_condition
|
||||
Page::Project::Pipeline::Index.perform(&:click_on_latest_pipeline)
|
||||
end
|
||||
|
||||
def wait_for_latest_pipeline(pipeline_condition:)
|
||||
Page::Project::Menu.perform(&:click_ci_cd_pipelines)
|
||||
Page::Project::Pipeline::Index.perform(&:"wait_for_latest_pipeline_#{pipeline_condition}")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -22,11 +22,11 @@ module QA
|
|||
all_elements(:pipeline_url_link, minimum: 1, wait: QA::Support::Repeater::DEFAULT_MAX_WAIT_TIME).first.click
|
||||
end
|
||||
|
||||
def wait_for_latest_pipeline_success
|
||||
def wait_for_latest_pipeline_succeeded
|
||||
wait_for_latest_pipeline_status { has_text?('passed') }
|
||||
end
|
||||
|
||||
def wait_for_latest_pipeline_completion
|
||||
def wait_for_latest_pipeline_completed
|
||||
wait_for_latest_pipeline_status { has_text?('passed') || has_text?('failed') }
|
||||
end
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ module QA
|
|||
add_included_files
|
||||
add_main_ci_file
|
||||
project.visit!
|
||||
view_the_last_pipeline
|
||||
Flow::Pipeline.visit_latest_pipeline(pipeline_condition: 'succeeded')
|
||||
end
|
||||
|
||||
after do
|
||||
|
@ -78,12 +78,6 @@ module QA
|
|||
end
|
||||
end
|
||||
|
||||
def view_the_last_pipeline
|
||||
Page::Project::Menu.perform(&:click_ci_cd_pipelines)
|
||||
Page::Project::Pipeline::Index.perform(&:wait_for_latest_pipeline_success)
|
||||
Page::Project::Pipeline::Index.perform(&:click_on_latest_pipeline)
|
||||
end
|
||||
|
||||
def main_ci_file
|
||||
{
|
||||
file_path: '.gitlab-ci.yml',
|
||||
|
|
|
@ -41,7 +41,7 @@ module QA
|
|||
add_ci_file(downstream_project, downstream_ci_file)
|
||||
add_ci_file(upstream_project, upstream_ci_file)
|
||||
upstream_project.visit!
|
||||
Flow::Pipeline.visit_latest_pipeline(pipeline_condition: 'success')
|
||||
Flow::Pipeline.visit_latest_pipeline(pipeline_condition: 'succeeded')
|
||||
end
|
||||
|
||||
after do
|
||||
|
|
|
@ -25,7 +25,7 @@ module QA
|
|||
Flow::Login.sign_in
|
||||
add_ci_files
|
||||
project.visit!
|
||||
Flow::Pipeline.visit_latest_pipeline(pipeline_condition: 'success')
|
||||
Flow::Pipeline.visit_latest_pipeline(pipeline_condition: 'succeeded')
|
||||
end
|
||||
|
||||
after do
|
||||
|
|
|
@ -81,8 +81,7 @@ module QA
|
|||
end
|
||||
|
||||
project.visit!
|
||||
Page::Project::Menu.perform(&:click_ci_cd_pipelines)
|
||||
Page::Project::Pipeline::Index.perform(&:click_on_latest_pipeline)
|
||||
Flow::Pipeline.visit_latest_pipeline
|
||||
|
||||
Page::Project::Pipeline::Show.perform do |pipeline|
|
||||
pipeline.click_job('publish')
|
||||
|
|
|
@ -67,8 +67,7 @@ module QA
|
|||
end
|
||||
|
||||
project.visit!
|
||||
Page::Project::Menu.perform(&:click_ci_cd_pipelines)
|
||||
Page::Project::Pipeline::Index.perform(&:click_on_latest_pipeline)
|
||||
Flow::Pipeline.visit_latest_pipeline
|
||||
|
||||
Page::Project::Pipeline::Show.perform do |pipeline|
|
||||
pipeline.click_job('upload')
|
||||
|
|
|
@ -27,7 +27,7 @@ module QA
|
|||
|
||||
it 'parent pipelines passes if child passes', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/751' do
|
||||
add_ci_files(success_child_ci_file)
|
||||
Flow::Pipeline.visit_latest_pipeline(pipeline_condition: 'completion')
|
||||
Flow::Pipeline.visit_latest_pipeline(pipeline_condition: 'completed')
|
||||
|
||||
Page::Project::Pipeline::Show.perform do |parent_pipeline|
|
||||
expect(parent_pipeline).to have_child_pipeline
|
||||
|
@ -37,7 +37,7 @@ module QA
|
|||
|
||||
it 'parent pipeline fails if child fails', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/752' do
|
||||
add_ci_files(fail_child_ci_file)
|
||||
Flow::Pipeline.visit_latest_pipeline(pipeline_condition: 'completion')
|
||||
Flow::Pipeline.visit_latest_pipeline(pipeline_condition: 'completed')
|
||||
|
||||
Page::Project::Pipeline::Show.perform do |parent_pipeline|
|
||||
expect(parent_pipeline).to have_child_pipeline
|
||||
|
|
|
@ -27,7 +27,7 @@ module QA
|
|||
|
||||
it 'parent pipelines passes if child passes', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/754' do
|
||||
add_ci_files(success_child_ci_file)
|
||||
Flow::Pipeline.visit_latest_pipeline(pipeline_condition: 'completion')
|
||||
Flow::Pipeline.visit_latest_pipeline(pipeline_condition: 'completed')
|
||||
|
||||
Page::Project::Pipeline::Show.perform do |parent_pipeline|
|
||||
expect(parent_pipeline).to have_child_pipeline
|
||||
|
@ -37,7 +37,7 @@ module QA
|
|||
|
||||
it 'parent pipeline passes even if child fails', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/753' do
|
||||
add_ci_files(fail_child_ci_file)
|
||||
Flow::Pipeline.visit_latest_pipeline(pipeline_condition: 'completion')
|
||||
Flow::Pipeline.visit_latest_pipeline(pipeline_condition: 'completed')
|
||||
|
||||
Page::Project::Pipeline::Show.perform do |parent_pipeline|
|
||||
expect(parent_pipeline).to have_child_pipeline
|
||||
|
|
|
@ -24,16 +24,6 @@ RSpec.describe Groups::Settings::IntegrationsController do
|
|||
group.add_owner(user)
|
||||
end
|
||||
|
||||
context 'when group_level_integrations not enabled' do
|
||||
it 'returns not_found' do
|
||||
stub_feature_flags(group_level_integrations: false)
|
||||
|
||||
get :index, params: { group_id: group }
|
||||
|
||||
expect(response).to have_gitlab_http_status(:not_found)
|
||||
end
|
||||
end
|
||||
|
||||
it 'successfully displays the template' do
|
||||
get :index, params: { group_id: group }
|
||||
|
||||
|
@ -57,16 +47,6 @@ RSpec.describe Groups::Settings::IntegrationsController do
|
|||
group.add_owner(user)
|
||||
end
|
||||
|
||||
context 'when group_level_integrations not enabled' do
|
||||
it 'returns not_found' do
|
||||
stub_feature_flags(group_level_integrations: false)
|
||||
|
||||
get :edit, params: { group_id: group, id: Service.available_services_names(include_project_specific: false).sample }
|
||||
|
||||
expect(response).to have_gitlab_http_status(:not_found)
|
||||
end
|
||||
end
|
||||
|
||||
Service.available_services_names(include_project_specific: false).each do |integration_name|
|
||||
context "#{integration_name}" do
|
||||
it 'successfully displays the template' do
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Severity Summary given the message {"countMessage": "%{criticalStart}0 Critical%{criticalEnd} %{highStart}1 High%{highEnd} and %{otherStart}0 Others%{otherEnd}", "critical": 0, "high": 1, "message": "Security scanning detected %{totalStart}1%{totalEnd} potential vulnerability", "other": 0, "status": "", "total": 1} interpolates correctly 1`] = `
|
||||
exports[`SecuritySummary component given the message {"countMessage": "%{criticalStart}0 Critical%{criticalEnd} %{highStart}1 High%{highEnd} and %{otherStart}0 Others%{otherEnd}", "critical": 0, "high": 1, "message": "Security scanning detected %{totalStart}1%{totalEnd} potential vulnerability", "other": 0, "status": "", "total": 1} interpolates correctly 1`] = `
|
||||
<span>
|
||||
Security scanning detected
|
||||
<strong>
|
||||
|
@ -43,7 +43,7 @@ exports[`Severity Summary given the message {"countMessage": "%{criticalStart}0
|
|||
</span>
|
||||
`;
|
||||
|
||||
exports[`Severity Summary given the message {"countMessage": "%{criticalStart}1 Critical%{criticalEnd} %{highStart}0 High%{highEnd} and %{otherStart}0 Others%{otherEnd}", "critical": 1, "high": 0, "message": "Security scanning detected %{totalStart}1%{totalEnd} potential vulnerability", "other": 0, "status": "", "total": 1} interpolates correctly 1`] = `
|
||||
exports[`SecuritySummary component given the message {"countMessage": "%{criticalStart}1 Critical%{criticalEnd} %{highStart}0 High%{highEnd} and %{otherStart}0 Others%{otherEnd}", "critical": 1, "high": 0, "message": "Security scanning detected %{totalStart}1%{totalEnd} potential vulnerability", "other": 0, "status": "", "total": 1} interpolates correctly 1`] = `
|
||||
<span>
|
||||
Security scanning detected
|
||||
<strong>
|
||||
|
@ -86,7 +86,7 @@ exports[`Severity Summary given the message {"countMessage": "%{criticalStart}1
|
|||
</span>
|
||||
`;
|
||||
|
||||
exports[`Severity Summary given the message {"countMessage": "%{criticalStart}1 Critical%{criticalEnd} %{highStart}2 High%{highEnd} and %{otherStart}0 Others%{otherEnd}", "critical": 1, "high": 2, "message": "Security scanning detected %{totalStart}3%{totalEnd} potential vulnerabilities", "other": 0, "status": "", "total": 3} interpolates correctly 1`] = `
|
||||
exports[`SecuritySummary component given the message {"countMessage": "%{criticalStart}1 Critical%{criticalEnd} %{highStart}2 High%{highEnd} and %{otherStart}0 Others%{otherEnd}", "critical": 1, "high": 2, "message": "Security scanning detected %{totalStart}3%{totalEnd} potential vulnerabilities", "other": 0, "status": "", "total": 3} interpolates correctly 1`] = `
|
||||
<span>
|
||||
Security scanning detected
|
||||
<strong>
|
||||
|
@ -129,14 +129,14 @@ exports[`Severity Summary given the message {"countMessage": "%{criticalStart}1
|
|||
</span>
|
||||
`;
|
||||
|
||||
exports[`Severity Summary given the message {"message": ""} interpolates correctly 1`] = `
|
||||
exports[`SecuritySummary component given the message {"message": ""} interpolates correctly 1`] = `
|
||||
<span>
|
||||
|
||||
<!---->
|
||||
</span>
|
||||
`;
|
||||
|
||||
exports[`Severity Summary given the message {"message": "foo"} interpolates correctly 1`] = `
|
||||
exports[`SecuritySummary component given the message {"message": "foo"} interpolates correctly 1`] = `
|
||||
<span>
|
||||
foo
|
||||
<!---->
|
||||
|
|
|
@ -3,7 +3,7 @@ import { shallowMount } from '@vue/test-utils';
|
|||
import SecuritySummary from '~/vue_shared/security_reports/components/security_summary.vue';
|
||||
import { groupedTextBuilder } from '~/vue_shared/security_reports/store/utils';
|
||||
|
||||
describe('Severity Summary', () => {
|
||||
describe('SecuritySummary component', () => {
|
||||
let wrapper;
|
||||
|
||||
const createWrapper = message => {
|
||||
|
|
|
@ -28,38 +28,6 @@ RSpec.describe ServicesHelper do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#group_level_integrations?' do
|
||||
subject { helper.group_level_integrations? }
|
||||
|
||||
context 'when no group is present' do
|
||||
it { is_expected.to eq(false) }
|
||||
end
|
||||
|
||||
context 'when group is present' do
|
||||
let(:group) { build_stubbed(:group) }
|
||||
|
||||
before do
|
||||
assign(:group, group)
|
||||
end
|
||||
|
||||
context 'when `group_level_integrations` is not enabled' do
|
||||
it 'returns false' do
|
||||
stub_feature_flags(group_level_integrations: false)
|
||||
|
||||
is_expected.to eq(false)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when `group_level_integrations` is enabled for the group' do
|
||||
it 'returns true' do
|
||||
stub_feature_flags(group_level_integrations: group)
|
||||
|
||||
is_expected.to eq(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#scoped_reset_integration_path' do
|
||||
let(:integration) { build_stubbed(:jira_service) }
|
||||
let(:group) { nil }
|
||||
|
|
41
spec/lib/gitlab/auth/otp/session_enforcer_spec.rb
Normal file
41
spec/lib/gitlab/auth/otp/session_enforcer_spec.rb
Normal file
|
@ -0,0 +1,41 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::Auth::Otp::SessionEnforcer, :clean_gitlab_redis_shared_state do
|
||||
let_it_be(:key) { create(:key)}
|
||||
|
||||
describe '#update_session' do
|
||||
it 'registers a session in Redis' do
|
||||
redis = double(:redis)
|
||||
expect(Gitlab::Redis::SharedState).to receive(:with).and_yield(redis)
|
||||
|
||||
expect(redis).to(
|
||||
receive(:setex)
|
||||
.with("#{described_class::OTP_SESSIONS_NAMESPACE}:#{key.id}",
|
||||
described_class::DEFAULT_EXPIRATION,
|
||||
true)
|
||||
.once)
|
||||
|
||||
described_class.new(key).update_session
|
||||
end
|
||||
end
|
||||
|
||||
describe '#access_restricted?' do
|
||||
subject { described_class.new(key).access_restricted? }
|
||||
|
||||
context 'with existing session' do
|
||||
before do
|
||||
Gitlab::Redis::SharedState.with do |redis|
|
||||
redis.set("#{described_class::OTP_SESSIONS_NAMESPACE}:#{key.id}", true )
|
||||
end
|
||||
end
|
||||
|
||||
it { is_expected.to be_falsey }
|
||||
end
|
||||
|
||||
context 'without an existing session' do
|
||||
it { is_expected.to be_truthy }
|
||||
end
|
||||
end
|
||||
end
|
|
@ -387,6 +387,108 @@ RSpec.describe Gitlab::GitAccess do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#check_otp_session!' do
|
||||
let_it_be(:user) { create(:user, :two_factor_via_otp)}
|
||||
let_it_be(:key) { create(:key, user: user) }
|
||||
let_it_be(:actor) { key }
|
||||
|
||||
before do
|
||||
project.add_developer(user)
|
||||
stub_feature_flags(two_factor_for_cli: true)
|
||||
end
|
||||
|
||||
context 'with an OTP session', :clean_gitlab_redis_shared_state do
|
||||
before do
|
||||
Gitlab::Redis::SharedState.with do |redis|
|
||||
redis.set("#{Gitlab::Auth::Otp::SessionEnforcer::OTP_SESSIONS_NAMESPACE}:#{key.id}", true)
|
||||
end
|
||||
end
|
||||
|
||||
it 'allows push and pull access' do
|
||||
aggregate_failures do
|
||||
expect { push_access_check }.not_to raise_error
|
||||
expect { pull_access_check }.not_to raise_error
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'without OTP session' do
|
||||
it 'does not allow push or pull access' do
|
||||
user = 'jane.doe'
|
||||
host = 'fridge.ssh'
|
||||
port = 42
|
||||
|
||||
stub_config(
|
||||
gitlab_shell: {
|
||||
ssh_user: user,
|
||||
ssh_host: host,
|
||||
ssh_port: port
|
||||
}
|
||||
)
|
||||
|
||||
error_message = "OTP verification is required to access the repository.\n\n"\
|
||||
" Use: ssh #{user}@#{host} -p #{port} 2fa_verify"
|
||||
|
||||
aggregate_failures do
|
||||
expect { push_access_check }.to raise_forbidden(error_message)
|
||||
expect { pull_access_check }.to raise_forbidden(error_message)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when protocol is HTTP' do
|
||||
let(:protocol) { 'http' }
|
||||
|
||||
it 'allows push and pull access' do
|
||||
aggregate_failures do
|
||||
expect { push_access_check }.not_to raise_error
|
||||
expect { pull_access_check }.not_to raise_error
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when actor is not an SSH key' do
|
||||
let(:deploy_key) { create(:deploy_key, user: user) }
|
||||
let(:actor) { deploy_key }
|
||||
|
||||
before do
|
||||
deploy_key.deploy_keys_projects.create(project: project, can_push: true)
|
||||
end
|
||||
|
||||
it 'allows push and pull access' do
|
||||
aggregate_failures do
|
||||
expect { push_access_check }.not_to raise_error
|
||||
expect { pull_access_check }.not_to raise_error
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when 2FA is not enabled for the user' do
|
||||
let(:user) { create(:user)}
|
||||
let(:actor) { create(:key, user: user) }
|
||||
|
||||
it 'allows push and pull access' do
|
||||
aggregate_failures do
|
||||
expect { push_access_check }.not_to raise_error
|
||||
expect { pull_access_check }.not_to raise_error
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(two_factor_for_cli: false)
|
||||
end
|
||||
|
||||
it 'allows push and pull access' do
|
||||
aggregate_failures do
|
||||
expect { push_access_check }.not_to raise_error
|
||||
expect { pull_access_check }.not_to raise_error
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#check_db_accessibility!' do
|
||||
context 'when in a read-only GitLab instance' do
|
||||
before do
|
||||
|
|
|
@ -1336,9 +1336,13 @@ RSpec.describe API::Internal::Base do
|
|||
end
|
||||
|
||||
context 'when the OTP is valid' do
|
||||
it 'returns success' do
|
||||
it 'registers a new OTP session and returns success' do
|
||||
allow_any_instance_of(Users::ValidateOtpService).to receive(:execute).with(otp).and_return(status: :success)
|
||||
|
||||
expect_next_instance_of(::Gitlab::Auth::Otp::SessionEnforcer) do |session_enforcer|
|
||||
expect(session_enforcer).to receive(:update_session).once
|
||||
end
|
||||
|
||||
subject
|
||||
|
||||
expect(json_response['success']).to be_truthy
|
||||
|
|
Loading…
Reference in a new issue