- Переименовано Nextcloud на F7cloud - Добавлены зависимости Firefox ESR и Geckodriver - Создан скрипт установки с поддержкой параметров HPB - Добавлена документация и инструкции по установке Co-authored-by: Cursor <cursoragent@cursor.com>
415 lines
12 KiB
Python
415 lines
12 KiB
Python
#
|
|
# SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
|
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
#
|
|
|
|
# pylint: disable=missing-docstring
|
|
|
|
import sys
|
|
from ipaddress import ip_address, ip_network
|
|
|
|
import pytest
|
|
|
|
# pulsectl tries to load the PulseAudio library on initialization, so a fake
|
|
# module is set instead to prevent a failure when (indirectly) importing it if
|
|
# the library is not installed in the system.
|
|
sys.modules['pulsectl'] = {}
|
|
|
|
# pylint: disable=wrong-import-position
|
|
from f7cloud.talk.recording.Server import isAddressInNetworks, TrustedProxiesFix
|
|
|
|
@pytest.mark.parametrize('address, networks, expectedResult', [
|
|
('192.168.57.42', [], False),
|
|
('192.168.57.42', ['192.168.58.0/24'], False),
|
|
('192.168.57.42', ['192.168.57.0/24'], True),
|
|
('2001:db8::abc', [], False),
|
|
('2001:db8::abc', ['2001:db8::b00/120'], False),
|
|
('2001:db8::abc', ['2001:db8::a00/120'], True),
|
|
('192.168.57.42', ['192.168.58.0/24', '2001:db8::a00/120', '192.168.57.42', '2001:db8::b00/120'], True),
|
|
('192.168.59.42', ['192.168.58.0/24', '2001:db8::a00/120', '192.168.57.42', '2001:db8::b00/120'], False),
|
|
('2001:db8::abc', ['192.168.58.0/24', '2001:db8::a00/120', '192.168.57.42', '2001:db8::b00/120'], True),
|
|
('2001:db8::cbc', ['192.168.58.0/24', '2001:db8::a00/120', '192.168.57.42', '2001:db8::b00/120'], False),
|
|
])
|
|
def testIsAddressInNetworks(address, networks, expectedResult):
|
|
address = ip_address(address)
|
|
networks = [ip_network(network) for network in networks]
|
|
|
|
assert isAddressInNetworks(address, networks) == expectedResult
|
|
|
|
class TrustedProxiesFixTest:
|
|
|
|
@pytest.fixture
|
|
def fakeConfig(self):
|
|
class FakeConfig:
|
|
def __init__(self):
|
|
self.trustedProxies = []
|
|
|
|
def getTrustedProxies(self):
|
|
return self.trustedProxies
|
|
|
|
return FakeConfig()
|
|
|
|
@pytest.mark.parametrize('remoteAddress, xForwardedFor, trustedProxies, expectedRemoteAddress', [
|
|
# No trusted proxy
|
|
(
|
|
'4.8.15.16',
|
|
'',
|
|
'',
|
|
'4.8.15.16'
|
|
),
|
|
(
|
|
'4.8.15.16',
|
|
'23.42.108.0',
|
|
'',
|
|
'4.8.15.16'
|
|
),
|
|
(
|
|
'4.8.15.16',
|
|
'23.42.108.0, 10.11.12.13',
|
|
'',
|
|
'4.8.15.16'
|
|
),
|
|
(
|
|
'4.8.15.16:12345',
|
|
'',
|
|
'',
|
|
'4.8.15.16:12345'
|
|
),
|
|
(
|
|
'2001:db8:4815::16',
|
|
'',
|
|
'',
|
|
'2001:db8:4815::16'
|
|
),
|
|
(
|
|
'2001:db8:4815::16',
|
|
'2001:db8:2342::108',
|
|
'',
|
|
'2001:db8:4815::16'
|
|
),
|
|
(
|
|
'2001:db8:4815::16',
|
|
'2001:db8:2342::108, 2001:db8:1011::1213',
|
|
'',
|
|
'2001:db8:4815::16'
|
|
),
|
|
(
|
|
'[2001:db8:4815::16]:12345',
|
|
'',
|
|
'',
|
|
'[2001:db8:4815::16]:12345'
|
|
),
|
|
(
|
|
'4.8.15.16',
|
|
'2001:db8:2342::108',
|
|
'',
|
|
'4.8.15.16'
|
|
),
|
|
(
|
|
'2001:db8:4815::16',
|
|
'23.42.108.0',
|
|
'',
|
|
'2001:db8:4815::16'
|
|
),
|
|
# Trusted proxy not matching remote address
|
|
(
|
|
'4.8.15.16',
|
|
'',
|
|
'10.11.12.13',
|
|
'4.8.15.16'
|
|
),
|
|
(
|
|
'4.8.15.16',
|
|
'10.11.12.13',
|
|
'10.11.12.13',
|
|
'4.8.15.16'
|
|
),
|
|
(
|
|
'4.8.15.16',
|
|
'23.42.108.0',
|
|
'10.11.12.13',
|
|
'4.8.15.16'
|
|
),
|
|
(
|
|
'4.8.15.16',
|
|
'23.42.108.0, 10.11.12.13',
|
|
'10.11.12.13',
|
|
'4.8.15.16'
|
|
),
|
|
(
|
|
'4.8.15.16',
|
|
'23.42.108.0, 10.11.12.13',
|
|
'4.8.16.0/24, 10.11.12.13',
|
|
'4.8.15.16'
|
|
),
|
|
(
|
|
'4.8.15.16:12345',
|
|
'',
|
|
'10.11.12.13',
|
|
'4.8.15.16:12345'
|
|
),
|
|
(
|
|
'2001:db8:4815::16',
|
|
'2001:db8:1011::1213',
|
|
'2001:db8:1011::1213',
|
|
'2001:db8:4815::16'
|
|
),
|
|
(
|
|
'2001:db8:4815::16',
|
|
'2001:db8:2342::108, 2001:db8:1011::1213',
|
|
'2001:db8:4816::0/48, 2001:db8:1011::1213',
|
|
'2001:db8:4815::16'
|
|
),
|
|
(
|
|
'[2001:db8:4815::16]:12345',
|
|
'2001:db8:1011::1213',
|
|
'2001:db8:1011::1213',
|
|
'[2001:db8:4815::16]:12345'
|
|
),
|
|
(
|
|
'4.8.15.16',
|
|
'23.42.108.0, 2001:db8:1011::1213',
|
|
'2001:db8:1011::1213',
|
|
'4.8.15.16'
|
|
),
|
|
(
|
|
'2001:db8:4815::16',
|
|
'2001:db8:2342::108, 10.11.12.13',
|
|
'10.11.12.13',
|
|
'2001:db8:4815::16'
|
|
),
|
|
# Trusted proxy matching remote address
|
|
(
|
|
'4.8.15.16',
|
|
'',
|
|
'4.8.15.16',
|
|
'4.8.15.16'
|
|
),
|
|
(
|
|
'4.8.15.16',
|
|
'23.42.108.0',
|
|
'4.8.15.16',
|
|
'23.42.108.0'
|
|
),
|
|
(
|
|
'4.8.15.16',
|
|
'23.42.108.0',
|
|
'4.8.15.0/24',
|
|
'23.42.108.0'
|
|
),
|
|
(
|
|
'4.8.15.16',
|
|
'23.42.108.0',
|
|
'10.11.12.13, 4.8.15.0/24',
|
|
'23.42.108.0'
|
|
),
|
|
(
|
|
'4.8.15.16',
|
|
'23.42.108.0',
|
|
'10.11.12.13, 4.8.15.0/24, 10.11.12.14',
|
|
'23.42.108.0'
|
|
),
|
|
(
|
|
'4.8.15.16',
|
|
'10.11.12.13, 23.42.108.0',
|
|
'4.8.15.16',
|
|
'23.42.108.0'
|
|
),
|
|
(
|
|
'2001:db8:4815::16',
|
|
'2001:db8:2342::108',
|
|
'2001:db8:4815::16',
|
|
'2001:db8:2342::108'
|
|
),
|
|
(
|
|
'4.8.15.16',
|
|
'2001:db8:2342::108',
|
|
'4.8.15.0/24',
|
|
'2001:db8:2342::108'
|
|
),
|
|
(
|
|
'2001:db8:4815::16',
|
|
'23.42.108.0',
|
|
'2001:db8:4815::0/112',
|
|
'23.42.108.0'
|
|
),
|
|
# Trusted proxy matching remote address and forwarded header
|
|
(
|
|
'4.8.15.16',
|
|
'23.42.108.0',
|
|
'4.8.15.16, 23.42.108.0',
|
|
'23.42.108.0'
|
|
),
|
|
(
|
|
'4.8.15.16',
|
|
'23.42.108.0, 4.8.15.108',
|
|
'4.8.15.0/24',
|
|
'23.42.108.0'
|
|
),
|
|
(
|
|
'4.8.15.16',
|
|
'23.42.108.0, 10.11.12.13',
|
|
'4.8.15.16, 10.11.12.13',
|
|
'23.42.108.0'
|
|
),
|
|
(
|
|
'4.8.15.16',
|
|
'23.42.108.0, 10.11.12.13',
|
|
'10.11.12.13, 4.8.15.16',
|
|
'23.42.108.0'
|
|
),
|
|
(
|
|
'4.8.15.16',
|
|
'10.11.12.13, 23.42.108.0',
|
|
'4.8.15.16, 10.11.12.13',
|
|
'23.42.108.0'
|
|
),
|
|
(
|
|
'4.8.15.16',
|
|
'23.42.108.0, 10.11.12.13',
|
|
'4.8.15.16, 10.11.12.0/24',
|
|
'23.42.108.0'
|
|
),
|
|
(
|
|
'4.8.15.16',
|
|
'10.11.12.15, 23.42.108.0, 10.11.12.14, 10.11.12.13',
|
|
'4.8.15.16, 10.11.12.0/24',
|
|
'23.42.108.0'
|
|
),
|
|
(
|
|
'4.8.15.16',
|
|
'10.11.12.15, 23.42.108.0, 10.11.12.14, 10.11.12.13',
|
|
'4.8.15.16, 10.11.12.13, 10.11.12.14, 10.11.12.15',
|
|
'23.42.108.0'
|
|
),
|
|
(
|
|
'4.8.15.16:12345',
|
|
'10.11.12.15:23456, 23.42.108.0:34567, 10.11.12.14:45678, 10.11.12.13:56789',
|
|
'4.8.15.16, 10.11.12.13, 10.11.12.14, 10.11.12.15',
|
|
'23.42.108.0'
|
|
),
|
|
(
|
|
'2001:db8:4815::16',
|
|
'2001:db8:2342::108',
|
|
'2001:db8:4815::16, 2001:db8:2342::108',
|
|
'2001:db8:2342::108'
|
|
),
|
|
(
|
|
'2001:db8:4815::16',
|
|
'2001:db8:1011::1215, 2001:db8:2342::108, 2001:db8:1011::1214, 2001:db8:1011::1213',
|
|
'2001:db8:1011::0/48, 2001:db8:4815::16',
|
|
'2001:db8:2342::108'
|
|
),
|
|
(
|
|
'4.8.15.16',
|
|
'10.11.12.15, 2001:db8:2342::108, 10.11.12.14, 2001:db8:1011::1213',
|
|
'2001:db8:1011::0/48, 4.8.15.16, 10.11.12.14',
|
|
'2001:db8:2342::108'
|
|
),
|
|
(
|
|
'2001:db8:4815::16',
|
|
'10.11.12.15, 23.42.108.0, 2001:db8:1011::1214, 10.11.12.13',
|
|
'10.11.12.13, 2001:db8::0/32',
|
|
'23.42.108.0'
|
|
),
|
|
(
|
|
'[2001:db8:4815::16]:12345',
|
|
'10.11.12.15:23456, 23.42.108.0:34567, [2001:db8:1112::1314], [2001:db8:1011::1214]:45678, 10.11.12.13:56789',
|
|
'10.11.12.13, 2001:db8::0/32',
|
|
'23.42.108.0'
|
|
),
|
|
# Invalid IP in forwarded header
|
|
(
|
|
'4.8.15.16',
|
|
'not-an-ip',
|
|
'4.8.15.0/24',
|
|
'4.8.15.16'
|
|
),
|
|
(
|
|
'4.8.15.16',
|
|
'23.42.108.0, not-an-ip',
|
|
'4.8.15.0/24',
|
|
'4.8.15.16'
|
|
),
|
|
(
|
|
'4.8.15.16',
|
|
'23.42.108.0, not-an-ip, 4.8.15.108',
|
|
'4.8.15.0/24',
|
|
'4.8.15.108'
|
|
),
|
|
(
|
|
'2001:db8:4815::16',
|
|
'2001:db8:2342::108, not-an-ip, 2001:db8:4815::108',
|
|
'2001:db8:4815::0/112',
|
|
'2001:db8:4815::108'
|
|
),
|
|
(
|
|
'4.8.15.16',
|
|
'23.42.108.0, not-an-ip, 2001:db8:4815::108',
|
|
'4.8.15.16, 2001:db8:4815::108',
|
|
'2001:db8:4815::108'
|
|
),
|
|
(
|
|
'2001:db8:4815::16',
|
|
'2001:db8:2342::108, not-an-ip, 4.8.15.108',
|
|
'2001:db8:4815::16, 4.8.15.108',
|
|
'4.8.15.108'
|
|
),
|
|
(
|
|
'2001:db8:4815::16',
|
|
',,not-an-ip,,2001:db8:2342::108,,, , 4.8.15.108 ',
|
|
'2001:db8:4815::16, 4.8.15.108',
|
|
'4.8.15.108'
|
|
),
|
|
])
|
|
def testGetRemoteAddress(self, fakeConfig, remoteAddress, xForwardedFor, trustedProxies, expectedRemoteAddress):
|
|
environment = {
|
|
'REMOTE_ADDR': remoteAddress,
|
|
}
|
|
if xForwardedFor:
|
|
environment['HTTP_X_FORWARDED_FOR'] = xForwardedFor
|
|
|
|
trustedProxies = [ip_network(trustedProxy.strip()) for trustedProxy in trustedProxies.split(',') if trustedProxy]
|
|
fakeConfig.trustedProxies = trustedProxies
|
|
|
|
trustedProxiesFix = TrustedProxiesFix(None, fakeConfig)
|
|
|
|
assert trustedProxiesFix.getRemoteAddress(environment) == expectedRemoteAddress
|
|
|
|
def testGetRemoteAddressWithoutOriginalRemoteAddress(self, fakeConfig):
|
|
trustedProxiesFix = TrustedProxiesFix(None, fakeConfig)
|
|
|
|
with pytest.raises(ValueError):
|
|
trustedProxiesFix.getRemoteAddress({})
|
|
|
|
def testGetRemoteAddressWithEmptyOriginalRemoteAddress(self, fakeConfig):
|
|
trustedProxiesFix = TrustedProxiesFix(None, fakeConfig)
|
|
|
|
with pytest.raises(ValueError):
|
|
trustedProxiesFix.getRemoteAddress({
|
|
'REMOTE_ADDR': '',
|
|
})
|
|
|
|
@pytest.mark.parametrize('address, expectedAddress', [
|
|
('192.168.0.42', '192.168.0.42'),
|
|
('192.168.0.42:12345', '192.168.0.42'),
|
|
('::1', '::1'),
|
|
('2001:db8::0', '2001:db8::0'),
|
|
('2001:0db8:1234:5678:90ab:cdef:1234:5678', '2001:0db8:1234:5678:90ab:cdef:1234:5678'),
|
|
('[::1]', '::1'),
|
|
('[2001:db8::0]', '2001:db8::0'),
|
|
('[2001:0db8:1234:5678:90ab:cdef:1234:5678]', '2001:0db8:1234:5678:90ab:cdef:1234:5678'),
|
|
('[::1]:12345', '::1'),
|
|
('[2001:db8::0]:12345', '2001:db8::0'),
|
|
('[2001:0db8:1234:5678:90ab:cdef:1234:5678]:12345', '2001:0db8:1234:5678:90ab:cdef:1234:5678'),
|
|
('not-an-ip', 'not-an-ip'),
|
|
('not-an-ip:at-all', 'not-an-ip'),
|
|
('not:an:ip::at-all', 'not:an:ip::at-all'),
|
|
('[not:an:ip][very][::weird]', 'not:an:ip][very][::weird'),
|
|
])
|
|
def testGetAddressWithoutPort(self, fakeConfig, address, expectedAddress):
|
|
trustedProxiesFix = TrustedProxiesFix(None, fakeConfig)
|
|
|
|
# pylint: disable=protected-access
|
|
assert trustedProxiesFix._getAddressWithoutPort(address) == expectedAddress
|