. */ namespace Fisharebest\Webtrees; use Fisharebest\Webtrees\Controller\PageController; use Fisharebest\Webtrees\Functions\FunctionsEdit; use PDO; define('WT_SCRIPT_NAME', 'admin_site_access.php'); require './includes/session.php'; $rules_display = array( 'unknown' => I18N::translate('unknown'), 'allow' => /* I18N: An access rule - allow access to the site */ I18N::translate('allow'), 'deny' => /* I18N: An access rule - deny access to the site */ I18N::translate('deny'), 'robot' => /* I18N: http://en.wikipedia.org/wiki/Web_crawler */ I18N::translate('robot'), ); $rules_edit = array( 'unknown' => I18N::translate('unknown'), 'allow' => /* I18N: An access rule - allow access to the site */ I18N::translate('allow'), 'deny' => /* I18N: An access rule - deny access to the site */ I18N::translate('deny'), 'robot' => /* I18N: http://en.wikipedia.org/wiki/Web_crawler */ I18N::translate('robot'), ); // Form actions switch (Filter::post('action')) { case 'save': if (Filter::checkCsrf()) { $site_access_rule_id = Filter::postInteger('site_access_rule_id'); $ip_address_start = Filter::post('ip_address_start', WT_REGEX_IPV4); $ip_address_end = Filter::post('ip_address_end', WT_REGEX_IPV4); $user_agent_pattern = Filter::post('user_agent_pattern'); $rule = Filter::post('rule', 'allow|deny|robot'); $comment = Filter::post('comment'); $user_agent_string = Filter::server('HTTP_USER_AGENT'); $ip_address = WT_CLIENT_IP; if ($ip_address_start !== null && $ip_address_end !== null && $user_agent_pattern !== null && $rule !== null) { // This doesn't work with named placeholders. The :user_agent_string parameter is not recognised. $oops = $rule !== 'allow' && Database::prepare( "SELECT INET_ATON(:ip_address) BETWEEN INET_ATON(:ip_address_start) AND INET_ATON(:ip_address_end)" . " AND :user_agent_string LIKE :user_agent_pattern" )->execute(array( 'ip_address' => $ip_address, 'ip_address_start' => $ip_address_start, 'ip_address_end' => $ip_address_end, 'user_agent_string' => $user_agent_string, 'user_agent_pattern' => $user_agent_pattern, ))->fetchOne(); if ($oops) { FlashMessages::addMessage(I18N::translate('You cannot create a rule which would prevent yourself from accessing the website.'), 'danger'); } elseif ($site_access_rule_id === null) { Database::prepare( "INSERT INTO `##site_access_rule` (ip_address_start, ip_address_end, user_agent_pattern, rule, comment) VALUES (INET_ATON(:ip_address_start), INET_ATON(:ip_address_end), :user_agent_pattern, :rule, :comment)" )->execute(array( 'ip_address_start' => $ip_address_start, 'ip_address_end' => $ip_address_end, 'user_agent_pattern' => $user_agent_pattern, 'rule' => $rule, 'comment' => $comment, )); FlashMessages::addMessage(I18N::translate('The website access rule has been created.'), 'success'); } else { Database::prepare( "UPDATE `##site_access_rule` SET ip_address_start = INET_ATON(:ip_address_start), ip_address_end = INET_ATON(:ip_address_end), user_agent_pattern = :user_agent_pattern, rule = :rule, comment = :comment WHERE site_access_rule_id = :site_access_rule_id" )->execute(array( 'ip_address_start' => $ip_address_start, 'ip_address_end' => $ip_address_end, 'user_agent_pattern' => $user_agent_pattern, 'rule' => $rule, 'comment' => $comment, 'site_access_rule_id' => $site_access_rule_id, )); FlashMessages::addMessage(I18N::translate('The website access rule has been updated.'), 'success'); } } } header('Location: ' . WT_BASE_URL . WT_SCRIPT_NAME); return; case 'delete': if (Filter::checkCsrf()) { $site_access_rule_id = Filter::postInteger('site_access_rule_id'); Database::prepare( "DELETE FROM `##site_access_rule` WHERE site_access_rule_id = :site_access_rule_id" )->execute(array( 'site_access_rule_id' => $site_access_rule_id, )); FlashMessages::addMessage(I18N::translate('The website access rule has been deleted.'), 'success'); } header('Location: ' . WT_BASE_URL . WT_SCRIPT_NAME); return; } // Delete any "unknown" visitors that are now "known". // This could happen every time we create/update a rule. Database::exec( "DELETE unknown" . " FROM `##site_access_rule` AS unknown" . " JOIN `##site_access_rule` AS known ON (unknown.user_agent_pattern LIKE known.user_agent_pattern)" . " WHERE unknown.rule='unknown' AND known.rule<>'unknown'" . " AND unknown.ip_address_start BETWEEN known.ip_address_start AND known.ip_address_end" ); $controller = new PageController; $controller ->restrictAccess(Auth::isAdmin()) ->addExternalJavascript(WT_JQUERY_DATATABLES_JS_URL) ->addExternalJavascript(WT_DATATABLES_BOOTSTRAP_JS_URL) ->setPageTitle(I18N::translate('Website access rules')); $action = Filter::get('action'); switch ($action) { case 'load': // AJAX callback for datatables $search = Filter::get('search'); $search = $search['value']; $start = Filter::getInteger('start'); $length = Filter::getInteger('length'); $sql = "SELECT SQL_CACHE SQL_CALC_FOUND_ROWS" . " '', INET_NTOA(ip_address_start), ip_address_start, INET_NTOA(ip_address_end), ip_address_end, user_agent_pattern, rule, comment, site_access_rule_id" . " FROM `##site_access_rule`"; $args = array(); if ($search) { $sql .= " WHERE (INET_ATON(:search_1) BETWEEN ip_address_start AND ip_address_end" . " OR INET_NTOA(ip_address_start) LIKE CONCAT('%', :search_2, '%')" . " OR INET_NTOA(ip_address_end) LIKE CONCAT('%', :search_3, '%')" . " OR user_agent_pattern LIKE CONCAT('%', :search_4, '%')" . " OR comment LIKE CONCAT('%', :search_5, '%'))"; $args['search_1'] = Filter::escapeLike($search); $args['search_2'] = Filter::escapeLike($search); $args['search_3'] = Filter::escapeLike($search); $args['search_4'] = Filter::escapeLike($search); $args['search_5'] = Filter::escapeLike($search); } $order = Filter::getArray('order'); $sql .= ' ORDER BY'; if ($order) { foreach ($order as $key => $value) { if ($key > 0) { $sql .= ','; } // Datatables numbers columns 0, 1, 2 // MySQL numbers columns 1, 2, 3 switch ($value['dir']) { case 'asc': $sql .= " :col_" . $key . " ASC"; break; case 'desc': $sql .= " :col_" . $key . " DESC"; break; } $args['col_' . $key] = 1 + $value['column']; } } else { $sql .= ' 1 ASC'; } if ($length > 0) { $sql .= " LIMIT :length OFFSET :start"; $args['length'] = $length; $args['start'] = $start; } // This becomes a JSON list, not a JSON array, so we need numeric keys. $data = Database::prepare($sql)->execute($args)->fetchAll(PDO::FETCH_NUM); // Reformat the data for display foreach ($data as &$datum) { $site_access_rule_id = $datum[8]; $datum[0] = '
- | - |
---|