simplify ban fetching code
This commit is contained in:
		
							parent
							
								
									56b8d88ca4
								
							
						
					
					
						commit
						3ed3ea7234
					
				
							
								
								
									
										8
									
								
								composer.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										8
									
								
								composer.lock
									
									
									
										generated
									
									
									
								
							| @ -388,12 +388,12 @@ | |||||||
|             "source": { |             "source": { | ||||||
|                 "type": "git", |                 "type": "git", | ||||||
|                 "url": "https://github.com/shish/microcrud.git", |                 "url": "https://github.com/shish/microcrud.git", | ||||||
|                 "reference": "41a8aea2af6441c212467670776dc182518c5ff4" |                 "reference": "6471a4c7445e872282f12d1de3730db55d5c06e2" | ||||||
|             }, |             }, | ||||||
|             "dist": { |             "dist": { | ||||||
|                 "type": "zip", |                 "type": "zip", | ||||||
|                 "url": "https://api.github.com/repos/shish/microcrud/zipball/41a8aea2af6441c212467670776dc182518c5ff4", |                 "url": "https://api.github.com/repos/shish/microcrud/zipball/6471a4c7445e872282f12d1de3730db55d5c06e2", | ||||||
|                 "reference": "41a8aea2af6441c212467670776dc182518c5ff4", |                 "reference": "6471a4c7445e872282f12d1de3730db55d5c06e2", | ||||||
|                 "shasum": "" |                 "shasum": "" | ||||||
|             }, |             }, | ||||||
|             "require": { |             "require": { | ||||||
| @ -429,7 +429,7 @@ | |||||||
|                 "crud", |                 "crud", | ||||||
|                 "generator" |                 "generator" | ||||||
|             ], |             ], | ||||||
|             "time": "2019-11-28T15:23:53+00:00" |             "time": "2019-11-28T15:53:53+00:00" | ||||||
|         }, |         }, | ||||||
|         { |         { | ||||||
|             "name": "shish/microhtml", |             "name": "shish/microhtml", | ||||||
|  | |||||||
| @ -260,140 +260,68 @@ class IPBan extends Extension | |||||||
|     private function check_ip_ban() |     private function check_ip_ban() | ||||||
|     { |     { | ||||||
|         $remote = $_SERVER['REMOTE_ADDR']; |         $remote = $_SERVER['REMOTE_ADDR']; | ||||||
|         $bans = $this->get_active_bans_sorted(); |         list($ips, $networks) = $this->get_active_bans_grouped(); | ||||||
| 
 |         if (isset($ips[$remote])) { | ||||||
|         // bans[0] = IPs
 |             $this->block($ips[$remote]);  // never returns
 | ||||||
|         if (isset($bans[0][$remote])) { |  | ||||||
|             $this->block($remote);  // never returns
 |  | ||||||
|         } |         } | ||||||
| 
 |         foreach ($networks as $range => $ban_id) { | ||||||
|         // bans[1] = CIDR nets
 |             if (ip_in_range($remote, $range)) { | ||||||
|         foreach ($bans[1] as $ip => $true) { |                 $this->block($ban_id);  // never returns
 | ||||||
|             if (ip_in_range($remote, $ip)) { |  | ||||||
|                 $this->block($remote);  // never returns
 |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private function block(string $remote) |     private function block(int $ban_id) | ||||||
|     { |     { | ||||||
|         global $config, $database; |         global $config, $database; | ||||||
| 
 | 
 | ||||||
|         $prefix = ($database->get_driver_name() == DatabaseDriver::SQLITE ? "bans." : ""); |         $row = $database->get_row("SELECT * FROM bans WHERE id=:id", ["id"=>$ban_id]); | ||||||
| 
 | 
 | ||||||
|         $bans = $this->get_bans(false, null); |  | ||||||
| 
 |  | ||||||
|         foreach ($bans as $row) { |  | ||||||
|             $ip = $row[$prefix."ip"]; |  | ||||||
|             if ( |  | ||||||
|                 (strstr($ip, '/') && ip_in_range($remote, $ip)) || |  | ||||||
|                 ($ip == $remote) |  | ||||||
|             ) { |  | ||||||
|                 $reason = $row[$prefix.'reason']; |  | ||||||
|                 $admin = User::by_id($row[$prefix.'banner_id']); |  | ||||||
|                 $date = $row['expires']; |  | ||||||
|         $msg = $config->get_string("ipban_message"); |         $msg = $config->get_string("ipban_message"); | ||||||
|                 $msg = str_replace('$IP', $ip, $msg); |         $msg = str_replace('$IP', $row["ip"], $msg); | ||||||
|                 $msg = str_replace('$DATE', $date, $msg); |         $msg = str_replace('$DATE', $row['expires'], $msg); | ||||||
|                 $msg = str_replace('$ADMIN', $admin->name, $msg); |         $msg = str_replace('$ADMIN', User::by_id($row['banner_id'])->name, $msg); | ||||||
|                 $msg = str_replace('$REASON', $reason, $msg); |         $msg = str_replace('$REASON', $row['reason'], $msg); | ||||||
|         $contact_link = contact_link(); |         $contact_link = contact_link(); | ||||||
|         if (!empty($contact_link)) { |         if (!empty($contact_link)) { | ||||||
|             $msg = str_replace('$CONTACT', "<a href='$contact_link'>Contact the staff (be sure to include this message)</a>", $msg); |             $msg = str_replace('$CONTACT', "<a href='$contact_link'>Contact the staff (be sure to include this message)</a>", $msg); | ||||||
|         } else { |         } else { | ||||||
|             $msg = str_replace('$CONTACT', "", $msg); |             $msg = str_replace('$CONTACT', "", $msg); | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|         header("HTTP/1.0 403 Forbidden"); |         header("HTTP/1.0 403 Forbidden"); | ||||||
|         print "$msg"; |         print "$msg"; | ||||||
| 
 |  | ||||||
|         exit; |         exit; | ||||||
|     } |     } | ||||||
|         } |  | ||||||
|         log_error("ipban", "block($remote) called but no bans matched"); |  | ||||||
|         exit; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private function get_bans(bool $all, ?int $page) |  | ||||||
|     { |  | ||||||
|         global $database; |  | ||||||
| 
 |  | ||||||
|         $size = 100; |  | ||||||
|         if (@$_GET['limit']) { |  | ||||||
|             $size = int_escape($_GET['limit']); |  | ||||||
|         } |  | ||||||
|         $filters = ["1=1"]; |  | ||||||
|         $args = []; |  | ||||||
| 
 |  | ||||||
|         if (!$all) { |  | ||||||
|             $filters[] = "((expires > CURRENT_TIMESTAMP) OR (expires IS NULL))"; |  | ||||||
|         } |  | ||||||
|         if (@$_GET['s_ip']) { |  | ||||||
|             $filters[] = "(ip = :ip)"; |  | ||||||
|             $args['ip'] = $_GET['s_ip']; |  | ||||||
|         } |  | ||||||
|         if (@$_GET['s_reason']) { |  | ||||||
|             $filters[] = "(reason LIKE :reason)"; |  | ||||||
|             $args['reason'] = '%' . $_GET['s_reason'] . "%"; |  | ||||||
|         } |  | ||||||
|         if (@$_GET['s_banner']) { |  | ||||||
|             $filters[] = "(banner_id = :banner_id)"; |  | ||||||
|             $args['banner_id'] = User::by_name($_GET['s_banner'])->id; |  | ||||||
|         } |  | ||||||
|         if (@$_GET['s_added']) { |  | ||||||
|             $filters[] = "(added LIKE :added)"; |  | ||||||
|             $args['added'] = '%' . $_GET['s_added'] . "%"; |  | ||||||
|         } |  | ||||||
|         if (@$_GET['s_expires']) { |  | ||||||
|             $filters[] = "(expires LIKE :expires)"; |  | ||||||
|             $args['expires'] = '%' . $_GET['s_expires'] . "%"; |  | ||||||
|         } |  | ||||||
|         if (@$_GET['s_mode']) { |  | ||||||
|             $filters[] = "(mode = :mode)"; |  | ||||||
|             $args['mode'] = $_GET['s_mode']; |  | ||||||
|         } |  | ||||||
|         $filter = implode(" AND ", $filters); |  | ||||||
| 
 |  | ||||||
|         if (is_null($page)) { |  | ||||||
|             $pager = ""; |  | ||||||
|         } else { |  | ||||||
|             $pager = "LIMIT :limit OFFSET :offset"; |  | ||||||
|             $args["offset"] = ($page-1)*$size; |  | ||||||
|             $args['limit'] = $size; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return $database->get_all(" |  | ||||||
| 			SELECT bans.*, users.name as banner_name |  | ||||||
| 			FROM bans |  | ||||||
| 			JOIN users ON banner_id = users.id |  | ||||||
| 			WHERE $filter |  | ||||||
| 			ORDER BY expires, bans.id |  | ||||||
| 			$pager |  | ||||||
| 		", $args);
 |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     // returns [ips, nets]
 |     // returns [ips, nets]
 | ||||||
|     private function get_active_bans_sorted() |     private function get_active_bans_grouped() | ||||||
|     { |     { | ||||||
|         global $cache; |         global $cache, $database; | ||||||
| 
 | 
 | ||||||
|         $cached = $cache->get("ip_bans_sorted"); |         $cached = $cache->get("ip_to_ban_id_grouped"); | ||||||
|         if ($cached) { |         if ($cached) { | ||||||
|             return $cached; |             return $cached; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         $bans = $this->get_bans(false, null); |         $rows = $database->get_pairs(" | ||||||
|         $ips = []; # "0.0.0.0" => false);
 |             SELECT ip, id | ||||||
|         $nets = []; # "0.0.0.0/32" => false);
 |             FROM bans | ||||||
|         foreach ($bans as $row) { |             WHERE ((expires > CURRENT_TIMESTAMP) OR (expires IS NULL)) | ||||||
|             if (strstr($row['ip'], '/')) { |         ");
 | ||||||
|                 $nets[$row['ip']] = true; | 
 | ||||||
|  |         $ips = []; # "0.0.0.0" => 123;
 | ||||||
|  |         $nets = []; # "0.0.0.0/32" => 456;
 | ||||||
|  |         foreach ($rows as $ip => $id) { | ||||||
|  |             if (strstr($ip, '/')) { | ||||||
|  |                 $nets[$ip] = $id; | ||||||
|             } else { |             } else { | ||||||
|                 $ips[$row['ip']] = true; |                 $ips[$ip] = $id; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         $sorted = [$ips, $nets]; |         $sorted = [$ips, $nets]; | ||||||
|         $cache->set("ip_bans_sorted", $sorted, 600); |         $cache->set("ip_to_ban_id_grouped", $sorted, 600); | ||||||
|         return $sorted; |         return $sorted; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user