added admin option for configuring Aria2 globally;option for diallowing aria2 settings for non-privileged users;cleanining up

This commit is contained in:
huangjx
2022-07-31 22:30:32 +08:00
parent e85b8b87ba
commit b1b8bcf988
16 changed files with 284 additions and 129 deletions

View File

@@ -9,6 +9,8 @@ use OCA\NCDownloader\Tools\Helper;
class Aria2
{
//global Aria2 Config
private $config = [];
//extra Aria2 download options
private $options = array();
//optional token for authenticating with Aria2
@@ -25,18 +27,33 @@ class Aria2
private $filterResponse = true;
//absolute download path
private $downloadDir;
//top-level aria2 configuration dir
private $confDir;
//aria2 session file
private $sessionFile;
//aria2 rpc url
private $rpcUrl;
//php binary path;
private $php;
public function __construct($options = array())
{
$options += array(
'host' => '127.0.0.1',
'port' => 6800,
$options += [
'rpcHost' => '127.0.0.1',
'rpcPort' => 6800,
'dir' => '/tmp/Downloads',
'torrents_dir' => '/tmp/Torrents',
'token' => null,
'conf_dir' => '/tmp/aria2',
'completeHook' => $_SERVER['DOCUMENT_ROOT'] . "/apps/ncdownloader/hooks/completeHook.sh",
'torrentsDir' => '/tmp/Torrents',
'token' => 'ncdownloader123',
'confDir' => '/tmp/aria2',
//settings for each aria2 downloads
'settings' => [],
);
//options wich which aria2c starts
'aria2Conf' => []
];
//set the hooks if no user-defined equivalents
$options["aria2Conf"] += [
'on-download-complete' => $_SERVER['DOCUMENT_ROOT'] . "/apps/ncdownloader/hooks/completeHook.sh",
'on-download-start' => $_SERVER['DOCUMENT_ROOT'] . "/apps/ncdownloader/hooks/startHook.sh",
];
//turn keys in $options into variables
extract($options);
if (isset($binary) && $this->isExecutable($binary)) {
@@ -47,27 +64,12 @@ class Aria2
if ($this->isInstalled() && !$this->isExecutable()) {
chmod($this->bin, 0744);
}
$this->setDownloadDir($dir);
$this->setTorrentsDir($torrents_dir);
if (!empty($settings)) {
foreach ($settings as $key => $value) {
$this->setOption($key, $value);
}
}
$this->confDir = $confDir;
$this->php = Helper::findBinaryPath('php');
$this->completeHook = $completeHook;
$this->startHook = $startHook;
$this->rpcUrl = sprintf("http://%s:%s/jsonrpc", $host, $port);
$this->tokenString = $token ?? 'ncdownloader123';
$this->rpcPort = $rpcPort ?? 6800;
$this->dlSpeed = $dlSpeed ?? 0;
$this->upSpeed = $upSpeed ?? "1M";
$this->logLevel = $logLevel ?? 'warn';
$this->setToken($this->tokenString);
$this->confDir = $conf_dir;
$this->sessionFile = $this->confDir . "/aria2.session";
//$this->confFile = $this->confDir . "/aria2.conf";
$this->logFile = $this->confDir . "/aria2.log";
$this->rpcUrl = sprintf("http://%s:%s/jsonrpc", $rpcHost, $rpcPort);
$this->sessionFile = $sessionFile ?? $this->confDir . "/aria2.session";
$this->configureGlobalAria2($options);
$this->configureLocalAria2($options);
}
public function init()
{
@@ -81,6 +83,32 @@ class Aria2
$this->configure();
}
private function configureLocalAria2(array $options)
{
$this->setDownloadDir($options["dir"]);
$this->setTorrentsDir($options["torrentsDir"]);
$this->setToken($options["token"]);
if (!empty($options["settings"])) {
foreach ($options["settings"] as $key => $value) {
$this->setOption($key, $value);
}
}
}
private function configureGlobalAria2(array $options)
{
$runOptions = new RunOptions($options["aria2Conf"]);
$runOptions->add("--rpc-secret=" . $options["token"]);
$runOptions->add("--rpc-listen-port=" . $options["rpcPort"]);
$runOptions->add("--save-session=" . $this->sessionFile);
$runOptions->add("--input-file=" . $this->sessionFile);
$runOptions->add("--log=" . $this->confDir . "/aria2.log");
//$this->logFile = $this->confDir . "/aria2.log";
$this->config = $runOptions->getOptions();
}
public function setonDownloadStart($path)
{
$this->onDownloadStart = $path;
@@ -284,11 +312,6 @@ class Aria2
{
return $this->tellStatus($gid);
}
public function restart()
{
$this->stop();
$this->start();
}
public function download(String $url)
{
@@ -325,35 +348,19 @@ class Aria2
return false;
}
public function getDefaults()
public function restart()
{
return [
'--continue',
'--daemon=true',
'--enable-rpc=true',
'--rpc-secret=' . $this->tokenString,
'--listen-port=51413',
'--save-session=' . $this->sessionFile,
'--input-file=' . $this->sessionFile,
'--log=' . $this->logFile,
'--rpc-listen-port=' . $this->rpcPort,
'--follow-torrent=true',
'--enable-dht=true',
'--enable-peer-exchange=true',
'--peer-id-prefix=-TR2770-',
'--user-agent=Transmission/2.77',
'--log-level=' . $this->logLevel,
'--seed-ratio=1.0',
'--bt-seed-unverified=true',
'--max-overall-upload-limit=' . $this->upSpeed,
'--max-overall-download-limit=' . $this->dlSpeed,
'--max-connection-per-server=4',
'--max-concurrent-downloads=10',
'--check-certificate=false',
'--on-download-complete=' . $this->completeHook,
'--on-download-start=' . $this->startHook,
];
$this->stop();
$this->start();
}
public function stop()
{
$resp = $this->shutdown();
sleep(3);
return $resp ?? null;
}
public function start($bin = null)
{
//aria2c refuses to start with no errors when input-file is set but missing
@@ -362,9 +369,8 @@ class Aria2
}
//$process = new Process([$this->bin, "--conf-path=" . $this->confFile]);
$defaults = $this->getDefaults();
array_unshift($defaults, $this->bin);
$process = new Process($defaults);
array_unshift($this->config, $this->bin);
$process = new Process($this->config);
try {
$process->mustRun();
$output = $process->getOutput();
@@ -399,10 +405,4 @@ class Aria2
{
return $this->bin;
}
public function stop()
{
$resp = $this->shutdown();
sleep(3);
return $resp ?? null;
}
}

82
lib/Aria2/RunOptions.php Normal file
View File

@@ -0,0 +1,82 @@
<?php
namespace OCA\NCDownloader\Aria2;
class RunOptions
{
protected $options = [
'--continue',
'--daemon=true',
'--enable-rpc=true',
'--rpc-secret=ncdownloader123',
'--listen-port=51413',
'--rpc-listen-port=6800',
'--follow-torrent=true',
'--enable-dht=true',
'--enable-peer-exchange=true',
'--peer-id-prefix=-TR2770-',
'--user-agent=Transmission/2.77',
'--log-level=notice',
'--seed-ratio=1.0',
'--bt-seed-unverified=true',
// '--max-overall-upload-limit=' . $this->upSpeed,
// '--max-overall-download-limit=' . $this->dlSpeed,
'--max-connection-per-server=4',
'--max-concurrent-downloads=10',
'--check-certificate=false',
];
public function __construct($options)
{
foreach ($options as $name => $value) {
$name = trim($name);
$value = trim($value);
if (!str_starts_with($value, "--")) {
$name = "--" . $name;
}
if ($value) {
$option = $name . "=" . $value;
} else {
$option = $name;
}
$this->add($option);
}
}
public function add($option)
{
$option = trim($option);
if ($i = $this->find($option)) {
$this->options[$i] = $option;
return $this;
}
array_push($this->options, $option);
return $this;
}
protected function find($option)
{
if (!str_starts_with($option, "--")) {
$option = "--" . $option;
}
if (($i = stripos($option, '=')) === false) {
return $i;
}
$name = substr($option, 0, $i);
foreach ($this->options as $index => $value) {
list($optionName,) = explode("=", $value);
if ($name == $optionName) {
return $index;
}
}
return false;
}
public function has($option)
{
return (bool) array_search($option, $this->options);
}
public function getOptions()
{
return $this->options;
}
}

View File

@@ -42,7 +42,7 @@ class MainController extends Controller
$this->ytdl = $ytdl;
$this->isAdmin = \OC_User::isAdminUser($this->uid);
$this->hideError = Helper::getSettings("ncd_hide_errors", false);
$this->disable_bt_nonadmin = Helper::getSettings("ncd_disable_bt", false, Settings::TYPE["SYSTEM"]);
$this->disable_bt_nonadmin = Helper::getAdminSettings("ncd_disable_bt");
$this->accessDenied = $this->l10n->t("Sorry,only admin users can download files via BT!");
}
/**
@@ -117,6 +117,7 @@ class MainController extends Controller
'ncd_hide_errors' => $this->hideError,
'ncd_disable_bt' => $this->disable_bt_nonadmin,
'ncd_downloader_dir' => Helper::getSettings("ncd_downloader_dir"),
'disallow_aria2_settings' => Helper::getAdminSettings('disallow_aria2_settings'),
]);
return $params;
}
@@ -159,7 +160,7 @@ class MainController extends Controller
'type' => Helper::DOWNLOADTYPE['ARIA2'],
'filename' => empty($filename) ? "unknown" : $filename,
'timestamp' => time(),
'data' => serialize(['link' => $url,'path' => Helper::getDownloadDir()]),
'data' => serialize(['link' => $url, 'path' => Helper::getDownloadDir()]),
];
$this->dbconn->save($data);
$resp = ['message' => $filename, 'result' => $result, 'file' => $filename];
@@ -217,5 +218,4 @@ class MainController extends Controller
$counter = $this->counters->getCounters();
return new JSONResponse(['counter' => $counter]);
}
}

View File

@@ -41,7 +41,7 @@ class SettingsController extends Controller
* @NoAdminRequired
* @NoCSRFRequired
*/
public function personal()
public function saveCustom()
{
$params = $this->request->getParams();
foreach ($params as $key => $value) {
@@ -54,31 +54,33 @@ class SettingsController extends Controller
* @NoAdminRequired
* @NoCSRFRequired
*/
public function aria2Get()
public function getCustomAria2()
{
$data = json_decode($this->settings->get("custom_aria2_settings"));
return new JSONResponse($data);
}
public function admin()
public function saveAdmin()
{
$this->settings->setType($this->settings::TYPE['SYSTEM']);
$params = $this->request->getParams();
$data = $this->settings->setType(Settings::TYPE["SYSTEM"])->get("ncd_admin_settings", []);
foreach ($params as $key => $value) {
$resp = $this->save($key, $value);
if (substr($key, 0, 1) == '_') {
continue;
}
$data[$key] = $value;
}
$resp = $this->save("ncd_admin_settings", $data, Settings::TYPE["SYSTEM"]);
return new JSONResponse($resp);
}
public function saveAria2Admin()
public function saveGlobalAria2()
{
$this->settings->setType($this->settings::TYPE['SYSTEM']);
$params = $this->request->getParams();
$data = Helper::filterData($params, Helper::aria2Options());
Helper::log($data);
$resp = $this->settings->save("admin_aria2_settings", $data);
$resp = $this->save("global_aria2_config", $data, $this->settings::TYPE['SYSTEM']);
return new JSONResponse($resp);
}
@@ -86,16 +88,21 @@ class SettingsController extends Controller
*
* @NoCSRFRequired
*/
public function getAria2Admin()
public function getGlobalAria2()
{
return new JSONResponse(Helper::getSettings("admin_aria2_settings", "", $this->settings::TYPE['SYSTEM']));
return new JSONResponse(Helper::getSettings("global_aria2_config", "", $this->settings::TYPE['SYSTEM']));
}
/**
* @NoAdminRequired
* @NoCSRFRequired
*/
public function aria2Save()
public function saveCustomAria2()
{
$noAria2Settings = (bool) Helper::getAdminSettings("disallow_aria2_settings");
if (!$noAria2Settings) {
$resp = ["error" => "forbidden", "status" => false];
return new JSONResponse($resp);
}
$params = $this->request->getParams();
$data = Helper::filterData($params, Helper::aria2Options());
$resp = $this->settings->save("custom_aria2_settings", json_encode($data));
@@ -105,7 +112,7 @@ class SettingsController extends Controller
* @NoAdminRequired
* @NoCSRFRequired
*/
public function aria2Delete()
public function deleteCustomAria2()
{
$saved = json_decode($this->settings->get("custom_aria2_settings"), 1);
$params = $this->request->getParams();
@@ -121,13 +128,13 @@ class SettingsController extends Controller
* @NoAdminRequired
* @NoCSRFRequired
*/
public function ytdlGet()
public function getYtdl()
{
$data = json_decode($this->settings->get("custom_ytdl_settings"));
return new JSONResponse($data);
}
public function ytdlSave()
public function saveYtdl()
{
$params = $this->request->getParams();
$data = array_filter($params, function ($key) {
@@ -140,7 +147,7 @@ class SettingsController extends Controller
* @NoAdminRequired
* @NoCSRFRequired
*/
public function ytdlDelete()
public function deleteYtdl()
{
$saved = json_decode($this->settings->get("custom_ytdl_settings"), 1);
$params = $this->request->getParams();
@@ -150,15 +157,22 @@ class SettingsController extends Controller
$resp = $this->settings->save("custom_ytdl_settings", json_encode($saved));
return new JSONResponse($resp);
}
public function save($key, $value)
public function save($key, $value, $type = Settings::TYPE["USER"])
{
//key starting with _ is invalid
if (substr($key, 0, 1) == '_') {
return;
}
$key = Helper::sanitize($key);
$value = Helper::sanitize($value);
if (is_array($value)) {
foreach ($value as $k => &$v) {
$value[$k] = Helper::sanitize($v);
}
} else {
$value = Helper::sanitize($value);
}
try {
$this->settings->setType($type);
$this->settings->save($key, $value);
} catch (\Exception $e) {
return ['error' => $e->getMessage(), "status" => false];

View File

@@ -8,6 +8,8 @@ use OCP\IConfig;
use OCP\IDBConnection;
use OCP\Settings\ISettings;
use OCA\NCDownloader\Db\Settings;
use OCA\NCDownloader\Tools\Helper;
class Admin implements ISettings
{
@@ -36,16 +38,13 @@ class Admin implements ISettings
*/
public function getForm()
{
$this->settings->setType($this->settings::TYPE['SYSTEM']);
$settings = Helper::getAllAdminSettings();
$settings += [
"path" => "/apps/ncdownloader/admin/save",
];
$parameters = [
'settings' => [
"path" => "/apps/ncdownloader/admin/save",
"ncd_yt_binary" => $this->settings->get("ncd_yt_binary"),
"ncd_aria2_binary" => $this->settings->get("ncd_aria2_binary"),
"ncd_rpctoken" => $this->settings->get("ncd_rpctoken"),
"ncd_aria2_rpc_host" => $this->settings->get("ncd_aria2_rpc_host"),
"ncd_aria2_rpc_port" => $this->settings->get("ncd_aria2_rpc_port"),
]
'settings' => $settings,
];
return new TemplateResponse('ncdownloader', 'settings/Admin', $parameters, '');
}

View File

@@ -45,6 +45,7 @@ class Personal implements ISettings
'ncd_seed_time_unit' => $this->settings->get("ncd_seed_time_unit"),
'ncd_seed_time' => $this->settings->get("ncd_seed_time"),
"path" => '/apps/ncdownloader/personal/save',
"disallow_aria2_settings" => Helper::getAdminSettings("disallow_aria2_settings"),
]
];

View File

@@ -454,22 +454,28 @@ class Helper
$torrentsDir = Helper::getRealTorrentsDir();
$appPath = self::getAppPath();
$dataDir = self::getDataDir();
$aria2_dir = $dataDir . "/aria2";
$aria2Dir = $dataDir . "/aria2";
$options['seed_time'] = $settings->get("ncd_seed_time");
$options['seed_ratio'] = $settings->get("ncd_seed_ratio");
if (is_array($customSettings = $settings->getAria2())) {
$options = array_merge($customSettings, $options);
}
$token = $settings->setType(Settings::TYPE['SYSTEM'])->get('ncd_rpctoken');
$token = Helper::getAdminSettings("ncd_aria2_rpc_token");
$rpcHost = Helper::getAdminSettings("ncd_aria2_rpc_host");
$rpcPort = Helper::getAdminSettings("ncd_aria2_rpc_port");
$binary = Helper::getAdminSettings("ncd_aria2_binary");
$config = [
'dir' => $realDownloadDir,
'torrents_dir' => $torrentsDir,
'conf_dir' => $aria2_dir,
'token' => $token,
'torrentsDir' => $torrentsDir,
'confDir' => $aria2Dir,
'token' => $token ? $token : "ncdownloader123",
'settings' => $options,
'binary' => $settings->setType(Settings::TYPE['SYSTEM'])->get('ncd_aria2_binary'),
'rpcHost' => $rpcHost ? $rpcHost : "127.0.0.1",
'rpcPort' => $rpcPort ? $rpcPort : "6800",
'binary' => $binary,
'startHook' => $appPath . "/hooks/startHook.sh",
'completeHook' => $appPath . "/hooks/completeHook.sh",
'aria2Conf' => Helper::getSettings("global_aria2_config", [], $settings::TYPE['SYSTEM'])
];
return $config;
}
@@ -522,4 +528,13 @@ class Helper
{
return self::isLegacyVersion() ? \OC::$server->getDatabaseConnection() : \OC::$server->get(\OCP\IDBConnection::class);
}
public static function getAdminSettings($key): string
{
$settings = self::getAllAdminSettings();
return $settings[$key] ?? "";
}
public static function getAllAdminSettings(): array
{
return Helper::getSettings("ncd_admin_settings", [], Settings::TYPE["SYSTEM"]);
}
}