mirror of
https://github.com/RSS-Bridge/rss-bridge.git
synced 2024-11-28 14:18:52 +03:00
feat: enable bridges using env var (#3428)
* refactor: bridgefactory, add tests * refactor: move defaultly enabled bridges to config * refactor * refactor * feat: add support for enabling bridges with env var
This commit is contained in:
parent
d9490c6518
commit
0a8fe57003
19 changed files with 179 additions and 182 deletions
20
README.md
20
README.md
|
@ -51,9 +51,6 @@ chown www-data:www-data /var/www/rss-bridge/cache
|
||||||
|
|
||||||
# Optionally copy over the default config file
|
# Optionally copy over the default config file
|
||||||
cp config.default.ini.php config.ini.php
|
cp config.default.ini.php config.ini.php
|
||||||
|
|
||||||
# Optionally copy over the default whitelist file
|
|
||||||
cp whitelist.default.txt whitelist.txt
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Example config for nginx:
|
Example config for nginx:
|
||||||
|
@ -169,22 +166,17 @@ Learn more in [bridge api](https://rss-bridge.github.io/rss-bridge/Bridge_API/in
|
||||||
|
|
||||||
### How to enable all bridges
|
### How to enable all bridges
|
||||||
|
|
||||||
Write an asterisks to `whitelist.txt`:
|
enabled_bridges[] = *
|
||||||
|
|
||||||
echo '*' > whitelist.txt
|
### How to enable some bridges
|
||||||
|
|
||||||
Learn more in [enabling briges](https://rss-bridge.github.io/rss-bridge/For_Hosts/Whitelisting.html)
|
```
|
||||||
|
enabled_bridges[] = TwitchBridge
|
||||||
### How to enable a bridge
|
enabled_bridges[] = GettrBridge
|
||||||
|
```
|
||||||
Add the bridge name to `whitelist.txt`:
|
|
||||||
|
|
||||||
echo 'FirefoxAddonsBridge' >> whitelist.txt
|
|
||||||
|
|
||||||
### How to enable debug mode
|
### How to enable debug mode
|
||||||
|
|
||||||
Set in `config.ini.php`:
|
|
||||||
|
|
||||||
enable_debug_mode = true
|
enable_debug_mode = true
|
||||||
|
|
||||||
Learn more in [debug mode](https://rss-bridge.github.io/rss-bridge/For_Developers/Debug_mode.html).
|
Learn more in [debug mode](https://rss-bridge.github.io/rss-bridge/For_Developers/Debug_mode.html).
|
||||||
|
|
|
@ -41,18 +41,14 @@ class ConnectivityAction implements ActionInterface
|
||||||
return render_template('connectivity.html.php');
|
return render_template('connectivity.html.php');
|
||||||
}
|
}
|
||||||
|
|
||||||
$bridgeClassName = $this->bridgeFactory->sanitizeBridgeName($request['bridge']);
|
$bridgeClassName = $this->bridgeFactory->createBridgeClassName($request['bridge']);
|
||||||
|
|
||||||
if ($bridgeClassName === null) {
|
|
||||||
throw new \InvalidArgumentException('Bridge name invalid!');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->reportBridgeConnectivity($bridgeClassName);
|
return $this->reportBridgeConnectivity($bridgeClassName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function reportBridgeConnectivity($bridgeClassName)
|
private function reportBridgeConnectivity($bridgeClassName)
|
||||||
{
|
{
|
||||||
if (!$this->bridgeFactory->isWhitelisted($bridgeClassName)) {
|
if (!$this->bridgeFactory->isEnabled($bridgeClassName)) {
|
||||||
throw new \Exception('Bridge is not whitelisted!');
|
throw new \Exception('Bridge is not whitelisted!');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ class DetectAction implements ActionInterface
|
||||||
$bridgeFactory = new BridgeFactory();
|
$bridgeFactory = new BridgeFactory();
|
||||||
|
|
||||||
foreach ($bridgeFactory->getBridgeClassNames() as $bridgeClassName) {
|
foreach ($bridgeFactory->getBridgeClassNames() as $bridgeClassName) {
|
||||||
if (!$bridgeFactory->isWhitelisted($bridgeClassName)) {
|
if (!$bridgeFactory->isEnabled($bridgeClassName)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,20 +18,13 @@ class DisplayAction implements ActionInterface
|
||||||
{
|
{
|
||||||
$bridgeFactory = new BridgeFactory();
|
$bridgeFactory = new BridgeFactory();
|
||||||
|
|
||||||
$bridgeClassName = null;
|
$bridgeClassName = $bridgeFactory->createBridgeClassName($request['bridge'] ?? '');
|
||||||
if (isset($request['bridge'])) {
|
|
||||||
$bridgeClassName = $bridgeFactory->sanitizeBridgeName($request['bridge']);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($bridgeClassName === null) {
|
|
||||||
throw new \InvalidArgumentException('Bridge name invalid!');
|
|
||||||
}
|
|
||||||
|
|
||||||
$format = $request['format'] ?? null;
|
$format = $request['format'] ?? null;
|
||||||
if (!$format) {
|
if (!$format) {
|
||||||
throw new \Exception('You must specify a format!');
|
throw new \Exception('You must specify a format!');
|
||||||
}
|
}
|
||||||
if (!$bridgeFactory->isWhitelisted($bridgeClassName)) {
|
if (!$bridgeFactory->isEnabled($bridgeClassName)) {
|
||||||
throw new \Exception('This bridge is not whitelisted');
|
throw new \Exception('This bridge is not whitelisted');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ final class FrontpageAction implements ActionInterface
|
||||||
|
|
||||||
$body = '';
|
$body = '';
|
||||||
foreach ($bridgeClassNames as $bridgeClassName) {
|
foreach ($bridgeClassNames as $bridgeClassName) {
|
||||||
if ($bridgeFactory->isWhitelisted($bridgeClassName)) {
|
if ($bridgeFactory->isEnabled($bridgeClassName)) {
|
||||||
$body .= BridgeCard::displayBridgeCard($bridgeClassName, $formats);
|
$body .= BridgeCard::displayBridgeCard($bridgeClassName, $formats);
|
||||||
$activeBridges++;
|
$activeBridges++;
|
||||||
} elseif ($showInactive) {
|
} elseif ($showInactive) {
|
||||||
|
|
|
@ -26,7 +26,7 @@ class ListAction implements ActionInterface
|
||||||
$bridge = $bridgeFactory->create($bridgeClassName);
|
$bridge = $bridgeFactory->create($bridgeClassName);
|
||||||
|
|
||||||
$list->bridges[$bridgeClassName] = [
|
$list->bridges[$bridgeClassName] = [
|
||||||
'status' => $bridgeFactory->isWhitelisted($bridgeClassName) ? 'active' : 'inactive',
|
'status' => $bridgeFactory->isEnabled($bridgeClassName) ? 'active' : 'inactive',
|
||||||
'uri' => $bridge->getURI(),
|
'uri' => $bridge->getURI(),
|
||||||
'donationUri' => $bridge->getDonationURI(),
|
'donationUri' => $bridge->getDonationURI(),
|
||||||
'name' => $bridge->getName(),
|
'name' => $bridge->getName(),
|
||||||
|
|
|
@ -23,17 +23,10 @@ class SetBridgeCacheAction implements ActionInterface
|
||||||
|
|
||||||
$bridgeFactory = new BridgeFactory();
|
$bridgeFactory = new BridgeFactory();
|
||||||
|
|
||||||
$bridgeClassName = null;
|
$bridgeClassName = $bridgeFactory->createBridgeClassName($request['bridge'] ?? '');
|
||||||
if (isset($request['bridge'])) {
|
|
||||||
$bridgeClassName = $bridgeFactory->sanitizeBridgeName($request['bridge']);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($bridgeClassName === null) {
|
|
||||||
throw new \InvalidArgumentException('Bridge name invalid!');
|
|
||||||
}
|
|
||||||
|
|
||||||
// whitelist control
|
// whitelist control
|
||||||
if (!$bridgeFactory->isWhitelisted($bridgeClassName)) {
|
if (!$bridgeFactory->isEnabled($bridgeClassName)) {
|
||||||
throw new \Exception('This bridge is not whitelisted', 401);
|
throw new \Exception('This bridge is not whitelisted', 401);
|
||||||
die;
|
die;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,17 @@
|
||||||
|
|
||||||
[system]
|
[system]
|
||||||
|
|
||||||
|
; Only these bridges are available for feed production
|
||||||
|
enabled_bridges[] = Youtube
|
||||||
|
enabled_bridges[] = Twitter
|
||||||
|
enabled_bridges[] = Telegram
|
||||||
|
enabled_bridges[] = Reddit
|
||||||
|
enabled_bridges[] = Filter
|
||||||
|
enabled_bridges[] = Vk
|
||||||
|
enabled_bridges[] = FeedMerge
|
||||||
|
enabled_bridges[] = Twitch
|
||||||
|
enabled_bridges[] = ThePirateBay
|
||||||
|
|
||||||
; Defines the timezone used by RSS-Bridge
|
; Defines the timezone used by RSS-Bridge
|
||||||
; Find a list of supported timezones at
|
; Find a list of supported timezones at
|
||||||
; https://www.php.net/manual/en/timezones.php
|
; https://www.php.net/manual/en/timezones.php
|
||||||
|
|
|
@ -45,5 +45,5 @@ services:
|
||||||
If you want to add a bridge that is not part of [`/bridges`](https://github.com/RSS-Bridge/rss-bridge/tree/master/bridges), you can map a folder to the `/config` folder of the `rss-bridge` container.
|
If you want to add a bridge that is not part of [`/bridges`](https://github.com/RSS-Bridge/rss-bridge/tree/master/bridges), you can map a folder to the `/config` folder of the `rss-bridge` container.
|
||||||
|
|
||||||
1. Create a folder in the location of your docker-compose.yml or your general docker working area (in this example it will be `/home/docker/rssbridge/config` ).
|
1. Create a folder in the location of your docker-compose.yml or your general docker working area (in this example it will be `/home/docker/rssbridge/config` ).
|
||||||
2. Copy your [custom bridges](../05_Bridge_API/01_How_to_create_a_new_bridge.md) to the `/home/docker/rssbridge/config` folder. You can also add your custom [whitelist.txt](../03_For_Hosts/05_Whitelisting.md) file and your custom [config.ini.php](../03_For_Hosts/08_Custom_Configuration.md) to this folder.
|
2. Copy your [custom bridges](../05_Bridge_API/01_How_to_create_a_new_bridge.md) to the `/home/docker/rssbridge/config` folder. Applies also to [config.ini.php](../03_For_Hosts/08_Custom_Configuration.md).
|
||||||
3. Map the folder to `/config` inside the container. To do that, replace the `</local/custom/path>` from the previous examples with `/home/docker/rssbridge/config`
|
3. Map the folder to `/config` inside the container. To do that, replace the `</local/custom/path>` from the previous examples with `/home/docker/rssbridge/config`
|
|
@ -14,7 +14,7 @@ You can simply press the button below to easily deploy RSS Bridge on Heroku and
|
||||||
|
|
||||||
![image](../images/fork_button.png)
|
![image](../images/fork_button.png)
|
||||||
|
|
||||||
2. To customise what bridges can be used if need, create a `whitelist.txt` file in your fork and follow the instructions given [here](../03_For_Hosts/05_Whitelisting.md). You don’t need to do this if you’re fine with the default bridges.
|
2. To customise what bridges can be used if need, see [here](../03_For_Hosts/05_Whitelisting.md). You don’t need to do this if you’re fine with the default bridges.
|
||||||
|
|
||||||
3. [Log in to Heroku](https://dashboard.heroku.com) and create a new app. The app name will be the URL of the RSS Bridge (appname.herokuapp.com)
|
3. [Log in to Heroku](https://dashboard.heroku.com) and create a new app. The app name will be the URL of the RSS Bridge (appname.herokuapp.com)
|
||||||
|
|
||||||
|
|
|
@ -1,38 +1,26 @@
|
||||||
RSS-Bridge supports whitelists in order to limit the available bridges on your web server.
|
Modify `config.ini.php` to limit available bridges.
|
||||||
|
|
||||||
A default whitelist file (`whitelist.default.txt`) is shipped with RSS-Bridge. Please do not edit this file, as it gets replaced when upgrading RSS-Bridge!
|
## Enable all bridges
|
||||||
|
|
||||||
You should, however, use this file as template to create your own whitelist (or leave it as is, to keep the default bridges). In order to create your own whitelist perform following actions:
|
```
|
||||||
|
enabled_bridges[] = *
|
||||||
* Copy the file `whitelist.default.txt` in the RSS-Bridge root folder
|
|
||||||
* Rename the new file to `whitelist.txt`
|
|
||||||
* Change the lines to satisfy your requirements
|
|
||||||
|
|
||||||
RSS-Bridge will automatically detect the `whitelist.txt` and use it. If the file doesn't exist it will default to `whitelist.default.txt` automatically.
|
|
||||||
|
|
||||||
# Specific whitelisting
|
|
||||||
|
|
||||||
In order to specifically whitelist bridges, open `whitelist.txt` and add one line for each bridge you want to show. Make sure you use normal [line-feeds](https://en.wikipedia.org/wiki/Newline "Line-feed") at the end of a line (LF not [CRLF](https://en.wikipedia.org/wiki/Carriage_return "Carriage-return line-feed")). The bridge name must match the filename of the bridge in the bridges folder (see [folder structure](../04_For_Developers/03_Folder_structure.md)). The name may or may not include the 'Bridge' part.
|
|
||||||
|
|
||||||
**Examples**:
|
|
||||||
```TEXT
|
|
||||||
FacebookBridge
|
|
||||||
WikipediaBridge
|
|
||||||
TwitterBridge
|
|
||||||
```
|
```
|
||||||
|
|
||||||
or
|
## Enable some bridges
|
||||||
|
|
||||||
```TEXT
|
```
|
||||||
Facebook
|
enabled_bridges[] = TwitchBridge
|
||||||
Wikipedia
|
enabled_bridges[] = GettrBridge
|
||||||
Twitter
|
|
||||||
```
|
```
|
||||||
|
|
||||||
# Global whitelisting
|
## Enable all bridges (legacy shortcut)
|
||||||
|
|
||||||
In order to globally whitelist all bridges, open the `whitelist.txt` file, remove all contents and just write an asterisk `*` into the file (only this one character).
|
```
|
||||||
|
echo '*' > whitelist.txt
|
||||||
```TEXT
|
```
|
||||||
*
|
|
||||||
|
## Enable some bridges (legacy shortcut)
|
||||||
|
|
||||||
|
```
|
||||||
|
echo -e "TwitchBridge\nTwitterBridge" > whitelist.txt
|
||||||
```
|
```
|
|
@ -2,101 +2,69 @@
|
||||||
|
|
||||||
final class BridgeFactory
|
final class BridgeFactory
|
||||||
{
|
{
|
||||||
/** @var array<class-string<BridgeInterface>> */
|
|
||||||
private $bridgeClassNames = [];
|
private $bridgeClassNames = [];
|
||||||
|
private $enabledBridges = [];
|
||||||
/** @var array<class-string<BridgeInterface>> */
|
|
||||||
private $whitelist = [];
|
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
// create names
|
// Create all possible bridge class names from fs
|
||||||
foreach (scandir(__DIR__ . '/../bridges/') as $file) {
|
foreach (scandir(__DIR__ . '/../bridges/') as $file) {
|
||||||
if (preg_match('/^([^.]+Bridge)\.php$/U', $file, $m)) {
|
if (preg_match('/^([^.]+Bridge)\.php$/U', $file, $m)) {
|
||||||
$this->bridgeClassNames[] = $m[1];
|
$this->bridgeClassNames[] = $m[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// create whitelist
|
$enabledBridges = Configuration::getConfig('system', 'enabled_bridges');
|
||||||
if (file_exists(WHITELIST)) {
|
if ($enabledBridges === null) {
|
||||||
$contents = trim(file_get_contents(WHITELIST));
|
throw new \Exception('No bridges are enabled... wtf?');
|
||||||
} elseif (file_exists(WHITELIST_DEFAULT)) {
|
|
||||||
$contents = trim(file_get_contents(WHITELIST_DEFAULT));
|
|
||||||
} else {
|
|
||||||
$contents = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($contents === '*') {
|
|
||||||
// Whitelist all bridges
|
|
||||||
$this->whitelist = $this->getBridgeClassNames();
|
|
||||||
} else {
|
|
||||||
foreach (explode("\n", $contents) as $bridgeName) {
|
|
||||||
$bridgeClassName = $this->sanitizeBridgeName($bridgeName);
|
|
||||||
if ($bridgeClassName !== null) {
|
|
||||||
$this->whitelist[] = $bridgeClassName;
|
|
||||||
}
|
}
|
||||||
|
foreach ($enabledBridges as $enabledBridge) {
|
||||||
|
if ($enabledBridge === '*') {
|
||||||
|
$this->enabledBridges = $this->bridgeClassNames;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
$this->enabledBridges[] = $this->createBridgeClassName($enabledBridge);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param class-string<BridgeInterface> $name
|
|
||||||
*/
|
|
||||||
public function create(string $name): BridgeInterface
|
public function create(string $name): BridgeInterface
|
||||||
{
|
{
|
||||||
return new $name();
|
return new $name();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function isEnabled(string $bridgeName): bool
|
||||||
* @return array<class-string<BridgeInterface>>
|
{
|
||||||
*/
|
return in_array($bridgeName, $this->enabledBridges);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function createBridgeClassName(string $bridgeName): ?string
|
||||||
|
{
|
||||||
|
$name = self::normalizeBridgeName($bridgeName);
|
||||||
|
$namesLoweredCase = array_map('strtolower', $this->bridgeClassNames);
|
||||||
|
$nameLoweredCase = strtolower($name);
|
||||||
|
|
||||||
|
if (! in_array($nameLoweredCase, $namesLoweredCase)) {
|
||||||
|
throw new \Exception(sprintf('Bridge name invalid: %s', $bridgeName));
|
||||||
|
}
|
||||||
|
|
||||||
|
$index = array_search($nameLoweredCase, $namesLoweredCase);
|
||||||
|
|
||||||
|
return $this->bridgeClassNames[$index];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function normalizeBridgeName(string $name)
|
||||||
|
{
|
||||||
|
if (preg_match('/(.+)(?:\.php)/', $name, $matches)) {
|
||||||
|
$name = $matches[1];
|
||||||
|
}
|
||||||
|
if (!preg_match('/(Bridge)$/i', $name)) {
|
||||||
|
$name = sprintf('%sBridge', $name);
|
||||||
|
}
|
||||||
|
return $name;
|
||||||
|
}
|
||||||
|
|
||||||
public function getBridgeClassNames(): array
|
public function getBridgeClassNames(): array
|
||||||
{
|
{
|
||||||
return $this->bridgeClassNames;
|
return $this->bridgeClassNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param class-string<BridgeInterface>|null $name
|
|
||||||
*/
|
|
||||||
public function isWhitelisted(string $name): bool
|
|
||||||
{
|
|
||||||
return in_array($name, $this->whitelist);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tries to turn a potentially human produced bridge name into a class name.
|
|
||||||
*
|
|
||||||
* @param mixed $name
|
|
||||||
* @return class-string<BridgeInterface>|null
|
|
||||||
*/
|
|
||||||
public function sanitizeBridgeName($name): ?string
|
|
||||||
{
|
|
||||||
if (!is_string($name)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trim trailing '.php' if exists
|
|
||||||
if (preg_match('/(.+)(?:\.php)/', $name, $matches)) {
|
|
||||||
$name = $matches[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Append 'Bridge' suffix if not present.
|
|
||||||
if (!preg_match('/(Bridge)$/i', $name)) {
|
|
||||||
$name = sprintf('%sBridge', $name);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Improve performance for correctly written bridge names
|
|
||||||
if (in_array($name, $this->getBridgeClassNames())) {
|
|
||||||
$index = array_search($name, $this->getBridgeClassNames());
|
|
||||||
return $this->getBridgeClassNames()[$index];
|
|
||||||
}
|
|
||||||
|
|
||||||
// The name is valid if a corresponding bridge file is found on disk
|
|
||||||
if (in_array(strtolower($name), array_map('strtolower', $this->getBridgeClassNames()))) {
|
|
||||||
$index = array_search(strtolower($name), array_map('strtolower', $this->getBridgeClassNames()));
|
|
||||||
return $this->getBridgeClassNames()[$index];
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,21 +98,6 @@ final class Configuration
|
||||||
self::setConfig($header, $key, $value);
|
self::setConfig($header, $key, $value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach ($env as $envName => $envValue) {
|
|
||||||
$nameParts = explode('_', $envName);
|
|
||||||
if ($nameParts[0] === 'RSSBRIDGE') {
|
|
||||||
if (count($nameParts) < 3) {
|
|
||||||
// Invalid env name
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$header = $nameParts[1];
|
|
||||||
$key = $nameParts[2];
|
|
||||||
if ($envValue === 'true' || $envValue === 'false') {
|
|
||||||
$envValue = filter_var($envValue, FILTER_VALIDATE_BOOLEAN);
|
|
||||||
}
|
|
||||||
self::setConfig($header, $key, $envValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file_exists(__DIR__ . '/../DEBUG')) {
|
if (file_exists(__DIR__ . '/../DEBUG')) {
|
||||||
// The debug mode has been moved to config. Preserve existing installs which has this DEBUG file.
|
// The debug mode has been moved to config. Preserve existing installs which has this DEBUG file.
|
||||||
|
@ -123,6 +108,47 @@ final class Configuration
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (file_exists(__DIR__ . '/../whitelist.txt')) {
|
||||||
|
$whitelist = trim(file_get_contents(__DIR__ . '/../whitelist.txt'));
|
||||||
|
if ($whitelist === '*') {
|
||||||
|
self::setConfig('system', 'enabled_bridges', ['*']);
|
||||||
|
} else {
|
||||||
|
self::setConfig('system', 'enabled_bridges', explode("\n", $whitelist));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($env as $envName => $envValue) {
|
||||||
|
$nameParts = explode('_', $envName);
|
||||||
|
if ($nameParts[0] === 'RSSBRIDGE') {
|
||||||
|
if (count($nameParts) < 3) {
|
||||||
|
// Invalid env name
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The variable is named $header but it's actually the section in config.ini.php
|
||||||
|
$header = $nameParts[1];
|
||||||
|
|
||||||
|
// Recombine the key if it had multiple underscores
|
||||||
|
$key = implode('_', array_slice($nameParts, 2));
|
||||||
|
|
||||||
|
// Handle this specifically because it's an array
|
||||||
|
if ($key === 'enabled_bridges') {
|
||||||
|
$envValue = explode(',', $envValue);
|
||||||
|
$envValue = array_map('trim', $envValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($envValue === 'true' || $envValue === 'false') {
|
||||||
|
$envValue = filter_var($envValue, FILTER_VALIDATE_BOOLEAN);
|
||||||
|
}
|
||||||
|
|
||||||
|
self::setConfig($header, $key, $envValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_array(self::getConfig('system', 'enabled_bridges'))) {
|
||||||
|
self::throwConfigError('system', 'enabled_bridges', 'Is not an array');
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!is_string(self::getConfig('system', 'timezone'))
|
!is_string(self::getConfig('system', 'timezone'))
|
||||||
|| !in_array(self::getConfig('system', 'timezone'), timezone_identifiers_list(DateTimeZone::ALL_WITH_BC))
|
|| !in_array(self::getConfig('system', 'timezone'), timezone_identifiers_list(DateTimeZone::ALL_WITH_BC))
|
||||||
|
|
|
@ -29,12 +29,6 @@ const PATH_LIB_ACTIONS = __DIR__ . '/../actions/';
|
||||||
/** Path to the cache folder */
|
/** Path to the cache folder */
|
||||||
const PATH_CACHE = __DIR__ . '/../cache/';
|
const PATH_CACHE = __DIR__ . '/../cache/';
|
||||||
|
|
||||||
/** Path to the whitelist file */
|
|
||||||
const WHITELIST = __DIR__ . '/../whitelist.txt';
|
|
||||||
|
|
||||||
/** Path to the default whitelist file */
|
|
||||||
const WHITELIST_DEFAULT = __DIR__ . '/../whitelist.default.txt';
|
|
||||||
|
|
||||||
/** URL to the RSS-Bridge repository */
|
/** URL to the RSS-Bridge repository */
|
||||||
const REPOSITORY = 'https://github.com/RSS-Bridge/rss-bridge/';
|
const REPOSITORY = 'https://github.com/RSS-Bridge/rss-bridge/';
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,11 @@ class ActionImplementationTest extends TestCase
|
||||||
private $class;
|
private $class;
|
||||||
private $obj;
|
private $obj;
|
||||||
|
|
||||||
|
public function setUp(): void
|
||||||
|
{
|
||||||
|
\Configuration::loadConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider dataActionsProvider
|
* @dataProvider dataActionsProvider
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -7,6 +7,11 @@ use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
class ListActionTest extends TestCase
|
class ListActionTest extends TestCase
|
||||||
{
|
{
|
||||||
|
public function setUp(): void
|
||||||
|
{
|
||||||
|
\Configuration::loadConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
public function testHeaders()
|
public function testHeaders()
|
||||||
{
|
{
|
||||||
$action = new \ListAction();
|
$action = new \ListAction();
|
||||||
|
|
30
tests/BridgeFactoryTest.php
Normal file
30
tests/BridgeFactoryTest.php
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace RssBridge\Tests;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
class BridgeFactoryTest extends TestCase
|
||||||
|
{
|
||||||
|
public function setUp(): void
|
||||||
|
{
|
||||||
|
\Configuration::loadConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testNormalizeBridgeName()
|
||||||
|
{
|
||||||
|
$this->assertSame('TwitterBridge', \BridgeFactory::normalizeBridgeName('TwitterBridge'));
|
||||||
|
$this->assertSame('TwitterBridge', \BridgeFactory::normalizeBridgeName('TwitterBridge.php'));
|
||||||
|
$this->assertSame('TwitterBridge', \BridgeFactory::normalizeBridgeName('Twitter'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testSanitizeBridgeName()
|
||||||
|
{
|
||||||
|
$sut = new \BridgeFactory();
|
||||||
|
|
||||||
|
$this->assertSame('TwitterBridge', $sut->createBridgeClassName('twitterbridge'));
|
||||||
|
$this->assertSame('TwitterBridge', $sut->createBridgeClassName('twitter'));
|
||||||
|
$this->assertSame('TwitterBridge', $sut->createBridgeClassName('tWitTer'));
|
||||||
|
$this->assertSame('TwitterBridge', $sut->createBridgeClassName('TWITTERBRIDGE'));
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,13 +26,18 @@ final class ConfigurationTest extends TestCase
|
||||||
|
|
||||||
public function testValueFromEnv()
|
public function testValueFromEnv()
|
||||||
{
|
{
|
||||||
putenv('RSSBRIDGE_system_timezone=Europe/Berlin');
|
$env = [
|
||||||
putenv('RSSBRIDGE_TwitterV2Bridge_twitterv2apitoken=aaa');
|
'RSSBRIDGE_system_timezone' => 'Europe/Berlin',
|
||||||
putenv('RSSBRIDGE_SQLiteCache_file=bbb');
|
'RSSBRIDGE_SYSTEM_MESSAGE' => 'hello',
|
||||||
Configuration::loadConfiguration([], getenv());
|
'RSSBRIDGE_system_enabled_bridges' => 'TwitterBridge,GettrBridge',
|
||||||
|
'RSSBRIDGE_system_enable_debug_mode' => 'true',
|
||||||
|
'RSSBRIDGE_fileCache_path' => '/tmp/kek',
|
||||||
|
];
|
||||||
|
Configuration::loadConfiguration([], $env);
|
||||||
$this->assertSame('Europe/Berlin', Configuration::getConfig('system', 'timezone'));
|
$this->assertSame('Europe/Berlin', Configuration::getConfig('system', 'timezone'));
|
||||||
$this->assertSame('aaa', Configuration::getConfig('TwitterV2Bridge', 'twitterv2apitoken'));
|
$this->assertSame('hello', Configuration::getConfig('system', 'message'));
|
||||||
$this->assertSame('bbb', Configuration::getConfig('SQLiteCache', 'file'));
|
$this->assertSame(true, Configuration::getConfig('system', 'enable_debug_mode'));
|
||||||
$this->assertSame('bbb', Configuration::getConfig('sqlitecache', 'file'));
|
$this->assertSame('/tmp/kek', Configuration::getConfig('FileCache', 'path'));
|
||||||
|
$this->assertSame(['TwitterBridge', 'GettrBridge'], Configuration::getConfig('system', 'enabled_bridges'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
Youtube
|
|
||||||
Twitter
|
|
||||||
Telegram
|
|
||||||
Reddit
|
|
||||||
Filter
|
|
||||||
Vk
|
|
||||||
FeedMerge
|
|
||||||
Twitch
|
|
||||||
ThePirateBay
|
|
Loading…
Reference in a new issue