Skip to content

Commit

Permalink
fix: move debug mode to config (#3324)
Browse files Browse the repository at this point in the history
* fix: move debug mode to config

* fix: also move debug_whitelist to .ini config

* fix: move logic back to Debug class

* docs

* docs

* fix: disable debug mode by default

* fix: restore previous behavior for alerts

* fix: center-align alert text
  • Loading branch information
dvikan committed Jun 2, 2023
1 parent c5cd229 commit ee498ea
Show file tree
Hide file tree
Showing 18 changed files with 119 additions and 156 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,9 +183,9 @@ Add the bridge name to `whitelist.txt`:

### How to enable debug mode

Create a file named `DEBUG`:
Set in `config.ini.php`:

touch DEBUG
enable_debug_mode = true

Learn more in [debug mode](https://rss-bridge.github.io/rss-bridge/For_Developers/Debug_mode.html).

Expand Down
8 changes: 4 additions & 4 deletions actions/DisplayAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public function execute(array $request)
&& (time() - $cache_timeout < $mtime)
&& !Debug::isEnabled()
) {
// At this point we found the feed in the cache
// At this point we found the feed in the cache and debug mode is disabled

if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
// The client wants to know if the feed has changed since its last check
Expand All @@ -118,7 +118,7 @@ public function execute(array $request)
}
}

// Fetch the cached feed from the cache and prepare it
// Load the feed from cache and prepare it
$cached = $cache->loadData();
if (isset($cached['items']) && isset($cached['extraInfos'])) {
foreach ($cached['items'] as $item) {
Expand All @@ -127,7 +127,7 @@ public function execute(array $request)
$infos = $cached['extraInfos'];
}
} else {
// At this point we did NOT find the feed in the cache. So invoke the bridge!
// At this point we did NOT find the feed in the cache or debug mode is enabled.
try {
$bridge->setDatas($bridge_params);
$bridge->collectData();
Expand Down Expand Up @@ -200,7 +200,7 @@ private function createFeedItemFromException($e, BridgeInterface $bridge): FeedI
$item->setURI(get_current_url());
$item->setTimestamp(time());

// Create a item identifier for feed readers e.g. "staysafetv twitch videos_19389"
// Create an item identifier for feed readers e.g. "staysafetv twitch videos_19389"
$item->setUid($bridge->getName() . '_' . $uniqueIdentifier);

$content = render_template(__DIR__ . '/../templates/bridge-error.html.php', [
Expand Down
1 change: 1 addition & 0 deletions actions/FrontpageAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public function execute(array $request)
}

return render(__DIR__ . '/../templates/frontpage.html.php', [
'messages' => [],
'admin_email' => Configuration::getConfig('admin', 'email'),
'admin_telegram' => Configuration::getConfig('admin', 'telegram'),
'bridges' => $body,
Expand Down
4 changes: 0 additions & 4 deletions bridges/SchweinfurtBuergerinformationenBridge.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,6 @@ public function collectData()

foreach ($articleIDs as $articleID) {
$this->items[] = $this->generateItemFromArticle($articleID);

if (Debug::isEnabled()) {
break;
}
}
}

Expand Down
7 changes: 7 additions & 0 deletions config.default.ini.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@
; Display a system message to users.
message = ""

; Whether to enable debug mode.
enable_debug_mode = false

; Enable debug mode only for these permitted ip addresses
; debug_mode_whitelist[] = 127.0.0.1
; debug_mode_whitelist[] = 192.168.1.10

[http]
timeout = 60
useragent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0"
Expand Down
20 changes: 13 additions & 7 deletions docs/04_For_Developers/05_Debug_mode.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,29 @@ Enabling debug mode on a public server may result in malicious clients retrievin
***

Debug mode enables error reporting and prevents loading data from the cache (data is still written to the cache).
To enable debug mode, create a file named 'DEBUG' in the root directory of RSS-Bridge (next to `index.php`). For further security, insert your IP address in the file. You can add multiple addresses, one per line.
To enable debug mode, set in `config.ini.php`:

enable_debug_mode = true

Allow only explicit ip addresses:

debug_mode_whitelist[] = 127.0.0.1
debug_mode_whitelist[] = 192.168.1.10

_Notice_:

* An empty file enables debug mode for anyone!
* The bridge whitelist still applies! (debug mode does **not** enable all bridges)

RSS-Bridge will give you a visual feedback when debug mode is enabled:

![twitter bridge](../images/debug_mode.png)
RSS-Bridge will give you a visual feedback when debug mode is enabled.

While debug mode is active, RSS-Bridge will write additional data to your servers `error.log`.

Debug mode is controlled by the static class `Debug`. It provides three core functions:

`Debug::isEnabled()`: Returns `true` if debug mode is enabled.
`Debug::isSecure()`: Returns `true` if your client is on the debug whitelist.
`Debug::log($message)`: Adds a message to `error.log`. It takes one parameter, which can be anything. For example: `Debug::log('Hello World!');`
* `Debug::isEnabled()`: Returns `true` if debug mode is enabled.
* `Debug::log($message)`: Adds a message to `error.log`. It takes one parameter, which can be anything.

Example: `Debug::log('Hello World!');`

**Notice**: `Debug::log($message)` calls `Debug::isEnabled()` internally. You don't have to do that manually.
Binary file removed docs/images/debug_mode.png
Binary file not shown.
16 changes: 16 additions & 0 deletions lib/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -114,13 +114,29 @@ public static function loadConfiguration(array $customConfig = [], array $env =
}
}

if (file_exists(__DIR__ . '/../DEBUG')) {
// The debug mode has been moved to config. Preserve existing installs which has this DEBUG file.
self::setConfig('system', 'enable_debug_mode', true);
$debug = trim(file_get_contents(__DIR__ . '/../DEBUG'));
if ($debug) {
self::setConfig('system', 'debug_mode_whitelist', explode("\n", str_replace("\r", '', $debug)));
}
}

if (
!is_string(self::getConfig('system', 'timezone'))
|| !in_array(self::getConfig('system', 'timezone'), timezone_identifiers_list(DateTimeZone::ALL_WITH_BC))
) {
self::throwConfigError('system', 'timezone');
}

if (!is_bool(self::getConfig('system', 'enable_debug_mode'))) {
self::throwConfigError('system', 'enable_debug_mode', 'Is not a valid Boolean');
}
if (!is_array(self::getConfig('system', 'debug_mode_whitelist') ?: [])) {
self::throwConfigError('system', 'debug_mode_whitelist', 'Is not a valid array');
}

if (!is_string(self::getConfig('proxy', 'url'))) {
self::throwConfigError('proxy', 'url', 'Is not a valid string');
}
Expand Down
99 changes: 8 additions & 91 deletions lib/Debug.php
Original file line number Diff line number Diff line change
@@ -1,106 +1,23 @@
<?php

/**
* This file is part of RSS-Bridge, a PHP project capable of generating RSS and
* Atom feeds for websites that don't have one.
*
* For the full license information, please view the UNLICENSE file distributed
* with this source code.
*
* @package Core
* @license http://unlicense.org/ UNLICENSE
* @link https://github.com/rss-bridge/rss-bridge
*/

/**
* Implements functions for debugging purposes. Debugging can be enabled by
* placing a file named DEBUG in {@see PATH_ROOT}.
*
* The file specifies a whitelist of IP addresses on which debug mode will be
* enabled. An empty file enables debug mode for everyone (highly discouraged
* for public servers!). Each line in the file specifies one client in the
* whitelist. For example:
*
* * `192.168.1.72`
* * `127.0.0.1`
* * `::1`
*
* Notice: If you are running RSS-Bridge on your local machine, you need to add
* localhost (either `127.0.0.1` for IPv4 or `::1` for IPv6) to your whitelist!
*
* Warning: In debug mode your server may display sensitive information! For
* security reasons it is recommended to whitelist only specific IP addresses.
*/
class Debug
{
/**
* Indicates if debug mode is enabled.
*
* Do not access this property directly!
* Use {@see Debug::isEnabled()} instead.
*
* @var bool
* Convenience function for Configuration::getConfig('system', 'enable_debug_mode')
*/
private static $enabled = false;

/**
* Indicates if debug mode is secure.
*
* Do not access this property directly!
* Use {@see Debug::isSecure()} instead.
*
* @var bool
*/
private static $secure = false;

/**
* Returns true if debug mode is enabled
*
* If debug mode is enabled, sets `display_errors = 1` and `error_reporting = E_ALL`
*
* @return bool True if enabled.
*/
public static function isEnabled()
public static function isEnabled(): bool
{
static $firstCall = true; // Initialized on first call

if ($firstCall && file_exists(__DIR__ . '/../DEBUG')) {
$debug_whitelist = trim(file_get_contents(__DIR__ . '/../DEBUG'));

self::$enabled = empty($debug_whitelist) || in_array(
$_SERVER['REMOTE_ADDR'],
explode("\n", str_replace("\r", '', $debug_whitelist))
);

if (self::$enabled) {
self::$secure = !empty($debug_whitelist);
}

$firstCall = false; // Skip check on next call
$ip = $_SERVER['REMOTE_ADDR'];
$enableDebugMode = Configuration::getConfig('system', 'enable_debug_mode');
$debugModeWhitelist = Configuration::getConfig('system', 'debug_mode_whitelist') ?: [];
if ($enableDebugMode && ($debugModeWhitelist === [] || in_array($ip, $debugModeWhitelist))) {
return true;
}

return self::$enabled;
}

/**
* Returns true if debug mode is enabled only for specific IP addresses.
*
* Notice: The security flag is set by {@see Debug::isEnabled()}. If this
* function is called before {@see Debug::isEnabled()}, the default value is
* false!
*
* @return bool True if debug mode is secure
*/
public static function isSecure()
{
return self::$secure;
return false;
}

public static function log($message)
{
if (!self::isEnabled()) {
return;
}
$e = new \Exception();
$trace = trace_from_exception($e);
// Drop the current frame
Expand Down
4 changes: 1 addition & 3 deletions lib/FeedExpander.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,7 @@ public function collectExpandableDatas($url, $maxItems = -1)
if ($rssContent === false) {
$xmlErrors = libxml_get_errors();
foreach ($xmlErrors as $xmlError) {
if (Debug::isEnabled()) {
Debug::log(trim($xmlError->message));
}
Logger::debug(trim($xmlError->message));
}
if ($xmlErrors) {
// Render only the first error into exception message
Expand Down
15 changes: 12 additions & 3 deletions lib/Logger.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ final class Logger
{
public static function debug(string $message, array $context = [])
{
if (Debug::isEnabled()) {
self::log('DEBUG', $message, $context);
}
self::log('DEBUG', $message, $context);
}

public static function info(string $message, array $context = []): void
Expand All @@ -28,6 +26,11 @@ public static function error(string $message, array $context = []): void

private static function log(string $level, string $message, array $context = []): void
{
if (!Debug::isEnabled() && $level === 'DEBUG') {
// Don't log this debug log record because debug mode is disabled
return;
}

if (isset($context['e'])) {
/** @var \Throwable $e */
$e = $context['e'];
Expand Down Expand Up @@ -66,7 +69,13 @@ private static function log(string $level, string $message, array $context = [])
$message,
$context ? Json::encode($context) : ''
);

// Log to stderr/stdout whatever that is
// todo: extract to log handler
error_log($text);

// Log to file
// todo: extract to log handler
//file_put_contents('/tmp/rss-bridge.log', $text, FILE_APPEND);
}
}
2 changes: 2 additions & 0 deletions lib/RssBridge.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ private function run($request): void
);
Logger::warning($text);
if (Debug::isEnabled()) {
// todo: extract to log handler
print sprintf("<pre>%s</pre>\n", e($text));
}
});
Expand All @@ -59,6 +60,7 @@ private function run($request): void
);
Logger::error($message);
if (Debug::isEnabled()) {
// todo: extract to log handler
print sprintf("<pre>%s</pre>\n", e($message));
}
}
Expand Down
1 change: 1 addition & 0 deletions lib/bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
const REPOSITORY = 'https://github.com/RSS-Bridge/rss-bridge/';

// Allow larger files for simple_html_dom
// todo: extract to config (if possible)
const MAX_FILE_SIZE = 10000000;

// Files
Expand Down
7 changes: 5 additions & 2 deletions lib/contents.php
Original file line number Diff line number Diff line change
Expand Up @@ -438,14 +438,17 @@ function getSimpleHTMLDOMCached(
$time !== false
&& (time() - $duration < $time)
&& !Debug::isEnabled()
) { // Contents within duration
) {
// Contents within duration and debug mode is disabled
$content = $cache->loadData();
} else { // Content not within duration
} else {
// Contents not within duration, or debug mode is enabled
$content = getContents(
$url,
$header ?? [],
$opts ?? []
);
// todo: fix bad if statement
if ($content !== false) {
$cache->saveData($content);
}
Expand Down
Loading

0 comments on commit ee498ea

Please sign in to comment.