From f81c441920d2de087099c85f0119e823d15225c4 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Tue, 4 Oct 2016 21:06:37 +0200 Subject: Fix bug language option for new user https://github.com/FreshRSS/FreshRSS/issues/1273 --- app/Controllers/userController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'app/Controllers/userController.php') diff --git a/app/Controllers/userController.php b/app/Controllers/userController.php index 0521bc008..c259ffde9 100644 --- a/app/Controllers/userController.php +++ b/app/Controllers/userController.php @@ -121,7 +121,7 @@ class FreshRSS_user_Controller extends Minz_ActionController { $new_user_language = Minz_Request::param('new_user_language', FreshRSS_Context::$user_conf->language); $languages = Minz_Translate::availableLanguages(); - if (!isset($languages[$new_user_language])) { + if (!in_array($new_user_language, $languages)) { $new_user_language = FreshRSS_Context::$user_conf->language; } @@ -165,7 +165,7 @@ class FreshRSS_user_Controller extends Minz_ActionController { } if ($ok) { $userDAO = new FreshRSS_UserDAO(); - $ok &= $userDAO->createUser($new_user_name); + $ok &= $userDAO->createUser($new_user_name, $new_user_language); } invalidateHttpCache(); -- cgit v1.2.3 From e1f214e9e2e09a83a9920e33fbf617dfe48fbb7e Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sat, 22 Oct 2016 12:58:06 +0200 Subject: CLI list-users and create-user https://github.com/FreshRSS/FreshRSS/issues/1095 https://github.com/FreshRSS/FreshRSS/issues/1090 --- app/Controllers/userController.php | 125 +++++++++++++++++++------------------ app/Models/Context.php | 2 +- app/Models/Feed.php | 2 +- app/actualize_script.php | 4 +- cli/.htaccess | 3 + cli/_cli.php | 39 ++++++++++++ cli/create-user.php | 41 ++++++++++++ cli/index.html | 13 ++++ cli/list-users.php | 14 +++++ lib/lib_rss.php | 9 ++- 10 files changed, 184 insertions(+), 68 deletions(-) create mode 100644 cli/.htaccess create mode 100644 cli/_cli.php create mode 100644 cli/create-user.php create mode 100644 cli/index.html create mode 100644 cli/list-users.php (limited to 'app/Controllers/userController.php') diff --git a/app/Controllers/userController.php b/app/Controllers/userController.php index c259ffde9..f880b951d 100644 --- a/app/Controllers/userController.php +++ b/app/Controllers/userController.php @@ -24,6 +24,16 @@ class FreshRSS_user_Controller extends Minz_ActionController { } } + private static function hashPassword($passwordPlain) { + if (!function_exists('password_hash')) { + include_once(LIB_PATH . '/password_compat.php'); + } + $passwordHash = password_hash($passwordPlain, PASSWORD_BCRYPT, array('cost' => self::BCRYPT_COST)); + $passwordPlain = ''; + $passwordHash = preg_replace('/^\$2[xy]\$/', '\$2a\$', $passwordHash); //Compatibility with bcrypt.js + return $passwordHash == '' ? '' : $passwordHash; + } + /** * This action displays the user profile page. */ @@ -41,12 +51,7 @@ class FreshRSS_user_Controller extends Minz_ActionController { if ($passwordPlain != '') { Minz_Request::_param('newPasswordPlain'); //Discard plain-text password ASAP $_POST['newPasswordPlain'] = ''; - if (!function_exists('password_hash')) { - include_once(LIB_PATH . '/password_compat.php'); - } - $passwordHash = password_hash($passwordPlain, PASSWORD_BCRYPT, array('cost' => self::BCRYPT_COST)); - $passwordPlain = ''; - $passwordHash = preg_replace('/^\$2[xy]\$/', '\$2a\$', $passwordHash); //Compatibility with bcrypt.js + $passwordHash = self::hashPassword($passwordPlain); $ok &= ($passwordHash != ''); FreshRSS_Context::$user_conf->passwordHash = $passwordHash; } @@ -54,12 +59,7 @@ class FreshRSS_user_Controller extends Minz_ActionController { $passwordPlain = Minz_Request::param('apiPasswordPlain', '', true); if ($passwordPlain != '') { - if (!function_exists('password_hash')) { - include_once(LIB_PATH . '/password_compat.php'); - } - $passwordHash = password_hash($passwordPlain, PASSWORD_BCRYPT, array('cost' => self::BCRYPT_COST)); - $passwordPlain = ''; - $passwordHash = preg_replace('/^\$2[xy]\$/', '\$2a\$', $passwordHash); //Compatibility with bcrypt.js + $passwordHash = self::hashPassword($passwordPlain); $ok &= ($passwordHash != ''); FreshRSS_Context::$user_conf->apiPasswordHash = $passwordHash; } @@ -99,6 +99,53 @@ class FreshRSS_user_Controller extends Minz_ActionController { $this->view->size_user = $entryDAO->size(); } + public static function createUser($new_user_name, $passwordPlain, $apiPasswordPlain, $userConfig = array()) { + if (!is_array($userConfig)) { + $userConfig = array(); + } + + $ok = ($new_user_name != '') && ctype_alnum($new_user_name); + + if ($ok) { + $languages = Minz_Translate::availableLanguages(); + if (empty($userConfig['language']) || !in_array($userConfig['language'], $languages)) { + $userConfig['language'] = 'en'; + } + + $default_user = FreshRSS_Context::$system_conf->default_user; + $ok &= (strcasecmp($new_user_name, $default_user) !== 0); //It is forbidden to alter the default user + + $ok &= !in_array(strtoupper($new_user_name), array_map('strtoupper', listUsers())); //Not an existing user, case-insensitive + + $configPath = join_path(DATA_PATH, 'users', $new_user_name, 'config.php'); + $ok &= !file_exists($configPath); + } + if ($ok) { + $passwordHash = ''; + if ($passwordPlain != '') { + $passwordHash = self::hashPassword($passwordPlain); + $ok &= ($passwordHash != ''); + } + + $apiPasswordHash = ''; + if ($apiPasswordPlain != '') { + $apiPasswordHash = self::hashPassword($apiPasswordPlain); + $ok &= ($apiPasswordHash != ''); + } + } + if ($ok) { + mkdir(join_path(DATA_PATH, 'users', $new_user_name)); + $userConfig['passwordHash'] = $passwordHash; + $userConfig['apiPasswordHash'] = $apiPasswordHash; + $ok &= (file_put_contents($configPath, "createUser($new_user_name, $userConfig['language']); + } + return $ok; + } + /** * This action creates a new user. * @@ -116,57 +163,13 @@ class FreshRSS_user_Controller extends Minz_ActionController { FreshRSS_Auth::hasAccess('admin') || !max_registrations_reached() )) { - $db = FreshRSS_Context::$system_conf->db; - require_once(APP_PATH . '/SQL/install.sql.' . $db['type'] . '.php'); - - $new_user_language = Minz_Request::param('new_user_language', FreshRSS_Context::$user_conf->language); - $languages = Minz_Translate::availableLanguages(); - if (!in_array($new_user_language, $languages)) { - $new_user_language = FreshRSS_Context::$user_conf->language; - } - $new_user_name = Minz_Request::param('new_user_name'); - $ok = ($new_user_name != '') && ctype_alnum($new_user_name); - - if ($ok) { - $default_user = FreshRSS_Context::$system_conf->default_user; - $ok &= (strcasecmp($new_user_name, $default_user) !== 0); //It is forbidden to alter the default user - - $ok &= !in_array(strtoupper($new_user_name), array_map('strtoupper', listUsers())); //Not an existing user, case-insensitive + $passwordPlain = Minz_Request::param('new_user_passwordPlain', '', true); + $new_user_language = Minz_Request::param('new_user_language', FreshRSS_Context::$user_conf->language); - $configPath = join_path(DATA_PATH, 'users', $new_user_name, 'config.php'); - $ok &= !file_exists($configPath); - } - if ($ok) { - $passwordPlain = Minz_Request::param('new_user_passwordPlain', '', true); - $passwordHash = ''; - if ($passwordPlain != '') { - Minz_Request::_param('new_user_passwordPlain'); //Discard plain-text password ASAP - $_POST['new_user_passwordPlain'] = ''; - if (!function_exists('password_hash')) { - include_once(LIB_PATH . '/password_compat.php'); - } - $passwordHash = password_hash($passwordPlain, PASSWORD_BCRYPT, array('cost' => self::BCRYPT_COST)); - $passwordPlain = ''; - $passwordHash = preg_replace('/^\$2[xy]\$/', '\$2a\$', $passwordHash); //Compatibility with bcrypt.js - $ok &= ($passwordHash != ''); - } - if (empty($passwordHash)) { - $passwordHash = ''; - } - } - if ($ok) { - mkdir(join_path(DATA_PATH, 'users', $new_user_name)); - $config_array = array( - 'language' => $new_user_language, - 'passwordHash' => $passwordHash, - ); - $ok &= (file_put_contents($configPath, "createUser($new_user_name, $new_user_language); - } + $ok = self::createUser($new_user_name, $passwordPlain, '', array('language' => $new_user_language)); + Minz_Request::_param('new_user_passwordPlain'); //Discard plain-text password ASAP + $_POST['new_user_passwordPlain'] = ''; invalidateHttpCache(); $notif = array( diff --git a/app/Models/Context.php b/app/Models/Context.php index fe4fa6281..fd0e79fc1 100644 --- a/app/Models/Context.php +++ b/app/Models/Context.php @@ -37,7 +37,7 @@ class FreshRSS_Context { public static $id_max = ''; public static $sinceHours = 0; - public static $isCron = false; + public static $isCli = false; /** * Initialize the context. diff --git a/app/Models/Feed.php b/app/Models/Feed.php index 55c2db4d6..97cb1c47e 100644 --- a/app/Models/Feed.php +++ b/app/Models/Feed.php @@ -141,7 +141,7 @@ class FreshRSS_Feed extends Minz_Model { if (!file_exists($txt)) { file_put_contents($txt, $url); } - if (FreshRSS_Context::$isCron) { + if (FreshRSS_Context::$isCli) { $ico = $favicons_dir . $this->hash() . '.ico'; $ico_mtime = @filemtime($ico); $txt_mtime = @filemtime($txt); diff --git a/app/actualize_script.php b/app/actualize_script.php index 78712d721..deaa1bf7c 100755 --- a/app/actualize_script.php +++ b/app/actualize_script.php @@ -28,13 +28,13 @@ $app = new FreshRSS(); $system_conf = Minz_Configuration::get('system'); $system_conf->auth_type = 'none'; // avoid necessity to be logged in (not saved!) -FreshRSS_Context::$isCron = true; +FreshRSS_Context::$isCli = true; // Create the list of users to actualize. // Users are processed in a random order but always start with admin $users = listUsers(); shuffle($users); -if ($system_conf->default_user !== ''){ +if ($system_conf->default_user !== '') { array_unshift($users, $system_conf->default_user); $users = array_unique($users); } diff --git a/cli/.htaccess b/cli/.htaccess new file mode 100644 index 000000000..9e768397d --- /dev/null +++ b/cli/.htaccess @@ -0,0 +1,3 @@ +Order Allow,Deny +Deny from all +Satisfy all diff --git a/cli/_cli.php b/cli/_cli.php new file mode 100644 index 000000000..cb6d8ec32 --- /dev/null +++ b/cli/_cli.php @@ -0,0 +1,39 @@ + empty($options['language']) ? '' : $options['language'], + 'token' => empty($options['token']) ? '' : $options['token'], + )); + +invalidateHttpCache(FreshRSS_Context::$system_conf->default_user); + +echo 'Result: ', ($ok ? 'success' : 'fail'), ".\n"; +exit($ok ? 0 : 1); diff --git a/cli/index.html b/cli/index.html new file mode 100644 index 000000000..85faaa37e --- /dev/null +++ b/cli/index.html @@ -0,0 +1,13 @@ + + + + + +Redirection + + + + +

Redirection

+ + diff --git a/cli/list-users.php b/cli/list-users.php new file mode 100644 index 000000000..cc1cf5269 --- /dev/null +++ b/cli/list-users.php @@ -0,0 +1,14 @@ +#!/usr/bin/php +default_user !== '') { + array_unshift($users, $system_conf->default_user); + $users = array_unique($users); +} + +foreach ($users as $user) { + echo $user, "\n"; +} diff --git a/lib/lib_rss.php b/lib/lib_rss.php index 75046fd54..143b55bee 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -282,9 +282,12 @@ function uSecString() { return str_pad($t['usec'], 6, '0'); } -function invalidateHttpCache() { - Minz_Session::_param('touch', uTimeString()); - return touch(join_path(DATA_PATH, 'users', Minz_Session::param('currentUser', '_'), 'log.txt')); +function invalidateHttpCache($username = '') { + if (($username == '') || (!ctype_alnum($username))) { + Minz_Session::_param('touch', uTimeString()); + $username = Minz_Session::param('currentUser', '_'); + } + return touch(join_path(DATA_PATH, 'users', $username, 'log.txt')); } function listUsers() { -- cgit v1.2.3 From 5b1b43ab57da6a7bc1599c224d47455b2e56d53d Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sat, 22 Oct 2016 20:32:16 +0200 Subject: CLI delete user https://github.com/FreshRSS/FreshRSS/issues/1095 --- app/Controllers/userController.php | 39 ++++++++++++++++++++++---------------- cli/delete-user.php | 33 ++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 16 deletions(-) create mode 100755 cli/delete-user.php (limited to 'app/Controllers/userController.php') diff --git a/app/Controllers/userController.php b/app/Controllers/userController.php index f880b951d..2f04c7a1d 100644 --- a/app/Controllers/userController.php +++ b/app/Controllers/userController.php @@ -186,6 +186,27 @@ class FreshRSS_user_Controller extends Minz_ActionController { Minz_Request::forward($redirect_url, true); } + public static function deleteUser($username) { + $db = FreshRSS_Context::$system_conf->db; + require_once(APP_PATH . '/SQL/install.sql.' . $db['type'] . '.php'); + + $ok = ctype_alnum($username); + if ($ok) { + $default_user = FreshRSS_Context::$system_conf->default_user; + $ok &= (strcasecmp($username, $default_user) !== 0); //It is forbidden to delete the default user + } + $user_data = join_path(DATA_PATH, 'users', $username); + if ($ok) { + $ok &= is_dir($user_data); + } + if ($ok) { + $userDAO = new FreshRSS_UserDAO(); + $ok &= $userDAO->deleteUser($username); + $ok &= recursive_unlink($user_data); + } + return $ok; + } + /** * This action delete an existing user. * @@ -207,16 +228,7 @@ class FreshRSS_user_Controller extends Minz_ActionController { FreshRSS_Auth::hasAccess('admin') || $self_deletion )) { - $db = FreshRSS_Context::$system_conf->db; - require_once(APP_PATH . '/SQL/install.sql.' . $db['type'] . '.php'); - - $ok = ctype_alnum($username); - $user_data = join_path(DATA_PATH, 'users', $username); - - if ($ok) { - $default_user = FreshRSS_Context::$system_conf->default_user; - $ok &= (strcasecmp($username, $default_user) !== 0); //It is forbidden to delete the default user - } + $ok = true; if ($ok && $self_deletion) { // We check the password if it's a self-destruction $nonce = Minz_Session::param('nonce'); @@ -228,12 +240,7 @@ class FreshRSS_user_Controller extends Minz_ActionController { ); } if ($ok) { - $ok &= is_dir($user_data); - } - if ($ok) { - $userDAO = new FreshRSS_UserDAO(); - $ok &= $userDAO->deleteUser($username); - $ok &= recursive_unlink($user_data); + $ok &= self::deleteUser($username); } if ($ok && $self_deletion) { FreshRSS_Auth::removeAccess(); diff --git a/cli/delete-user.php b/cli/delete-user.php new file mode 100755 index 000000000..46332fe34 --- /dev/null +++ b/cli/delete-user.php @@ -0,0 +1,33 @@ +#!/usr/bin/php +default_user) === 0) { + fail('FreshRSS error: default user must not be deleted: “' . $username . '”'); +} + +echo 'FreshRSS deleting user “', $username, "”…\n"; + +$ok = FreshRSS_user_Controller::deleteUser($username); + +invalidateHttpCache(FreshRSS_Context::$system_conf->default_user); + +echo 'Result: ', ($ok ? 'success' : 'fail'), ".\n"; +exit($ok ? 0 : 1); -- cgit v1.2.3 From ab4ece6780cf841f6ce4e89f7b81a1ff1661f615 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Mon, 24 Oct 2016 01:41:09 +0200 Subject: CLI do-install https://github.com/FreshRSS/FreshRSS/issues/1095 https://github.com/FreshRSS/FreshRSS/issues/1090 --- app/Controllers/userController.php | 5 +- app/install.php | 161 +++++++------------------------------ cli/_cli.php | 7 +- cli/create-user.php | 10 ++- cli/do-install.php | 102 +++++++++++++++++++++++ lib/lib_install.php | 115 ++++++++++++++++++++++++++ 6 files changed, 260 insertions(+), 140 deletions(-) create mode 100644 cli/do-install.php create mode 100644 lib/lib_install.php (limited to 'app/Controllers/userController.php') diff --git a/app/Controllers/userController.php b/app/Controllers/userController.php index 2f04c7a1d..9dee16e8c 100644 --- a/app/Controllers/userController.php +++ b/app/Controllers/userController.php @@ -24,7 +24,7 @@ class FreshRSS_user_Controller extends Minz_ActionController { } } - private static function hashPassword($passwordPlain) { + public static function hashPassword($passwordPlain) { if (!function_exists('password_hash')) { include_once(LIB_PATH . '/password_compat.php'); } @@ -112,9 +112,6 @@ class FreshRSS_user_Controller extends Minz_ActionController { $userConfig['language'] = 'en'; } - $default_user = FreshRSS_Context::$system_conf->default_user; - $ok &= (strcasecmp($new_user_name, $default_user) !== 0); //It is forbidden to alter the default user - $ok &= !in_array(strtoupper($new_user_name), array_map('strtoupper', listUsers())); //Not an existing user, case-insensitive $configPath = join_path(DATA_PATH, 'users', $new_user_name, 'config.php'); diff --git a/app/install.php b/app/install.php index 1972379e5..6956761c7 100644 --- a/app/install.php +++ b/app/install.php @@ -4,15 +4,12 @@ if (function_exists('opcache_reset')) { } header("Content-Security-Policy: default-src 'self'"); -define('BCRYPT_COST', 9); +require(LIB_PATH . '/lib_install.php'); session_name('FreshRSS'); session_set_cookie_params(0, dirname(empty($_SERVER['REQUEST_URI']) ? '/' : dirname($_SERVER['REQUEST_URI'])), null, false, true); session_start(); -Minz_Configuration::register('default_system', join_path(DATA_PATH, 'config.default.php')); -Minz_Configuration::register('default_user', join_path(USERS_PATH, '_', 'config.default.php')); - if (isset($_GET['step'])) { define('STEP',(int)$_GET['step']); } else { @@ -26,13 +23,13 @@ if (STEP === 3 && isset($_POST['type'])) { if (isset($_SESSION['bd_type'])) { switch ($_SESSION['bd_type']) { case 'mysql': - include(APP_PATH . '/SQL/install.sql.mysql.php'); + include_once(APP_PATH . '/SQL/install.sql.mysql.php'); break; case 'sqlite': - include(APP_PATH . '/SQL/install.sql.sqlite.php'); + include_once(APP_PATH . '/SQL/install.sql.sqlite.php'); break; case 'pgsql': - include(APP_PATH . '/SQL/install.sql.pgsql.php'); + include_once(APP_PATH . '/SQL/install.sql.pgsql.php'); break; } } @@ -131,12 +128,7 @@ function saveStep2() { $password_plain = param('passwordPlain', false); if ($password_plain !== false && cryptAvailable()) { - if (!function_exists('password_hash')) { - include_once(LIB_PATH . '/password_compat.php'); - } - $passwordHash = password_hash($password_plain, PASSWORD_BCRYPT, array('cost' => BCRYPT_COST)); - $passwordHash = preg_replace('/^\$2[xy]\$/', '\$2a\$', $passwordHash); //Compatibility with bcrypt.js - $_SESSION['passwordHash'] = $passwordHash; + $_SESSION['passwordHash'] = FreshRSS_user_Controller::hashPassword($password_plain); } if (empty($_SESSION['old_entries']) || @@ -149,7 +141,7 @@ function saveStep2() { return false; } - $_SESSION['salt'] = sha1(uniqid(mt_rand(), true).implode('', stat(__FILE__))); + $_SESSION['salt'] = generateSalt(); if ((!ctype_digit($_SESSION['old_entries'])) ||($_SESSION['old_entries'] < 1)) { $_SESSION['old_entries'] = $user_default_config->old_entries; } @@ -171,7 +163,7 @@ function saveStep2() { recursive_unlink($user_dir); mkdir($user_dir); - file_put_contents($user_config_path, " 0 && $s0['all'] != 'ok') { @@ -279,49 +265,6 @@ function checkStep0() { ); } -function checkStep1() { - $php = version_compare(PHP_VERSION, '5.3.3') >= 0; - $minz = file_exists(join_path(LIB_PATH, 'Minz')); - $curl = extension_loaded('curl'); - $pdo_mysql = extension_loaded('pdo_mysql'); - $pdo_sqlite = extension_loaded('pdo_sqlite'); - $pdo_pgsql = extension_loaded('pdo_pgsql'); - $pdo = $pdo_mysql || $pdo_sqlite || $pdo_pgsql; - $pcre = extension_loaded('pcre'); - $ctype = extension_loaded('ctype'); - $dom = class_exists('DOMDocument'); - $xml = function_exists('xml_parser_create'); - $json = function_exists('json_encode'); - $data = DATA_PATH && is_writable(DATA_PATH); - $cache = CACHE_PATH && is_writable(CACHE_PATH); - $users = USERS_PATH && is_writable(USERS_PATH); - $favicons = is_writable(join_path(DATA_PATH, 'favicons')); - $http_referer = is_referer_from_same_domain(); - - return array( - 'php' => $php ? 'ok' : 'ko', - 'minz' => $minz ? 'ok' : 'ko', - 'curl' => $curl ? 'ok' : 'ko', - 'pdo-mysql' => $pdo_mysql ? 'ok' : 'ko', - 'pdo-sqlite' => $pdo_sqlite ? 'ok' : 'ko', - 'pdo-pgsql' => $pdo_pgsql ? 'ok' : 'ko', - 'pdo' => $pdo ? 'ok' : 'ko', - 'pcre' => $pcre ? 'ok' : 'ko', - 'ctype' => $ctype ? 'ok' : 'ko', - 'dom' => $dom ? 'ok' : 'ko', - 'xml' => $xml ? 'ok' : 'ko', - 'json' => $json ? 'ok' : 'ko', - 'data' => $data ? 'ok' : 'ko', - 'cache' => $cache ? 'ok' : 'ko', - 'users' => $users ? 'ok' : 'ko', - 'favicons' => $favicons ? 'ok' : 'ko', - 'http_referer' => $http_referer ? 'ok' : 'ko', - 'all' => $php && $minz && $curl && $pdo && $pcre && $ctype && $dom && $xml && - $data && $cache && $users && $favicons && $http_referer ? - 'ok' : 'ko' - ); -} - function freshrss_already_installed() { $conf_path = join_path(DATA_PATH, 'config.php'); if (!file_exists($conf_path)) { @@ -392,60 +335,15 @@ function checkStep3() { ); } -function checkBD() { +function checkDbUser(&$dbOptions) { $ok = false; - + $str = $dbOptions['bd_dsn']; + $driver_options = $dbOptions['bd_options']; try { - $str = ''; - $driver_options = null; - switch ($_SESSION['bd_type']) { - case 'mysql': - $driver_options = array( - PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8mb4' - ); - - try { // on ouvre une connexion juste pour créer la base si elle n'existe pas - $str = 'mysql:host=' . $_SESSION['bd_host'] . ';'; - $c = new PDO($str, $_SESSION['bd_user'], $_SESSION['bd_password'], $driver_options); - $sql = sprintf(SQL_CREATE_DB, $_SESSION['bd_base']); - $res = $c->query($sql); - } catch (PDOException $e) { - } - - // on écrase la précédente connexion en sélectionnant la nouvelle BDD - $str = 'mysql:host=' . $_SESSION['bd_host'] . ';dbname=' . $_SESSION['bd_base']; - break; - case 'sqlite': - $str = 'sqlite:' . join_path(USERS_PATH, $_SESSION['default_user'], 'db.sqlite'); - $driver_options = array( - PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, - ); - break; - case 'pgsql': - $driver_options = array( - PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, - ); - - try { // on ouvre une connexion juste pour créer la base si elle n'existe pas - $str = 'pgsql:host=' . $_SESSION['bd_host'] . ';dbname=postgres'; - $c = new PDO($str, $_SESSION['bd_user'], $_SESSION['bd_password'], $driver_options); - $sql = sprintf(SQL_CREATE_DB, $_SESSION['bd_base']); - $res = $c->query($sql); - } catch (PDOException $e) { - syslog(LOG_DEBUG, 'pgsql ' . $e->getMessage()); - } - - // on écrase la précédente connexion en sélectionnant la nouvelle BDD - $str = 'pgsql:host=' . $_SESSION['bd_host'] . ';dbname=' . $_SESSION['bd_base']; - break; - default: - return false; - } - - $c = new PDO($str, $_SESSION['bd_user'], $_SESSION['bd_password'], $driver_options); + $c = new PDO($str, $dbOptions['bd_user'], $dbOptions['bd_password'], $driver_options); if (defined('SQL_CREATE_TABLES')) { - $sql = sprintf(SQL_CREATE_TABLES, $_SESSION['bd_prefix_user'], _t('gen.short.default_category')); + $sql = sprintf(SQL_CREATE_TABLES, $dbOptions['bd_prefix_user'], _t('gen.short.default_category')); $stm = $c->prepare($sql); $ok = $stm->execute(); } else { @@ -453,7 +351,7 @@ function checkBD() { if (is_array($SQL_CREATE_TABLES)) { $ok = true; foreach ($SQL_CREATE_TABLES as $instruction) { - $sql = sprintf($instruction, $_SESSION['bd_prefix_user'], _t('gen.short.default_category')); + $sql = sprintf($instruction, $dbOptions['bd_prefix_user'], _t('gen.short.default_category')); $stm = $c->prepare($sql); $ok &= $stm->execute(); } @@ -461,13 +359,8 @@ function checkBD() { } } catch (PDOException $e) { $ok = false; - $_SESSION['bd_error'] = $e->getMessage(); + $dbOptions['bd_error'] = $e->getMessage(); } - - if (!$ok) { - @unlink(join_path(DATA_PATH, 'config.php')); - } - return $ok; } @@ -510,7 +403,7 @@ function printStep0() { // @todo refactor this view with the check_install action function printStep1() { - $res = checkStep1(); + $res = checkRequirements(); ?> @@ -805,7 +698,9 @@ case 3: case 4: break; case 5: - deleteInstall(); + if (deleteInstall()) { + header('Location: index.php'); + } break; } ?> diff --git a/cli/_cli.php b/cli/_cli.php index 66506f07a..7d1a7c6b2 100644 --- a/cli/_cli.php +++ b/cli/_cli.php @@ -38,7 +38,12 @@ function cliInitUser($username) { return $username; } -function done($ok) { +function accessRights() { + echo '• Remember to re-apply the appropriate access rights, such as:' , "\n", + "\t", 'sudo chown -R :www-data . && sudo chmod -R g+r . && sudo chmod -R g+w ./data/', "\n"; +} + +function done($ok = true) { fwrite(STDERR, 'Result: ' . ($ok ? 'success' : 'fail') . "\n"); exit($ok ? 0 : 1); } diff --git a/cli/create-user.php b/cli/create-user.php index 243e65a35..5e93d4605 100755 --- a/cli/create-user.php +++ b/cli/create-user.php @@ -12,8 +12,8 @@ $options = getopt('', array( )); if (empty($options['user'])) { - fail('Usage: ' . basename(__FILE__) . " --user username --password 'password' --api-password 'api_password'" . - " --language en --email user@example.net --token 'longRandomString'"); + fail('Usage: ' . basename(__FILE__) . " --user username ( --password 'password' --api-password 'api_password'" . + " --language en --email user@example.net --token 'longRandomString' )"); } $username = $options['user']; if (!ctype_alnum($username)) { @@ -35,6 +35,12 @@ $ok = FreshRSS_user_Controller::createUser($username, 'token' => empty($options['token']) ? '' : $options['token'], )); +if (!$ok) { + fail('FreshRSS could not create user!'); +} + invalidateHttpCache(FreshRSS_Context::$system_conf->default_user); +accessRights(); + done($ok); diff --git a/cli/do-install.php b/cli/do-install.php new file mode 100644 index 000000000..5eeedc626 --- /dev/null +++ b/cli/do-install.php @@ -0,0 +1,102 @@ +#!/usr/bin/php + $check) { + if ($check !== 'ok' && $requirement !== 'all') { + $message .= '• ' . $requirement . "\n"; + } + } + fail($message); +} + +if (!ctype_alnum($options['default_user'])) { + fail('FreshRSS invalid default username (must be ASCII alphanumeric): ' . $options['default_user']); +} + +if (!in_array($options['auth_type'], array('form', 'http_auth', 'none'))) { + fail('FreshRSS invalid authentication method (auth_type must be one of { form, http_auth, none }: ' . $options['auth_type']); +} + +$config = array( + 'salt' => generateSalt(), + 'db' => FreshRSS_Context::$system_conf->db, + ); + +foreach ($params as $param) { + $param = rtrim($param, ':'); + if (isset($options[$param])) { + $config[$param] = $options[$param] === false ? true : $options[$param]; + } +} + +if ((!empty($config['base_url'])) && server_is_public($config['base_url'])) { + $config['pubsubhubbub_enabled'] = true; +} + +foreach ($dBparams as $dBparam) { + $dBparam = rtrim($dBparam, ':'); + if (!empty($options[$dBparam])) { + $param = substr($dBparam, strlen('db-')); + $config['db'][$param] = $options[$dBparam]; + } +} + +if (file_put_contents(join_path(DATA_PATH, 'config.php'), "= 0; + $minz = file_exists(join_path(LIB_PATH, 'Minz')); + $curl = extension_loaded('curl'); + $pdo_mysql = extension_loaded('pdo_mysql'); + $pdo_sqlite = extension_loaded('pdo_sqlite'); + $pdo_pgsql = extension_loaded('pdo_pgsql'); + $pdo = $pdo_mysql || $pdo_sqlite || $pdo_pgsql; + $pcre = extension_loaded('pcre'); + $ctype = extension_loaded('ctype'); + $dom = class_exists('DOMDocument'); + $xml = function_exists('xml_parser_create'); + $json = function_exists('json_encode'); + $data = DATA_PATH && is_writable(DATA_PATH); + $cache = CACHE_PATH && is_writable(CACHE_PATH); + $users = USERS_PATH && is_writable(USERS_PATH); + $favicons = is_writable(join_path(DATA_PATH, 'favicons')); + $http_referer = is_referer_from_same_domain(); + + return array( + 'php' => $php ? 'ok' : 'ko', + 'minz' => $minz ? 'ok' : 'ko', + 'curl' => $curl ? 'ok' : 'ko', + 'pdo-mysql' => $pdo_mysql ? 'ok' : 'ko', + 'pdo-sqlite' => $pdo_sqlite ? 'ok' : 'ko', + 'pdo-pgsql' => $pdo_pgsql ? 'ok' : 'ko', + 'pdo' => $pdo ? 'ok' : 'ko', + 'pcre' => $pcre ? 'ok' : 'ko', + 'ctype' => $ctype ? 'ok' : 'ko', + 'dom' => $dom ? 'ok' : 'ko', + 'xml' => $xml ? 'ok' : 'ko', + 'json' => $json ? 'ok' : 'ko', + 'data' => $data ? 'ok' : 'ko', + 'cache' => $cache ? 'ok' : 'ko', + 'users' => $users ? 'ok' : 'ko', + 'favicons' => $favicons ? 'ok' : 'ko', + 'http_referer' => $http_referer ? 'ok' : 'ko', + 'all' => $php && $minz && $curl && $pdo && $pcre && $ctype && $dom && $xml && + $data && $cache && $users && $favicons && $http_referer ? + 'ok' : 'ko' + ); +} + +function generateSalt() { + return sha1(uniqid(mt_rand(), true).implode('', stat(__FILE__))); +} + +function checkDb(&$dbOptions) { + $dsn = ''; + try { + $driver_options = null; + switch ($dbOptions['type']) { + case 'mysql': + include_once(APP_PATH . '/SQL/install.sql.mysql.php'); + $driver_options = array( + PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8mb4' + ); + try { // on ouvre une connexion juste pour créer la base si elle n'existe pas + $dsn = 'mysql:host=' . $dbOptions['host'] . ';'; + $c = new PDO($dsn, $dbOptions['user'], $dbOptions['password'], $driver_options); + $sql = sprintf(SQL_CREATE_DB, $dbOptions['base']); + $res = $c->query($sql); + } catch (PDOException $e) { + syslog(LOG_DEBUG, 'FreshRSS MySQL warning: ' . $e->getMessage()); + } + // on écrase la précédente connexion en sélectionnant la nouvelle BDD + $dsn = 'mysql:host=' . $dbOptions['host'] . ';dbname=' . $dbOptions['base']; + break; + case 'sqlite': + include_once(APP_PATH . '/SQL/install.sql.sqlite.php'); + $dsn = 'sqlite:' . join_path(USERS_PATH, $dbOptions['default_user'], 'db.sqlite'); + $driver_options = array( + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, + ); + break; + case 'pgsql': + include_once(APP_PATH . '/SQL/install.sql.pgsql.php'); + $driver_options = array( + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, + ); + try { // on ouvre une connexion juste pour créer la base si elle n'existe pas + $dsn = 'pgsql:host=' . $dbOptions['host'] . ';dbname=postgres'; + $c = new PDO($dsn, $dbOptions['user'], $dbOptions['password'], $driver_options); + $sql = sprintf(SQL_CREATE_DB, $dbOptions['base']); + $res = $c->query($sql); + } catch (PDOException $e) { + syslog(LOG_DEBUG, 'FreshRSS PostgreSQL warning: ' . $e->getMessage()); + } + // on écrase la précédente connexion en sélectionnant la nouvelle BDD + $dsn = 'pgsql:host=' . $dbOptions['host'] . ';dbname=' . $dbOptions['base']; + break; + default: + return false; + } + } catch (PDOException $e) { + $dsn = ''; + $dbOptions['error'] = $e->getMessage(); + } + $dbOptions['dsn'] = $dsn; + $dbOptions['options'] = $driver_options; + return $dsn != ''; +} + +function deleteInstall() { + $path = join_path(DATA_PATH, 'do-install.txt'); + @unlink($path); + return !file_exists($path); +} -- cgit v1.2.3 From 1182129ce5f07892afed190ffbb2ea4c7fc28967 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Mon, 24 Oct 2016 20:29:08 +0200 Subject: CLI option no-default-feeds https://github.com/FreshRSS/FreshRSS/issues/1095 --- app/Controllers/userController.php | 4 ++-- app/Models/UserDAO.php | 18 +++++++++++++++++- app/SQL/install.sql.mysql.php | 3 +++ app/SQL/install.sql.pgsql.php | 4 ++++ app/SQL/install.sql.sqlite.php | 4 ++++ app/install.php | 15 +++++++++++++++ cli/create-user.php | 7 +++++-- 7 files changed, 50 insertions(+), 5 deletions(-) (limited to 'app/Controllers/userController.php') diff --git a/app/Controllers/userController.php b/app/Controllers/userController.php index 9dee16e8c..9d6ae18e6 100644 --- a/app/Controllers/userController.php +++ b/app/Controllers/userController.php @@ -99,7 +99,7 @@ class FreshRSS_user_Controller extends Minz_ActionController { $this->view->size_user = $entryDAO->size(); } - public static function createUser($new_user_name, $passwordPlain, $apiPasswordPlain, $userConfig = array()) { + public static function createUser($new_user_name, $passwordPlain, $apiPasswordPlain, $userConfig = array(), $insertDefaultFeeds = true) { if (!is_array($userConfig)) { $userConfig = array(); } @@ -138,7 +138,7 @@ class FreshRSS_user_Controller extends Minz_ActionController { } if ($ok) { $userDAO = new FreshRSS_UserDAO(); - $ok &= $userDAO->createUser($new_user_name, $userConfig['language']); + $ok &= $userDAO->createUser($new_user_name, $userConfig['language'], $insertDefaultFeeds); } return $ok; } diff --git a/app/Models/UserDAO.php b/app/Models/UserDAO.php index 597182693..a95ee6bc4 100644 --- a/app/Models/UserDAO.php +++ b/app/Models/UserDAO.php @@ -1,7 +1,7 @@ db; require_once(APP_PATH . '/SQL/install.sql.' . $db['type'] . '.php'); @@ -28,6 +28,22 @@ class FreshRSS_UserDAO extends Minz_ModelPdo { } } } + if ($insertDefaultFeeds) { + if (defined('SQL_INSERT_FEEDS')) { //E.g. MySQL + $sql = sprintf(SQL_INSERT_FEEDS, $bd_prefix_user); + $stm = $userPDO->bd->prepare($sql); + $ok &= $stm && $stm->execute(); + } else { //E.g. SQLite + global $SQL_INSERT_FEEDS; + if (is_array($SQL_INSERT_FEEDS)) { + foreach ($SQL_INSERT_FEEDS as $instruction) { + $sql = sprintf($instruction, $bd_prefix_user); + $stm = $userPDO->bd->prepare($sql); + $ok &= ($stm && $stm->execute()); + } + } + } + } } catch (Exception $e) { Minz_Log::error('Error while creating user: ' . $e->getMessage()); } diff --git a/app/SQL/install.sql.mysql.php b/app/SQL/install.sql.mysql.php index ca181303e..a454829d5 100644 --- a/app/SQL/install.sql.mysql.php +++ b/app/SQL/install.sql.mysql.php @@ -59,6 +59,9 @@ CREATE TABLE IF NOT EXISTS `%1$sentry` ( ENGINE = INNODB; INSERT IGNORE INTO `%1$scategory` (id, name) VALUES(1, "%2$s"); +'); + +define('SQL_INSERT_FEEDS', ' INSERT IGNORE INTO `%1$sfeed` (url, category, name, website, description, ttl) VALUES("http://freshrss.org/feeds/all.atom.xml", 1, "FreshRSS.org", "http://freshrss.org/", "FreshRSS, a free, self-hostable aggregator…", 86400); INSERT IGNORE INTO `%1$sfeed` (url, category, name, website, description, ttl) VALUES("https://github.com/FreshRSS/FreshRSS/releases.atom", 1, "FreshRSS @ GitHub", "https://github.com/FreshRSS/FreshRSS/", "FreshRSS releases @ GitHub", 86400); '); diff --git a/app/SQL/install.sql.pgsql.php b/app/SQL/install.sql.pgsql.php index b343bda86..9f4240b98 100644 --- a/app/SQL/install.sql.pgsql.php +++ b/app/SQL/install.sql.pgsql.php @@ -52,6 +52,10 @@ $SQL_CREATE_TABLES = array( 'CREATE INDEX %1$sentry_lastSeen_index ON "%1$sentry" ("lastSeen");', 'INSERT INTO "%1$scategory" (name) SELECT \'%2$s\' WHERE NOT EXISTS (SELECT id FROM "%1$scategory" WHERE id = 1);', +); + +global $SQL_INSERT_FEEDS; +$SQL_INSERT_FEEDS = array( 'INSERT INTO "%1$sfeed" (url, category, name, website, description, ttl) SELECT \'http://freshrss.org/feeds/all.atom.xml\', 1, \'FreshRSS.org\', \'http://freshrss.org/\', \'FreshRSS, a free, self-hostable aggregator…\', 86400 WHERE NOT EXISTS (SELECT id FROM "%1$sfeed" WHERE url = \'http://freshrss.org/feeds/all.atom.xml\');', 'INSERT INTO "%1$sfeed" (url, category, name, website, description, ttl) SELECT \'https://github.com/FreshRSS/FreshRSS/releases.atom\', 1, \'FreshRSS @ GitHub\', \'https://github.com/FreshRSS/FreshRSS/\', \'FreshRSS releases @ GitHub\', 86400 WHERE NOT EXISTS (SELECT id FROM "%1$sfeed" WHERE url = \'https://github.com/FreshRSS/FreshRSS/releases.atom\');', ); diff --git a/app/SQL/install.sql.sqlite.php b/app/SQL/install.sql.sqlite.php index 1d3a5d92f..68d93ba92 100644 --- a/app/SQL/install.sql.sqlite.php +++ b/app/SQL/install.sql.sqlite.php @@ -55,6 +55,10 @@ $SQL_CREATE_TABLES = array( 'CREATE INDEX IF NOT EXISTS entry_lastSeen_index ON `entry`(`lastSeen`);', //v1.1.1 'INSERT OR IGNORE INTO `category` (id, name) VALUES(1, "%2$s");', +); + +global $SQL_INSERT_FEEDS; +$SQL_INSERT_FEEDS = array( 'INSERT OR IGNORE INTO `feed` (url, category, name, website, description, ttl) VALUES("http://freshrss.org/feeds/all.atom.xml", 1, "FreshRSS.org", "http://freshrss.org/", "FreshRSS, a free, self-hostable aggregator…", 86400);', 'INSERT OR IGNORE INTO `feed` (url, category, name, website, description, ttl) VALUES("https://github.com/FreshRSS/FreshRSS/releases.atom", 1, "FreshRSS releases", "https://github.com/FreshRSS/FreshRSS/", "FreshRSS releases @ GitHub", 86400);', ); diff --git a/app/install.php b/app/install.php index 6956761c7..0daa02b1b 100644 --- a/app/install.php +++ b/app/install.php @@ -357,6 +357,21 @@ function checkDbUser(&$dbOptions) { } } } + + if (defined('SQL_INSERT_FEEDS')) { + $sql = sprintf(SQL_INSERT_FEEDS, $dbOptions['bd_prefix_user']); + $stm = $c->prepare($sql); + $ok &= $stm->execute(); + } else { + global $SQL_INSERT_FEEDS; + if (is_array($SQL_INSERT_FEEDS)) { + foreach ($SQL_INSERT_FEEDS as $instruction) { + $sql = sprintf($instruction, $dbOptions['bd_prefix_user']); + $stm = $c->prepare($sql); + $ok &= $stm->execute(); + } + } + } } catch (PDOException $e) { $ok = false; $dbOptions['bd_error'] = $e->getMessage(); diff --git a/cli/create-user.php b/cli/create-user.php index 5e93d4605..c790acb59 100755 --- a/cli/create-user.php +++ b/cli/create-user.php @@ -9,11 +9,12 @@ $options = getopt('', array( 'language:', 'email:', 'token:', + 'no-default-feeds', )); if (empty($options['user'])) { fail('Usage: ' . basename(__FILE__) . " --user username ( --password 'password' --api-password 'api_password'" . - " --language en --email user@example.net --token 'longRandomString' )"); + " --language en --email user@example.net --token 'longRandomString --no-default-feeds' )"); } $username = $options['user']; if (!ctype_alnum($username)) { @@ -33,7 +34,9 @@ $ok = FreshRSS_user_Controller::createUser($username, array( 'language' => empty($options['language']) ? '' : $options['language'], 'token' => empty($options['token']) ? '' : $options['token'], - )); + ), + !isset($options['no-default-feeds']) + ); if (!$ok) { fail('FreshRSS could not create user!'); -- cgit v1.2.3