Refactor SystemHookUrlValidator and specs
Simplify SystemHookUrlValidator to inherit from PublicUrlValidator Refactor specs to move out shared examples to be used in both system hooks and public url validators.
This commit is contained in:
parent
ac7661924e
commit
8abf920d1f
|
|
@ -14,8 +14,7 @@ class SystemHook < WebHook
|
|||
default_value_for :repository_update_events, true
|
||||
default_value_for :merge_requests_events, false
|
||||
|
||||
validates :url, presence: true, public_url: false, system_hook_url: { allow_localhost: lambda(&:allow_local_requests?),
|
||||
allow_local_network: lambda(&:allow_local_requests?) }
|
||||
validates :url, system_hook_url: true
|
||||
|
||||
# Allow urls pointing localhost and the local network
|
||||
def allow_local_requests?
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ class WebHook < ApplicationRecord
|
|||
|
||||
has_many :web_hook_logs, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
|
||||
validates :url, presence: true, public_url: { allow_localhost: lambda(&:allow_local_requests?),
|
||||
allow_local_network: lambda(&:allow_local_requests?) }
|
||||
validates :url, presence: true
|
||||
validates :url, public_url: true, unless: ->(hook) { hook.is_a?(SystemHook) }
|
||||
|
||||
validates :token, format: { without: /\n/ }
|
||||
validates :push_events_branch_filter, branch_filter: true
|
||||
|
|
|
|||
|
|
@ -7,23 +7,11 @@
|
|||
# ApplicationSetting.allow_local_requests_from_system_hooks
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# class SystemHook < WebHook
|
||||
# validates :url, system_hook_url: { allow_localhost: true, allow_local_network: true }
|
||||
# validates :url, system_hook_url: true
|
||||
# end
|
||||
#
|
||||
class SystemHookUrlValidator < AddressableUrlValidator
|
||||
DEFAULT_OPTIONS = {
|
||||
allow_localhost: false,
|
||||
allow_local_network: false
|
||||
}.freeze
|
||||
|
||||
def initialize(options)
|
||||
options.reverse_merge!(DEFAULT_OPTIONS)
|
||||
|
||||
super(options)
|
||||
end
|
||||
|
||||
class SystemHookUrlValidator < PublicUrlValidator
|
||||
def self.allow_setting_local_requests?
|
||||
ApplicationSetting.current&.allow_local_requests_from_system_hooks?
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,4 +2,4 @@
|
|||
title: Add new outbound network requests application setting for system hooks
|
||||
merge_request: 31177
|
||||
author:
|
||||
type: changed
|
||||
type: added
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@ class RenameAllowLocalRequestsFromHooksAndServicesApplicationSetting < ActiveRec
|
|||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
rename_column :application_settings, :allow_local_requests_from_hooks_and_services, :allow_local_requests_from_web_hooks_and_services
|
||||
rename_column_concurrently :application_settings, :allow_local_requests_from_hooks_and_services, :allow_local_requests_from_web_hooks_and_services
|
||||
end
|
||||
|
||||
def down
|
||||
rename_column :application_settings, :allow_local_requests_from_web_hooks_and_services, :allow_local_requests_from_hooks_and_services
|
||||
cleanup_concurrent_column_rename :application_settings, :allow_local_requests_from_web_hooks_and_services, :allow_local_requests_from_hooks_and_services
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class CleanupAllowLocalRequestsFromHooksAndServicesApplicationSettingRename < ActiveRecord::Migration[5.2]
|
||||
include Gitlab::Database::MigrationHelpers
|
||||
|
||||
DOWNTIME = false
|
||||
|
||||
def up
|
||||
cleanup_concurrent_column_rename :application_settings, :allow_local_requests_from_hooks_and_services, :allow_local_requests_from_web_hooks_and_services
|
||||
end
|
||||
|
||||
def down
|
||||
rename_column_concurrently :application_settings, :allow_local_requests_from_web_hooks_and_services, :allow_local_requests_from_hooks_and_services
|
||||
end
|
||||
end
|
||||
|
|
@ -183,7 +183,6 @@ ActiveRecord::Schema.define(version: 2019_07_31_084415) do
|
|||
t.string "external_authorization_service_default_label"
|
||||
t.boolean "pages_domain_verification_enabled", default: true, null: false
|
||||
t.string "user_default_internal_regex"
|
||||
t.boolean "allow_local_requests_from_web_hooks_and_services", default: false, null: false
|
||||
t.float "external_authorization_service_timeout", default: 0.5
|
||||
t.text "external_auth_client_cert"
|
||||
t.text "encrypted_external_auth_client_key"
|
||||
|
|
@ -230,6 +229,7 @@ ActiveRecord::Schema.define(version: 2019_07_31_084415) do
|
|||
t.string "grafana_url", default: "/-/grafana", null: false
|
||||
t.string "outbound_local_requests_whitelist", limit: 255, default: [], null: false, array: true
|
||||
t.integer "raw_blob_request_limit", default: 300, null: false
|
||||
t.boolean "allow_local_requests_from_web_hooks_and_services", default: false, null: false
|
||||
t.boolean "allow_local_requests_from_system_hooks", default: true, null: false
|
||||
t.index ["custom_project_templates_group_id"], name: "index_application_settings_on_custom_project_templates_group_id"
|
||||
t.index ["file_template_project_id"], name: "index_application_settings_on_file_template_project_id"
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 7.1 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
|
|
@ -38,11 +38,12 @@ local network from web hooks and services"* in the *"Outbound requests"* section
|
|||
inside the Admin area under **Settings**
|
||||
(`/admin/application_settings/network`):
|
||||
|
||||

|
||||

|
||||
|
||||
>**Note:**
|
||||
*System hooks* are enabled to make requests to local network by default since they are set up by admins.
|
||||
However, it can be turned off by disabling *"Allow requests to the local network from system hooks"* option.
|
||||
NOTE: **Note:**
|
||||
*System hooks* are enabled to make requests to local network by default since they are
|
||||
set up by administrators. However, you can turn this off by disabling the
|
||||
**Allow requests to the local network from system hooks** option.
|
||||
|
||||
<!-- ## Troubleshooting
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ module Gitlab
|
|||
private
|
||||
|
||||
def allow_local_requests?
|
||||
Gitlab::CurrentSettings.allow_local_requests_from_hooks_and_services?
|
||||
Gitlab::CurrentSettings.allow_local_requests_from_web_hooks_and_services?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ describe Gitlab::Octokit::Middleware do
|
|||
|
||||
context 'when localhost requests are not allowed' do
|
||||
before do
|
||||
stub_application_setting(allow_local_requests_from_hooks_and_services: false)
|
||||
stub_application_setting(allow_local_requests_from_web_hooks_and_services: false)
|
||||
end
|
||||
|
||||
it_behaves_like 'Local URL'
|
||||
|
|
@ -38,7 +38,7 @@ describe Gitlab::Octokit::Middleware do
|
|||
|
||||
context 'when localhost requests are allowed' do
|
||||
before do
|
||||
stub_application_setting(allow_local_requests_from_hooks_and_services: true)
|
||||
stub_application_setting(allow_local_requests_from_web_hooks_and_services: true)
|
||||
end
|
||||
|
||||
it_behaves_like 'Public URL'
|
||||
|
|
@ -50,7 +50,7 @@ describe Gitlab::Octokit::Middleware do
|
|||
|
||||
context 'when local network requests are not allowed' do
|
||||
before do
|
||||
stub_application_setting(allow_local_requests_from_hooks_and_services: false)
|
||||
stub_application_setting(allow_local_requests_from_web_hooks_and_services: false)
|
||||
end
|
||||
|
||||
it_behaves_like 'Local URL'
|
||||
|
|
@ -58,7 +58,7 @@ describe Gitlab::Octokit::Middleware do
|
|||
|
||||
context 'when local network requests are allowed' do
|
||||
before do
|
||||
stub_application_setting(allow_local_requests_from_hooks_and_services: true)
|
||||
stub_application_setting(allow_local_requests_from_web_hooks_and_services: true)
|
||||
end
|
||||
|
||||
it_behaves_like 'Public URL'
|
||||
|
|
|
|||
|
|
@ -23,14 +23,14 @@ describe WebHookService do
|
|||
stub_application_setting(setting_name => setting)
|
||||
end
|
||||
|
||||
shared_examples_for 'respecting outbound network setting' do
|
||||
context 'local requests are allowed' do
|
||||
shared_examples_for 'respects outbound network setting' do
|
||||
context 'when local requests are allowed' do
|
||||
let(:setting) { true }
|
||||
|
||||
it { expect(hook.request_options[:allow_local_requests]).to be_truthy }
|
||||
end
|
||||
|
||||
context 'local requests are not allowed' do
|
||||
context 'when local requests are not allowed' do
|
||||
let(:setting) { false }
|
||||
|
||||
it { expect(hook.request_options[:allow_local_requests]).to be_falsey }
|
||||
|
|
@ -41,14 +41,14 @@ describe WebHookService do
|
|||
let(:setting_name) { :allow_local_requests_from_system_hooks }
|
||||
let(:hook) { described_class.new(build(:system_hook), data, :system_hook) }
|
||||
|
||||
include_examples 'respecting outbound network setting'
|
||||
include_examples 'respects outbound network setting'
|
||||
end
|
||||
|
||||
context 'when ProjectHook' do
|
||||
let(:setting_name) { :allow_local_requests_from_web_hooks_and_services }
|
||||
let(:hook) { described_class.new(build(:project_hook), data, :project_hook) }
|
||||
|
||||
include_examples 'respecting outbound network setting'
|
||||
include_examples 'respects outbound network setting'
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.shared_examples 'url validator examples' do |schemes|
|
||||
let(:validator) { described_class.new(attributes: [:link_url], **options) }
|
||||
let!(:badge) { build(:badge, link_url: 'http://www.example.com') }
|
||||
|
||||
subject { validator.validate(badge) }
|
||||
|
||||
describe '#validate' do
|
||||
let(:validator) { described_class.new(attributes: [:link_url], **options) }
|
||||
let(:badge) { build(:badge, link_url: 'http://www.example.com') }
|
||||
|
||||
subject { validator.validate(badge) }
|
||||
|
||||
context 'with no options' do
|
||||
let(:options) { {} }
|
||||
|
||||
|
|
@ -42,3 +42,52 @@ RSpec.shared_examples 'url validator examples' do |schemes|
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
RSpec.shared_examples 'public url validator examples' do |setting|
|
||||
let(:validator) { described_class.new(attributes: [:link_url]) }
|
||||
let(:badge) { build(:badge, link_url: 'http://www.example.com') }
|
||||
|
||||
subject { validator.validate(badge) }
|
||||
|
||||
context 'by default' do
|
||||
it 'blocks urls pointing to localhost' do
|
||||
badge.link_url = 'https://127.0.0.1'
|
||||
|
||||
subject
|
||||
|
||||
expect(badge.errors).to be_present
|
||||
end
|
||||
|
||||
it 'blocks urls pointing to the local network' do
|
||||
badge.link_url = 'https://192.168.1.1'
|
||||
|
||||
subject
|
||||
|
||||
expect(badge.errors).to be_present
|
||||
end
|
||||
end
|
||||
|
||||
context 'when local requests are allowed' do
|
||||
let!(:settings) { create(:application_setting) }
|
||||
|
||||
before do
|
||||
stub_application_setting(setting)
|
||||
end
|
||||
|
||||
it 'does not block urls pointing to localhost' do
|
||||
badge.link_url = 'https://127.0.0.1'
|
||||
|
||||
subject
|
||||
|
||||
expect(badge.errors).not_to be_present
|
||||
end
|
||||
|
||||
it 'does not block urls pointing to the local network' do
|
||||
badge.link_url = 'https://192.168.1.1'
|
||||
|
||||
subject
|
||||
|
||||
expect(badge.errors).not_to be_present
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,27 +2,5 @@ require 'spec_helper'
|
|||
|
||||
describe PublicUrlValidator do
|
||||
include_examples 'url validator examples', AddressableUrlValidator::DEFAULT_OPTIONS[:schemes]
|
||||
|
||||
context 'by default' do
|
||||
let(:validator) { described_class.new(attributes: [:link_url]) }
|
||||
let!(:badge) { build(:badge, link_url: 'http://www.example.com') }
|
||||
|
||||
subject { validator.validate(badge) }
|
||||
|
||||
it 'blocks urls pointing to localhost' do
|
||||
badge.link_url = 'https://127.0.0.1'
|
||||
|
||||
subject
|
||||
|
||||
expect(badge.errors).to be_present
|
||||
end
|
||||
|
||||
it 'blocks urls pointing to the local network' do
|
||||
badge.link_url = 'https://192.168.1.1'
|
||||
|
||||
subject
|
||||
|
||||
expect(badge.errors).to be_present
|
||||
end
|
||||
end
|
||||
include_examples 'public url validator examples', allow_local_requests_from_web_hooks_and_services: true
|
||||
end
|
||||
|
|
|
|||
|
|
@ -4,55 +4,5 @@ require 'spec_helper'
|
|||
|
||||
describe SystemHookUrlValidator do
|
||||
include_examples 'url validator examples', AddressableUrlValidator::DEFAULT_OPTIONS[:schemes]
|
||||
|
||||
context 'by default' do
|
||||
let(:validator) { described_class.new(attributes: [:link_url]) }
|
||||
let!(:badge) { build(:badge, link_url: 'http://www.example.com') }
|
||||
|
||||
subject { validator.validate(badge) }
|
||||
|
||||
it 'blocks urls pointing to localhost' do
|
||||
badge.link_url = 'https://127.0.0.1'
|
||||
|
||||
subject
|
||||
|
||||
expect(badge.errors).to be_present
|
||||
end
|
||||
|
||||
it 'blocks urls pointing to the local network' do
|
||||
badge.link_url = 'https://192.168.1.1'
|
||||
|
||||
subject
|
||||
|
||||
expect(badge.errors).to be_present
|
||||
end
|
||||
end
|
||||
|
||||
context 'when local requests are allowed' do
|
||||
let(:validator) { described_class.new(attributes: [:link_url]) }
|
||||
let!(:badge) { build(:badge, link_url: 'http://www.example.com') }
|
||||
let!(:settings) { create(:application_setting) }
|
||||
|
||||
subject { validator.validate(badge) }
|
||||
|
||||
before do
|
||||
stub_application_setting(allow_local_requests_from_system_hooks: true)
|
||||
end
|
||||
|
||||
it 'does not block urls pointing to localhost' do
|
||||
badge.link_url = 'https://127.0.0.1'
|
||||
|
||||
subject
|
||||
|
||||
expect(badge.errors).not_to be_present
|
||||
end
|
||||
|
||||
it 'does not block urls pointing to the local network' do
|
||||
badge.link_url = 'https://192.168.1.1'
|
||||
|
||||
subject
|
||||
|
||||
expect(badge.errors).not_to be_present
|
||||
end
|
||||
end
|
||||
include_examples 'public url validator examples', allow_local_requests_from_system_hooks: true
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in New Issue