Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2021-03-18 00:08:58 +00:00
parent a0b4a462b0
commit 099333e261
73 changed files with 408 additions and 292 deletions

View File

@ -482,7 +482,7 @@ class ApplicationController < ActionController::Base
end
def set_current_admin(&block)
return yield unless Feature.enabled?(:user_mode_in_session)
return yield unless Gitlab::CurrentSettings.admin_mode
return yield unless current_user
Gitlab::Auth::CurrentUserMode.with_current_admin(current_user, &block)

View File

@ -15,7 +15,7 @@ module EnforcesAdminAuthentication
def authenticate_admin!
return render_404 unless current_user.admin?
return unless Feature.enabled?(:user_mode_in_session)
return unless Gitlab::CurrentSettings.admin_mode
unless current_user_mode.admin_mode?
current_user_mode.request_admin_mode!

View File

@ -10,26 +10,31 @@
# track_redis_hll_event :index, :show, name: 'i_analytics_dev_ops_score'
#
# You can also pass custom conditions using `if:`, using the same format as with Rails callbacks.
# You can also pass an optional block that calculates and returns a custom id to track.
module RedisTracking
extend ActiveSupport::Concern
class_methods do
def track_redis_hll_event(*controller_actions, name:, if: nil)
def track_redis_hll_event(*controller_actions, name:, if: nil, &block)
custom_conditions = Array.wrap(binding.local_variable_get('if'))
conditions = [:trackable_request?, *custom_conditions]
after_action only: controller_actions, if: conditions do
track_unique_redis_hll_event(name)
track_unique_redis_hll_event(name, &block)
end
end
end
private
def track_unique_redis_hll_event(event_name)
return unless visitor_id
def track_unique_redis_hll_event(event_name, &block)
custom_id = block_given? ? yield(self) : nil
Gitlab::UsageDataCounters::HLLRedisCounter.track_event(event_name, values: visitor_id)
unique_id = custom_id || visitor_id
return unless unique_id
Gitlab::UsageDataCounters::HLLRedisCounter.track_event(event_name, values: unique_id)
end
def trackable_request?

View File

@ -27,7 +27,7 @@ module SessionlessAuthentication
end
def sessionless_bypass_admin_mode!(&block)
return yield unless Feature.enabled?(:user_mode_in_session)
return yield unless Gitlab::CurrentSettings.admin_mode
Gitlab::Auth::CurrentUserMode.bypass_session!(current_user.id, &block)
end

View File

@ -16,7 +16,7 @@ class Ldap::OmniauthCallbacksController < OmniauthCallbacksController
def ldap
return unless Gitlab::Auth::Ldap::Config.sign_in_enabled?
if Feature.enabled?(:user_mode_in_session)
if Gitlab::CurrentSettings.admin_mode
return admin_mode_flow(Gitlab::Auth::Ldap::User) if current_user_mode.admin_mode_requested?
end

View File

@ -95,7 +95,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
end
def after_omniauth_failure_path_for(scope)
if Feature.enabled?(:user_mode_in_session)
if Gitlab::CurrentSettings.admin_mode
return new_admin_session_path if current_user_mode.admin_mode_requested?
end
@ -112,7 +112,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
log_audit_event(current_user, with: oauth['provider'])
if Feature.enabled?(:user_mode_in_session)
if Gitlab::CurrentSettings.admin_mode
return admin_mode_flow(auth_module::User) if current_user_mode.admin_mode_requested?
end

View File

@ -179,6 +179,7 @@ module ApplicationSettingsHelper
def visible_attributes
[
:abuse_notification_email,
:admin_mode,
:after_sign_out_path,
:after_sign_up_text,
:akismet_api_key,

View File

@ -92,10 +92,8 @@ module NavHelper
links << :admin_impersonation
end
if Feature.enabled?(:user_mode_in_session)
if current_user_mode.admin_mode?
links << :admin_mode
end
if Gitlab::CurrentSettings.admin_mode && current_user_mode.admin_mode?
links << :admin_mode
end
links

View File

@ -465,6 +465,9 @@ class ApplicationSetting < ApplicationRecord
length: { maximum: 100, message: N_('is too long (maximum is 100 entries)') },
allow_nil: false
validates :admin_mode,
inclusion: { in: [true, false], message: _('must be a boolean value') }
attr_encrypted :asset_proxy_secret_key,
mode: :per_attribute_iv,
key: Settings.attr_encrypted_db_key_base_truncated,

View File

@ -35,6 +35,7 @@ module ApplicationSettingImplementation
class_methods do
def defaults
{
admin_mode: false,
after_sign_up_text: nil,
akismet_enabled: false,
allow_local_requests_from_system_hooks: true,

View File

@ -6,7 +6,7 @@ class BasePolicy < DeclarativePolicy::Base
desc "User is an instance admin"
with_options scope: :user, score: 0
condition(:admin) do
if Feature.enabled?(:user_mode_in_session)
if Gitlab::CurrentSettings.admin_mode
Gitlab::Auth::CurrentUserMode.new(@user).admin_mode?
else
@user&.admin?

View File

@ -31,6 +31,15 @@
= f.check_box :require_two_factor_authentication, class: 'form-check-input'
= f.label :require_two_factor_authentication, class: 'form-check-label' do
Require all users to set up Two-factor authentication
.form-group
= f.label :admin_mode, _('Admin Mode'), class: 'label-bold'
= sprite_icon('lock', css_class: 'gl-icon')
.form-check
= f.check_box :admin_mode, class: 'form-check-input'
= f.label :admin_mode, class: 'form-check-label' do
= _('Require additional authentication for administrative tasks')
.form-text.text-muted
= link_to _('Learn more.'), help_page_path('user/admin_area/settings/sign_in_restrictions', anchor: 'admin-mode')
.form-group
= f.label :unknown_sign_in, _('Email notification for unknown sign-ins'), class: 'label-bold'
.form-check

View File

@ -50,7 +50,7 @@
= nav_link(controller: 'admin/dashboard') do
= link_to admin_root_path, class: 'admin-icon qa-admin-area-link d-xl-none' do
= _('Admin Area')
- if Feature.enabled?(:user_mode_in_session)
- if Gitlab::CurrentSettings.admin_mode
- if header_link?(:admin_mode)
= nav_link(controller: 'admin/sessions') do
= link_to destroy_admin_session_path, method: :post, class: 'd-lg-none lock-open-icon' do
@ -69,7 +69,7 @@
= link_to admin_root_path, class: 'admin-icon qa-admin-area-link', title: _('Admin Area'), aria: { label: _('Admin Area') }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= sprite_icon('admin', size: 18)
- if Feature.enabled?(:user_mode_in_session)
- if Gitlab::CurrentSettings.admin_mode
- if header_link?(:admin_mode)
= nav_link(controller: 'admin/sessions', html_options: { class: "d-none d-lg-block"}) do
= link_to destroy_admin_session_path, method: :post, title: _('Leave Admin Mode'), aria: { label: _('Leave Admin Mode') }, data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do

View File

@ -15,7 +15,7 @@
= render 'shared/new_commit_form', placeholder: _("Add new directory")
.form-actions
= submit_tag _("Create directory"), class: 'btn gl-button btn-success'
= link_to "Cancel", '#', class: "btn gl-button btn-cancel", "data-dismiss" => "modal"
= submit_tag _("Create directory"), class: 'btn gl-button btn-confirm'
= link_to "Cancel", '#', class: "btn gl-button btn-default btn-cancel", "data-dismiss" => "modal"
= render 'shared/projects/edit_information'

View File

@ -20,9 +20,9 @@
= render 'shared/new_commit_form', placeholder: placeholder, ref: local_assigns[:ref]
.form-actions
= button_tag class: 'btn gl-button btn-success btn-upload-file', id: 'submit-all', type: 'button' do
= button_tag class: 'btn gl-button btn-confirm btn-upload-file', id: 'submit-all', type: 'button' do
.spinner.spinner-sm.gl-mr-2.js-loading-icon.hidden
= button_title
= link_to _("Cancel"), '#', class: "btn gl-button btn-cancel", "data-dismiss" => "modal"
= link_to _("Cancel"), '#', class: "btn gl-button btn-default btn-cancel", "data-dismiss" => "modal"
= render 'shared/projects/edit_information'

View File

@ -17,4 +17,4 @@
= link_to _("Select"), project_forks_path(@project, namespace_key: namespace.id),
data: { qa_selector: 'fork_namespace_button', qa_name: namespace.human_name },
method: "POST",
class: ["btn gl-button btn-success", ("disabled" unless can_create_project)]
class: ["btn gl-button btn-confirm", ("disabled" unless can_create_project)]

View File

@ -30,11 +30,11 @@
- if current_user && can?(current_user, :fork_project, @project)
- if current_user.already_forked?(@project) && current_user.manageable_namespaces.size < 2
= link_to namespace_project_path(current_user, current_user.fork_of(@project)), title: _('Go to your fork'), class: 'btn gl-button btn-success' do
= link_to namespace_project_path(current_user, current_user.fork_of(@project)), title: _('Go to your fork'), class: 'btn gl-button btn-confirm' do
= sprite_icon('fork', size: 12)
%span= _('Fork')
- else
= link_to new_project_fork_path(@project), title: _("Fork project"), class: 'btn gl-button btn-success' do
= link_to new_project_fork_path(@project), title: _("Fork project"), class: 'btn gl-button btn-confirm' do
= sprite_icon('fork', size: 12)
%span= _('Fork')

View File

@ -0,0 +1,5 @@
---
title: Move from btn-success to btn-confirm in blob directory
merge_request: 56213
author: Yogi (@yo)
type: changed

View File

@ -0,0 +1,5 @@
---
title: Move from btn-success to btn-confirm in forks directory
merge_request: 56333
author: Yogi (@yo)
type: changed

View File

@ -0,0 +1,5 @@
---
title: Convert admin mode feature flag to system application setting
merge_request: 53610
author: Diego Louzán
type: added

View File

@ -1,8 +1,8 @@
---
name: user_mode_in_session
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/16981
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/321025
milestone: 12.4
name: use_marker_ranges
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56361
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/324638
milestone: '13.10'
type: development
group: group::access
group: group::source code
default_enabled: false

View File

@ -1,18 +0,0 @@
---
key_path: usage_activity_by_stage_monthly.secure.user_preferences_group_overview_security_dashboard
description: Users who set personal preference to see Security Dashboard on Group
overview page
product_section: sec
product_stage: secure
product_group: group::threat insights
product_category: vulnerability_management
value_type: number
status: data_available
time_frame: 28d
data_source:
distribution:
- ce
- ee
tier:
- ultimate
skip_validation: true

View File

@ -1,18 +0,0 @@
---
key_path: counts.user_preferences_group_overview_details
description: Count of users who set personal preference to see Details on Group overview
page
product_section: sec
product_stage: secure
product_group: group::threat insights
product_category: vulnerability_management
value_type: number
status: data_available
time_frame: all
data_source: database
distribution:
- ce
- ee
tier:
- ultimate
skip_validation: true

View File

@ -1,18 +0,0 @@
---
key_path: counts.user_preferences_group_overview_security_dashboard
description: Count of users who set personal preference to see Security Dashboard
on Group overview page
product_section: sec
product_stage: secure
product_group: group::threat insights
product_category: vulnerability_management
value_type: number
status: data_available
time_frame: all
data_source: database
distribution:
- ce
- ee
tier:
- ultimate
skip_validation: true

View File

@ -1,17 +0,0 @@
---
key_path: usage_activity_by_stage.secure.user_preferences_group_overview_security_dashboard
description: Users who set personal preference to see Details on Group overview page
product_section: sec
product_stage: secure
product_group: group::threat insights
product_category: vulnerability_management
value_type: number
status: data_available
time_frame: all
data_source:
distribution:
- ce
- ee
tier:
- ultimate
skip_validation: true

View File

@ -0,0 +1,9 @@
# frozen_string_literal: true
class AddAdminModeToApplicationSetting < ActiveRecord::Migration[6.0]
DOWNTIME = false
def change
add_column :application_settings, :admin_mode, :boolean, default: false, null: false
end
end

View File

@ -0,0 +1 @@
968ba7808c969e29f1c3b6b635bff22f986b60e56cb001737ad8aba1825fd945

View File

@ -9432,39 +9432,39 @@ CREATE TABLE application_settings (
elasticsearch_indexed_file_size_limit_kb integer DEFAULT 1024 NOT NULL,
enforce_namespace_storage_limit boolean DEFAULT false NOT NULL,
container_registry_delete_tags_service_timeout integer DEFAULT 250 NOT NULL,
kroki_url character varying,
kroki_enabled boolean,
elasticsearch_client_request_timeout integer DEFAULT 0 NOT NULL,
gitpod_enabled boolean DEFAULT false NOT NULL,
gitpod_url text DEFAULT 'https://gitpod.io/'::text,
elasticsearch_client_request_timeout integer DEFAULT 0 NOT NULL,
abuse_notification_email character varying,
require_admin_approval_after_user_signup boolean DEFAULT true NOT NULL,
help_page_documentation_base_url text,
automatic_purchased_storage_allocation boolean DEFAULT false NOT NULL,
container_registry_expiration_policies_worker_capacity integer DEFAULT 0 NOT NULL,
encrypted_ci_jwt_signing_key text,
encrypted_ci_jwt_signing_key_iv text,
secret_detection_token_revocation_enabled boolean DEFAULT false NOT NULL,
secret_detection_token_revocation_url text,
encrypted_secret_detection_token_revocation_token text,
encrypted_secret_detection_token_revocation_token_iv text,
container_registry_expiration_policies_worker_capacity integer DEFAULT 0 NOT NULL,
elasticsearch_analyzers_smartcn_enabled boolean DEFAULT false NOT NULL,
elasticsearch_analyzers_smartcn_search boolean DEFAULT false NOT NULL,
elasticsearch_analyzers_kuromoji_enabled boolean DEFAULT false NOT NULL,
elasticsearch_analyzers_kuromoji_search boolean DEFAULT false NOT NULL,
new_user_signups_cap integer,
secret_detection_token_revocation_enabled boolean DEFAULT false NOT NULL,
secret_detection_token_revocation_url text,
encrypted_secret_detection_token_revocation_token text,
encrypted_secret_detection_token_revocation_token_iv text,
domain_denylist_enabled boolean DEFAULT false,
domain_denylist text,
domain_allowlist text,
new_user_signups_cap integer,
encrypted_cloud_license_auth_token text,
encrypted_cloud_license_auth_token_iv text,
secret_detection_revocation_token_types_url text,
cloud_license_enabled boolean DEFAULT false NOT NULL,
kroki_url text,
kroki_enabled boolean DEFAULT false NOT NULL,
disable_feed_token boolean DEFAULT false NOT NULL,
personal_access_token_prefix text,
rate_limiting_response_text text,
container_registry_cleanup_tags_service_max_list_size integer DEFAULT 200 NOT NULL,
invisible_captcha_enabled boolean DEFAULT false NOT NULL,
container_registry_cleanup_tags_service_max_list_size integer DEFAULT 200 NOT NULL,
enforce_ssh_key_expiration boolean DEFAULT false NOT NULL,
git_two_factor_session_expiry integer DEFAULT 15 NOT NULL,
keep_latest_artifact boolean DEFAULT true NOT NULL,
@ -9473,9 +9473,10 @@ CREATE TABLE application_settings (
kroki_formats jsonb DEFAULT '{}'::jsonb NOT NULL,
in_product_marketing_emails_enabled boolean DEFAULT true NOT NULL,
asset_proxy_whitelist text,
admin_mode boolean DEFAULT false NOT NULL,
CONSTRAINT app_settings_container_reg_cleanup_tags_max_list_size_positive CHECK ((container_registry_cleanup_tags_service_max_list_size >= 0)),
CONSTRAINT app_settings_registry_exp_policies_worker_capacity_positive CHECK ((container_registry_expiration_policies_worker_capacity >= 0)),
CONSTRAINT check_17d9558205 CHECK ((char_length(kroki_url) <= 1024)),
CONSTRAINT check_17d9558205 CHECK ((char_length((kroki_url)::text) <= 1024)),
CONSTRAINT check_2dba05b802 CHECK ((char_length(gitpod_url) <= 255)),
CONSTRAINT check_51700b31b5 CHECK ((char_length(default_branch_name) <= 255)),
CONSTRAINT check_57123c9593 CHECK ((char_length(help_page_documentation_base_url) <= 255)),
@ -14675,8 +14676,7 @@ CREATE TABLE namespaces (
shared_runners_enabled boolean DEFAULT true NOT NULL,
allow_descendants_override_disabled_shared_runners boolean DEFAULT false NOT NULL,
traversal_ids integer[] DEFAULT '{}'::integer[] NOT NULL,
delayed_project_removal boolean DEFAULT false NOT NULL,
resource_access_tokens_enabled boolean DEFAULT true NOT NULL
delayed_project_removal boolean DEFAULT false NOT NULL
);
CREATE SEQUENCE namespaces_id_seq

View File

@ -86,7 +86,8 @@ Example response:
"require_admin_approval_after_user_signup": false,
"personal_access_token_prefix": "GL-",
"rate_limiting_response_text": null,
"keep_latest_artifact": true
"keep_latest_artifact": true,
"admin_mode": false
}
```
@ -181,7 +182,8 @@ Example response:
"require_admin_approval_after_user_signup": false,
"personal_access_token_prefix": "GL-",
"rate_limiting_response_text": null,
"keep_latest_artifact": true
"keep_latest_artifact": true,
"admin_mode": false
}
```
@ -208,6 +210,7 @@ listed in the descriptions of the relevant settings.
| Attribute | Type | Required | Description |
|------------------------------------------|------------------|:------------------------------------:|-------------|
| `admin_mode` | boolean | no | Require admins to enable Admin Mode by re-authenticating for administrative tasks. |
| `admin_notification_email` | string | no | Deprecated: Use `abuse_notification_email` instead. If set, [abuse reports](../user/admin_area/abuse_reports.md) are sent to this address. Abuse reports are always available in the Admin Area. |
| `abuse_notification_email` | string | no | If set, [abuse reports](../user/admin_area/abuse_reports.md) are sent to this address. Abuse reports are always available in the Admin Area. |
| `after_sign_out_path` | string | no | Where to redirect users after logout. |

View File

@ -565,7 +565,7 @@ In some scenarios such as [this one](https://gitlab.com/gitlab-org/gitlab/-/issu
return unless user
# Sessions are enforced to be unavailable for API calls, so ignore them for admin mode
Gitlab::Auth::CurrentUserMode.bypass_session!(user.id) if Feature.enabled?(:user_mode_in_session)
Gitlab::Auth::CurrentUserMode.bypass_session!(user.id) if Gitlab::CurrentSettings.admin_mode
unless api_access_allowed?(user)
forbidden!(api_access_denied_message(user))
@ -581,7 +581,7 @@ In order to prevent this from happening, it is recommended to use the method `us
user = find_user_from_sources
return unless user
if user.is_a?(User) && Feature.enabled?(:user_mode_in_session)
if user.is_a?(User) && Gitlab::CurrentSettings.admin_mode
# Sessions are enforced to be unavailable for API calls, so ignore them for admin mode
Gitlab::Auth::CurrentUserMode.bypass_session!(user.id)
end

View File

@ -5940,7 +5940,7 @@ Tiers: `free`, `premium`, `ultimate`
Count of users who set personal preference to see Details on Group overview page
[YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/counts_all/20210216182203_user_preferences_group_overview_details.yml)
[YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/config/metrics/counts_all/20210216182203_user_preferences_group_overview_details.yml)
Group: `group::threat insights`
@ -5952,7 +5952,7 @@ Tiers: `ultimate`
Count of users who set personal preference to see Security Dashboard on Group overview page
[YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/counts_all/20210216182205_user_preferences_group_overview_security_dashboard.yml)
[YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/config/metrics/counts_all/20210216182205_user_preferences_group_overview_security_dashboard.yml)
Group: `group::threat insights`
@ -15408,7 +15408,7 @@ Tiers: `ultimate`
Users who set personal preference to see Details on Group overview page
[YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/counts_all/20210216182207_user_preferences_group_overview_security_dashboard.yml)
[YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/config/metrics/counts_all/20210216182207_user_preferences_group_overview_security_dashboard.yml)
Group: `group::threat insights`
@ -17412,7 +17412,7 @@ Tiers: `ultimate`
Users who set personal preference to see Security Dashboard on Group overview page
[YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/counts_28d/20210216182209_user_preferences_group_overview_security_dashboard.yml)
[YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/config/metrics/counts_28d/20210216182209_user_preferences_group_overview_security_dashboard.yml)
Group: `group::threat insights`

View File

@ -502,13 +502,14 @@ Implemented using Redis methods [PFADD](https://redis.io/commands/pfadd) and [PF
Use one of the following methods to track events:
1. Track event in controller using `RedisTracking` module with `track_redis_hll_event(*controller_actions, name:, if: nil)`.
1. Track event in controller using `RedisTracking` module with `track_redis_hll_event(*controller_actions, name:, if: nil, &block)`.
Arguments:
- `controller_actions`: controller actions we want to track.
- `name`: event name.
- `if`: optional custom conditions, using the same format as with Rails callbacks.
- `&block`: optional block that computes and returns the `custom_id` that we want to track. This will override the `visitor_id`.
Example usage:

View File

@ -23,9 +23,63 @@ You can restrict the password authentication for web interface and Git over HTTP
- **Web interface**: When this feature is disabled, an [external authentication provider](../../../administration/auth/README.md) must be used.
- **Git over HTTP(S)**: When this feature is disabled, a [Personal Access Token](../../profile/personal_access_tokens.md) must be used to authenticate.
## Admin Mode
When this feature is enabled, instance administrators are limited as regular users. During that period,
they do not have access to all projects, groups, or the **Admin Area** menu.
To access potentially dangerous resources, an administrator can activate Admin Mode by:
- Selecting the *Enable Admin Mode* button
- Trying to access any part of the UI that requires an administrator role, specifically those which call `/admin` endpoints.
The main use case allows administrators to perform their regular tasks as a regular
user, based on their memberships, without having to set up a second account for
security reasons.
When Admin Mode status is disabled, administrative users cannot access resources unless
they've been explicitly granted access. For example, when Admin Mode is disabled, they
get a `404` error if they try to open a private group or project, unless
they are members of that group or project.
2FA should be enabled for administrators and is supported for the Admin Mode flow, as are
OmniAuth providers and LDAP auth. The Admin Mode status is stored in the active user
session and remains active until it is explicitly disabled (it will be disabled
automatically after a timeout otherwise).
### Limitations
The following access methods are **not** protected by Admin Mode:
- Git client access (SSH using public keys or HTTPS using Personal Access Tokens).
- API access using a Personal Access Token.
In other words, administrators who are otherwise limited by Admin Mode can still use
Git clients, and access RESTful API endpoints as administrators, without additional
authentication steps.
We may address these limitations in the future. For more information see the following epic:
[Admin mode for GitLab Administrators](https://gitlab.com/groups/gitlab-org/-/epics/2158).
### Troubleshooting
If necessary, you can disable **Admin Mode** as an administrator by using one of these two methods:
- **API**:
```shell
curl --request PUT --header "PRIVATE-TOKEN:$ADMIN_TOKEN" "<gitlab-url>/api/v4/application/settings?admin_mode=false"
```
- [**Rails console**](../../../administration/operations/rails_console.md#starting-a-rails-console-session):
```ruby
::Gitlab::CurrentSettings.update_attributes!(admin_mode: false)
```
## Two-factor authentication
When this feature enabled, all users must use the [two-factor authentication](../../profile/account/two_factor_authentication.md).
When this feature is enabled, all users must use the [two-factor authentication](../../profile/account/two_factor_authentication.md).
After the two-factor authentication is configured as mandatory, users are allowed
to skip forced configuration of two-factor authentication for the configurable grace

View File

@ -517,6 +517,7 @@ removed, or promoted to regular features at any time.
Experimental features available are:
- Enable scanning of iOS and Android apps using the [MobSF analyzer](https://gitlab.com/gitlab-org/security-products/analyzers/mobsf/).
- Enable the [semgrep analyzer](https://gitlab.com/gitlab-org/security-products/analyzers/semgrep/).
#### Enable experimental features

View File

@ -119,7 +119,7 @@ Hover over an **Activity** entry and select a link go to that issue.
## Change status of vulnerabilities
> The option to select a status other than Dismissed was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/292636) in GitLab 13.10.
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/292636) in GitLab 13.10, all statuses became selectable.
To change the status of vulnerabilities in the table:

View File

@ -55,7 +55,7 @@ module API
user = find_user_from_sources
return unless user
if user.is_a?(User) && Feature.enabled?(:user_mode_in_session)
if user.is_a?(User) && Gitlab::CurrentSettings.admin_mode
# Sessions are enforced to be unavailable for API calls, so ignore them for admin mode
Gitlab::Auth::CurrentUserMode.bypass_session!(user.id)
end
@ -236,7 +236,7 @@ module API
def after
# Use a Grape middleware since the Grape `after` blocks might run
# before we are finished rendering the `Grape::Entity` classes
Gitlab::Auth::CurrentUserMode.reset_bypass_session! if Feature.enabled?(:user_mode_in_session)
Gitlab::Auth::CurrentUserMode.reset_bypass_session! if Gitlab::CurrentSettings.admin_mode
# Explicit nil is needed or the api call return value will be overwritten
nil

View File

@ -52,7 +52,7 @@ module API
actor.update_last_used_at!
check_result = begin
Gitlab::Auth::CurrentUserMode.bypass_session!(actor.user&.id) do
with_admin_mode_bypass!(actor.user&.id) do
access_check!(actor, params)
end
rescue Gitlab::GitAccess::ForbiddenError => e
@ -120,6 +120,14 @@ module API
def two_factor_otp_check
{ success: false, message: 'Feature is not available' }
end
def with_admin_mode_bypass!(actor_id)
return yield unless Gitlab::CurrentSettings.admin_mode
Gitlab::Auth::CurrentUserMode.bypass_session!(actor_id) do
yield
end
end
end
namespace 'internal' do

View File

@ -30,6 +30,7 @@ module API
success Entities::ApplicationSetting
end
params do
optional :admin_mode, type: Boolean, desc: 'Require admin users to re-authenticate for administrative (i.e. potentially dangerous) operations'
optional :admin_notification_email, type: String, desc: 'Deprecated: Use :abuse_notification_email instead. Abuse reports will be sent to this address if it is set. Abuse reports are always available in the admin area.'
optional :abuse_notification_email, type: String, desc: 'Abuse reports will be sent to this address if it is set. Abuse reports are always available in the admin area.'
optional :after_sign_up_text, type: String, desc: 'Text shown after sign up'

View File

@ -3,7 +3,7 @@
module Constraints
class AdminConstrainer
def matches?(request)
if Feature.enabled?(:user_mode_in_session)
if Gitlab::CurrentSettings.admin_mode
admin_mode_enabled?(request)
else
user_is_admin?(request)

View File

@ -3,7 +3,7 @@
module Gitlab
module Diff
class Highlight
attr_reader :diff_file, :diff_lines, :raw_lines, :repository, :project
attr_reader :diff_file, :diff_lines, :repository, :project
delegate :old_path, :new_path, :old_sha, :new_sha, to: :diff_file, prefix: :diff
@ -22,29 +22,15 @@ module Gitlab
end
def highlight
@diff_lines.map.with_index do |diff_line, i|
populate_marker_ranges if Feature.enabled?(:use_marker_ranges, project, default_enabled: :yaml)
@diff_lines.map.with_index do |diff_line, index|
diff_line = diff_line.dup
# ignore highlighting for "match" lines
next diff_line if diff_line.meta?
rich_line = highlight_line(diff_line) || ERB::Util.html_escape(diff_line.text)
if line_inline_diffs = inline_diffs[i]
begin
# MarkerRange objects are converted to Ranges to keep the previous behavior
# Issue: https://gitlab.com/gitlab-org/gitlab/-/issues/324068
if Feature.disabled?(:introduce_marker_ranges, project, default_enabled: :yaml)
line_inline_diffs = line_inline_diffs.map { |marker_range| marker_range.to_range }
end
rich_line = InlineDiffMarker.new(diff_line.text, rich_line).mark(line_inline_diffs)
# This should only happen when the encoding of the diff doesn't
# match the blob, which is a bug. But we shouldn't fail to render
# completely in that case, even though we want to report the error.
rescue RangeError => e
Gitlab::ErrorTracking.track_and_raise_for_dev_exception(e, issue_url: 'https://gitlab.com/gitlab-org/gitlab-foss/issues/45441')
end
end
rich_line = apply_syntax_highlight(diff_line)
rich_line = apply_marker_ranges_highlight(diff_line, rich_line, index)
diff_line.rich_text = rich_line
@ -54,6 +40,49 @@ module Gitlab
private
def populate_marker_ranges
pair_selector = Gitlab::Diff::PairSelector.new(@raw_lines)
pair_selector.each do |old_index, new_index|
old_line = diff_lines[old_index]
new_line = diff_lines[new_index]
old_diffs, new_diffs = Gitlab::Diff::InlineDiff.new(old_line.text, new_line.text, offset: 1).inline_diffs
old_line.set_marker_ranges(old_diffs)
new_line.set_marker_ranges(new_diffs)
end
end
def apply_syntax_highlight(diff_line)
highlight_line(diff_line) || ERB::Util.html_escape(diff_line.text)
end
def apply_marker_ranges_highlight(diff_line, rich_line, index)
marker_ranges = if Feature.enabled?(:use_marker_ranges, project, default_enabled: :yaml)
diff_line.marker_ranges
else
inline_diffs[index]
end
return rich_line if marker_ranges.blank?
begin
# MarkerRange objects are converted to Ranges to keep the previous behavior
# Issue: https://gitlab.com/gitlab-org/gitlab/-/issues/324068
if Feature.disabled?(:introduce_marker_ranges, project, default_enabled: :yaml)
marker_ranges = marker_ranges.map { |marker_range| marker_range.to_range }
end
InlineDiffMarker.new(diff_line.text, rich_line).mark(marker_ranges)
# This should only happen when the encoding of the diff doesn't
# match the blob, which is a bug. But we shouldn't fail to render
# completely in that case, even though we want to report the error.
rescue RangeError => e
Gitlab::ErrorTracking.track_and_raise_for_dev_exception(e, issue_url: 'https://gitlab.com/gitlab-org/gitlab-foss/issues/45441')
end
end
def highlight_line(diff_line)
return unless diff_file && diff_file.diff_refs
@ -72,6 +101,7 @@ module Gitlab
end
end
# Deprecated: https://gitlab.com/gitlab-org/gitlab/-/issues/324638
def inline_diffs
@inline_diffs ||= InlineDiff.for_lines(@raw_lines)
end

View File

@ -73,7 +73,8 @@ module Gitlab
'highlighted-diff-files',
diffable.cache_key, VERSION,
diff_options,
Feature.enabled?(:introduce_marker_ranges, diffable.project, default_enabled: :yaml)
Feature.enabled?(:introduce_marker_ranges, diffable.project, default_enabled: :yaml),
Feature.enabled?(:use_marker_ranges, diffable.project, default_enabled: :yaml)
].join(":")
end
end

View File

@ -18,6 +18,7 @@ module Gitlab
CharDiff.new(old_line, new_line).changed_ranges(offset: offset)
end
# Deprecated: https://gitlab.com/gitlab-org/gitlab/-/issues/324638
class << self
def for_lines(lines)
pair_selector = Gitlab::Diff::PairSelector.new(lines)

View File

@ -8,7 +8,7 @@ module Gitlab
#
SERIALIZE_KEYS = %i(line_code rich_text text type index old_pos new_pos).freeze
attr_reader :line_code
attr_reader :line_code, :marker_ranges
attr_writer :rich_text
attr_accessor :text, :index, :type, :old_pos, :new_pos
@ -21,6 +21,8 @@ module Gitlab
# When line code is not provided from cache store we build it
# using the parent_file(Diff::File or Conflict::File).
@line_code = line_code || calculate_line_code
@marker_ranges = []
end
def self.init_from_hash(hash)
@ -48,6 +50,10 @@ module Gitlab
hash
end
def set_marker_ranges(marker_ranges)
@marker_ranges = marker_ranges
end
def old_line
old_pos unless added? || meta?
end

View File

@ -8,7 +8,8 @@ module Gitlab
# If enabled then it injects a job field that persists through the job execution
class Client
def call(_worker_class, job, _queue, _redis_pool)
return yield unless ::Feature.enabled?(:user_mode_in_session)
# Not calling Gitlab::CurrentSettings.admin_mode on purpose on sidekiq middleware
# Only when admin mode application setting is enabled might the admin_mode_user_id be non-nil here
# Admin mode enabled in the original request or in a nested sidekiq job
admin_mode_user_id = find_admin_user_id

View File

@ -5,7 +5,8 @@ module Gitlab
module AdminMode
class Server
def call(_worker, job, _queue)
return yield unless Feature.enabled?(:user_mode_in_session)
# Not calling Gitlab::CurrentSettings.admin_mode on purpose on sidekiq middleware
# Only when admin_mode setting is enabled can it be true here
admin_mode_user_id = job['admin_mode_user_id']

View File

@ -2096,6 +2096,9 @@ msgstr ""
msgid "Admin Area"
msgstr ""
msgid "Admin Mode"
msgstr ""
msgid "Admin Note"
msgstr ""
@ -20403,6 +20406,12 @@ msgstr ""
msgid "NetworkPolicies|ports/protocols"
msgstr ""
msgid "NetworkPolicy|Policy"
msgstr ""
msgid "NetworkPolicy|Search by policy name"
msgstr ""
msgid "Never"
msgstr ""
@ -21574,6 +21583,9 @@ msgstr ""
msgid "Opens in a new window"
msgstr ""
msgid "Operation completed"
msgstr ""
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
@ -22945,7 +22957,7 @@ msgstr ""
msgid "Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Duplicate URLs are not allowed."
msgstr ""
msgid "Policy project doesn't exists"
msgid "Policy project doesn't exist"
msgstr ""
msgid "Popularity"
@ -25891,6 +25903,9 @@ msgstr ""
msgid "Requests to these domain(s)/address(es) on the local network will be allowed when local requests from hooks and services are not allowed. IP ranges such as 1:0:0:0:0:0:0:0/124 or 127.0.0.0/28 are supported. Domain wildcards are not supported currently. Use comma, semicolon, or newline to separate multiple entries. The allowlist can hold a maximum of 1000 entries. Domains should use IDNA encoding. Ex: example.com, 192.168.1.1, 127.0.0.0/28, xn--itlab-j1a.com."
msgstr ""
msgid "Require additional authentication for administrative tasks"
msgstr ""
msgid "Require admin approval for new sign-ups"
msgstr ""
@ -29210,9 +29225,6 @@ msgstr ""
msgid "Successful purchase image"
msgstr ""
msgid "Successfull"
msgstr ""
msgid "Successfully activated"
msgstr ""

View File

@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe Admin::ApplicationSettingsController do
RSpec.describe Admin::ApplicationSettingsController, :do_not_mock_admin_mode_setting do
include StubENV
include UsageDataHelpers
@ -164,6 +164,13 @@ RSpec.describe Admin::ApplicationSettingsController do
expect(ApplicationSetting.current.default_branch_name).to eq("example_branch_name")
end
it "updates admin_mode setting" do
put :update, params: { application_setting: { admin_mode: true } }
expect(response).to redirect_to(general_admin_application_settings_path)
expect(ApplicationSetting.current.admin_mode).to be(true)
end
context "personal access token prefix settings" do
let(:application_settings) { ApplicationSetting.current }

View File

@ -19,7 +19,7 @@ RSpec.describe EnforcesAdminAuthentication do
end
end
context 'feature flag :user_mode_in_session is enabled' do
context 'application setting :admin_mode is enabled' do
describe 'authenticate_admin!' do
context 'as an admin' do
let(:user) { create(:admin) }
@ -61,9 +61,9 @@ RSpec.describe EnforcesAdminAuthentication do
end
end
context 'feature flag :user_mode_in_session is disabled' do
context 'application setting :admin_mode is disabled' do
before do
stub_feature_flags(user_mode_in_session: false)
stub_application_setting(admin_mode: false)
end
describe 'authenticate_admin!' do

View File

@ -9,8 +9,8 @@ RSpec.describe RedisTracking do
include RedisTracking
skip_before_action :authenticate_user!, only: :show
track_redis_hll_event :index, :show, name: 'g_compliance_approval_rules',
if: [:custom_condition_one?, :custom_condition_two?]
track_redis_hll_event(:index, :show, name: 'g_compliance_approval_rules',
if: [:custom_condition_one?, :custom_condition_two?]) { |controller| controller.get_custom_id }
def index
render html: 'index'
@ -24,6 +24,10 @@ RSpec.describe RedisTracking do
render html: 'show'
end
def get_custom_id
'some_custom_id'
end
private
def custom_condition_one?
@ -92,19 +96,15 @@ RSpec.describe RedisTracking do
end
end
context 'when user is not logged in and there is a visitor_id' do
context 'when user is not logged in' do
let(:visitor_id) { SecureRandom.uuid }
before do
routes.draw { get 'show' => 'anonymous#show' }
end
it 'tracks the event' do
it 'tracks the event when there is a visitor id' do
cookies[:visitor_id] = { value: visitor_id, expires: 24.months }
expect_tracking
get :show
get :show, params: { id: 1 }
end
end
@ -114,5 +114,19 @@ RSpec.describe RedisTracking do
get :index
end
it 'tracks the event when there is custom id' do
expect_tracking
get :show, params: { id: 1 }
end
it 'does not track the event when there is no custom id' do
expect(controller).to receive(:get_custom_id).and_return(nil)
expect_no_tracking
get :show, params: { id: 2 }
end
end
end

View File

@ -1446,9 +1446,7 @@ RSpec.describe Projects::IssuesController do
expect_next_instance_of(Spam::AkismetService) do |akismet_service|
expect(akismet_service).to receive_messages(submit_spam: true)
end
expect_next_instance_of(ApplicationSetting) do |setting|
expect(setting).to receive_messages(akismet_enabled: true)
end
stub_application_setting(akismet_enabled: true)
end
def post_spam

View File

@ -14,7 +14,7 @@ RSpec.describe 'Admin mode' do
stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false')
end
context 'feature flag :user_mode_in_session is enabled', :request_store do
context 'application setting :admin_mode is enabled', :request_store do
before do
sign_in(admin)
end
@ -157,9 +157,9 @@ RSpec.describe 'Admin mode' do
end
end
context 'feature flag :user_mode_in_session is disabled' do
context 'application setting :admin_mode is disabled' do
before do
stub_feature_flags(user_mode_in_session: false)
stub_application_setting(admin_mode: false)
sign_in(admin)
end

View File

@ -9,7 +9,7 @@ RSpec.describe 'Admin updates settings' do
let(:admin) { create(:admin) }
context 'feature flag :user_mode_in_session is enabled', :request_store do
context 'application setting :admin_mode is enabled', :request_store do
before do
stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false')
sign_in(admin)
@ -615,9 +615,9 @@ RSpec.describe 'Admin updates settings' do
end
end
context 'feature flag :user_mode_in_session is disabled' do
context 'application setting :admin_mode is disabled' do
before do
stub_feature_flags(user_mode_in_session: false)
stub_application_setting(admin_mode: false)
stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false')

View File

@ -7,9 +7,7 @@ RSpec.describe 'IDE Clientside Preview CSP' do
shared_context 'disable feature' do
before do
allow_next_instance_of(ApplicationSetting) do |instance|
allow(instance).to receive(:web_ide_clientside_preview_enabled?).and_return(false)
end
stub_application_setting(web_ide_clientside_preview_enabled: false)
end
end
@ -24,10 +22,8 @@ RSpec.describe 'IDE Clientside Preview CSP' do
end
before do
allow_next_instance_of(ApplicationSetting) do |instance|
allow(instance).to receive(:web_ide_clientside_preview_enabled?).and_return(true)
allow(instance).to receive(:web_ide_clientside_preview_bundler_url).and_return(whitelisted_url)
end
stub_application_setting(web_ide_clientside_preview_enabled: true)
stub_application_setting(web_ide_clientside_preview_bundler_url: whitelisted_url)
sign_in(user)
end

View File

@ -1,42 +1,43 @@
import Vue from 'vue';
import mountComponent from 'helpers/vue_mount_component_helper';
import { shallowMount } from '@vue/test-utils';
import MrWidgetAuthor from '~/vue_merge_request_widget/components/mr_widget_author.vue';
import MrWidgetAuthorTime from '~/vue_merge_request_widget/components/mr_widget_author_time.vue';
describe('MrWidgetAuthorTime', () => {
let vm;
let wrapper;
const defaultProps = {
actionText: 'Merged by',
author: {
name: 'Administrator',
username: 'root',
webUrl: 'http://localhost:3000/root',
avatarUrl: 'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
},
dateTitle: '2017-03-23T23:02:00.807Z',
dateReadable: '12 hours ago',
};
beforeEach(() => {
const Component = Vue.extend(MrWidgetAuthorTime);
vm = mountComponent(Component, {
actionText: 'Merged by',
author: {
name: 'Administrator',
username: 'root',
webUrl: 'http://localhost:3000/root',
avatarUrl:
'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
},
dateTitle: '2017-03-23T23:02:00.807Z',
dateReadable: '12 hours ago',
wrapper = shallowMount(MrWidgetAuthorTime, {
propsData: defaultProps,
});
});
afterEach(() => {
vm.$destroy();
wrapper.destroy();
});
it('renders provided action text', () => {
expect(vm.$el.textContent).toContain('Merged by');
expect(wrapper.text()).toContain('Merged by');
});
it('renders author', () => {
expect(vm.$el.textContent).toContain('Administrator');
expect(wrapper.find(MrWidgetAuthor).props('author')).toStrictEqual(defaultProps.author);
});
it('renders provided time', () => {
expect(vm.$el.querySelector('time').getAttribute('title')).toEqual('2017-03-23T23:02:00.807Z');
expect(wrapper.find('time').attributes('title')).toBe('2017-03-23T23:02:00.807Z');
expect(vm.$el.querySelector('time').textContent.trim()).toEqual('12 hours ago');
expect(wrapper.find('time').text().trim()).toBe('12 hours ago');
});
});

View File

@ -44,7 +44,7 @@ RSpec.describe GitlabSchema.types['UsageTrendsMeasurement'] do
let(:user) { create(:user, :admin) }
before do
stub_feature_flags(user_mode_in_session: false)
stub_application_setting(admin_mode: false)
end
it 'returns data' do

View File

@ -316,9 +316,7 @@ RSpec.describe ApplicationHelper do
let(:user) { create(:user, static_object_token: 'hunter1') }
before do
allow_next_instance_of(ApplicationSetting) do |instance|
allow(instance).to receive(:static_objects_external_storage_url).and_return('https://cdn.gitlab.com')
end
stub_application_setting(static_objects_external_storage_url: 'https://cdn.gitlab.com')
allow(helper).to receive(:current_user).and_return(user)
end

View File

@ -35,7 +35,7 @@ RSpec.describe NavHelper do
context 'as admin' do
let(:user) { create(:user, :admin) }
context 'feature flag :user_mode_in_session is enabled' do
context 'application setting :admin_mode is enabled' do
it 'does not contain the admin mode link by default' do
expect(helper.header_links).not_to include(:admin_mode)
end
@ -52,9 +52,9 @@ RSpec.describe NavHelper do
end
end
context 'feature flag :user_mode_in_session is disabled' do
context 'application setting :admin_mode is disabled' do
before do
stub_feature_flags(user_mode_in_session: false)
stub_application_setting(admin_mode: false)
end
it 'does not contain the admin mode link' do

View File

@ -16,7 +16,7 @@ RSpec.describe Constraints::AdminConstrainer do
end
describe '#matches' do
context 'feature flag :user_mode_in_session is enabled' do
context 'application setting :admin_mode is enabled' do
context 'when user is a regular user' do
it 'forbids access' do
expect(subject.matches?(request)).to be(false)
@ -46,9 +46,9 @@ RSpec.describe Constraints::AdminConstrainer do
end
end
context 'feature flag :user_mode_in_session is disabled' do
context 'application setting :admin_mode is disabled' do
before do
stub_feature_flags(user_mode_in_session: false)
stub_application_setting(admin_mode: false)
end
context 'when user is a regular user' do

View File

@ -38,7 +38,7 @@ RSpec.describe Gitlab::DatabaseImporters::InstanceAdministrators::CreateGroup do
end
end
context 'with application settings and admin users' do
context 'with application settings and admin users', :do_not_mock_admin_mode_setting do
let(:group) { result[:group] }
let(:application_setting) { Gitlab::CurrentSettings.current_application_settings }

View File

@ -238,7 +238,7 @@ RSpec.describe Gitlab::Diff::HighlightCache, :clean_gitlab_redis_cache do
subject { cache.key }
it 'returns cache key' do
is_expected.to eq("highlighted-diff-files:#{cache.diffable.cache_key}:2:#{cache.diff_options}:true")
is_expected.to eq("highlighted-diff-files:#{cache.diffable.cache_key}:2:#{cache.diff_options}:true:true")
end
context 'when feature flag is disabled' do
@ -247,7 +247,17 @@ RSpec.describe Gitlab::Diff::HighlightCache, :clean_gitlab_redis_cache do
end
it 'returns the original version of the cache' do
is_expected.to eq("highlighted-diff-files:#{cache.diffable.cache_key}:2:#{cache.diff_options}:false")
is_expected.to eq("highlighted-diff-files:#{cache.diffable.cache_key}:2:#{cache.diff_options}:false:true")
end
end
context 'when use marker ranges feature flag is disabled' do
before do
stub_feature_flags(use_marker_ranges: false)
end
it 'returns the original version of the cache' do
is_expected.to eq("highlighted-diff-files:#{cache.diffable.cache_key}:2:#{cache.diff_options}:true:false")
end
end
end

View File

@ -65,6 +65,14 @@ RSpec.describe Gitlab::Diff::Highlight do
expect(subject[5].rich_text).to eq(code)
end
context 'when use_marker_ranges feature flag is false too' do
it 'does not affect the result' do
code = %Q{+<span id="LC9" class="line" lang="ruby"> <span class="k">raise</span> <span class="no"><span class="idiff left">RuntimeError</span></span><span class="p"><span class="idiff">,</span></span><span class="idiff right"> </span><span class="s2">"System commands must be given as an array of strings"</span></span>\n}
expect(subject[5].rich_text).to eq(code)
end
end
end
context 'when no diff_refs' do
@ -132,6 +140,18 @@ RSpec.describe Gitlab::Diff::Highlight do
end
end
context 'when `use_marker_ranges` feature flag is disabled' do
it 'returns the same result' do
with_feature_flag = described_class.new(diff_file, repository: project.repository).highlight
stub_feature_flags(use_marker_ranges: false)
without_feature_flag = described_class.new(diff_file, repository: project.repository).highlight
expect(with_feature_flag.map(&:rich_text)).to eq(without_feature_flag.map(&:rich_text))
end
end
context 'when no inline diffs' do
it_behaves_like 'without inline diffs'
end

View File

@ -3,68 +3,30 @@
require 'spec_helper'
RSpec.describe Gitlab::Diff::InlineDiff do
describe '.for_lines' do
let(:diff) do
<<-EOF.strip_heredoc
class Test
- def initialize(test = true)
+ def initialize(test = false)
@test = test
- if true
- @foo = "bar"
+ unless false
+ @foo = "baz"
end
end
end
EOF
end
describe '#inline_diffs' do
subject { described_class.new(old_line, new_line, offset: offset).inline_diffs }
let(:subject) { described_class.for_lines(diff.lines) }
let(:old_line) { 'XXX def initialize(test = true)' }
let(:new_line) { 'YYY def initialize(test = false)' }
let(:offset) { 3 }
it 'finds all inline diffs' do
expect(subject[0]).to be_nil
expect(subject[1]).to eq([25..27])
expect(subject[2]).to eq([25..28])
expect(subject[3]).to be_nil
expect(subject[4]).to eq([5..10])
expect(subject[5]).to eq([17..17])
expect(subject[6]).to eq([5..15])
expect(subject[7]).to eq([17..17])
expect(subject[8]).to be_nil
end
it 'can handle unchanged empty lines' do
expect { described_class.for_lines(['- bar', '+ baz', '']) }.not_to raise_error
it 'finds the inline diff', :aggregate_failures do
expect(subject[0]).to eq([Gitlab::MarkerRange.new(26, 28, mode: :deletion)])
expect(subject[1]).to eq([Gitlab::MarkerRange.new(26, 29, mode: :addition)])
end
context 'when lines have multiple changes' do
let(:diff) do
<<~EOF
- Hello, how are you?
+ Hi, how are you doing?
EOF
let(:old_line) { '- Hello, how are you?' }
let(:new_line) { '+ Hi, how are you doing?' }
let(:offset) { 1 }
it 'finds all inline diffs', :aggregate_failures do
expect(subject[0]).to eq([Gitlab::MarkerRange.new(3, 6, mode: :deletion)])
expect(subject[1]).to eq([
Gitlab::MarkerRange.new(3, 3, mode: :addition),
Gitlab::MarkerRange.new(17, 22, mode: :addition)
])
end
let(:subject) { described_class.for_lines(diff.lines) }
it 'finds all inline diffs' do
expect(subject[0]).to eq([3..6])
expect(subject[1]).to eq([3..3, 17..22])
end
end
end
describe "#inline_diffs" do
let(:old_line) { "XXX def initialize(test = true)" }
let(:new_line) { "YYY def initialize(test = false)" }
let(:subject) { described_class.new(old_line, new_line, offset: 3).inline_diffs }
it "finds the inline diff" do
old_diffs, new_diffs = subject
expect(old_diffs).to eq([26..28])
expect(new_diffs).to eq([26..29])
end
end
end

View File

@ -17,6 +17,8 @@ RSpec.describe Gitlab::Diff::Line do
rich_text: rich_text)
end
let(:rich_text) { nil }
describe '.init_from_hash' do
let(:rich_text) { '&lt;input&gt;' }
@ -51,4 +53,14 @@ RSpec.describe Gitlab::Diff::Line do
expect(line[:rich_text]).to eq("&lt;input&gt;")
end
end
describe '#set_marker_ranges' do
let(:marker_ranges) { [Gitlab::MarkerRange.new(1, 10, mode: :deletion)] }
it 'stores MarkerRanges in Diff::Line object' do
line.set_marker_ranges(marker_ranges)
expect(line.marker_ranges).to eq(marker_ranges)
end
end
end

View File

@ -74,9 +74,9 @@ RSpec.describe Gitlab::SidekiqMiddleware::AdminMode::Client, :request_store do
end
end
context 'admin mode feature disabled' do
context 'admin mode setting disabled' do
before do
stub_feature_flags(user_mode_in_session: false)
stub_application_setting(admin_mode: false)
end
it 'yields block' do

View File

@ -52,9 +52,9 @@ RSpec.describe Gitlab::SidekiqMiddleware::AdminMode::Server, :request_store do
end
end
context 'admin mode feature disabled' do
context 'admin mode setting disabled' do
before do
stub_feature_flags(user_mode_in_session: false)
stub_application_setting(admin_mode: false)
end
it 'yields block' do

View File

@ -205,7 +205,7 @@ RSpec.describe CacheableAttributes do
end
end
it 'uses RequestStore in addition to process memory cache', :request_store do
it 'uses RequestStore in addition to process memory cache', :request_store, :do_not_mock_admin_mode_setting do
# Warm up the cache
create(:application_setting).cache!

View File

@ -347,7 +347,7 @@ RSpec.describe Clusters::ClusterPresenter do
before do
project.add_maintainer(user)
stub_feature_flags(user_mode_in_session: false)
stub_application_setting(admin_mode: false)
end
context 'user can read logs' do
@ -363,7 +363,7 @@ RSpec.describe Clusters::ClusterPresenter do
before do
project.add_developer(user)
stub_feature_flags(user_mode_in_session: false)
stub_application_setting(admin_mode: false)
end
it 'returns nil' do

View File

@ -1115,7 +1115,7 @@ RSpec.describe API::Internal::Base do
end
end
context 'feature flag :user_mode_in_session is enabled' do
context 'application setting :admin_mode is enabled' do
context 'with an admin user' do
let(:user) { create(:admin) }
@ -1147,9 +1147,9 @@ RSpec.describe API::Internal::Base do
end
end
context 'feature flag :user_mode_in_session is disabled' do
context 'application setting :admin_mode is disabled' do
before do
stub_feature_flags(user_mode_in_session: false)
stub_application_setting(admin_mode: false)
end
context 'with an admin user' do

View File

@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe API::Settings, 'Settings' do
RSpec.describe API::Settings, 'Settings', :do_not_mock_admin_mode_setting do
let(:user) { create(:user) }
let_it_be(:admin) { create(:admin) }
@ -44,6 +44,7 @@ RSpec.describe API::Settings, 'Settings' do
expect(json_response['wiki_page_max_content_bytes']).to be_a(Integer)
expect(json_response['require_admin_approval_after_user_signup']).to eq(true)
expect(json_response['personal_access_token_prefix']).to be_nil
expect(json_response['admin_mode']).to be(false)
end
end
@ -124,7 +125,8 @@ RSpec.describe API::Settings, 'Settings' do
disabled_oauth_sign_in_sources: 'unknown',
import_sources: 'github,bitbucket',
wiki_page_max_content_bytes: 12345,
personal_access_token_prefix: "GL-"
personal_access_token_prefix: "GL-",
admin_mode: true
}
expect(response).to have_gitlab_http_status(:ok)
@ -169,6 +171,7 @@ RSpec.describe API::Settings, 'Settings' do
expect(json_response['import_sources']).to match_array(%w(github bitbucket))
expect(json_response['wiki_page_max_content_bytes']).to eq(12345)
expect(json_response['personal_access_token_prefix']).to eq("GL-")
expect(json_response['admin_mode']).to be(true)
end
end

View File

@ -180,10 +180,11 @@ RSpec.describe JwtController do
end
context 'when internal auth is disabled' do
before do
stub_application_setting(password_authentication_enabled_for_git: false)
end
it 'rejects the authorization attempt with personal access token message' do
allow_next_instance_of(ApplicationSetting) do |instance|
allow(instance).to receive(:password_authentication_enabled_for_git?) { false }
end
get '/jwt/auth', params: parameters, headers: headers
expect(response).to have_gitlab_http_status(:unauthorized)

View File

@ -297,7 +297,7 @@ RSpec.configure do |config|
Sidekiq::Worker.clear_all
# Administrators have to re-authenticate in order to access administrative
# functionality when feature flag :user_mode_in_session is active. Any spec
# functionality when application setting admin_mode is active. Any spec
# that requires administrative access can use the tag :enable_admin_mode
# to avoid the second auth step (provided the user is already an admin):
#
@ -314,6 +314,9 @@ RSpec.configure do |config|
end
end
# Make sure specs test by default admin mode setting on, unless forced to the opposite
stub_application_setting(admin_mode: true) unless example.metadata[:do_not_mock_admin_mode_setting]
allow(Gitlab::CurrentSettings).to receive(:current_application_settings?).and_return(false)
end

0
vendor/gitignore/C++.gitignore vendored Normal file → Executable file
View File

0
vendor/gitignore/Java.gitignore vendored Normal file → Executable file
View File