Commit 984061fa authored by GitLab Bot's avatar GitLab Bot

Automatic merge of gitlab-org/gitlab master

parents 4be2b998 e430a1ed
...@@ -31,7 +31,7 @@ import initFrequentItemDropdowns from './frequent_items'; ...@@ -31,7 +31,7 @@ import initFrequentItemDropdowns from './frequent_items';
import initBreadcrumbs from './breadcrumb'; import initBreadcrumbs from './breadcrumb';
import initPersistentUserCallouts from './persistent_user_callouts'; import initPersistentUserCallouts from './persistent_user_callouts';
import { initUserTracking, initDefaultTrackers } from './tracking'; import { initUserTracking, initDefaultTrackers } from './tracking';
import initUsagePingConsent from './usage_ping_consent'; import initServicePingConsent from './service_ping_consent';
import GlFieldErrors from './gl_field_errors'; import GlFieldErrors from './gl_field_errors';
import initUserPopovers from './user_popovers'; import initUserPopovers from './user_popovers';
import initBroadcastNotifications from './broadcast_notification'; import initBroadcastNotifications from './broadcast_notification';
...@@ -86,7 +86,7 @@ function deferredInitialisation() { ...@@ -86,7 +86,7 @@ function deferredInitialisation() {
initBreadcrumbs(); initBreadcrumbs();
initTodoToggle(); initTodoToggle();
initLogoAnimation(); initLogoAnimation();
initUsagePingConsent(); initServicePingConsent();
initUserPopovers(); initUserPopovers();
initBroadcastNotifications(); initBroadcastNotifications();
initFrequentItemDropdowns(); initFrequentItemDropdowns();
......
...@@ -5,19 +5,20 @@ import { parseBoolean } from './lib/utils/common_utils'; ...@@ -5,19 +5,20 @@ import { parseBoolean } from './lib/utils/common_utils';
import { __ } from './locale'; import { __ } from './locale';
export default () => { export default () => {
$('body').on('click', '.js-usage-consent-action', (e) => { $('body').on('click', '.js-service-ping-consent-action', (e) => {
e.preventDefault(); e.preventDefault();
e.stopImmediatePropagation(); // overwrite rails listener e.stopImmediatePropagation(); // overwrite rails listener
const { url, checkEnabled, pingEnabled } = e.target.dataset; const { url, checkEnabled, servicePingEnabled } = e.target.dataset;
const data = { const data = {
application_setting: { application_setting: {
version_check_enabled: parseBoolean(checkEnabled), version_check_enabled: parseBoolean(checkEnabled),
usage_ping_enabled: parseBoolean(pingEnabled), service_ping_enabled: parseBoolean(servicePingEnabled),
}, },
}; };
const hideConsentMessage = () => hideFlash(document.querySelector('.ping-consent-message')); const hideConsentMessage = () =>
hideFlash(document.querySelector('.service-ping-consent-message'));
axios axios
.put(url, data) .put(url, data)
......
.usage-data { .service-data-payload-container {
max-height: 400px; max-height: 400px;
} }
...@@ -151,14 +151,14 @@ module AuthenticatesWithTwoFactor ...@@ -151,14 +151,14 @@ module AuthenticatesWithTwoFactor
def handle_two_factor_failure(user, method, message) def handle_two_factor_failure(user, method, message)
user.increment_failed_attempts! user.increment_failed_attempts!
log_failed_two_factor(user, method, request.remote_ip) log_failed_two_factor(user, method)
Gitlab::AppLogger.info("Failed Login: user=#{user.username} ip=#{request.remote_ip} method=#{method}") Gitlab::AppLogger.info("Failed Login: user=#{user.username} ip=#{request.remote_ip} method=#{method}")
flash.now[:alert] = message flash.now[:alert] = message
prompt_for_two_factor(user) prompt_for_two_factor(user)
end end
def log_failed_two_factor(user, method, ip_address) def log_failed_two_factor(user, method)
# overridden in EE # overridden in EE
end end
......
...@@ -98,7 +98,7 @@ module AuthenticatesWithTwoFactorForAdminMode ...@@ -98,7 +98,7 @@ module AuthenticatesWithTwoFactorForAdminMode
def admin_handle_two_factor_failure(user, method, message) def admin_handle_two_factor_failure(user, method, message)
user.increment_failed_attempts! user.increment_failed_attempts!
log_failed_two_factor(user, method, request.remote_ip) log_failed_two_factor(user, method)
Gitlab::AppLogger.info("Failed Admin Mode Login: user=#{user.username} ip=#{request.remote_ip} method=#{method}") Gitlab::AppLogger.info("Failed Admin Mode Login: user=#{user.username} ip=#{request.remote_ip} method=#{method}")
flash.now[:alert] = message flash.now[:alert] = message
......
...@@ -15,7 +15,7 @@ class Projects::ArtifactsController < Projects::ApplicationController ...@@ -15,7 +15,7 @@ class Projects::ArtifactsController < Projects::ApplicationController
MAX_PER_PAGE = 20 MAX_PER_PAGE = 20
feature_category :continuous_integration feature_category :build_artifacts
def index def index
# Loading artifacts is very expensive in projects with a lot of artifacts. # Loading artifacts is very expensive in projects with a lot of artifacts.
......
...@@ -8,7 +8,7 @@ class Projects::BuildArtifactsController < Projects::ApplicationController ...@@ -8,7 +8,7 @@ class Projects::BuildArtifactsController < Projects::ApplicationController
before_action :extract_ref_name_and_path before_action :extract_ref_name_and_path
before_action :validate_artifacts!, except: [:download] before_action :validate_artifacts!, except: [:download]
feature_category :continuous_integration feature_category :build_artifacts
def download def download
redirect_to download_project_job_artifacts_path(project, job, params: request.query_parameters) redirect_to download_project_job_artifacts_path(project, job, params: request.query_parameters)
......
...@@ -16,7 +16,7 @@ class AuditEventService ...@@ -16,7 +16,7 @@ class AuditEventService
@author = build_author(author) @author = build_author(author)
@entity = entity @entity = entity
@details = details @details = details
@ip_address = resolve_ip_address(@details, @author) @ip_address = resolve_ip_address(@author)
end end
# Builds the @details attribute for authentication # Builds the @details attribute for authentication
...@@ -64,8 +64,7 @@ class AuditEventService ...@@ -64,8 +64,7 @@ class AuditEventService
end end
end end
def resolve_ip_address(details, author) def resolve_ip_address(author)
details[:ip_address].presence ||
Gitlab::RequestContext.instance.client_ip || Gitlab::RequestContext.instance.client_ip ||
author.current_sign_in_ip author.current_sign_in_ip
end end
......
- payload_class = 'js-usage-ping-payload' - payload_class = 'js-service-ping-payload'
= form_for @application_setting, url: metrics_and_profiling_admin_application_settings_path(anchor: 'js-usage-settings'), html: { class: 'fieldset-form' } do |f| = form_for @application_setting, url: metrics_and_profiling_admin_application_settings_path(anchor: 'js-usage-settings'), html: { class: 'fieldset-form' } do |f|
= form_errors(@application_setting) = form_errors(@application_setting)
...@@ -17,23 +17,23 @@ ...@@ -17,23 +17,23 @@
.form-check .form-check
= f.check_box :usage_ping_enabled, disabled: !can_be_configured, class: 'form-check-input' = f.check_box :usage_ping_enabled, disabled: !can_be_configured, class: 'form-check-input'
= f.label :usage_ping_enabled, class: 'form-check-label' do = f.label :usage_ping_enabled, class: 'form-check-label' do
= _('Enable usage ping') = _('Enable service ping')
.form-text.text-muted .form-text.text-muted
- if can_be_configured - if can_be_configured
%p.mb-2= _('To help improve GitLab and its user experience, GitLab will periodically collect usage information.') %p.mb-2= _('To help improve GitLab and its user experience, GitLab will periodically collect usage information.')
- usage_ping_path = help_page_path('user/admin_area/settings/usage_statistics', anchor: 'usage-ping') - service_ping_path = help_page_path('user/admin_area/settings/usage_statistics', anchor: 'usage-ping')
- usage_ping_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: usage_ping_path } - service_ping_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: service_ping_path }
%p.mb-2= s_('%{usage_ping_link_start}Learn more%{usage_ping_link_end} about what information is shared with GitLab Inc.').html_safe % { usage_ping_link_start: usage_ping_link_start, usage_ping_link_end: '</a>'.html_safe } %p.mb-2= s_('%{service_ping_link_start}Learn more%{service_ping_link_end} about what information is shared with GitLab Inc.').html_safe % { service_ping_link_start: service_ping_link_start, service_ping_link_end: '</a>'.html_safe }
%button.gl-button.btn.btn-default.js-payload-preview-trigger{ type: 'button', data: { payload_selector: ".#{payload_class}" } } %button.gl-button.btn.btn-default.js-payload-preview-trigger{ type: 'button', data: { payload_selector: ".#{payload_class}" } }
.gl-spinner.js-spinner.gl-display-none.gl-mr-2 .gl-spinner.js-spinner.gl-display-none.gl-mr-2
.js-text.d-inline= _('Preview payload') .js-text.d-inline= _('Preview payload')
%pre.usage-data.js-syntax-highlight.code.highlight.mt-2.d-none{ class: payload_class, data: { endpoint: usage_data_admin_application_settings_path(format: :html) } } %pre.service-data-payload-container.js-syntax-highlight.code.highlight.mt-2.d-none{ class: payload_class, data: { endpoint: usage_data_admin_application_settings_path(format: :html) } }
- else - else
= _('The usage ping is disabled, and cannot be configured through this form.') = _('Service ping is disabled, and cannot be configured through this form.')
- deactivating_usage_ping_path = help_page_path('development/usage_ping/index.md', anchor: 'disable-usage-ping') - deactivating_service_ping_path = help_page_path('development/usage_ping/index.md', anchor: 'disable-usage-ping')
- deactivating_usage_ping_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: deactivating_usage_ping_path } - deactivating_service_ping_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: deactivating_service_ping_path }
= s_('For more information, see the documentation on %{deactivating_usage_ping_link_start}deactivating the usage ping%{deactivating_usage_ping_link_end}.').html_safe % { deactivating_usage_ping_link_start: deactivating_usage_ping_link_start, deactivating_usage_ping_link_end: '</a>'.html_safe } = s_('For more information, see the documentation on %{deactivating_service_ping_link_start}deactivating service ping%{deactivating_service_ping_link_end}.').html_safe % { deactivating_service_ping_link_start: deactivating_service_ping_link_start, deactivating_service_ping_link_end: '</a>'.html_safe }
= f.submit _('Save changes'), class: "gl-button btn btn-confirm" = f.submit _('Save changes'), class: "gl-button btn btn-confirm"
...@@ -47,7 +47,7 @@ ...@@ -47,7 +47,7 @@
%button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand') = expanded_by_default? ? _('Collapse') : _('Expand')
%p %p
= _('Enable or disable version check and usage ping.') = _('Enable or disable version check and service ping.')
.settings-content .settings-content
= render 'usage' = render 'usage'
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
= render "layouts/header/service_templates_deprecation_callout" = render "layouts/header/service_templates_deprecation_callout"
= render "layouts/nav/classification_level_banner" = render "layouts/nav/classification_level_banner"
= yield :flash_message = yield :flash_message
= render "shared/ping_consent" = render "shared/service_ping_consent"
= render_account_recovery_regular_check = render_account_recovery_regular_check
= render_if_exists "layouts/header/ee_subscribable_banner" = render_if_exists "layouts/header/ee_subscribable_banner"
= render_if_exists "shared/namespace_storage_limit_alert" = render_if_exists "shared/namespace_storage_limit_alert"
......
- if session[:ask_for_usage_stats_consent] - if session[:ask_for_usage_stats_consent]
.ping-consent-message.gl-alert.gl-alert-info .service-ping-consent-message.gl-alert.gl-alert-info
= sprite_icon('information-o', css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title') = sprite_icon('information-o', css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
%button.js-close.gl-alert-dismiss{ type: 'button', 'aria-label' => _('Dismiss') } %button.js-close.gl-alert-dismiss{ type: 'button', 'aria-label' => _('Dismiss') }
= sprite_icon('close', css_class: 'gl-icon') = sprite_icon('close', css_class: 'gl-icon')
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
- settings_link = link_to _('your settings'), metrics_and_profiling_admin_application_settings_path(anchor: 'js-usage-settings'), class: 'gl-link' - settings_link = link_to _('your settings'), metrics_and_profiling_admin_application_settings_path(anchor: 'js-usage-settings'), class: 'gl-link'
= s_('To help improve GitLab, we would like to periodically %{docs_link}. This can be changed at any time in %{settings_link}.').html_safe % { docs_link: docs_link, settings_link: settings_link } = s_('To help improve GitLab, we would like to periodically %{docs_link}. This can be changed at any time in %{settings_link}.').html_safe % { docs_link: docs_link, settings_link: settings_link }
.gl-alert-actions.gl-mt-3 .gl-alert-actions.gl-mt-3
- send_usage_data_path = admin_application_settings_path(application_setting: { version_check_enabled: 1, usage_ping_enabled: 1 }) - send_service_data_path = admin_application_settings_path(application_setting: { version_check_enabled: 1, usage_ping_enabled: 1 })
- not_now_path = admin_application_settings_path(application_setting: { version_check_enabled: 0, usage_ping_enabled: 0 }) - not_now_path = admin_application_settings_path(application_setting: { version_check_enabled: 0, usage_ping_enabled: 0 })
= link_to _("Send usage data"), send_usage_data_path, 'data-url' => admin_application_settings_path, method: :put, 'data-check-enabled': true, 'data-ping-enabled': true, class: 'js-usage-consent-action alert-link btn gl-button btn-info' = link_to _("Send service data"), send_service_data_path, 'data-url' => admin_application_settings_path, method: :put, 'data-check-enabled': true, 'data-service-ping-enabled': true, class: 'js-service-ping-consent-action alert-link btn gl-button btn-info'
= link_to _("Don't send usage data"), not_now_path, 'data-url' => admin_application_settings_path, method: :put, 'data-check-enabled': false, 'data-ping-enabled': false, class: 'js-usage-consent-action alert-link btn gl-button btn-default gl-ml-2' = link_to _("Don't send service data"), not_now_path, 'data-url' => admin_application_settings_path, method: :put, 'data-check-enabled': false, 'data-service-ping-enabled': false, class: 'js-service-ping-consent-action alert-link btn gl-button btn-default gl-ml-2'
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
- auto_devops - auto_devops
- backup_restore - backup_restore
- boards - boards
- build_artifacts
- chatops - chatops
- cloud_native_installation - cloud_native_installation
- cluster_cost_management - cluster_cost_management
...@@ -83,12 +84,14 @@ ...@@ -83,12 +84,14 @@
- mlops - mlops
- mobile_signing_deployment - mobile_signing_deployment
- navigation - navigation
- not_owned
- omnibus_package - omnibus_package
- on_call_schedule_management - on_call_schedule_management
- onboarding - onboarding
- package_registry - package_registry
- pages - pages
- performance_testing - performance_testing
- pipeline_abuse_prevention
- pipeline_authoring - pipeline_authoring
- planning_analytics - planning_analytics
- privacy_control_center - privacy_control_center
...@@ -110,6 +113,7 @@ ...@@ -110,6 +113,7 @@
- self_monitoring - self_monitoring
- serverless - serverless
- service_desk - service_desk
- service_ping
- sharding - sharding
- snippets - snippets
- source_code_management - source_code_management
...@@ -127,7 +131,6 @@ ...@@ -127,7 +131,6 @@
- value_stream_management - value_stream_management
- vulnerability_database - vulnerability_database
- vulnerability_management - vulnerability_management
- web_firewall
- web_ide - web_ide
- wiki - wiki
- workflow_automation - workflow_automation
...@@ -19,7 +19,7 @@ feature is still under development, and is not ready for production use. ...@@ -19,7 +19,7 @@ feature is still under development, and is not ready for production use.
By default, GitLab is configured to use only one main database. To By default, GitLab is configured to use only one main database. To
opt-in to use a main database, and CI database, modify the opt-in to use a main database, and CI database, modify the
`config/database.yml` file to have a `primary` and a `ci` database `config/database.yml` file to have a `main` and a `ci` database
configurations. For example, given a `config/database.yml` like below: configurations. For example, given a `config/database.yml` like below:
```yaml ```yaml
...@@ -48,7 +48,7 @@ Edit the `config/database.yml` to look like this: ...@@ -48,7 +48,7 @@ Edit the `config/database.yml` to look like this:
```yaml ```yaml
development: development:
primary: main:
adapter: postgresql adapter: postgresql
encoding: unicode encoding: unicode
database: gitlabhq_development database: gitlabhq_development
...@@ -69,7 +69,7 @@ development: ...@@ -69,7 +69,7 @@ development:
statement_timeout: 120s statement_timeout: 120s
test: &test test: &test
primary: main:
adapter: postgresql adapter: postgresql
encoding: unicode encoding: unicode
database: gitlabhq_test database: gitlabhq_test
...@@ -90,9 +90,6 @@ test: &test ...@@ -90,9 +90,6 @@ test: &test
statement_timeout: 120s statement_timeout: 120s
``` ```
Note that we use `primary` in the `config/database.yml` to refer to the main
database. This is to match the default name Rails has.
### Migrations ### Migrations
Any migrations that affect `Ci::BaseModel` models Any migrations that affect `Ci::BaseModel` models
......
...@@ -392,8 +392,12 @@ end ...@@ -392,8 +392,12 @@ end
If a large number of background jobs get scheduled at once, queueing of jobs may If a large number of background jobs get scheduled at once, queueing of jobs may
occur while jobs wait for a worker node to be become available. This is normal occur while jobs wait for a worker node to be become available. This is normal
and gives the system resilience by allowing it to gracefully handle spikes in and gives the system resilience by allowing it to gracefully handle spikes in
traffic. Some jobs, however, are more sensitive to latency than others. Examples traffic. Some jobs, however, are more sensitive to latency than others.
of these jobs include:
In general, latency-sensitive jobs perform operations that a user could
reasonably expect to happen synchronously, rather than asynchronously in a
background worker. A common example is a write following an action. Examples of
these jobs include:
1. A job which updates a merge request following a push to a branch. 1. A job which updates a merge request following a push to a branch.
1. A job which invalidates a cache of known branches for a project after a push 1. A job which invalidates a cache of known branches for a project after a push
......
...@@ -5,11 +5,10 @@ module EE ...@@ -5,11 +5,10 @@ module EE
extend ::Gitlab::Utils::Override extend ::Gitlab::Utils::Override
override :log_failed_two_factor override :log_failed_two_factor
def log_failed_two_factor(user, method, ip_address) def log_failed_two_factor(user, method)
::AuditEventService.new( ::AuditEventService.new(
user, user,
user, user,
ip_address: ip_address,
with: method with: method
).for_failed_login.unauth_security_event ).for_failed_login.unauth_security_event
end end
......
...@@ -21,7 +21,6 @@ module EE ...@@ -21,7 +21,6 @@ module EE
::AuditEventService.new( ::AuditEventService.new(
author, author,
nil, nil,
ip_address: request.remote_ip,
with: provider with: provider
).for_failed_login.unauth_security_event ).for_failed_login.unauth_security_event
end end
......
...@@ -64,7 +64,7 @@ module EE ...@@ -64,7 +64,7 @@ module EE
override :log_failed_login override :log_failed_login
def log_failed_login def log_failed_login
login = request.filtered_parameters.dig('user', 'login') login = request.filtered_parameters.dig('user', 'login')
audit_event_service = ::AuditEventService.new(login, nil, ip_address: request.remote_ip) audit_event_service = ::AuditEventService.new(login, nil)
audit_event_service.for_failed_login.unauth_security_event audit_event_service.for_failed_login.unauth_security_event
super super
......
...@@ -10,7 +10,7 @@ module Projects ...@@ -10,7 +10,7 @@ module Projects
push_frontend_feature_flag(:scan_execution_policy_ui, @project) push_frontend_feature_flag(:scan_execution_policy_ui, @project)
end end
feature_category :web_firewall feature_category :not_owned
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
def alert_details def alert_details
......
...@@ -8,13 +8,13 @@ module AuditEvents ...@@ -8,13 +8,13 @@ module AuditEvents
# @raise [MissingAttributeError] when required attributes are blank # @raise [MissingAttributeError] when required attributes are blank
# #
# @return [BuildService] # @return [BuildService]
def initialize(author:, scope:, target:, ip_address:, message:) def initialize(author:, scope:, target:, message:)
raise MissingAttributeError if missing_attribute?(author, scope, target, ip_address, message) raise MissingAttributeError if missing_attribute?(author, scope, target, message)
@author = build_author(author) @author = build_author(author)
@scope = scope @scope = scope
@target = target @target = target
@ip_address = ip_address @ip_address = build_ip_address
@message = build_message(message) @message = build_message(message)
end end
...@@ -27,7 +27,7 @@ module AuditEvents ...@@ -27,7 +27,7 @@ module AuditEvents
private private
def missing_attribute?(author, scope, target, ip_address, message) def missing_attribute?(author, scope, target, message)
author.blank? || scope.blank? || target.blank? || message.blank? author.blank? || scope.blank? || target.blank? || message.blank?
end end
...@@ -35,11 +35,11 @@ module AuditEvents ...@@ -35,11 +35,11 @@ module AuditEvents
if License.feature_available?(:admin_audit_log) if License.feature_available?(:admin_audit_log)
base_payload.merge( base_payload.merge(
details: base_details_payload.merge( details: base_details_payload.merge(
ip_address: ip_address, ip_address: @ip_address,
entity_path: @scope.full_path, entity_path: @scope.full_path,
custom_message: @message custom_message: @message
), ),
ip_address: ip_address ip_address: @ip_address
) )
else else
base_payload.merge(details: base_details_payload) base_payload.merge(details: base_details_payload)
...@@ -78,8 +78,8 @@ module AuditEvents ...@@ -78,8 +78,8 @@ module AuditEvents
end end
end end
def ip_address def build_ip_address
@ip_address.presence || @author.current_sign_in_ip Gitlab::RequestContext.instance.client_ip || @author.current_sign_in_ip
end end
end end
end end
...@@ -33,8 +33,7 @@ module EE ...@@ -33,8 +33,7 @@ module EE
target_type: token&.class&.name, target_type: token&.class&.name,
target_details: token&.user&.name, target_details: token&.user&.name,
action: :custom, action: :custom,
custom_message: message, custom_message: message
ip_address: current_user.current_sign_in_ip
).security_event ).security_event
end end
end end
......
...@@ -26,8 +26,7 @@ module EE ...@@ -26,8 +26,7 @@ module EE
target_type: token.class.name, target_type: token.class.name,
target_details: token.user.name, target_details: token.user.name,
action: :custom, action: :custom,
custom_message: message, custom_message: message
ip_address: current_user.current_sign_in_ip
).security_event ).security_event
end end
end end
......
...@@ -10,7 +10,6 @@ module Gitlab ...@@ -10,7 +10,6 @@ module Gitlab
# @option context [User] :author the user who authors the change # @option context [User] :author the user who authors the change
# @option context [User, Project, Group] :scope the scope which audit event belongs to # @option context [User, Project, Group] :scope the scope which audit event belongs to
# @option context [Object] :target the target object being audited # @option context [Object] :target the target object being audited
# @option context [Object] :ip_address the request IP address
# @option context [String] :message the message describing the action # @option context [String] :message the message describing the action
# #
# @example Using block (useful when events are emitted deep in the call stack) # @example Using block (useful when events are emitted deep in the call stack)
...@@ -21,7 +20,6 @@ module Gitlab ...@@ -21,7 +20,6 @@ module Gitlab
# author: current_user, # author: current_user,
# scope: project_alpha, # scope: project_alpha,
# target: merge_approval_rule, # target: merge_approval_rule,
# ip_address: request.remote_ip
# message: 'a user has attempted to update an approval rule' # message: 'a user has attempted to update an approval rule'
# } # }
# #
...@@ -58,7 +56,6 @@ module Gitlab ...@@ -58,7 +56,6 @@ module Gitlab
@author = @context.fetch(:author) @author = @context.fetch(:author)
@scope = @context.fetch(:scope) @scope = @context.fetch(:scope)
@target = @context.fetch(:target) @target = @context.fetch(:target)
@ip_address = @context.fetch(:ip_address, nil)
@message = @context.fetch(:message, '') @message = @context.fetch(:message, '')
end end
...@@ -91,7 +88,6 @@ module Gitlab ...@@ -91,7 +88,6 @@ module Gitlab
author: @author, author: @author,
scope: @scope, scope: @scope,
target: @target, target: @target,
ip_address: @ip_address,
message: message message: message
).execute ).execute
end end
......
...@@ -7,8 +7,7 @@ RSpec.describe Gitlab::Audit::Auditor do ...@@ -7,8 +7,7 @@ RSpec.describe Gitlab::Audit::Auditor do
let(:author) { build_stubbed(:user) } let(:author) { build_stubbed(:user) }
let(:scope) { build_stubbed(:group) } let(:scope) { build_stubbed(:group) }
let(:target) { build_stubbed(:project) } let(:target) { build_stubbed(:project) }
let(:ip_address) { '192.168.8.8' } let(:context) { { name: name, author: author, scope: scope, target: target } }
let(:context) { { name: name, author: author, scope: scope, target: target, ip_address: ip_address } }
let(:add_message) { 'Added an interesting field from project Gotham' } let(:add_message) { 'Added an interesting field from project Gotham' }
let(:remove_message) { 'Removed an interesting field from project Gotham' } let(:remove_message) { 'Removed an interesting field from project Gotham' }
let(:operation) do let(:operation) do
...@@ -85,7 +84,7 @@ RSpec.describe Gitlab::Audit::Auditor do ...@@ -85,7 +84,7 @@ RSpec.describe Gitlab::Audit::Auditor do
let(:audit!) { auditor.audit(context) } let(:audit!) { auditor.audit(context) }
let(:context) do let(:context) do
{ {
name: name, author: author, scope: scope, target: target, ip_address: ip_address, name: name, author: author, scope: scope, target: target,
message: 'Project has been deleted' message: 'Project has been deleted'
} }
end end
......
...@@ -2,16 +2,20 @@ ...@@ -2,16 +2,20 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe AuditEventService do RSpec.describe AuditEventService, :request_store do
let(:project) { build_stubbed(:project) } let(:project) { build_stubbed(:project) }
let_it_be(:user) { create(:user, current_sign_in_ip: '192.168.68.104') } let_it_be(:user) { create(:user, current_sign_in_ip: '192.168.68.104') }
let_it_be(:project_member) { create(:project_member, user: user, expires_at: 1.day.from_now) } let_it_be(:project_member) { create(:project_member, user: user, expires_at: 1.day.from_now) }
let(:request_ip_address) { '127.0.0.1' } let(:request_ip_address) { '127.0.0.1' }
let(:details) { { action: :destroy, ip_address: request_ip_address } } let(:details) { { action: :destroy } }
let(:service) { described_class.new(user, project, details) } let(:service) { described_class.new(user, project, details) }
before do
allow(Gitlab::RequestContext.instance).to receive(:client_ip).and_return(request_ip_address)
end
describe '#for_member' do describe '#for_member' do
let(:event) { service.for_member(project_member).security_event } let(:event) { service.for_member(project_member).security_event }
let(:event_details) { event[:details] } let(:event_details) { event[:details] }
...@@ -103,25 +107,47 @@ RSpec.describe AuditEventService do ...@@ -103,25 +107,47 @@ RSpec.describe AuditEventService do
end end
context 'for an unauthenticated user' do context 'for an unauthenticated user' do
let(:details) { { ip_address: '10.11.12.13' } }
let(:user) { Gitlab::Audit::UnauthenticatedAuthor.new } let(:user) { Gitlab::Audit::UnauthenticatedAuthor.new }
it 'defaults to the IP address in the details hash' do context 'when request IP address is present' do
it 'has the request IP address' do
event = service.security_event event = service.security_event
expect(event.ip_address).to eq('10.11.12.13') expect(event.details[:ip_address]).to eq(request_ip_address)
expect(event.details[:ip_address]).to eq('10.11.12.13') expect(event.ip_address).to eq(request_ip_address)
end end
end end
context 'for an authenticated user' do context 'when request IP address is not present' do
let(:details) { {} } let(:request_ip_address) { nil }
it 'has the user IP address' do it 'has the user IP address' do
event = service.security_event event = service.security_event
expect(event.details[:ip_address]).to eq(user.current_sign_in_ip)
expect(event.ip_address).to eq(user.current_sign_in_ip) expect(event.ip_address).to eq(user.current_sign_in_ip)
end
end
end
context 'for an authenticated user' do
context 'when request IP address is present' do
it 'has the request IP address' do
event = service.security_event
expect(event.details[:ip_address]).to eq(request_ip_address)
expect(event.ip_address).to eq(request_ip_address)
end
end
context 'when request IP address is not present' do
let(:request_ip_address) { nil }
it 'has the user IP address' do
event = service.security_event
expect(event.details[:ip_address]).to eq(user.current_sign_in_ip) expect(event.details[:ip_address]).to eq(user.current_sign_in_ip)
expect(event.ip_address).to eq(user.current_sign_in_ip)
end end
it 'tracks exceptions when the event cannot be created' do it 'tracks exceptions when the event cannot be created' do
...@@ -135,17 +161,31 @@ RSpec.describe AuditEventService do ...@@ -135,17 +161,31 @@ RSpec.describe AuditEventService do
service.security_event service.security_event
end end
end end
end
context 'for an impersonated user' do context 'for an impersonated user' do
let(:details) { {} } let(:details) { {} }
let(:impersonator) { build(:user, name: 'Donald Duck', current_sign_in_ip: '192.168.88.88') } let(:impersonator) { build(:user, name: 'Donald Duck', current_sign_in_ip: '192.168.88.88') }
let(:user) { create(:user, impersonator: impersonator) } let(:user) { create(:user, impersonator: impersonator) }
context 'when request IP address is present' do
it 'has the request IP address' do
event = service.security_event
expect(event.details[:ip_address]).to eq(request_ip_address)
expect(event.ip_address).to eq(request_ip_address)
end
end
context 'when request IP address is not present' do
let(:request_ip_address) { nil }
it 'has the impersonator IP address' do it 'has the impersonator IP address' do
event = service.security_event event = service.security_event
expect(event.details[:ip_address]).to eq('192.168.88.88') expect(event.details[:ip_address]).to eq(impersonator.current_sign_in_ip)
expect(event.ip_address).to eq('192.168.88.88') expect(event.ip_address).to eq(impersonator.current_sign_in_ip)
end
end end
it 'has the impersonator name' do it 'has the impersonator name' do
...@@ -245,7 +285,7 @@ RSpec.describe AuditEventService do ...@@ -245,7 +285,7 @@ RSpec.describe AuditEventService do
describe '#for_failed_login' do describe '#for_failed_login' do
let(:author_name) { 'testuser' } let(:author_name) { 'testuser' }
let(:service) { described_class.new(author_name, nil, ip_address: request_ip_address) } let(:service) { described_class.new(author_name, nil) }
let(:event) { service.for_failed_login.unauth_security_event } let(:event) { service.for_failed_login.unauth_security_event }
before do before do
...@@ -520,9 +560,7 @@ RSpec.describe AuditEventService do ...@@ -520,9 +560,7 @@ RSpec.describe AuditEventService do
expect(event.details[:entity_path]).to eq(project.full_path) expect(event.details[:entity_path]).to eq(project.full_path)
end end
context 'request IP address is provided' do context 'request IP address is present' do
let(:details) { { action: :destroy, ip_address: request_ip_address } }
it 'has the IP address in the details hash' do it 'has the IP address in the details hash' do
expect(event.details[:ip_address]).to eq(request_ip_address) expect(event.details[:ip_address]).to eq(request_ip_address)
end end
...@@ -532,8 +570,8 @@ RSpec.describe AuditEventService do ...@@ -532,8 +570,8 @@ RSpec.describe AuditEventService do
end end
end end
context 'request IP address is not provided' do context 'request IP address is not present' do
let(:details) { { action: :destroy } } let(:request_ip_address) { nil }
it 'has the IP address in the details hash' do it 'has the IP address in the details hash' do
expect(event.details[:ip_address]).to eq(user.current_sign_in_ip) expect(event.details[:ip_address]).to eq(user.current_sign_in_ip)
......
...@@ -14,14 +14,17 @@ RSpec.describe AuditEvents::BuildService do ...@@ -14,14 +14,17 @@ RSpec.describe AuditEvents::BuildService do
author: author, author: author,
scope: scope, scope: scope,
target: target, target: target,
ip_address: ip_address,
message: message message: message
) )
end end
describe '#execute' do describe '#execute', :request_store do
subject(:event) { service.execute } subject(:event) { service.execute }
before do
allow(Gitlab::RequestContext.instance).to receive(:client_ip).and_return(ip_address)
end
context 'when licensed' do context 'when licensed' do
before do before do
stub_licensed_features(admin_audit_log: true) stub_licensed_features(admin_audit_log: true)
......
...@@ -7,7 +7,7 @@ RSpec.shared_examples 'an auditable failed authentication' do ...@@ -7,7 +7,7 @@ RSpec.shared_examples 'an auditable failed authentication' do
operation operation
expect(AuditEventService).to have_received(:new).with(user, user, ip_address: '0.0.0.0', with: method) expect(AuditEventService).to have_received(:new).with(user, user, with: method)
expect(audit_event_service).to have_received(:for_failed_login) expect(audit_event_service).to have_received(:for_failed_login)
expect(audit_event_service).to have_received(:unauth_security_event) expect(audit_event_service).to have_received(:unauth_security_event)
end end
......
...@@ -4,7 +4,7 @@ module API ...@@ -4,7 +4,7 @@ module API
class JobArtifacts < ::API::Base class JobArtifacts < ::API::Base
before { authenticate_non_get! } before { authenticate_non_get! }
feature_category :continuous_integration feature_category :build_artifacts
# EE::API::JobArtifacts would override the following helpers # EE::API::JobArtifacts would override the following helpers
helpers do helpers do
......
...@@ -839,6 +839,9 @@ msgid_plural "%{securityScanner} results are not available because a pipeline ha ...@@ -839,6 +839,9 @@ msgid_plural "%{securityScanner} results are not available because a pipeline ha
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
msgid "%{service_ping_link_start}Learn more%{service_ping_link_end} about what information is shared with GitLab Inc."
msgstr ""
msgid "%{size} %{unit}" msgid "%{size} %{unit}"
msgstr "" msgstr ""
...@@ -972,9 +975,6 @@ msgstr "" ...@@ -972,9 +975,6 @@ msgstr ""
msgid "%{total} warnings found: showing first %{warningsDisplayed}" msgid "%{total} warnings found: showing first %{warningsDisplayed}"
msgstr "" msgstr ""
msgid "%{usage_ping_link_start}Learn more%{usage_ping_link_end} about what information is shared with GitLab Inc."
msgstr ""
msgid "%{userName} (cannot merge)" msgid "%{userName} (cannot merge)"
msgstr "" msgstr ""
...@@ -11482,7 +11482,7 @@ msgstr "" ...@@ -11482,7 +11482,7 @@ msgstr ""
msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'." msgid "Don't paste the private part of the GPG key. Paste the public part which begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----'."
msgstr "" msgstr ""
msgid "Don't send usage data" msgid "Don't send service data"
msgstr "" msgstr ""
msgid "Don't show again" msgid "Don't show again"
...@@ -12034,7 +12034,7 @@ msgstr "" ...@@ -12034,7 +12034,7 @@ msgstr ""
msgid "Enable or disable the Pseudonymizer data collection." msgid "Enable or disable the Pseudonymizer data collection."
msgstr "" msgstr ""
msgid "Enable or disable version check and usage ping." msgid "Enable or disable version check and service ping."
msgstr "" msgstr ""
msgid "Enable protected paths rate limit" msgid "Enable protected paths rate limit"
...@@ -12052,6 +12052,9 @@ msgstr "" ...@@ -12052,6 +12052,9 @@ msgstr ""
msgid "Enable reCAPTCHA, Invisible Captcha, Akismet and set IP limits. For reCAPTCHA, we currently only support %{recaptcha_v2_link_start}v2%{recaptcha_v2_link_end}" msgid "Enable reCAPTCHA, Invisible Captcha, Akismet and set IP limits. For reCAPTCHA, we currently only support %{recaptcha_v2_link_start}v2%{recaptcha_v2_link_end}"
msgstr "" msgstr ""
msgid "Enable service ping"
msgstr ""
msgid "Enable shared runners for all projects and subgroups in this group." msgid "Enable shared runners for all projects and subgroups in this group."
msgstr "" msgstr ""
...@@ -12076,9 +12079,6 @@ msgstr "" ...@@ -12076,9 +12079,6 @@ msgstr ""
msgid "Enable unauthenticated request rate limit" msgid "Enable unauthenticated request rate limit"
msgstr "" msgstr ""
msgid "Enable usage ping"
msgstr ""
msgid "Enable version check" msgid "Enable version check"
msgstr "" msgstr ""
...@@ -14068,7 +14068,7 @@ msgstr "" ...@@ -14068,7 +14068,7 @@ msgstr ""
msgid "For more information, see the File Hooks documentation." msgid "For more information, see the File Hooks documentation."
msgstr "" msgstr ""
msgid "For more information, see the documentation on %{deactivating_usage_ping_link_start}deactivating the usage ping%{deactivating_usage_ping_link_end}." msgid "For more information, see the documentation on %{deactivating_service_ping_link_start}deactivating service ping%{deactivating_service_ping_link_end}."
msgstr "" msgstr ""
msgid "Forgot your password?" msgid "Forgot your password?"
...@@ -29336,7 +29336,7 @@ msgstr "" ...@@ -29336,7 +29336,7 @@ msgstr ""
msgid "Send report" msgid "Send report"
msgstr "" msgstr ""
msgid "Send usage data" msgid "Send service data"
msgstr "" msgstr ""
msgid "Sentry API URL" msgid "Sentry API URL"
...@@ -29462,6 +29462,9 @@ msgstr "" ...@@ -29462,6 +29462,9 @@ msgstr ""
msgid "Service URL" msgid "Service URL"
msgstr "" msgstr ""
msgid "Service ping is disabled, and cannot be configured through this form."
msgstr ""
msgid "ServiceDesk|Enable Service Desk" msgid "ServiceDesk|Enable Service Desk"
msgstr "" msgstr ""
...@@ -32541,9 +32544,6 @@ msgstr "" ...@@ -32541,9 +32544,6 @@ msgstr ""
msgid "The uploaded file was invalid. Supported file extensions are %{extensions}." msgid "The uploaded file was invalid. Supported file extensions are %{extensions}."
msgstr "" msgstr ""
msgid "The usage ping is disabled, and cannot be configured through this form."
msgstr ""
msgid "The user is being deleted." msgid "The user is being deleted."
msgstr "" msgstr ""
......
...@@ -567,7 +567,7 @@ RSpec.describe 'Admin updates settings' do ...@@ -567,7 +567,7 @@ RSpec.describe 'Admin updates settings' do
wait_for_requests wait_for_requests
expect(page).to have_selector '.js-usage-ping-payload' expect(page).to have_selector '.js-service-ping-payload'
expect(page).to have_button 'Hide payload' expect(page).to have_button 'Hide payload'
expect(page).to have_content expected_payload_content expect(page).to have_content expected_payload_content
end end
......
...@@ -27,7 +27,7 @@ RSpec.describe 'Usage stats consent' do ...@@ -27,7 +27,7 @@ RSpec.describe 'Usage stats consent' do
expect(page).to have_content(message) expect(page).to have_content(message)
click_link 'Send usage data' click_link 'Send service data'
expect(page).not_to have_content(message) expect(page).not_to have_content(message)
expect(page).to have_content('Application settings saved successfully') expect(page).to have_content('Application settings saved successfully')
......
...@@ -79,15 +79,14 @@ RSpec.describe AuditEventService do ...@@ -79,15 +79,14 @@ RSpec.describe AuditEventService do
context 'with IP address', :request_store do context 'with IP address', :request_store do
using RSpec::Parameterized::TableSyntax using RSpec::Parameterized::TableSyntax
where(:from_caller, :from_context, :from_author_sign_in, :output) do where(:from_context, :from_author_sign_in, :output) do
'192.168.0.1' | '192.168.0.2' | '192.168.0.3' | '192.168.0.1' '192.168.0.2' | '192.168.0.3' | '192.168.0.2'
nil | '192.168.0.2' | '192.168.0.3' | '192.168.0.2' nil | '192.168.0.3' | '192.168.0.3'
nil | nil | '192.168.0.3' | '192.168.0.3'
end end
with_them do with_them do
let(:user) { create(:user, current_sign_in_ip: from_author_sign_in) } let(:user) { create(:user, current_sign_in_ip: from_author_sign_in) }
let(:audit_service) { described_class.new(user, user, with: 'standard', ip_address: from_caller) } let(:audit_service) { described_class.new(user, user, with: 'standard') }
before do before do
allow(Gitlab::RequestContext.instance).to receive(:client_ip).and_return(from_context) allow(Gitlab::RequestContext.instance).to receive(:client_ip).and_return(from_context)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment