Commit 33604625 authored by Reuben Pereira's avatar Reuben Pereira Committed by Mayra Cabrera

[ADD] outbound requests whitelist

Signed-off-by: default avatarIstvan szalai <istvan.szalai@savoirfairelinux.com>
parent e2710429
......@@ -177,6 +177,7 @@ module ApplicationSettingsHelper
:domain_blacklist_enabled,
:domain_blacklist_raw,
:domain_whitelist_raw,
:outbound_local_requests_whitelist_raw,
:dsa_key_restriction,
:ecdsa_key_restriction,
:ed25519_key_restriction,
......
......@@ -41,6 +41,11 @@ class ApplicationSetting < ApplicationRecord
validates :uuid, presence: true
validates :outbound_local_requests_whitelist,
length: { maximum: 1_000, message: N_('is too long (maximum is 1000 entries)') }
validates :outbound_local_requests_whitelist, qualified_domain_array: true, allow_blank: true
validates :session_expire_delay,
presence: true,
numericality: { only_integer: true, greater_than_or_equal_to: 0 }
......
......@@ -2,6 +2,7 @@
module ApplicationSettingImplementation
extend ActiveSupport::Concern
include Gitlab::Utils::StrongMemoize
DOMAIN_LIST_SEPARATOR = %r{\s*[,;]\s* # comma or semicolon, optionally surrounded by whitespace
| # or
......@@ -96,7 +97,8 @@ module ApplicationSettingImplementation
diff_max_patch_bytes: Gitlab::Git::Diff::DEFAULT_MAX_PATCH_BYTES,
commit_email_hostname: default_commit_email_hostname,
protected_ci_variables: false,
local_markdown_version: 0
local_markdown_version: 0,
outbound_local_requests_whitelist: []
}
end
......@@ -131,31 +133,52 @@ module ApplicationSettingImplementation
end
def domain_whitelist_raw
self.domain_whitelist&.join("\n")
array_to_string(self.domain_whitelist)
end
def domain_blacklist_raw
self.domain_blacklist&.join("\n")
array_to_string(self.domain_blacklist)
end
def domain_whitelist_raw=(values)
self.domain_whitelist = []
self.domain_whitelist = values.split(DOMAIN_LIST_SEPARATOR)
self.domain_whitelist.reject! { |d| d.empty? }
self.domain_whitelist
self.domain_whitelist = domain_strings_to_array(values)
end
def domain_blacklist_raw=(values)
self.domain_blacklist = []
self.domain_blacklist = values.split(DOMAIN_LIST_SEPARATOR)
self.domain_blacklist.reject! { |d| d.empty? }
self.domain_blacklist
self.domain_blacklist = domain_strings_to_array(values)
end
def domain_blacklist_file=(file)
self.domain_blacklist_raw = file.read
end
def outbound_local_requests_whitelist_raw
array_to_string(self.outbound_local_requests_whitelist)
end
def outbound_local_requests_whitelist_raw=(values)
self.outbound_local_requests_whitelist = domain_strings_to_array(values)
end
def outbound_local_requests_whitelist_arrays
strong_memoize(:outbound_local_requests_whitelist_arrays) do
ip_whitelist = []
domain_whitelist = []
self.outbound_local_requests_whitelist.each do |str|
ip_obj = Gitlab::Utils.string_to_ip_object(str)
if ip_obj
ip_whitelist << ip_obj
else
domain_whitelist << str
end
end
[ip_whitelist, domain_whitelist]
end
end
def repository_storages
Array(read_attribute(:repository_storages))
end
......@@ -255,6 +278,17 @@ module ApplicationSettingImplementation
private
def array_to_string(arr)
arr&.join("\n")
end
def domain_strings_to_array(values)
values
.split(DOMAIN_LIST_SEPARATOR)
.reject(&:empty?)
.uniq
end
def ensure_uuid!
return if uuid?
......
......@@ -8,6 +8,13 @@
= f.label :allow_local_requests_from_hooks_and_services, class: 'form-check-label' do
Allow requests to the local network from hooks and services
.form-group
= f.label :outbound_local_requests_whitelist_raw, class: 'label-bold' do
= _('Whitelist to allow requests to the local network from hooks and services')
= f.text_area :outbound_local_requests_whitelist_raw, placeholder: "example.com, 192.168.1.1", class: 'form-control', rows: 8
%span.form-text.text-muted
= _('Requests to these domain(s)/address(es) on the local network will be allowed when local requests from hooks and services are disabled. 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 whitelist can hold a maximum of 4000 entries. Domains should use IDNA encoding. Ex: domain.com, 192.168.1.1, 127.0.0.0/28.')
.form-group
.form-check
= f.check_box :dns_rebinding_protection_enabled, class: 'form-check-input'
......
---
title: Add Outbound requests whitelist for local networks
merge_request: 30350
author: Istvan Szalai
type: added
# frozen_string_literal: true
class AddOutboundRequestsWhitelistToApplicationSettings < ActiveRecord::Migration[5.1]
DOWNTIME = false
def change
add_column :application_settings, :outbound_local_requests_whitelist, :string, array: true, limit: 255
end
end
......@@ -228,6 +228,7 @@ ActiveRecord::Schema.define(version: 2019_07_15_114644) do
t.boolean "lock_memberships_to_ldap", default: false, null: false
t.boolean "time_tracking_limit_to_hours", default: false, null: false
t.string "grafana_url", default: "/-/grafana", null: false
t.string "outbound_local_requests_whitelist", limit: 255, array: true
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"
t.index ["usage_stats_set_by_user_id"], name: "index_application_settings_on_usage_stats_set_by_user_id"
......
......@@ -39,6 +39,7 @@ Example response:
"session_expire_delay" : 10080,
"home_page_url" : null,
"default_snippet_visibility" : "private",
"outbound_local_requests_whitelist": [],
"domain_whitelist" : [],
"domain_blacklist_enabled" : false,
"domain_blacklist" : [],
......@@ -113,6 +114,7 @@ Example response:
"default_project_visibility": "internal",
"default_snippet_visibility": "private",
"default_group_visibility": "private",
"outbound_local_requests_whitelist": [],
"domain_whitelist": [],
"domain_blacklist_enabled" : false,
"domain_blacklist" : [],
......@@ -193,6 +195,7 @@ are listed in the descriptions of the relevant settings.
| `domain_blacklist` | array of strings | required by: `domain_blacklist_enabled` | Users with e-mail addresses that match these domain(s) will NOT be able to sign-up. Wildcards allowed. Use separate lines for multiple entries. Ex: `domain.com`, `*.domain.com`. |
| `domain_blacklist_enabled` | boolean | no | (**If enabled, requires:** `domain_blacklist`) Allows blocking sign-ups from emails from specific domains. |
| `domain_whitelist` | array of strings | no | Force people to use only corporate emails for sign-up. Default is `null`, meaning there is no restriction. |
| `outbound_local_requests_whitelist` | array of strings | no | Define a list of trusted domains or ip addresses to which local requests are allowed when local requests for hooks and services are disabled.
| `dsa_key_restriction` | integer | no | The minimum allowed bit length of an uploaded DSA key. Default is `0` (no restriction). `-1` disables DSA keys. |
| `ecdsa_key_restriction` | integer | no | The minimum allowed curve size (in bits) of an uploaded ECDSA key. Default is `0` (no restriction). `-1` disables ECDSA keys. |
| `ed25519_key_restriction` | integer | no | The minimum allowed curve size (in bits) of an uploaded ED25519 key. Default is `0` (no restriction). `-1` disables ED25519 keys. |
......
......@@ -45,18 +45,21 @@ module Gitlab
ascii_only: ascii_only
)
normalized_hostname = uri.normalized_host
hostname = uri.hostname
port = get_port(uri)
address_info = get_address_info(hostname, port)
return [uri, nil] unless address_info
protected_uri_with_hostname = enforce_uri_hostname(address_info, uri, hostname, dns_rebind_protection)
ip_address = ip_address(address_info)
protected_uri_with_hostname = enforce_uri_hostname(ip_address, uri, hostname, dns_rebind_protection)
# Allow url from the GitLab instance itself but only for the configured hostname and ports
return protected_uri_with_hostname if internal?(uri)
validate_local_request(
normalized_hostname: normalized_hostname,
address_info: address_info,
allow_localhost: allow_localhost,
allow_local_network: allow_local_network
......@@ -83,10 +86,7 @@ module Gitlab
#
# The original hostname is used to validate the SSL, given in that scenario
# we'll be making the request to the IP address, instead of using the hostname.
def enforce_uri_hostname(addrs_info, uri, hostname, dns_rebind_protection)
address = addrs_info.first
ip_address = address&.ip_address
def enforce_uri_hostname(ip_address, uri, hostname, dns_rebind_protection)
return [uri, nil] unless dns_rebind_protection && ip_address && ip_address != hostname
uri = uri.dup
......@@ -94,6 +94,10 @@ module Gitlab
[uri, hostname]
end
def ip_address(address_info)
address_info.first&.ip_address
end
def validate_uri(uri:, schemes:, ports:, enforce_sanitization:, enforce_user:, ascii_only:)
validate_html_tags(uri) if enforce_sanitization
......@@ -113,9 +117,19 @@ module Gitlab
rescue SocketError
end
def validate_local_request(address_info:, allow_localhost:, allow_local_network:)
def validate_local_request(
normalized_hostname:,
address_info:,
allow_localhost:,
allow_local_network:)
return if allow_local_network && allow_localhost
ip_whitelist, domain_whitelist =
Gitlab::CurrentSettings.outbound_local_requests_whitelist_arrays
return if local_domain_whitelisted?(domain_whitelist, normalized_hostname) ||
local_ip_whitelisted?(ip_whitelist, ip_address(address_info))
unless allow_localhost
validate_localhost(address_info)
validate_loopback(address_info)
......@@ -231,6 +245,16 @@ module Gitlab
(uri.port.blank? || uri.port == config.gitlab_shell.ssh_port)
end
def local_ip_whitelisted?(ip_whitelist, ip_string)
ip_obj = Gitlab::Utils.string_to_ip_object(ip_string)
ip_whitelist.any? { |ip| ip.include?(ip_obj) }
end
def local_domain_whitelisted?(domain_whitelist, domain_string)
domain_whitelist.include?(domain_string)
end
def config
Gitlab.config
end
......
......@@ -131,5 +131,12 @@ module Gitlab
data
end
end
def string_to_ip_object(str)
return unless str
IPAddr.new(str)
rescue IPAddr::InvalidAddressError
end
end
end
......@@ -11777,6 +11777,9 @@ msgstr ""
msgid "Requests Profiles"
msgstr ""
msgid "Requests to these domain(s)/address(es) on the local network will be allowed when local requests from hooks and services are disabled. 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 whitelist can hold a maximum of 4000 entries. Domains should use IDNA encoding. Ex: domain.com, 192.168.1.1, 127.0.0.0/28."
msgstr ""
msgid "Require all users in this group to setup Two-factor authentication"
msgstr ""
......@@ -15957,6 +15960,9 @@ msgstr ""
msgid "White helpers give contextual information."
msgstr ""
msgid "Whitelist to allow requests to the local network from hooks and services"
msgstr ""
msgid "Who can see this group?"
msgstr ""
......@@ -17109,6 +17115,9 @@ msgstr ""
msgid "is not an email you own"
msgstr ""
msgid "is too long (maximum is 1000 entries)"
msgstr ""
msgid "issue"
msgstr ""
......
......@@ -220,53 +220,53 @@ describe Gitlab::UrlBlocker do
end
let(:fake_domain) { 'www.fakedomain.fake' }
context 'true (default)' do
shared_examples 'allows local requests' do |url_blocker_attributes|
it 'does not block urls from private networks' do
local_ips.each do |ip|
stub_domain_resolv(fake_domain, ip)
expect(described_class).not_to be_blocked_url("http://#{fake_domain}")
unstub_domain_resolv
stub_domain_resolv(fake_domain, ip) do
expect(described_class).not_to be_blocked_url("http://#{fake_domain}", url_blocker_attributes)
end
expect(described_class).not_to be_blocked_url("http://#{ip}")
expect(described_class).not_to be_blocked_url("http://#{ip}", url_blocker_attributes)
end
end
it 'allows localhost endpoints' do
expect(described_class).not_to be_blocked_url('http://0.0.0.0', allow_localhost: true)
expect(described_class).not_to be_blocked_url('http://localhost', allow_localhost: true)
expect(described_class).not_to be_blocked_url('http://127.0.0.1', allow_localhost: true)
expect(described_class).not_to be_blocked_url('http://0.0.0.0', url_blocker_attributes)
expect(described_class).not_to be_blocked_url('http://localhost', url_blocker_attributes)
expect(described_class).not_to be_blocked_url('http://127.0.0.1', url_blocker_attributes)
end
it 'allows loopback endpoints' do
expect(described_class).not_to be_blocked_url('http://127.0.0.2', allow_localhost: true)
expect(described_class).not_to be_blocked_url('http://127.0.0.2', url_blocker_attributes)
end
it 'allows IPv4 link-local endpoints' do
expect(described_class).not_to be_blocked_url('http://169.254.169.254')
expect(described_class).not_to be_blocked_url('http://169.254.168.100')
expect(described_class).not_to be_blocked_url('http://169.254.169.254', url_blocker_attributes)
expect(described_class).not_to be_blocked_url('http://169.254.168.100', url_blocker_attributes)
end
it 'allows IPv6 link-local endpoints' do
expect(described_class).not_to be_blocked_url('http://[0:0:0:0:0:ffff:169.254.169.254]')
expect(described_class).not_to be_blocked_url('http://[::ffff:169.254.169.254]')
expect(described_class).not_to be_blocked_url('http://[::ffff:a9fe:a9fe]')
expect(described_class).not_to be_blocked_url('http://[0:0:0:0:0:ffff:169.254.168.100]')
expect(described_class).not_to be_blocked_url('http://[::ffff:169.254.168.100]')
expect(described_class).not_to be_blocked_url('http://[::ffff:a9fe:a864]')
expect(described_class).not_to be_blocked_url('http://[fe80::c800:eff:fe74:8]')
expect(described_class).not_to be_blocked_url('http://[0:0:0:0:0:ffff:169.254.169.254]', url_blocker_attributes)
expect(described_class).not_to be_blocked_url('http://[::ffff:169.254.169.254]', url_blocker_attributes)
expect(described_class).not_to be_blocked_url('http://[::ffff:a9fe:a9fe]', url_blocker_attributes)
expect(described_class).not_to be_blocked_url('http://[0:0:0:0:0:ffff:169.254.168.100]', url_blocker_attributes)
expect(described_class).not_to be_blocked_url('http://[::ffff:169.254.168.100]', url_blocker_attributes)
expect(described_class).not_to be_blocked_url('http://[::ffff:a9fe:a864]', url_blocker_attributes)
expect(described_class).not_to be_blocked_url('http://[fe80::c800:eff:fe74:8]', url_blocker_attributes)
end
end
context 'true (default)' do
it_behaves_like 'allows local requests', { allow_localhost: true, allow_local_network: true }
end
context 'false' do
it 'blocks urls from private networks' do
local_ips.each do |ip|
stub_domain_resolv(fake_domain, ip)
expect(described_class).to be_blocked_url("http://#{fake_domain}", allow_local_network: false)
unstub_domain_resolv
stub_domain_resolv(fake_domain, ip) do
expect(described_class).to be_blocked_url("http://#{fake_domain}", allow_local_network: false)
end
expect(described_class).to be_blocked_url("http://#{ip}", allow_local_network: false)
end
......@@ -286,15 +286,169 @@ describe Gitlab::UrlBlocker do
expect(described_class).to be_blocked_url('http://[::ffff:a9fe:a864]', allow_local_network: false)
expect(described_class).to be_blocked_url('http://[fe80::c800:eff:fe74:8]', allow_local_network: false)
end
context 'when local domain/IP is whitelisted' do
let(:url_blocker_attributes) do
{
allow_localhost: false,
allow_local_network: false
}
end
before do
stub_application_setting(outbound_local_requests_whitelist: whitelist)
end
context 'with IPs in whitelist' do
let(:whitelist) do
[
'0.0.0.0',
'127.0.0.1',
'127.0.0.2',
'192.168.1.1',
'192.168.1.2',
'0:0:0:0:0:ffff:192.168.1.2',
'::ffff:c0a8:102',
'10.0.0.2',
'0:0:0:0:0:ffff:10.0.0.2',
'::ffff:a00:2',
'172.16.0.2',
'0:0:0:0:0:ffff:172.16.0.2',
'::ffff:ac10:20',
'feef::1',
'fee2::',
'fc00:bf8b:e62c:abcd:abcd:aaaa:aaaa:aaaa',
'0:0:0:0:0:ffff:169.254.169.254',
'::ffff:a9fe:a9fe',
'::ffff:169.254.168.100',
'::ffff:a9fe:a864',
'fe80::c800:eff:fe74:8',
# garbage IPs
'45645632345',
'garbage456:more345gar:bage'
]
end
it_behaves_like 'allows local requests', { allow_localhost: false, allow_local_network: false }
it 'whitelists IP when dns_rebind_protection is disabled' do
stub_domain_resolv('example.com', '192.168.1.1') do
expect(described_class).not_to be_blocked_url("http://example.com",
url_blocker_attributes.merge(dns_rebind_protection: false))
end
end
end
context 'with domains in whitelist' do
let(:whitelist) do
[
'www.example.com',
'example.com',
'xn--itlab-j1a.com',
'garbage$^$%#$^&$'
]
end
it 'allows domains present in whitelist' do
domain = 'example.com'
subdomain1 = 'www.example.com'
subdomain2 = 'subdomain.example.com'
stub_domain_resolv(domain, '192.168.1.1') do
expect(described_class).not_to be_blocked_url("http://#{domain}",
url_blocker_attributes)
end
stub_domain_resolv(subdomain1, '192.168.1.1') do
expect(described_class).not_to be_blocked_url("http://#{subdomain1}",
url_blocker_attributes)
end
# subdomain2 is not part of the whitelist so it should be blocked
stub_domain_resolv(subdomain2, '192.168.1.1') do
expect(described_class).to be_blocked_url("http://#{subdomain2}",
url_blocker_attributes)
end
end
it 'works with unicode and idna encoded domains' do
unicode_domain = 'ğitlab.com'
idna_encoded_domain = 'xn--itlab-j1a.com'
stub_domain_resolv(unicode_domain, '192.168.1.1') do
expect(described_class).not_to be_blocked_url("http://#{unicode_domain}",
url_blocker_attributes)
end
stub_domain_resolv(idna_encoded_domain, '192.168.1.1') do
expect(described_class).not_to be_blocked_url("http://#{idna_encoded_domain}",
url_blocker_attributes)
end
end
end
context 'with ip ranges in whitelist' do
let(:ipv4_range) { '127.0.0.0/28' }
let(:ipv6_range) { 'fd84:6d02:f6d8:c89e::/124' }
let(:whitelist) do
[
ipv4_range,
ipv6_range
]
end
it 'blocks ipv4 range when not in whitelist' do
stub_application_setting(outbound_local_requests_whitelist: [])
IPAddr.new(ipv4_range).to_range.to_a.each do |ip|
expect(described_class).to be_blocked_url("http://#{ip}",
url_blocker_attributes)
end
end
it 'allows all ipv4s in the range when in whitelist' do
IPAddr.new(ipv4_range).to_range.to_a.each do |ip|
expect(described_class).not_to be_blocked_url("http://#{ip}",
url_blocker_attributes)
end
end
it 'blocks ipv6 range when not in whitelist' do
stub_application_setting(outbound_local_requests_whitelist: [])
IPAddr.new(ipv6_range).to_range.to_a.each do |ip|
expect(described_class).to be_blocked_url("http://[#{ip}]",
url_blocker_attributes)
end
end
it 'allows all ipv6s in the range when in whitelist' do
IPAddr.new(ipv6_range).to_range.to_a.each do |ip|
expect(described_class).not_to be_blocked_url("http://[#{ip}]",
url_blocker_attributes)
end
end
it 'blocks IPs outside the range' do
expect(described_class).to be_blocked_url("http://[fd84:6d02:f6d8:c89e:0:0:1:f]",
url_blocker_attributes)
expect(described_class).to be_blocked_url("http://127.0.1.15",
url_blocker_attributes)
end
end
end
end
def stub_domain_resolv(domain, ip)
def stub_domain_resolv(domain, ip, &block)
address = double(ip_address: ip, ipv4_private?: true, ipv6_link_local?: false, ipv4_loopback?: false, ipv6_loopback?: false, ipv4?: false)
allow(Addrinfo).to receive(:getaddrinfo).with(domain, any_args).and_return([address])
allow(address).to receive(:ipv6_v4mapped?).and_return(false)
end
def unstub_domain_resolv
yield
allow(Addrinfo).to receive(:getaddrinfo).and_call_original
end
end
......
......@@ -231,4 +231,23 @@ describe Gitlab::Utils do
end
end
end
describe '.string_to_ip_object' do
it 'returns nil when string is nil' do
expect(described_class.string_to_ip_object(nil)).to eq(nil)
end
it 'returns nil when string is invalid IP' do
expect(described_class.string_to_ip_object('invalid ip')).to eq(nil)
expect(described_class.string_to_ip_object('')).to eq(nil)
end
it 'returns IP object when string is valid IP' do
expect(described_class.string_to_ip_object('192.168.1.1')).to eq(IPAddr.new('192.168.1.1'))
expect(described_class.string_to_ip_object('::ffff:a9fe:a864')).to eq(IPAddr.new('::ffff:a9fe:a864'))
expect(described_class.string_to_ip_object('[::ffff:a9fe:a864]')).to eq(IPAddr.new('::ffff:a9fe:a864'))
expect(described_class.string_to_ip_object('127.0.0.0/28')).to eq(IPAddr.new('127.0.0.0/28'))
expect(described_class.string_to_ip_object('1:0:0:0:0:0:0:0/124')).to eq(IPAddr.new('1:0:0:0:0:0:0:0/124'))
end
end
end
......@@ -37,6 +37,17 @@ describe ApplicationSetting do
it { is_expected.not_to allow_value("myemail@example.com").for(:lets_encrypt_notification_email) }
it { is_expected.to allow_value("myemail@test.example.com").for(:lets_encrypt_notification_email) }
it { is_expected.to allow_value(['192.168.1.1'] * 1_000).for(:outbound_local_requests_whitelist) }
it { is_expected.not_to allow_value(['192.168.1.1'] * 1_001).for(:outbound_local_requests_whitelist) }
it { is_expected.to allow_value(['1' * 255]).for(:outbound_local_requests_whitelist) }
it { is_expected.not_to allow_value(['1' * 256]).for(:outbound_local_requests_whitelist) }
it { is_expected.not_to allow_value(['ğitlab.com']).for(:outbound_local_requests_whitelist) }
it { is_expected.to allow_value(['xn--itlab-j1a.com']).for(:outbound_local_requests_whitelist) }
it { is_expected.not_to allow_value(['<h1></h1>']).for(:outbound_local_requests_whitelist) }
it { is_expected.to allow_value(['gitlab.com']).for(:outbound_local_requests_whitelist) }
it { is_expected.to allow_value(nil).for(:outbound_local_requests_whitelist) }
it { is_expected.to allow_value([]).for(:outbound_local_requests_whitelist) }
context "when user accepted let's encrypt terms of service" do
before do
setting.update(lets_encrypt_terms_of_service_accepted: true)
......
# frozen_string_literal: true
RSpec.shared_examples 'application settings examples' do
context 'restricted signup domains' do
it 'sets single domain' do
setting.domain_whitelist_raw = 'example.com'
expect(setting.domain_whitelist).to eq(['example.com'])
end
RSpec.shared_examples 'string of domains' do |attribute|
it 'sets single domain' do
setting.method("#{attribute}_raw=").call('example.com')
expect(setting.method(attribute).call).to eq(['example.com'])
end
it 'sets multiple domains with spaces' do
setting.domain_whitelist_raw = 'example.com *.example.com'
expect(setting.domain_whitelist).to eq(['example.com', '*.example.com'])
end
it 'sets multiple domains with spaces' do
setting.method("#{attribute}_raw=").call('example.com *.example.com')
expect(setting.method(attribute).call).to eq(['example.com', '*.example.com'])
end
it 'sets multiple domains with newlines and a space' do
setting.domain_whitelist_raw = "example.com\n *.example.com"
expect(setting.domain_whitelist).to eq(['example.com', '*.example.com'])
end
it 'sets multiple domains with newlines and a space' do
setting.method("#{attribute}_raw=").call("example.com\n *.example.com")
expect(setting.method(attribute).call).to eq(['example.com', '*.example.com'])
end
it 'sets multiple domains with commas' do
setting.domain_whitelist_raw = "example.com, *.example.com"
expect(setting.domain_whitelist).to eq(['example.com', '*.example.com'])
end
it 'sets multiple domains with commas' do
setting.method("#{attribute}_raw=").call("example.com, *.example.com")
expect(setting.method(attribute).call).to eq(['example.com', '*.example.com'])
end
context 'blacklisted signup domains' do
it 'sets single domain' do
setting.domain_blacklist_raw = 'example.com'
expect(setting.domain_blacklist).to contain_exactly('example.com')
end
it 'sets multiple domains with semicolon' do
setting.method("#{attribute}_raw=").call("example.com; *.example.com")
expect(setting.method(attribute).call).to contain_exactly('example.com', '*.example.com')
end
it 'sets multiple domains with spaces' do
setting.domain_blacklist_raw = 'example.com *.example.com'
expect(setting.domain_blacklist).to contain_exactly('example.com', '*.example.com')
end
it 'sets multiple domains with mixture of everything' do
setting.method("#{attribute}_raw=").call("example.com; *.example.com\n test.com\sblock.com yes.com")
expect(setting.method(attribute).call).to contain_exactly('example.com', '*.example.com', 'test.com', 'block.com', 'yes.com')
end
it 'sets multiple domains with newlines and a space' do
setting.domain_blacklist_raw = "example.com\n *.example.com"
expect(setting.domain_blacklist).to contain_exactly('example.com', '*.example.com')
end
it 'removes duplicates' do
setting.method("#{attribute}_raw=").call("example.com; example.com; 127.0.0.1; 127.0.0.1")
expect(setting.method(attribute).call).to contain_exactly('example.com', '127.0.0.1')
end
it 'sets multiple domains with commas' do
setting.domain_blacklist_raw = "example.com, *.example.com"
expect(setting.domain_blacklist).to contain_exactly('example.com', '*.example.com')
end
it 'does not fail with garbage values' do
setting.method("#{attribute}_raw=").call("example;34543:garbage:fdh5654;")
expect(setting.method(attribute).call).to contain_exactly('example', '34543:garbage:fdh5654')
end
end
it 'sets multiple domains with semicolon' do
setting.domain_blacklist_raw = "example.com; *.example.com"
expect(setting.domain_blacklist).to contain_exactly('example.com', '*.example.com')
end
RSpec.shared_examples 'application settings examples' do
context 'restricted signup domains' do
it_behaves_like 'string of domains', :domain_whitelist
end
it 'sets multiple domains with mixture of everything' do
setting.domain_blacklist_raw = "example.com; *.example.com\n test.com\sblock.com yes.com"
expect(setting.domain_blacklist).to contain_exactly('example.com', '*.example.com', 'test.com', 'block.com', 'yes.com')
end
context 'blacklisted signup domains' do
it_behaves_like 'string of domains', :domain_blacklist
it 'sets multiple domain with file' do
setting.domain_blacklist_file = File.open(Rails.root.join('spec/fixtures/', 'domain_blacklist.txt'))
......@@ -60,6 +56,27 @@ RSpec.shared_examples 'application settings examples' do
end
end
context 'outbound_local_requests_whitelist' do
it_behaves_like 'string of domains', :outbound_local_requests_whitelist
end
context 'outbound_local_requests_whitelist_arrays' do
it 'separates the IPs and domains' do
setting.outbound_local_requests_whitelist = [
'192.168.1.1', '127.0.0.0/28', 'www.example.com', 'example.com',
'::ffff:a00:2', '1:0:0:0:0:0:0:0/124', 'subdomain.example.com'
]
ip_whitelist = [
IPAddr.new('192.168.1.1'), IPAddr.new('127.0.0.0/8'),
IPAddr.new('::ffff:a00:2'), IPAddr.new('1:0:0:0:0:0:0:0/124')
]
domain_whitelist = ['www.example.com', 'example.com', 'subdomain.example.com']
expect(setting.outbound_local_requests_whitelist_arrays).to contain_exactly(ip_whitelist, domain_whitelist)
end
end
describe 'usage ping settings' do
context 'when the usage ping is disabled in gitlab.yml' do
before do
......
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