From cf0e747d512d665db210e838840c8d1f90ba340f Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sat, 29 Jul 2023 16:22:40 +0200 Subject: [PATCH] [ticket/9687] Add tests for ban manager and fix some inconsistencies PHPBB3-9687 --- phpBB/phpbb/ban/manager.php | 34 +- phpBB/phpbb/ban/type/base.php | 10 +- phpBB/phpbb/ban/type/email.php | 6 +- phpBB/phpbb/ban/type/ip.php | 20 +- phpBB/phpbb/ban/type/user.php | 6 +- tests/ban/ban_manager_test.php | 699 +++++++++++++++++++ tests/ban/fixtures/sessions_banlist.xml | 161 +++++ tests/bootstrap.php | 2 + tests/functions/validate_user_email_test.php | 2 +- tests/session/check_ban_test.php | 7 +- tests/session/testable_factory.php | 6 +- 11 files changed, 914 insertions(+), 39 deletions(-) create mode 100644 tests/ban/ban_manager_test.php create mode 100644 tests/ban/fixtures/sessions_banlist.xml diff --git a/phpBB/phpbb/ban/manager.php b/phpBB/phpbb/ban/manager.php index 4dcb3ca397..ab3471a79d 100644 --- a/phpBB/phpbb/ban/manager.php +++ b/phpBB/phpbb/ban/manager.php @@ -76,7 +76,7 @@ class manager * * @return bool */ - public function ban(string $mode, array $items, \DateTimeInterface $start, \DateTimeInterface $end, string $reason, string $display_reason = '') + public function ban(string $mode, array $items, \DateTimeInterface $start, \DateTimeInterface $end, string $reason, string $display_reason = ''): bool { if ($start > $end && $end->getTimestamp() !== 0) { @@ -122,11 +122,7 @@ class manager return false; } - $result = $this->db->sql_multi_insert($this->bans_table, $insert_array); - if ($result === false) - { - throw new ban_insert_failed_exception(); // TODO - } + $this->db->sql_multi_insert($this->bans_table, $insert_array); $ban_data = [ 'items' => $ban_items, @@ -138,7 +134,7 @@ class manager if ($ban_mode->after_ban($ban_data)) { - // TODO + // @todo: Add logging } $this->cache->destroy(self::CACHE_KEY_INFO); @@ -153,7 +149,7 @@ class manager * @param string $mode The ban type in which the ban IDs were created * @param array $items An array of ban IDs which should be removed */ - public function unban($mode, array $items) + public function unban(string $mode, array $items) { /** @var type_interface $ban_mode */ $ban_mode = $this->find_type($mode); @@ -245,7 +241,7 @@ class manager } else { - $regex = str_replace('\*', '.*?', preg_quote($ban_row['item'], '#')); + $regex = '#^' . str_replace('\*', '.*?', preg_quote($ban_row['item'], '#')) . '$#i'; if (preg_match($regex, $user_data[$user_column])) { return $ban_row + ['mode' => $mode]; @@ -279,7 +275,7 @@ class manager $sql = 'SELECT ban_id, ban_item, ban_start, ban_end, ban_reason, ban_reason_display FROM ' . $this->bans_table . " WHERE ban_mode = '" . $this->db->sql_escape($mode) . "' - AND (ban_end <= 0 OR ban_end >= " . (int) time() . ')'; + AND (ban_end = 0 OR ban_end >= " . time() . ')'; $result = $this->db->sql_query($sql); $rowset = $this->db->sql_fetchrowset($result); $this->db->sql_freeresult($result); @@ -294,7 +290,7 @@ class manager * * @return array */ - public function get_banned_users() + public function get_banned_users(): array { $banned_users = $this->cache->get(self::CACHE_KEY_USERS); if ($banned_users === false) @@ -375,10 +371,10 @@ class manager /** * Get ban end * - * @param \DateTimeInterface $ban_start - * @param int $length - * @param string $end_date - * @return \DateTimeInterface + * @param \DateTimeInterface $ban_start Ban start time + * @param int $length Ban length in minutes + * @param string $end_date Ban end date as YYYY-MM-DD string + * @return \DateTimeInterface Ban end as DateTimeInterface instance */ public function get_ban_end(\DateTimeInterface $ban_start, int $length, string $end_date): \DateTimeInterface { @@ -402,7 +398,7 @@ class manager } else { - trigger_error('LENGTH_BAN_INVALID', E_USER_WARNING); + throw new invalid_length_exception(); } } } @@ -434,11 +430,11 @@ class manager * Finds the ban type for the given mode string. * Returns false if none was found * - * @param string $mode The mode string + * @param string $mode The mode string * * @return bool|type\type_interface */ - protected function find_type($mode) + protected function find_type(string $mode) { /** @var type_interface $type */ foreach ($this->types as $type) @@ -461,7 +457,7 @@ class manager * * @return array */ - protected function get_info_cache() + protected function get_info_cache(): array { $ban_info = $this->cache->get(self::CACHE_KEY_INFO); if ($ban_info === false) diff --git a/phpBB/phpbb/ban/type/base.php b/phpBB/phpbb/ban/type/base.php index b5d07afd6b..f404e1bdeb 100644 --- a/phpBB/phpbb/ban/type/base.php +++ b/phpBB/phpbb/ban/type/base.php @@ -107,7 +107,7 @@ abstract class base implements type_interface * * @return bool */ - protected function get_excluded() + protected function get_excluded(): bool { $user_column = $this->get_user_column(); if (empty($user_column)) @@ -119,7 +119,7 @@ abstract class base implements type_interface if (!empty($this->user)) { - $this->excluded[(int) $this->user->data['user_id']] = $this->user->data[$user_column]; + $this->excluded[$this->user->id()] = $this->user->data[$user_column]; } $sql = "SELECT user_id, {$user_column} @@ -143,15 +143,15 @@ abstract class base implements type_interface * * @param array $ban_items * - * @return array + * @return array Logged out users */ - protected function logout_affected_users(array $ban_items) + protected function logout_affected_users(array $ban_items): array { $user_column = $this->get_user_column(); if (empty($user_column)) { - // TODO throw ex (it's a developer exception) + return []; } if ($user_column !== 'user_id') diff --git a/phpBB/phpbb/ban/type/email.php b/phpBB/phpbb/ban/type/email.php index a3e1dd4705..e4c6350b76 100644 --- a/phpBB/phpbb/ban/type/email.php +++ b/phpBB/phpbb/ban/type/email.php @@ -39,10 +39,8 @@ class email extends base */ public function prepare_for_storage(array $items): array { - if (!$this->get_excluded()) - { - throw new runtime_exception(); // TODO - } + $this->get_excluded(); + $regex = '#^.*?@.*|(([a-z0-9\-]+\.)+([a-z]{2,3}))$#i'; // TODO $ban_items = []; diff --git a/phpBB/phpbb/ban/type/ip.php b/phpBB/phpbb/ban/type/ip.php index 22ebce2ec2..d6466c2407 100644 --- a/phpBB/phpbb/ban/type/ip.php +++ b/phpBB/phpbb/ban/type/ip.php @@ -18,6 +18,7 @@ use Symfony\Component\HttpFoundation\IpUtils; class ip extends base { + private const USER_IP = 'user_ip'; /** * @inheritDoc @@ -32,7 +33,7 @@ class ip extends base */ public function get_user_column(): ?string { - return 'user_ip'; + return null; } /** @@ -40,7 +41,20 @@ class ip extends base */ public function check(array $ban_rows, array $user_data) { - return parent::check($ban_rows, $user_data); // TODO: Change the autogenerated stub + if (!isset($user_data[self::USER_IP])) + { + return false; + } + + foreach ($ban_rows as $ip_ban) + { + if (IpUtils::checkIp($user_data[self::USER_IP], $ip_ban['item'])) + { + return $ip_ban; + } + } + + return false; } /** @@ -61,10 +75,12 @@ class ip extends base $ban_items[] = $ip; } + // @codeCoverageIgnoreStart catch (\RuntimeException $exception) { // IPv6 not supported, therefore IPv6 address will not be added } + // @codeCoverageIgnoreEnd } if (empty($ban_items)) diff --git a/phpBB/phpbb/ban/type/user.php b/phpBB/phpbb/ban/type/user.php index c6b94a0388..1b8592e354 100644 --- a/phpBB/phpbb/ban/type/user.php +++ b/phpBB/phpbb/ban/type/user.php @@ -73,10 +73,8 @@ class user extends base */ public function prepare_for_storage(array $items): array { - if (!$this->get_excluded()) - { - throw new runtime_exception(); // TODO - } + // Fill excluded user list + $this->get_excluded(); $sql_usernames = []; $sql_or_like = []; diff --git a/tests/ban/ban_manager_test.php b/tests/ban/ban_manager_test.php new file mode 100644 index 0000000000..13ed2fd201 --- /dev/null +++ b/tests/ban/ban_manager_test.php @@ -0,0 +1,699 @@ +createXMLDataSet(__DIR__ . '/fixtures/sessions_banlist.xml'); + } + + public function setUp(): void + { + parent::setUp(); + + global $config, $phpbb_dispatcher, $phpbb_root_path, $phpEx; + + $language = new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx)); + $user = new \phpbb\user($language, '\phpbb\datetime'); + $user->data['user_id'] = 2; + $user->data['user_email'] = 'foo@bar.com'; + $config = new \phpbb\config\config([]); + $phpbb_dispatcher = new \phpbb_mock_event_dispatcher(); + + // Change the global cache object for this test because + // the mock cache object does not hit the database as is needed + // for this test. + $cache = new \phpbb\cache\service( + new \phpbb\cache\driver\dummy(), + $config, + $this->db, + $phpbb_dispatcher, + $phpbb_root_path, + $phpEx + ); + + $phpbb_container = new \phpbb_mock_container_builder(); + $ban_type_email = new \phpbb\ban\type\email($this->db, 'phpbb_users', 'phpbb_sessions', 'phpbb_sessions_keys'); + $ban_type_user = new \phpbb\ban\type\user($this->db, 'phpbb_users', 'phpbb_sessions', 'phpbb_sessions_keys'); + $ban_type_ip = new \phpbb\ban\type\ip($this->db, 'phpbb_users', 'phpbb_sessions', 'phpbb_sessions_keys'); + $phpbb_container->set('ban.type.email', $ban_type_email); + $phpbb_container->set('ban.type.user', $ban_type_user); + $phpbb_container->set('ban.type.ip', $ban_type_ip); + $collection = new \phpbb\di\service_collection($phpbb_container); + $collection->add('ban.type.email'); + $collection->add('ban.type.user'); + $collection->add('ban.type.ip'); + + $this->ban_manager = new \phpbb\ban\manager($collection, $cache, $this->db, $user, 'phpbb_bans', 'phpbb_users'); + $phpbb_container->set('ban.manager', $this->ban_manager); + $this->phpbb_container = $phpbb_container; + } + + public function data_check_ban(): array + { + return [ + [ + [], + false + ], + [ + ['user_ip' => '127.0.0.1'], + [ + 'item' => '127.0.0.1', + 'end' => '0', + 'reason' => '1', + 'mode' => 'ip', + ], + ], + [ + ['user_ip' => '10.0.0.1'], // first IP for 10.0.0.1/28 range + [ + 'item' => '10.0.0.1/28', + 'end' => '0', + 'reason' => '1', + 'mode' => 'ip', + ], + ], + [ + ['user_ip' => '10.0.0.14'], // last IP for 10.0.0.1/28 range + [ + 'item' => '10.0.0.1/28', + 'end' => '0', + 'reason' => '1', + 'mode' => 'ip', + ], + ], + [ + ['user_ip' => '10.0.0.15'], // first IP outside 10.0.0.1/28 range + [ + 'item' => '10.0.0.1/28', + 'end' => '0', + 'reason' => '1', + 'mode' => 'ip', + ], + ], + [ + ['user_ip' => '2001:4860:4860::8888'], // first IP in 2001:4860:4860::8888/12 range + [ + 'item' => '2001:4860:4860::8888/12', + 'end' => '0', + 'reason' => '1', + 'mode' => 'ip', + ], + ], + [ + ['user_ip' => '200F:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF'], // last IP in 2001:4860:4860::8888/12 range + [ + 'item' => '2001:4860:4860::8888/12', + 'end' => '0', + 'reason' => '1', + 'mode' => 'ip', + ], + ], + [ + ['user_ip' => '2010:4860:4860::1'], // IP outside the 2001:4860:4860::8888/12 range + false, + ], + [ + ['user_id' => 2], + false, + ], + [ + ['user_id' => 5], // there is only an expired ban + false, + ], + [ + ['user_id' => 4], + [ + 'item' => '4', + 'end' => '0', + 'reason' => '1', + 'mode' => 'user', + ], + ], + [ + ['user_email' => 'test@phpbb.com'], + false, + ], + [ + ['user_email' => 'bar@example.org'], + [ + 'item' => 'bar@example.org', + 'end' => '0', + 'reason' => '1', + 'mode' => 'email', + ], + ], + [ + ['user_email' => 'test@foo.bar'], + [ + 'item' => '*@foo.bar', + 'end' => '0', + 'reason' => '1', + 'mode' => 'email', + ], + ], + ]; + } + + /** + * @dataProvider data_check_ban + */ + public function test_check_ban($user_data, $expected) + { + $this->assertEquals($expected, $this->ban_manager->check($user_data)); + } + + public function data_get_bans(): array + { + return [ + [ + 'foo', + '', + type_not_found_exception::class + ], + [ + 'ip', + [ + [ + 'ban_id' => '2', + 'ban_item' => '127.0.0.1', + 'ban_start' => '1111', + 'ban_end' => '0', + 'ban_reason' => 'HAHAHA', + 'ban_reason_display' => '1', + ], + [ + 'ban_id' => '3', + 'ban_item' => '127.1.1.1', + 'ban_start' => '1111', + 'ban_end' => '0', + 'ban_reason' => 'HAHAHA', + 'ban_reason_display' => '1', + ], + [ + 'ban_id' => '6', + 'ban_item' => '10.0.0.1/28', + 'ban_start' => '1111', + 'ban_end' => '0', + 'ban_reason' => 'HAHAHA', + 'ban_reason_display' => '1', + ], + [ + 'ban_id' => '7', + 'ban_item' => '2001:4860:4860::8888/12', + 'ban_start' => '1111', + 'ban_end' => '0', + 'ban_reason' => 'HAHAHA', + 'ban_reason_display' => '1', + ], + ], + ], + [ + 'email', + [ + [ + 'ban_id' => '5', + 'ban_item' => 'bar@example.org', + 'ban_start' => '1111', + 'ban_end' => '0', + 'ban_reason' => 'HAHAHA', + 'ban_reason_display' => '1', + ], + [ + 'ban_id' => '9', + 'ban_item' => '*@foo.bar', + 'ban_start' => '1111', + 'ban_end' => '0', + 'ban_reason' => 'HAHAHA', + 'ban_reason_display' => '1', + ], + ], + ], + [ + 'user', + [ + [ + 'ban_id' => '4', + 'ban_item' => '4', + 'ban_start' => '1111', + 'ban_end' => '0', + 'ban_reason' => 'HAHAHA', + 'ban_reason_display' => '1', + ], + ], + ], + ]; + } + + /** + * @dataProvider data_get_bans + */ + public function test_get_bans($ban_type, $expected, $expected_exception = false) + { + if ($expected_exception !== false) + { + $this->expectException($expected_exception); + } + $this->assertEquals($expected, $this->ban_manager->get_bans($ban_type)); + } + + public function data_get_ban_end(): array + { + return [ + [ + 0, + 20, + 0, + ], + [ + 80, // 1 minute plus 20 seconds + 20, + 1, + ], + [ + 20, + 20, + -1, + ], + [ + 2 * 86400, // Ban end should be before this time + 20, + -1, + '1970-01-02', + ], + [ + 0, + 20, + -1, + '1970-01-02-15:30', // wrong format + invalid_length_exception::class, + ], + ]; + } + + /** + * @dataProvider data_get_ban_end + */ + public function test_get_ban_end($expected, $ban_start, $length, $end_date = '', $expected_exception = false) + { + if ($expected_exception) + { + $this->expectException($expected_exception); + } + + $start_time = new \DateTime(); + $start_time->setTimestamp($ban_start); + + $expected_end = new \DateTime(); + $expected_end->setTimestamp($expected); + + $ban_end = $this->ban_manager->get_ban_end($start_time, $length, $end_date); + + if ($length >= 0 || !$end_date) + { + $this->assertEquals($expected_end, $ban_end); + } + else + { + $this->assertLessThan($expected_end, $ban_end); + $this->assertGreaterThan($start_time, $ban_end); + } + } + + public function test_get_banned_users() + { + $banned_users = $this->ban_manager->get_banned_users(); + $this->assertEquals( + [ + 4 => 0, + 5 => 0 + ], + $banned_users + ); + } + + public function test_get_banned_users_own_method() + { + global $phpbb_root_path, $phpEx; + + $phpbb_container = new \phpbb_mock_container_builder(); + $ban_type_email = new \phpbb\ban\type\email($this->db, 'phpbb_users', 'phpbb_sessions', 'phpbb_sessions_keys'); + $ban_type_user = new \phpbb\ban\type\user($this->db, 'phpbb_users', 'phpbb_sessions', 'phpbb_sessions_keys'); + $ban_type_ip = $this->getMockBuilder(\phpbb\ban\type\ip::class) + ->setConstructorArgs([$this->db, 'phpbb_users', 'phpbb_sessions', 'phpbb_sessions_keys']) + ->getMock(); + $ban_type_ip->method('get_banned_users') + ->willReturn([19 => 1234, 20 => 0]); + $phpbb_container->set('ban.type.email', $ban_type_email); + $phpbb_container->set('ban.type.user', $ban_type_user); + $phpbb_container->set('ban.type.ip', $ban_type_ip); + $collection = new \phpbb\di\service_collection($phpbb_container); + $collection->add('ban.type.email'); + $collection->add('ban.type.user'); + $collection->add('ban.type.ip'); + + $language = new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx)); + $user = new \phpbb\user($language, '\phpbb\datetime'); + + $config = new \phpbb\config\config([]); + $phpbb_dispatcher = new \phpbb_mock_event_dispatcher(); + + // Change the global cache object for this test because + // the mock cache object does not hit the database as is needed + // for this test. + $cache = new \phpbb\cache\service( + new \phpbb\cache\driver\dummy(), + $config, + $this->db, + $phpbb_dispatcher, + $phpbb_root_path, + $phpEx + ); + + $ban_manager = new \phpbb\ban\manager($collection, $cache, $this->db, $user, 'phpbb_bans', 'phpbb_users'); + + $this->assertEquals( + [ + 4 => 0, + 5 => 0, + 20 => 0, + ], + $ban_manager->get_banned_users() + ); + + $ban_type_ip_reflection = new \ReflectionClass($ban_type_ip); + $get_excluded_reflection = $ban_type_ip_reflection->getMethod('get_excluded'); + $get_excluded_reflection->setAccessible(true); + $this->assertFalse($get_excluded_reflection->invoke($ban_type_ip)); + } + + public function test_ban_empty_ban_items() + { + global $phpbb_root_path, $phpEx; + + $phpbb_container = new \phpbb_mock_container_builder(); + $ban_type_email = new \phpbb\ban\type\email($this->db, 'phpbb_users', 'phpbb_sessions', 'phpbb_sessions_keys'); + $ban_type_user = new \phpbb\ban\type\user($this->db, 'phpbb_users', 'phpbb_sessions', 'phpbb_sessions_keys'); + $ban_type_ip = $this->getMockBuilder(\phpbb\ban\type\ip::class) + ->setConstructorArgs([$this->db, 'phpbb_users', 'phpbb_sessions', 'phpbb_sessions_keys']) + ->getMock(); + $ban_type_ip->method('prepare_for_storage') + ->willReturn([]); + $ban_type_ip->method('get_type') + ->willReturn('ip'); + $phpbb_container->set('ban.type.email', $ban_type_email); + $phpbb_container->set('ban.type.user', $ban_type_user); + $phpbb_container->set('ban.type.ip', $ban_type_ip); + $collection = new \phpbb\di\service_collection($phpbb_container); + $collection->add('ban.type.email'); + $collection->add('ban.type.user'); + $collection->add('ban.type.ip'); + + $language = new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx)); + $user = new \phpbb\user($language, '\phpbb\datetime'); + + $config = new \phpbb\config\config([]); + $phpbb_dispatcher = new \phpbb_mock_event_dispatcher(); + + // Change the global cache object for this test because + // the mock cache object does not hit the database as is needed + // for this test. + $cache = new \phpbb\cache\service( + new \phpbb\cache\driver\dummy(), + $config, + $this->db, + $phpbb_dispatcher, + $phpbb_root_path, + $phpEx + ); + + $ban_manager = new \phpbb\ban\manager($collection, $cache, $this->db, $user, 'phpbb_bans', 'phpbb_users'); + + $start_time = new \DateTime(); + $start_time->setTimestamp(1000); + $end_time = new \DateTime(); + $end_time->setTimestamp(0); + + $this->assertFalse($ban_manager->ban( + 'ip', + ['192.168.1.1'], + $start_time, + $end_time, + '' + )); + } + + public function data_test_ban(): array + { + return [ + [ + 'user', + ['normal_user'], + 1000, + 500, // end before start + '', + '', + false, + invalid_length_exception::class, + ], + [ + 'foo', // invalid ban type + ['normal_user'], + 1000, + 0, // end before start + '', + '', + false, + type_not_found_exception::class, + ], + [ + 'user', + [], // empty user list + 1000, + 0, + '', + '', + false, + no_valid_users_exception::class, + ], + [ + 'user', + ['founder'], // user same as current user + 1000, + 0, + '', + '', + false, + no_valid_users_exception::class, + ], + [ + 'user', + ['normal_user'], + 1000, + 0, + '', + '', + true, + ], + [ + 'user', + ['normal_u*'], + 1000, + 0, + '', + '', + true, + ], + [ + 'ip', + [], + 1000, + 0, + '', + '', + false, + no_valid_ips_exception::class, + ], + [ + 'ip', + ['192.168.I.1'], // invalid IP + 1000, + 0, + '', + '', + false, + no_valid_ips_exception::class, + ], + [ + 'ip', + ['192.168.1.1'], + 1000, + 0, + '', + '', + true, + ], + [ + 'email', + ['this_is_not_an_email'], + 1000, + 0, + '', + '', + false, + no_valid_emails_exception::class + ], + [ + 'email', + ['test@example.com'], + 1000, + 0, + '', + '', + true, + ], + [ + 'email', + ['*@foo.bar'], + 1000, + 0, + '', + '', + true, + ], + [ + 'email', + ['test@example.com', str_repeat('a', 100) . '@example.com'], // one email too long, shouldn't cause any issues though + 1000, + 0, + '', + '', + true, + ], + ]; + } + + /** + * @dataProvider data_test_ban + */ + public function test_ban($mode, $items, $start, $end, $reason, $display_reason, $expected, $expected_exception = '') + { + if ($expected_exception) + { + $this->expectException($expected_exception); + } + + $start_time = new \DateTime(); + $start_time->setTimestamp($start); + $end_time = new \DateTime(); + $end_time->setTimestamp($end); + + $ban_return = $this->ban_manager->ban($mode, $items, $start_time, $end_time, $reason, $display_reason); + + $this->assertEquals($expected, $ban_return); + } + + public function test_ban_actual() + { + $start_time = new \DateTime(); + $start_time->setTimestamp(1000); + $end_time = new \DateTime(); + $end_time->setTimestamp(0); + + $ban_return = $this->ban_manager->ban('ip', ['121.122.123.124'], $start_time, $end_time, '', 'because'); + + $this->assertTrue($ban_return); + + $this->assertEquals( + [ + 'item' => '121.122.123.124', + 'end' => 0, + 'reason' => 'because', + 'mode' => 'ip' + ], + $this->ban_manager->check(['user_ip' => '121.122.123.124']) + ); + } + + public function data_test_unban(): array + { + return [ + [ + 'does_not_exist', + [10], + [], + type_not_found_exception::class + ], + [ + 'user', + [4], + [ + [ + 'ban_id' => '4', + 'ban_item' => '4', + 'ban_start' => '1111', + 'ban_end' => '0', + 'ban_reason' => 'HAHAHA', + 'ban_reason_display' => '1', + ], + ], + ], + ]; + } + + /** + * @dataProvider data_test_unban + */ + public function test_unban($mode, $items, $expected, $expected_exception = '') + { + if ($expected_exception) + { + $this->expectException($expected_exception); + } + + $before_bans = $this->ban_manager->get_bans($mode); + + $this->ban_manager->unban($mode, $items); + + $after_bans = $this->ban_manager->get_bans($mode); + + $ban_diff = array_diff_assoc($before_bans, count($after_bans) ? $after_bans : []); + + $this->assertEquals($expected, $ban_diff); + } + + public function test_unban_invalid_type() + { + $this->expectException(type_not_found_exception::class); + + $this->ban_manager->unban('does_not_exist', []); + } + + public function test_base_type_methods() + { + $ban_type_ip = $this->phpbb_container->get('ban.type.ip'); + $base_type_reflection = new \ReflectionClass(\phpbb\ban\type\base::class); + $after_unban = $base_type_reflection->getMethod('after_unban'); + $this->assertEquals(['foo'], $after_unban->invoke($ban_type_ip, ['items' => ['foo']])); + + $check = $base_type_reflection->getMethod('check'); + $this->assertFalse($check->invoke($ban_type_ip, [], [])); + } +} diff --git a/tests/ban/fixtures/sessions_banlist.xml b/tests/ban/fixtures/sessions_banlist.xml new file mode 100644 index 0000000000..38f6c41e26 --- /dev/null +++ b/tests/ban/fixtures/sessions_banlist.xml @@ -0,0 +1,161 @@ + + + + user_id + username_clean + user_permissions + user_sig + user_email + user_ip + user_type + + 1 + anonymous + + + + 127.0.0.1 + 2 + + + 2 + founder + + + admin@foo.bar + 21.22.23.24 + 3 + + + 3 + normal_user + + + normal_user@foo.bar + 21.22.23.25 + 0 + + + 4 + ipv6_user + + + normal_user@foo.bar + 2345:0425:2CA1:0000:0000:0567:5673:23b5 + 0 + + + 5 + another_user + + + bar@example.org + 123.124.125.126 + 0 + +
+ + session_id + session_user_id + session_ip + session_browser + session_admin + + bar_session000000000000000000000 + 4 + 127.0.0.1 + user agent + 1 + +
+ + ban_id + ban_mode + ban_item + ban_start + ban_end + ban_reason + ban_reason_display + + 2 + ip + 127.0.0.1 + 1111 + 0 + HAHAHA + 1 + + + 3 + ip + 127.1.1.1 + 1111 + 0 + HAHAHA + 1 + + + 4 + user + 4 + 1111 + 0 + HAHAHA + 1 + + + 5 + email + bar@example.org + 1111 + 0 + HAHAHA + 1 + + + 6 + ip + 10.0.0.1/28 + 1111 + 0 + HAHAHA + 1 + + + 7 + ip + 2001:4860:4860::8888/12 + 1111 + 0 + HAHAHA + 1 + + + 8 + invalid_mode + foo + 1111 + 0 + HAHAHA + 1 + + + 9 + email + *@foo.bar + 1111 + 0 + HAHAHA + 1 + + + 10 + user + 3 + 1111 + 1234 + expired + 1 + +
+
diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 2aa9c6c986..7556dd8c90 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -34,6 +34,8 @@ $phpbb_class_loader_ext = new \phpbb\class_loader('\\', $phpbb_root_path . 'ext/ $phpbb_class_loader_ext->register(); $phpbb_class_loader = new \phpbb\class_loader('phpbb\\', $phpbb_root_path . 'phpbb/', "php"); $phpbb_class_loader->register(); +$phpbb_class_loader_tests = new \phpbb\class_loader('phpbb\\tests\\', $phpbb_root_path . '../tests/', 'php'); +$phpbb_class_loader_tests->register(); require_once 'test_framework/phpbb_test_case_helpers.php'; require_once 'test_framework/phpbb_test_case.php'; diff --git a/tests/functions/validate_user_email_test.php b/tests/functions/validate_user_email_test.php index 08fbe93b4b..404dcb5da9 100644 --- a/tests/functions/validate_user_email_test.php +++ b/tests/functions/validate_user_email_test.php @@ -59,7 +59,7 @@ class phpbb_functions_validate_user_email_test extends phpbb_database_test_case $collection->add('ban.type.email'); $collection->add('ban.type.user'); - $ban_manager = new \phpbb\ban\manager($collection, $cache, $this->db, 'phpbb_bans', 'phpbb_users'); + $ban_manager = new \phpbb\ban\manager($collection, $cache, $this->db, $this->user, 'phpbb_bans', 'phpbb_users'); $phpbb_container->set('ban.manager', $ban_manager); } diff --git a/tests/session/check_ban_test.php b/tests/session/check_ban_test.php index 95ad89cacd..0a064a817c 100644 --- a/tests/session/check_ban_test.php +++ b/tests/session/check_ban_test.php @@ -51,7 +51,10 @@ class phpbb_session_check_ban_test extends phpbb_session_test_case 'BAN_TRIGGERED_BY_USER' => 'BAN_TRIGGERED_BY_USER', ]; - global $cache, $config, $phpbb_root_path, $phpEx, $phpbb_filesystem, $phpbb_container; + global $cache, $config, $phpbb_root_path, $phpEx, $phpbb_filesystem, $phpbb_container, $user; + + $language = new phpbb\language\language(new phpbb\language\language_file_loader($phpbb_root_path, $phpEx)); + $user = new \phpbb\user($language, '\phpbb\datetime'); $phpbb_filesystem = new \phpbb\filesystem\filesystem(); @@ -81,7 +84,7 @@ class phpbb_session_check_ban_test extends phpbb_session_test_case $collection->add('ban.type.email'); $collection->add('ban.type.user'); - $ban_manager = new \phpbb\ban\manager($collection, $cache, $this->db, 'phpbb_bans', 'phpbb_users'); + $ban_manager = new \phpbb\ban\manager($collection, $cache, $this->db, $user, 'phpbb_bans', 'phpbb_users'); $phpbb_container->set('ban.manager', $ban_manager); } diff --git a/tests/session/testable_factory.php b/tests/session/testable_factory.php index c85053770a..ce45171be3 100644 --- a/tests/session/testable_factory.php +++ b/tests/session/testable_factory.php @@ -75,7 +75,7 @@ class phpbb_session_testable_factory { // set up all the global variables used by session global $SID, $_SID, $db, $config, $cache, $request, $phpbb_container, $phpbb_dispatcher; - global $phpbb_root_path, $phpEx; + global $user, $phpbb_root_path, $phpEx; $request = $this->request = new phpbb_mock_request( array(), @@ -90,6 +90,8 @@ class phpbb_session_testable_factory $cache = $this->cache = new phpbb_mock_cache($this->get_cache_data()); $SID = $_SID = null; + $language = new phpbb\language\language(new phpbb\language\language_file_loader($phpbb_root_path, $phpEx)); + $user = new \phpbb\user($language, '\phpbb\datetime'); $phpbb_container = $this->container = new phpbb_mock_container_builder(); $phpbb_container->set( @@ -124,7 +126,7 @@ class phpbb_session_testable_factory $collection->add('ban.type.email'); $collection->add('ban.type.user'); - $ban_manager = new \phpbb\ban\manager($collection, $cache_service, $db, 'phpbb_bans', 'phpbb_users'); + $ban_manager = new \phpbb\ban\manager($collection, $cache_service, $db, $user,'phpbb_bans', 'phpbb_users'); $phpbb_container->set('ban.manager', $ban_manager); $session = new phpbb_mock_session_testable;