From 497d295be470454b7bd068a5c5cceda8caa19527 Mon Sep 17 00:00:00 2001 From: Marien Fressinaud Date: Sun, 28 Dec 2014 19:35:20 +0100 Subject: Add a default users/_ dir Useful for default log path See https://github.com/FreshRSS/FreshRSS/issues/729 --- data/users/_/.gitkeep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 data/users/_/.gitkeep (limited to 'data/users/_') diff --git a/data/users/_/.gitkeep b/data/users/_/.gitkeep new file mode 100644 index 000000000..e69de29bb -- cgit v1.2.3 From 51a71ec4b9d62528054be8faee1576a8fd6d37f6 Mon Sep 17 00:00:00 2001 From: Marien Fressinaud Date: Mon, 5 Jan 2015 16:54:16 +0100 Subject: New configuration system (not working yet) - Use only Minz_Configuration - register() method to load a new configuration file - get() to get a configuration - new exceptions related to configuration - fix a list configuration calls to have FRSS working Current problems to resolve: - How to handle configuration param verifications (i.e. check auth_type is a value from none, http_auth, persona or form) - We must use $conf = Minz_Configuration::get('system'); $general_conf = $conf->general; to access global system configuration which is quite annoying. How to change that? See https://github.com/FreshRSS/FreshRSS/issues/730 --- app/Controllers/authController.php | 36 +- app/FreshRSS.php | 8 +- app/Models/Auth.php | 40 ++- app/Models/Context.php | 4 +- app/Models/Factory.php | 16 +- app/Models/Feed.php | 3 +- app/layout/header.phtml | 13 +- app/layout/layout.phtml | 3 +- app/views/helpers/javascript_vars.phtml | 3 +- data/config.default.php | 32 ++ data/users/_/config.default.php | 66 ++++ lib/Minz/BadConfigurationException.php | 9 - lib/Minz/Configuration.php | 517 ++++++++------------------- lib/Minz/ConfigurationException.php | 8 + lib/Minz/ConfigurationNamespaceException.php | 4 + lib/Minz/ConfigurationParamException.php | 4 + lib/Minz/Error.php | 7 +- lib/Minz/FrontController.php | 26 +- lib/Minz/Log.php | 11 +- lib/Minz/ModelPdo.php | 3 +- lib/Minz/Request.php | 3 +- lib/Minz/Translate.php | 3 +- lib/Minz/View.php | 4 +- p/i/index.php | 2 +- 24 files changed, 384 insertions(+), 441 deletions(-) create mode 100644 data/config.default.php create mode 100644 data/users/_/config.default.php delete mode 100644 lib/Minz/BadConfigurationException.php create mode 100644 lib/Minz/ConfigurationException.php create mode 100644 lib/Minz/ConfigurationNamespaceException.php create mode 100644 lib/Minz/ConfigurationParamException.php (limited to 'data/users/_') diff --git a/app/Controllers/authController.php b/app/Controllers/authController.php index ccc32ec0d..f68ea8da5 100644 --- a/app/Controllers/authController.php +++ b/app/Controllers/authController.php @@ -27,6 +27,8 @@ class FreshRSS_auth_Controller extends Minz_ActionController { if (Minz_Request::isPost()) { $ok = true; + $system_conf = Minz_Configuration::get('system'); + $general = $system_conf->general; $current_token = FreshRSS_Context::$conf->token; $token = Minz_Request::param('token', $current_token); FreshRSS_Context::$conf->_token($token); @@ -39,18 +41,21 @@ class FreshRSS_auth_Controller extends Minz_ActionController { $auth_type = Minz_Request::param('auth_type', 'none'); $unsafe_autologin = Minz_Request::param('unsafe_autologin', false); $api_enabled = Minz_Request::param('api_enabled', false); - if ($anon != Minz_Configuration::allowAnonymous() || - $auth_type != Minz_Configuration::authType() || - $anon_refresh != Minz_Configuration::allowAnonymousRefresh() || - $unsafe_autologin != Minz_Configuration::unsafeAutologinEnabled() || - $api_enabled != Minz_Configuration::apiEnabled()) { - - Minz_Configuration::_authType($auth_type); - Minz_Configuration::_allowAnonymous($anon); - Minz_Configuration::_allowAnonymousRefresh($anon_refresh); - Minz_Configuration::_enableAutologin($unsafe_autologin); - Minz_Configuration::_enableApi($api_enabled); - $ok &= Minz_Configuration::writeFile(); + if ($anon != $general['allow_anonymous'] || + $auth_type != $general['auth_type'] || + $anon_refresh != $general['allow_anonymous_refresh'] || + $unsafe_autologin != $general['unsafe_autologin_enabled'] || + $api_enabled != $general['api_enabled']) { + + // TODO: test values from form + $general['auth_type'] = $auth_type; + $general['allow_anonymous'] = $anon; + $general['allow_anonymous_refresh'] = $anon_refresh; + $general['unsafe_autologin_enabled'] = $unsafe_autologin; + $general['api_enabled'] = $api_enabled; + + $system_conf->general = $general; + $ok &= $system_conf->save(); } invalidateHttpCache(); @@ -76,7 +81,8 @@ class FreshRSS_auth_Controller extends Minz_ActionController { Minz_Request::forward(array('c' => 'index', 'a' => 'index'), true); } - $auth_type = Minz_Configuration::authType(); + $conf = Minz_Configuration::get('system'); + $auth_type = $conf->general['auth_type']; switch ($auth_type) { case 'form': Minz_Request::forward(array('c' => 'auth', 'a' => 'formLogin')); @@ -114,6 +120,8 @@ class FreshRSS_auth_Controller extends Minz_ActionController { $file_mtime = @filemtime(PUBLIC_PATH . '/scripts/bcrypt.min.js'); Minz_View::appendScript(Minz_Url::display('/scripts/bcrypt.min.js?' . $file_mtime)); + $conf = Minz_Configuration::get('system'); + if (Minz_Request::isPost()) { $nonce = Minz_Session::param('nonce'); $username = Minz_Request::param('username', ''); @@ -154,7 +162,7 @@ class FreshRSS_auth_Controller extends Minz_ActionController { Minz_Request::bad(_t('feedback.auth.login.invalid'), array('c' => 'auth', 'a' => 'login')); } - } elseif (Minz_Configuration::unsafeAutologinEnabled()) { + } elseif ($conf->general['unsafe_autologin_enabled']) { $username = Minz_Request::param('u', ''); $password = Minz_Request::param('p', ''); Minz_Request::_param('p'); diff --git a/app/FreshRSS.php b/app/FreshRSS.php index 6114a5d1a..455f2fefd 100644 --- a/app/FreshRSS.php +++ b/app/FreshRSS.php @@ -6,6 +6,11 @@ class FreshRSS extends Minz_FrontController { Minz_Session::init('FreshRSS'); } + $current_user = Minz_Session::param('currentUser', '_'); + Minz_Configuration::register('user', + join_path(USERS_PATH, $current_user, 'config.php'), + join_path(USERS_PATH, '_', 'config.default.php')); + // Need to be called just after session init because it initializes // current user. FreshRSS_Auth::init(); @@ -57,7 +62,8 @@ class FreshRSS extends Minz_FrontController { Minz_View::appendScript(Minz_Url::display('/scripts/shortcut.js?' . @filemtime(PUBLIC_PATH . '/scripts/shortcut.js'))); Minz_View::appendScript(Minz_Url::display('/scripts/main.js?' . @filemtime(PUBLIC_PATH . '/scripts/main.js'))); - if (Minz_Configuration::authType() === 'persona') { + $conf = Minz_Configuration::get('system'); + if ($conf->general['auth_type'] === 'persona') { // TODO move it in a plugin // Needed for login AND logout with Persona. Minz_View::appendScript('https://login.persona.org/include.js'); diff --git a/app/Models/Auth.php b/app/Models/Auth.php index 2971d65c8..84b4e3721 100644 --- a/app/Models/Auth.php +++ b/app/Models/Auth.php @@ -16,7 +16,8 @@ class FreshRSS_Auth { self::$login_ok = Minz_Session::param('loginOk', false); $current_user = Minz_Session::param('currentUser', ''); if ($current_user === '') { - $current_user = Minz_Configuration::defaultUser(); + $conf = Minz_Configuration::get('system'); + $current_user = $conf->general['default_user']; Minz_Session::_param('currentUser', $current_user); } @@ -40,7 +41,9 @@ class FreshRSS_Auth { * @return boolean true if user can be connected, false else. */ private static function accessControl() { - switch (Minz_Configuration::authType()) { + $conf = Minz_Configuration::get('system'); + $auth_type = $conf->general['auth_type']; + switch ($auth_type) { case 'form': $credentials = FreshRSS_FormAuth::getCredentialsFromCookie(); $current_user = ''; @@ -79,22 +82,19 @@ class FreshRSS_Auth { * Gives access to the current user. */ public static function giveAccess() { - $current_user = Minz_Session::param('currentUser'); - try { - $conf = new FreshRSS_Configuration($current_user); - } catch(Minz_Exception $e) { - die($e->getMessage()); - } + $user_conf = Minz_Configuration::get('user'); + $system_conf = Minz_Configuration::get('system'); + $auth_type = $system_conf->general['auth_type']; - switch (Minz_Configuration::authType()) { + switch ($auth_type) { case 'form': - self::$login_ok = Minz_Session::param('passwordHash') === $conf->passwordHash; + self::$login_ok = Minz_Session::param('passwordHash') === $user_conf->passwordHash; break; case 'http_auth': self::$login_ok = strcasecmp($current_user, httpAuthUser()) === 0; break; case 'persona': - self::$login_ok = strcasecmp(Minz_Session::param('mail'), $conf->mail_login) === 0; + self::$login_ok = strcasecmp(Minz_Session::param('mail'), $user_conf->mail_login) === 0; break; case 'none': self::$login_ok = true; @@ -114,12 +114,14 @@ class FreshRSS_Auth { * @return boolean true if user has corresponding access, false else. */ public static function hasAccess($scope = 'general') { + $conf = Minz_Configuration::get('system'); + $default_user = $conf->general['default_user']; $ok = self::$login_ok; switch ($scope) { case 'general': break; case 'admin': - $ok &= Minz_Session::param('currentUser') === Minz_Configuration::defaultUser(); + $ok &= Minz_Session::param('currentUser') === $default_user; break; default: $ok = false; @@ -133,9 +135,10 @@ class FreshRSS_Auth { public static function removeAccess() { Minz_Session::_param('loginOk'); self::$login_ok = false; - Minz_Session::_param('currentUser', Minz_Configuration::defaultUser()); + $conf = Minz_Configuration::get('system'); + Minz_Session::_param('currentUser', $conf->general['default_user']); - switch (Minz_Configuration::authType()) { + switch ($conf->general['auth_type']) { case 'form': Minz_Session::_param('passwordHash'); FreshRSS_FormAuth::deleteCookie(); @@ -151,6 +154,15 @@ class FreshRSS_Auth { // TODO: extensions } } + + /** + * Return if authentication is enabled on this instance of FRSS. + */ + public static function accessNeedLogin() { + $conf = Minz_Configuration::get('system'); + $auth_type = $conf->general['auth_type']; + return $auth_type === 'form' || $auth_type === 'persona'; + } } diff --git a/app/Models/Context.php b/app/Models/Context.php index c8a65063a..9bbad9857 100644 --- a/app/Models/Context.php +++ b/app/Models/Context.php @@ -41,10 +41,10 @@ class FreshRSS_Context { */ public static function init() { // Init configuration. - $current_user = Minz_Session::param('currentUser'); try { - self::$conf = new FreshRSS_Configuration($current_user); + self::$conf = Minz_Configuration::get('user'); } catch(Minz_Exception $e) { + $current_user = Minz_Session::param('currentUser', '_'); Minz_Log::error('Cannot load configuration file of user `' . $current_user . '`'); die($e->getMessage()); } diff --git a/app/Models/Factory.php b/app/Models/Factory.php index 91cb84998..db09d155d 100644 --- a/app/Models/Factory.php +++ b/app/Models/Factory.php @@ -3,8 +3,8 @@ class FreshRSS_Factory { public static function createFeedDao($username = null) { - $db = Minz_Configuration::dataBase(); - if ($db['type'] === 'sqlite') { + $conf = Minz_Configuration::get('system'); + if ($conf->db['type'] === 'sqlite') { return new FreshRSS_FeedDAOSQLite($username); } else { return new FreshRSS_FeedDAO($username); @@ -12,8 +12,8 @@ class FreshRSS_Factory { } public static function createEntryDao($username = null) { - $db = Minz_Configuration::dataBase(); - if ($db['type'] === 'sqlite') { + $conf = Minz_Configuration::get('system'); + if ($conf->db['type'] === 'sqlite') { return new FreshRSS_EntryDAOSQLite($username); } else { return new FreshRSS_EntryDAO($username); @@ -21,8 +21,8 @@ class FreshRSS_Factory { } public static function createStatsDAO($username = null) { - $db = Minz_Configuration::dataBase(); - if ($db['type'] === 'sqlite') { + $conf = Minz_Configuration::get('system'); + if ($conf->db['type'] === 'sqlite') { return new FreshRSS_StatsDAOSQLite($username); } else { return new FreshRSS_StatsDAO($username); @@ -30,8 +30,8 @@ class FreshRSS_Factory { } public static function createDatabaseDAO($username = null) { - $db = Minz_Configuration::dataBase(); - if ($db['type'] === 'sqlite') { + $conf = Minz_Configuration::get('system'); + if ($conf->db['type'] === 'sqlite') { return new FreshRSS_DatabaseDAOSQLite($username); } else { return new FreshRSS_DatabaseDAO($username); diff --git a/app/Models/Feed.php b/app/Models/Feed.php index 8f4b60097..071eafdf6 100644 --- a/app/Models/Feed.php +++ b/app/Models/Feed.php @@ -39,8 +39,9 @@ class FreshRSS_Feed extends Minz_Model { } public function hash() { + $conf = Minz_Configuration::get('system'); if ($this->hash === null) { - $this->hash = hash('crc32b', Minz_Configuration::salt() . $this->url); + $this->hash = hash('crc32b', $conf->general['salt'] . $this->url); } return $this->hash; } diff --git a/app/layout/header.phtml b/app/layout/header.phtml index ba13c2a45..2f16b5f63 100644 --- a/app/layout/header.phtml +++ b/app/layout/header.phtml @@ -1,5 +1,8 @@ - +
diff --git a/app/layout/layout.phtml b/app/layout/layout.phtml index 1827d6c26..656fbe9bc 100644 --- a/app/layout/layout.phtml +++ b/app/layout/layout.phtml @@ -10,6 +10,7 @@ renderHelper('javascript_vars'); ?> //]]> "> - + diff --git a/app/views/helpers/javascript_vars.phtml b/app/views/helpers/javascript_vars.phtml index 6577e0109..02f2014ee 100644 --- a/app/views/helpers/javascript_vars.phtml +++ b/app/views/helpers/javascript_vars.phtml @@ -1,6 +1,7 @@ "use strict"; mark_when; $mail = Minz_Session::param('mail', false); $auto_actualize = Minz_Session::param('actualize_feeds', false); @@ -29,7 +30,7 @@ echo 'var context={', 'does_lazyload:', FreshRSS_Context::$conf->lazyload ? 'true' : 'false', ',', 'sticky_post:', FreshRSS_Context::isStickyPostEnabled() ? 'true' : 'false', ',', 'html5_notif_timeout:', FreshRSS_Context::$conf->html5_notif_timeout, ',', - 'auth_type:"', Minz_Configuration::authType(), '",', + 'auth_type:"', $conf->general['auth_type'], '",', 'current_user_mail:', $mail ? ('"' . $mail . '"') : 'null', ',', 'current_view:"', Minz_Request::param('output', 'normal'), '"', "},\n"; diff --git a/data/config.default.php b/data/config.default.php new file mode 100644 index 000000000..a69d8050b --- /dev/null +++ b/data/config.default.php @@ -0,0 +1,32 @@ + array( + 'environment' => 'production', + 'salt' => '', + 'base_url' => '', + 'language' => 'en', + 'title' => 'FreshRSS', + 'default_user' => '_', + 'allow_anonymous' => false, + 'allow_anonymous_refresh' => false, + 'auth_type' => 'none', + 'api_enabled' => false, + 'unsafe_autologin_enabled' => false, + ), + 'limits' => array( + 'cache_duration' => 800, + 'timeout' => 10, + 'max_inactivity' => PHP_INT_MAX, + 'max_feeds' => 16384, + 'max_categories' => 16384, + ), + 'db' => array( + 'type' => 'sqlite', + 'host' => '', + 'user' => '', + 'password' => '', + 'base' => '', + 'prefix' => '', + ), +); diff --git a/data/users/_/config.default.php b/data/users/_/config.default.php new file mode 100644 index 000000000..56d54b293 --- /dev/null +++ b/data/users/_/config.default.php @@ -0,0 +1,66 @@ + 'en', + 'old_entries' => 3, + 'keep_history_default' => 0, + 'ttl_default' => 3600, + 'mail_login' => '', + 'token' => '', + 'passwordHash' => '', + 'apiPasswordHash' => '', + 'posts_per_page' => 20, + 'view_mode' => 'normal', + 'default_view' => 'adaptive', + 'default_state' => FreshRSS_Entry::STATE_NOT_READ, + 'auto_load_more' => true, + 'display_posts' => false, + 'display_categories' => false, + 'hide_read_feeds' => true, + 'onread_jump_next' => true, + 'lazyload' => true, + 'sticky_post' => true, + 'reading_confirm' => false, + 'auto_remove_article' => false, + 'sort_order' => 'DESC', + 'anon_access' => false, + 'mark_when' => array ( + 'article' => true, + 'site' => true, + 'scroll' => false, + 'reception' => false, + ), + 'theme' => 'Origine', + 'content_width' => 'thin', + 'shortcuts' => array ( + 'mark_read' => 'r', + 'mark_favorite' => 'f', + 'go_website' => 'space', + 'next_entry' => 'j', + 'prev_entry' => 'k', + 'first_entry' => 'home', + 'last_entry' => 'end', + 'collapse_entry' => 'c', + 'load_more' => 'm', + 'auto_share' => 's', + 'focus_search' => 'a', + 'user_filter' => 'u', + 'help' => 'f1', + 'close_dropdown' => 'escape', + ), + 'topline_read' => true, + 'topline_favorite' => true, + 'topline_date' => true, + 'topline_link' => true, + 'bottomline_read' => true, + 'bottomline_favorite' => true, + 'bottomline_sharing' => true, + 'bottomline_tags' => true, + 'bottomline_date' => true, + 'bottomline_link' => true, + 'sharing' => array ( + ), + 'queries' => array ( + ), + 'html5_notif_timeout' => 0, +); diff --git a/lib/Minz/BadConfigurationException.php b/lib/Minz/BadConfigurationException.php deleted file mode 100644 index a7b77d687..000000000 --- a/lib/Minz/BadConfigurationException.php +++ /dev/null @@ -1,9 +0,0 @@ - -*/ /** - * La classe Configuration permet de gérer la configuration de l'application + * Manage configuration for the application. */ class Minz_Configuration { - const CONF_PATH_NAME = '/config.php'; - /** - * VERSION est la version actuelle de MINZ + * The list of configurations. */ - const VERSION = '1.3.1.freshrss'; // version spéciale FreshRSS + private static $config_list = array(); /** - * valeurs possibles pour l'"environment" - * SILENT rend l'application muette (pas de log) - * PRODUCTION est recommandée pour une appli en production - * (log les erreurs critiques) - * DEVELOPMENT log toutes les erreurs + * Add a new configuration to the list of configuration. + * + * @param $namespace the name of the current configuration + * @param $config_filename the filename of the configuration + * @param $default_filename a filename containing default values for the configuration + * @throws Minz_ConfigurationNamespaceException if the namespace already exists. */ - const SILENT = 0; - const PRODUCTION = 1; - const DEVELOPMENT = 2; + public static function register($namespace, $config_filename, $default_filename = null) { + if (isset(self::$config_list[$namespace])) { + throw new Minz_ConfigurationNamespaceException( + $namespace . ' namespace already exists' + ); + } + + self::$config_list[$namespace] = new Minz_Configuration( + $namespace, $config_filename, $default_filename + ); + } /** - * définition des variables de configuration - * $salt une chaîne de caractères aléatoires (obligatoire) - * $environment gère le niveau d'affichage pour log et erreurs - * $base_url le chemin de base pour accéder à l'application - * $title le nom de l'application - * $language la langue par défaut de l'application - * $db paramètres pour la base de données (tableau) - * - host le serveur de la base - * - user nom d'utilisateur - * - password mot de passe de l'utilisateur - * - base le nom de la base de données + * Parse a file and return its data. + * + * If the file does not contain a valid PHP code returning an array, an + * empty array is returned anyway. + * + * @param $filename the name of the file to parse. + * @return an array of values + * @throws Minz_FileNotExistException if the file does not exist. */ - private static $salt = ''; - private static $environment = Minz_Configuration::PRODUCTION; - private static $base_url = ''; - private static $title = ''; - private static $language = 'en'; - private static $default_user = ''; - private static $allow_anonymous = false; - private static $allow_anonymous_refresh = false; - private static $auth_type = 'none'; - private static $api_enabled = false; - private static $unsafe_autologin_enabled = false; - - private static $db = array ( - 'type' => 'mysql', - 'host' => '', - 'user' => '', - 'password' => '', - 'base' => '', - 'prefix' => '', - ); - - const MAX_SMALL_INT = 16384; - private static $limits = array( - 'cache_duration' => 800, //SimplePie cache duration in seconds - 'timeout' => 10, //SimplePie timeout in seconds - 'max_inactivity' => PHP_INT_MAX, //Time in seconds after which a user who has not used the account is considered inactive (no auto-refresh of feeds). - 'max_feeds' => Minz_Configuration::MAX_SMALL_INT, - 'max_categories' => Minz_Configuration::MAX_SMALL_INT, - ); + public static function parseFile($filename) { + if (!file_exists($filename)) { + throw new Minz_FileNotExistException($filename); + } - /* - * Getteurs - */ - public static function salt () { - return self::$salt; + $data = @include($filename); + if (is_array($data)) { + return $data; + } else { + return array(); + } } - public static function environment ($str = false) { - $env = self::$environment; - if ($str) { - switch (self::$environment) { - case self::SILENT: - $env = 'silent'; - break; - case self::DEVELOPMENT: - $env = 'development'; - break; - case self::PRODUCTION: - default: - $env = 'production'; - } + /** + * Return the configuration related to a given namespace. + * + * @param $namespace the name of the configuration to get. + * @return a Minz_Configuration object + * @throws Minz_ConfigurationNamespaceException if the namespace does not exist. + */ + public static function get($namespace) { + if (!isset(self::$config_list[$namespace])) { + throw new Minz_ConfigurationNamespaceException( + $namespace . ' namespace does not exist' + ); } - return $env; - } - public static function baseUrl () { - return self::$base_url; - } - public static function title () { - return self::$title; - } - public static function language () { - return self::$language; - } - public static function dataBase () { - return self::$db; - } - public static function limits() { - return self::$limits; - } - public static function defaultUser () { - return self::$default_user; - } - public static function allowAnonymous() { - return self::$allow_anonymous; - } - public static function allowAnonymousRefresh() { - return self::$allow_anonymous_refresh; - } - public static function authType() { - return self::$auth_type; - } - public static function needsLogin() { - return self::$auth_type !== 'none'; - } - public static function canLogIn() { - return self::$auth_type === 'form' || self::$auth_type === 'persona'; - } - public static function apiEnabled() { - return self::$api_enabled; - } - public static function unsafeAutologinEnabled() { - return self::$unsafe_autologin_enabled; + return self::$config_list[$namespace]; } - public static function _allowAnonymous($allow = false) { - self::$allow_anonymous = ((bool)$allow) && self::canLogIn(); - } - public static function _allowAnonymousRefresh($allow = false) { - self::$allow_anonymous_refresh = ((bool)$allow) && self::allowAnonymous(); - } - public static function _authType($value) { - $value = strtolower($value); - switch ($value) { - case 'form': - case 'http_auth': - case 'persona': - case 'none': - self::$auth_type = $value; - break; - } - self::_allowAnonymous(self::$allow_anonymous); - } + /** + * The namespace of the current configuration. + */ + private $namespace = ''; - public static function _enableApi($value = false) { - self::$api_enabled = (bool)$value; - } - public static function _enableAutologin($value = false) { - self::$unsafe_autologin_enabled = (bool)$value; - } + /** + * The filename for the current configuration. + */ + private $config_filename = ''; + + /** + * The filename for the current default values, null by default. + */ + private $default_filename = null; + + /** + * The configuration values, an empty array by default. + */ + private $data = array(); + + /** + * The default values, an empty array by default. + */ + private $data_default = array(); /** - * Initialise les variables de configuration - * @exception Minz_FileNotExistException si le CONF_PATH_NAME n'existe pas - * @exception Minz_BadConfigurationException si CONF_PATH_NAME mal formaté + * Create a new Minz_Configuration object. + * + * @param $namespace the name of the current configuration. + * @param $config_filename the file containing configuration values. + * @param $default_filename the file containing default values, null by default. */ - public static function init () { + private function __construct($namespace, $config_filename, $default_filename = null) { + $this->namespace = $namespace; + $this->config_filename = $config_filename; + try { - self::parseFile (); - self::setReporting (); + $this->data = self::parseFile($this->config_filename); } catch (Minz_FileNotExistException $e) { - throw $e; - } catch (Minz_BadConfigurationException $e) { - throw $e; + if (is_null($default_filename)) { + throw $e; + } } - } - public static function writeFile() { - $ini_array = array( - 'general' => array( - 'environment' => self::environment(true), - 'salt' => self::$salt, - 'base_url' => self::$base_url, - 'title' => self::$title, - 'default_user' => self::$default_user, - 'allow_anonymous' => self::$allow_anonymous, - 'allow_anonymous_refresh' => self::$allow_anonymous_refresh, - 'auth_type' => self::$auth_type, - 'api_enabled' => self::$api_enabled, - 'unsafe_autologin_enabled' => self::$unsafe_autologin_enabled, - ), - 'limits' => self::$limits, - 'db' => self::$db, - ); - @rename(DATA_PATH . self::CONF_PATH_NAME, DATA_PATH . self::CONF_PATH_NAME . '.bak.php'); - $result = file_put_contents(DATA_PATH . self::CONF_PATH_NAME, "default_filename = $default_filename; + if (!is_null($this->default_filename)) { + $this->data_default = self::parseFile($this->default_filename); } - return (bool)$result; } /** - * Parse un fichier de configuration - * @exception Minz_PermissionDeniedException si le CONF_PATH_NAME n'est pas accessible - * @exception Minz_BadConfigurationException si CONF_PATH_NAME mal formaté + * Return the value of the given param. + * + * @param $key the name of the param. + * @param $default default value to return if key does not exist. + * @return the value corresponding to the key. + * @throws Minz_ConfigurationParamException if the param does not exist */ - private static function parseFile () { - $ini_array = include(DATA_PATH . self::CONF_PATH_NAME); - - if (!is_array($ini_array)) { - throw new Minz_PermissionDeniedException ( - DATA_PATH . self::CONF_PATH_NAME, - Minz_Exception::ERROR + public function param($key, $default = null) { + if (isset($this->data[$key])) { + return $this->data[$key]; + } elseif (!is_null($default)) { + return $default; + } elseif (isset($this->data_default[$key])) { + return $this->data_default[$key]; + } else { + throw new Minz_ConfigurationParamException( + $key . ' param does not exist' ); } + } - // [general] est obligatoire - if (!isset ($ini_array['general'])) { - throw new Minz_BadConfigurationException ( - '[general]', - Minz_Exception::ERROR - ); - } - $general = $ini_array['general']; + /** + * A wrapper for param(). + */ + public function __get($key) { + return $this->param($key); + } - // salt est obligatoire - if (!isset ($general['salt'])) { - if (isset($general['sel_application'])) { //v0.6 - $general['salt'] = $general['sel_application']; - } else { - throw new Minz_BadConfigurationException ( - 'salt', - Minz_Exception::ERROR - ); - } + /** + * Set or remove a param. + * + * @param $key the param name to set. + * @param $value the value to set. If null, the key is removed from the configuration. + */ + public function _param($key, $value = null) { + if (isset($this->data[$key]) && is_null($value)) { + unset($this->data[$key]); + } else { + $this->data[$key] = $value; } - self::$salt = $general['salt']; - - if (isset ($general['environment'])) { - switch ($general['environment']) { - case 'silent': - self::$environment = Minz_Configuration::SILENT; - break; - case 'development': - self::$environment = Minz_Configuration::DEVELOPMENT; - break; - case 'production': - self::$environment = Minz_Configuration::PRODUCTION; - break; - default: - if ($general['environment'] >= 0 && - $general['environment'] <= 2) { - // fallback 0.7-beta - self::$environment = $general['environment']; - } else { - throw new Minz_BadConfigurationException ( - 'environment', - Minz_Exception::ERROR - ); - } - } + } - } - if (isset ($general['base_url'])) { - self::$base_url = $general['base_url']; - } + /** + * A wrapper for _param(). + */ + public function __set($key, $value) { + $this->_param($key, $value); + } - if (isset ($general['title'])) { - self::$title = $general['title']; - } - if (isset ($general['language'])) { - self::$language = $general['language']; - } - if (isset ($general['default_user'])) { - self::$default_user = $general['default_user']; - } - if (isset ($general['auth_type'])) { - self::_authType($general['auth_type']); - } - if (isset ($general['allow_anonymous'])) { - self::$allow_anonymous = ( - ((bool)($general['allow_anonymous'])) && - ($general['allow_anonymous'] !== 'no') - ); - } - if (isset ($general['allow_anonymous_refresh'])) { - self::$allow_anonymous_refresh = ( - ((bool)($general['allow_anonymous_refresh'])) && - ($general['allow_anonymous_refresh'] !== 'no') - ); - } - if (isset ($general['api_enabled'])) { - self::$api_enabled = ( - ((bool)($general['api_enabled'])) && - ($general['api_enabled'] !== 'no') - ); - } - if (isset ($general['unsafe_autologin_enabled'])) { - self::$unsafe_autologin_enabled = ( - ((bool)($general['unsafe_autologin_enabled'])) && - ($general['unsafe_autologin_enabled'] !== 'no') - ); - } + /** + * Save the current configuration in the configuration file. + */ + public function save() { + $back_filename = $this->config_filename . '.bak.php'; + @rename($this->config_filename, $back_filename); - if (isset($ini_array['limits'])) { - $limits = $ini_array['limits']; - if (isset($limits['cache_duration'])) { - $v = intval($limits['cache_duration']); - if ($v > 0) { - self::$limits['cache_duration'] = $v; - } - } - if (isset($limits['timeout'])) { - $v = intval($limits['timeout']); - if ($v > 0) { - self::$limits['timeout'] = $v; - } - } - if (isset($limits['max_inactivity'])) { - $v = intval($limits['max_inactivity']); - if ($v > 0) { - self::$limits['max_inactivity'] = $v; - } - } - if (isset($limits['max_feeds'])) { - $v = intval($limits['max_feeds']); - if ($v > 0 && $v < Minz_Configuration::MAX_SMALL_INT) { - self::$limits['max_feeds'] = $v; - } - } - if (isset($limits['max_categories'])) { - $v = intval($limits['max_categories']); - if ($v > 0 && $v < Minz_Configuration::MAX_SMALL_INT) { - self::$limits['max_categories'] = $v; - } - } + if (file_put_contents($this->config_filename, + "data, true) . ';', + LOCK_EX) === false) { + return false; } - // Base de données - if (isset ($ini_array['db'])) { - $db = $ini_array['db']; - if (empty($db['type'])) { - throw new Minz_BadConfigurationException ( - 'type', - Minz_Exception::ERROR - ); - } - switch ($db['type']) { - case 'mysql': - if (empty($db['host'])) { - throw new Minz_BadConfigurationException ( - 'host', - Minz_Exception::ERROR - ); - } - if (empty($db['user'])) { - throw new Minz_BadConfigurationException ( - 'user', - Minz_Exception::ERROR - ); - } - if (!isset($db['password'])) { - throw new Minz_BadConfigurationException ( - 'password', - Minz_Exception::ERROR - ); - } - if (empty($db['base'])) { - throw new Minz_BadConfigurationException ( - 'base', - Minz_Exception::ERROR - ); - } - self::$db['host'] = $db['host']; - self::$db['user'] = $db['user']; - self::$db['password'] = $db['password']; - self::$db['base'] = $db['base']; - if (isset($db['prefix'])) { - self::$db['prefix'] = $db['prefix']; - } - break; - case 'sqlite': - self::$db['host'] = ''; - self::$db['user'] = ''; - self::$db['password'] = ''; - self::$db['base'] = ''; - self::$db['prefix'] = ''; - break; - default: - throw new Minz_BadConfigurationException ( - 'type', - Minz_Exception::ERROR - ); - break; - } - self::$db['type'] = $db['type']; + // Clear PHP 5.5+ cache for include + if (function_exists('opcache_invalidate')) { + opcache_invalidate($this->config_filename); } - } - private static function setReporting() { - switch (self::$environment) { - case self::PRODUCTION: - error_reporting(E_ALL); - ini_set('display_errors','Off'); - ini_set('log_errors', 'On'); - break; - case self::DEVELOPMENT: - error_reporting(E_ALL); - ini_set('display_errors','On'); - ini_set('log_errors', 'On'); - break; - case self::SILENT: - error_reporting(0); - break; - } + return true; } } diff --git a/lib/Minz/ConfigurationException.php b/lib/Minz/ConfigurationException.php new file mode 100644 index 000000000..f294c3341 --- /dev/null +++ b/lib/Minz/ConfigurationException.php @@ -0,0 +1,8 @@ + en fonction de l'environment */ private static function processLogs ($logs) { - $env = Minz_Configuration::environment (); + $conf = Minz_Configuration::get('system'); + $env = $conf->general['environment']; $logs_ok = array (); $error = array (); $warning = array (); @@ -98,10 +99,10 @@ class Minz_Error { $notice = $logs['notice']; } - if ($env == Minz_Configuration::PRODUCTION) { + if ($env == 'production') { $logs_ok = $error; } - if ($env == Minz_Configuration::DEVELOPMENT) { + if ($env == 'development') { $logs_ok = array_merge ($error, $warning, $notice); } diff --git a/lib/Minz/FrontController.php b/lib/Minz/FrontController.php index 3dac1e438..974cf4260 100644 --- a/lib/Minz/FrontController.php +++ b/lib/Minz/FrontController.php @@ -31,9 +31,12 @@ class Minz_FrontController { */ public function __construct () { try { - Minz_Configuration::init (); + Minz_Configuration::register('system', + DATA_PATH . '/config.php', + DATA_PATH . '/config.default.php'); + $this->setReporting(); - Minz_Request::init (); + Minz_Request::init(); $url = $this->buildUrl(); $url['params'] = array_merge ( @@ -110,4 +113,23 @@ class Minz_FrontController { } exit ('### Application problem ###
'."\n".$txt); } + + private function setReporting() { + $conf = Minz_Configuration::get('system'); + switch($conf->general['environment']) { + case 'production': + error_reporting(E_ALL); + ini_set('display_errors','Off'); + ini_set('log_errors', 'On'); + break; + case 'development': + error_reporting(E_ALL); + ini_set('display_errors','On'); + ini_set('log_errors', 'On'); + break; + case 'silent': + error_reporting(0); + break; + } + } } diff --git a/lib/Minz/Log.php b/lib/Minz/Log.php index d19edc1dc..2063efe7e 100644 --- a/lib/Minz/Log.php +++ b/lib/Minz/Log.php @@ -31,10 +31,15 @@ class Minz_Log { * @param $file_name fichier de log */ public static function record ($information, $level, $file_name = null) { - $env = Minz_Configuration::environment (); + try { + $conf = Minz_Configuration::get('system'); + $env = $conf->general['environment']; + } catch (Minz_ConfigurationException $e) { + $env = 'production'; + } - if (! ($env === Minz_Configuration::SILENT - || ($env === Minz_Configuration::PRODUCTION + if (! ($env === 'silent' + || ($env === 'production' && ($level >= Minz_Log::NOTICE)))) { if ($file_name === null) { $file_name = join_path(USERS_PATH, Minz_Session::param('currentUser', '_'), 'log.txt'); diff --git a/lib/Minz/ModelPdo.php b/lib/Minz/ModelPdo.php index 118d89ad2..ac7a1bed7 100644 --- a/lib/Minz/ModelPdo.php +++ b/lib/Minz/ModelPdo.php @@ -44,7 +44,8 @@ class Minz_ModelPdo { return; } - $db = Minz_Configuration::dataBase(); + $conf = Minz_Configuration::get('system'); + $db = $conf->db; if ($currentUser === null) { $currentUser = Minz_Session::param('currentUser', '_'); diff --git a/lib/Minz/Request.php b/lib/Minz/Request.php index 4b97a3caf..5f2f6a858 100644 --- a/lib/Minz/Request.php +++ b/lib/Minz/Request.php @@ -96,7 +96,8 @@ class Minz_Request { * @return la base de l'url */ public static function getBaseUrl() { - $defaultBaseUrl = Minz_Configuration::baseUrl(); + $conf = Minz_Configuration::get('system'); + $defaultBaseUrl = $conf->general['base_url']; if (!empty($defaultBaseUrl)) { return $defaultBaseUrl; } elseif (isset($_SERVER['REQUEST_URI'])) { diff --git a/lib/Minz/Translate.php b/lib/Minz/Translate.php index e7efb8665..7525e95cc 100644 --- a/lib/Minz/Translate.php +++ b/lib/Minz/Translate.php @@ -28,7 +28,8 @@ class Minz_Translate { * Load $lang_name and $lang_path based on configuration and selected language. */ public static function init() { - $l = Minz_Configuration::language(); + $conf = Minz_Configuration::get('system'); + $l = $conf->general['language']; self::$lang_name = Minz_Session::param('language', $l); self::$lang_path = APP_PATH . '/i18n/' . self::$lang_name . '/'; } diff --git a/lib/Minz/View.php b/lib/Minz/View.php index b40448491..24ad630d0 100644 --- a/lib/Minz/View.php +++ b/lib/Minz/View.php @@ -28,7 +28,9 @@ class Minz_View { public function __construct () { $this->change_view(Minz_Request::controllerName(), Minz_Request::actionName()); - self::$title = Minz_Configuration::title (); + + $conf = Minz_Configuration::get('system'); + self::$title = $conf->general['title']; } /** diff --git a/p/i/index.php b/p/i/index.php index 009d56bc3..d3fc0b37c 100755 --- a/p/i/index.php +++ b/p/i/index.php @@ -33,7 +33,7 @@ if (file_exists(DATA_PATH . '/do-install.txt')) { $currentUser = Minz_Session::param('currentUser', ''); $dateLastModification = $currentUser === '' ? time() : max( @filemtime(join_path(USERS_PATH, $currentUser, 'log.txt')), - @filemtime(join_path(DATA_PATH . 'config.php')) + @filemtime(join_path(DATA_PATH, 'config.php')) ); if (httpConditional($dateLastModification, 0, 0, false, PHP_COMPRESSION, true)) { exit(); //No need to send anything -- cgit v1.2.3 From 9c8a80e57f1e2eb60916eae2e2cbed86d991c750 Mon Sep 17 00:00:00 2001 From: Marien Fressinaud Date: Wed, 7 Jan 2015 15:39:24 +0100 Subject: Remove .gitkeep in data/users/_/ --- data/users/_/.gitkeep | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 data/users/_/.gitkeep (limited to 'data/users/_') diff --git a/data/users/_/.gitkeep b/data/users/_/.gitkeep deleted file mode 100644 index e69de29bb..000000000 -- cgit v1.2.3 From 0d0c6b7493161d350ca2eb1d4c45c0c70cfcbb92 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sun, 10 May 2015 14:04:12 +0200 Subject: Moved updated/unread option from global to user https://github.com/FreshRSS/FreshRSS/issues/798 --- app/Controllers/configureController.php | 1 + app/Controllers/feedController.php | 2 +- app/Models/ConfigurationSetter.php | 4 ++++ app/i18n/de/conf.php | 1 + app/i18n/en/conf.php | 1 + app/i18n/fr/conf.php | 1 + app/views/configure/reading.phtml | 9 +++++++++ data/config.default.php | 4 ---- data/users/_/config.default.php | 5 +++++ 9 files changed, 23 insertions(+), 5 deletions(-) (limited to 'data/users/_') diff --git a/app/Controllers/configureController.php b/app/Controllers/configureController.php index fc92aa0c2..248a3edcc 100755 --- a/app/Controllers/configureController.php +++ b/app/Controllers/configureController.php @@ -112,6 +112,7 @@ class FreshRSS_configure_Controller extends Minz_ActionController { FreshRSS_Context::$user_conf->sticky_post = Minz_Request::param('sticky_post', false); FreshRSS_Context::$user_conf->reading_confirm = Minz_Request::param('reading_confirm', false); FreshRSS_Context::$user_conf->auto_remove_article = Minz_Request::param('auto_remove_article', false); + FreshRSS_Context::$user_conf->mark_updated_article_unread = Minz_Request::param('mark_updated_article_unread', false); FreshRSS_Context::$user_conf->sort_order = Minz_Request::param('sort_order', 'DESC'); FreshRSS_Context::$user_conf->mark_when = array( 'article' => Minz_Request::param('mark_open_article', false), diff --git a/app/Controllers/feedController.php b/app/Controllers/feedController.php index 03f438888..a36a38ce2 100755 --- a/app/Controllers/feedController.php +++ b/app/Controllers/feedController.php @@ -343,7 +343,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { Minz_Log::debug('Entry with GUID `' . $entry->guid() . '` updated in feed ' . $feed->id() . ', old hash ' . $existingHash . ', new hash ' . $entry->hash()); //TODO: Make an updated/is_read policy by feed, in addition to the global one. - $entry->_isRead(FreshRSS_Context::$system_conf->mark_updated_article_unread ? false : null); //Change is_read according to policy. + $entry->_isRead(FreshRSS_Context::$user_conf->mark_updated_article_unread ? false : null); //Change is_read according to policy. if (!$entryDAO->hasTransaction()) { $entryDAO->beginTransaction(); } diff --git a/app/Models/ConfigurationSetter.php b/app/Models/ConfigurationSetter.php index 7f433239c..4bd29ecb0 100644 --- a/app/Models/ConfigurationSetter.php +++ b/app/Models/ConfigurationSetter.php @@ -189,6 +189,10 @@ class FreshRSS_ConfigurationSetter { $data['auto_remove_article'] = $this->handleBool($value); } + private function _mark_updated_article_unread(&$data, $value) { + $data['mark_updated_article_unread'] = $this->handleBool($value); + } + private function _display_categories(&$data, $value) { $data['display_categories'] = $this->handleBool($value); } diff --git a/app/i18n/de/conf.php b/app/i18n/de/conf.php index 64c2c0945..df2c07d49 100644 --- a/app/i18n/de/conf.php +++ b/app/i18n/de/conf.php @@ -84,6 +84,7 @@ return array( 'articles_per_page' => 'Anzahl der Artikel pro Seite', 'auto_load_more' => 'Die nächsten Artikel am Seitenende laden', 'auto_remove_article' => 'Artikel nach dem Lesen verstecken', + 'mark_updated_article_unread' => 'Markieren Sie aktualisierte Artikel als ungelesen', 'confirm_enabled' => 'Bei der Aktion „Alle als gelesen markieren“ einen Bestätigungsdialog anzeigen', 'display_articles_unfolded' => 'Artikel standardmäßig ausgeklappt zeigen', 'display_categories_unfolded' => 'Kategorien standardmäßig eingeklappt zeigen', diff --git a/app/i18n/en/conf.php b/app/i18n/en/conf.php index 308c45d2c..683781696 100644 --- a/app/i18n/en/conf.php +++ b/app/i18n/en/conf.php @@ -84,6 +84,7 @@ return array( 'articles_per_page' => 'Number of articles per page', 'auto_load_more' => 'Load next articles at the page bottom', 'auto_remove_article' => 'Hide articles after reading', + 'mark_updated_article_unread' => 'Mark updated articles as unread', 'confirm_enabled' => 'Display a confirmation dialog on “mark all as read” actions', 'display_articles_unfolded' => 'Show articles unfolded by default', 'display_categories_unfolded' => 'Show categories folded by default', diff --git a/app/i18n/fr/conf.php b/app/i18n/fr/conf.php index d38445b99..87f9be290 100644 --- a/app/i18n/fr/conf.php +++ b/app/i18n/fr/conf.php @@ -84,6 +84,7 @@ return array( 'articles_per_page' => 'Nombre d’articles par page', 'auto_load_more' => 'Charger les articles suivants en bas de page', 'auto_remove_article' => 'Cacher les articles après lecture', + 'mark_updated_article_unread' => 'Marquer les articles mis à jour comme non-lus', 'confirm_enabled' => 'Afficher une confirmation lors des actions “marquer tout comme lu”', 'display_articles_unfolded' => 'Afficher les articles dépliés par défaut', 'display_categories_unfolded' => 'Afficher les catégories pliées par défaut', diff --git a/app/views/configure/reading.phtml b/app/views/configure/reading.phtml index 8b123afa8..1b7a101df 100644 --- a/app/views/configure/reading.phtml +++ b/app/views/configure/reading.phtml @@ -125,6 +125,15 @@ +
+
+ +
+
+
diff --git a/data/config.default.php b/data/config.default.php index dc947f154..8be203d36 100644 --- a/data/config.default.php +++ b/data/config.default.php @@ -55,10 +55,6 @@ return array( # SimplePie, which is retrieving RSS feeds via HTTP requests. 'simplepie_syslog_enabled' => true, - # In the case an article has changed (e.g. updated content): - # Set to `true` to mark it unread, or `false` to leave it as-is. - 'mark_updated_article_unread' => false, - 'limits' => array( # Duration in seconds of the SimplePie cache, diff --git a/data/users/_/config.default.php b/data/users/_/config.default.php index 6d3f73a13..bf74ca1de 100644 --- a/data/users/_/config.default.php +++ b/data/users/_/config.default.php @@ -22,6 +22,11 @@ return array ( 'sticky_post' => true, 'reading_confirm' => false, 'auto_remove_article' => false, + + # In the case an article has changed (e.g. updated content): + # Set to `true` to mark it unread, or `false` to leave it as-is. + 'mark_updated_article_unread' => false, + 'sort_order' => 'DESC', 'anon_access' => false, 'mark_when' => array ( -- cgit v1.2.3 From 3adab4b70fab858048bd68ed72e71676c4d5badf Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sat, 16 May 2015 13:05:43 +0200 Subject: More PubSubHubbub https://github.com/FreshRSS/FreshRSS/issues/312 Show whether PubSubHubbub is enabled in the Web interface of feed configuration. When PubSubHubbub is used, do not pull refresh so often (hard-coded to max once per 24h for now). Improved logic for lease renewal, and some detection of lease problems. Updated read-me and changelog. --- CHANGELOG | 9 ++++++ README.fr.md | 22 +++++++------- README.md | 34 ++++++++++----------- app/Controllers/feedController.php | 36 ++++++++++++++-------- app/Models/Feed.php | 59 +++++++++++++++++++++++++++++++------ app/i18n/cz/conf.php | 1 + app/i18n/cz/sub.php | 1 + app/i18n/de/sub.php | 1 + app/i18n/en/sub.php | 1 + app/i18n/fr/sub.php | 1 + app/views/helpers/feed/update.phtml | 8 +++++ data/users/_/config.default.php | 2 +- p/api/pshb.php | 8 +++-- 13 files changed, 128 insertions(+), 55 deletions(-) (limited to 'data/users/_') diff --git a/CHANGELOG b/CHANGELOG index d1b49d339..f3559ccc4 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,15 @@ ## 2015-xx-xx FreshRSS 1.1.1 (beta) +* Features + * Support for PubSubHubbub for instant notifications from compatible Web sites. + * New option to detect and mark updated articles as unread. + * Support for internationalized domain name (IDN). +* Misc. + * Improved logic for automatic deletion of old articles. + * Attempt to better handle encoded titles. + + ## 2015-01-31 FreshRSS 1.0.0 / 1.1.0 (beta) * UI diff --git a/README.fr.md b/README.fr.md index 6c77ccf51..1110eb8e5 100644 --- a/README.fr.md +++ b/README.fr.md @@ -6,6 +6,7 @@ FreshRSS est un agrégateur de flux RSS à auto-héberger à l’image de [Leed] Il se veut léger et facile à prendre en main tout en étant un outil puissant et paramétrable. Il permet de gérer plusieurs utilisateurs, et dispose d’un mode de lecture anonyme. +Il supporte [PubSubHubbub](https://code.google.com/p/pubsubhubbub/) pour des notifications instantanées depuis les sites compatibles. * Site officiel : http://freshrss.org * Démo : http://demo.freshrss.org/ @@ -14,28 +15,25 @@ Il permet de gérer plusieurs utilisateurs, et dispose d’un mode de lecture an ![Logo de FreshRSS](http://marienfressinaud.fr/data/images/freshrss/freshrss_title.png) # Note sur les branches -**Ce logiciel est encore en développement !** Veuillez vous assurer d'utiliser la branche qui vous correspond : +**Ce logiciel est en développement permanent !** Veuillez vous assurer d'utiliser la branche qui vous correspond : * Utilisez [la branche master](https://github.com/FreshRSS/FreshRSS/tree/master/) si vous visez la stabilité. * [La branche beta](https://github.com/FreshRSS/FreshRSS/tree/beta) est celle par défaut : les nouveautés y sont ajoutées environ tous les mois. -* Pour les développeurs et ceux qui savent ce qu'ils font, [la branche dev](https://github.com/FreshRSS/FreshRSS/tree/dev) vous ouvre les bras ! +* Pour les développeurs et ceux qui veulent aider à tester les toutes dernières fonctionnalités, [la branche dev](https://github.com/FreshRSS/FreshRSS/tree/dev) vous ouvre les bras ! # Disclaimer -Cette application a été développée pour s’adapter à des besoins personnels et non professionnels. -Je ne garantis en aucun cas la sécurité de celle-ci, ni son bon fonctionnement. -Je m’engage néanmoins à répondre dans la mesure du possible aux demandes d’évolution si celles-ci me semblent justifiées. -Privilégiez pour cela des demandes sur GitHub -(https://github.com/FreshRSS/FreshRSS/issues). +Cette application a été développée pour s’adapter principalement à des besoins personnels, et aucune garantie n'est fournie. +Les demandes de fonctionnalités, rapports de bugs, et autres contributions sont les bienvenues. Privilégiez pour cela des [demandes sur GitHub](https://github.com/FreshRSS/FreshRSS/issues). -# Pré-requis +# Prérequis * Serveur modeste, par exemple sous Linux ou Windows * Fonctionne même sur un Raspberry Pi avec des temps de réponse < 1s (testé sur 150 flux, 22k articles, soit 32Mo de données partiellement compressées) * Serveur Web Apache2 (recommandé), ou nginx, lighttpd (non testé sur les autres) * PHP 5.2.1+ (PHP 5.3.7+ recommandé) - * Requis : [PDO_MySQL](http://php.net/pdo-mysql) ou [PDO_SQLite](http://php.net/pdo-sqlite), [cURL](http://php.net/curl), [GMP](http://php.net/gmp) (pour accès API sur platformes < 64 bits), [IDN](http://php.net/intl.idn) (pour les noms de domaines internationalisés) + * Requis : [PDO_MySQL](http://php.net/pdo-mysql) ou [PDO_SQLite](http://php.net/pdo-sqlite), [cURL](http://php.net/curl), [GMP](http://php.net/gmp) (pour accès API sur plateformes < 64 bits), [IDN](http://php.net/intl.idn) (pour les noms de domaines internationalisés) * Recommandés : [JSON](http://php.net/json), [mbstring](http://php.net/mbstring), [zlib](http://php.net/zlib), [Zip](http://php.net/zip) * MySQL 5.0.3+ (recommandé) ou SQLite 3.7.4+ -* Un navigateur Web récent tel Firefox 4+, Chrome, Opera, Safari, Internet Explorer 9+ +* Un navigateur Web récent tel Firefox, Chrome, Opera, Safari. [Internet Explorer ne fonctionne plus, mais ce sera corrigé](https://github.com/FreshRSS/FreshRSS/issues/772). * Fonctionne aussi sur mobile ![Capture d’écran de FreshRSS](http://marienfressinaud.fr/data/images/freshrss/freshrss_default-design.png) @@ -63,7 +61,7 @@ C’est une bonne idée d’utiliser le même utilisateur que votre serveur Web Par exemple, pour exécuter le script toutes les heures : ``` -7 * * * * php /chemin/vers/FreshRSS/app/actualize_script.php > /tmp/FreshRSS.log 2>&1 +7 * * * * php /votre-chemin/FreshRSS/app/actualize_script.php > /tmp/FreshRSS.log 2>&1 ``` # Conseils @@ -75,7 +73,7 @@ Par exemple, pour exécuter le script toutes les heures : # Sauvegarde * Il faut conserver vos fichiers `./data/config.php` ainsi que `./data/*_user.php` et éventuellement `./data/persona/` * Vous pouvez exporter votre liste de flux depuis FreshRSS au format OPML -* Pour sauvegarder les articles eux-même, vous pouvez utiliser [phpMyAdmin](http://www.phpmyadmin.net) ou les outils de MySQL : +* Pour sauvegarder les articles eux-mêmes, vous pouvez utiliser [phpMyAdmin](http://www.phpmyadmin.net) ou les outils de MySQL : ```bash mysqldump -u utilisateur -p --databases freshrss > freshrss.sql diff --git a/README.md b/README.md index 089bbd780..4430560fe 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,12 @@ * [Version française](README.fr.md) # FreshRSS -FreshRSS is a self-hosted RSS feed agregator like [Leed](http://projet.idleman.fr/leed/) or [Kriss Feed](http://tontof.net/kriss/feed/). +FreshRSS is a self-hosted RSS feed aggregator such as [Leed](http://projet.idleman.fr/leed/) or [Kriss Feed](http://tontof.net/kriss/feed/). -It is at the same time light-weight, easy to work with, powerful and customizable. +It is at the same time lightweight, easy to work with, powerful and customizable. It is a multi-user application with an anonymous reading mode. +It supports [PubSubHubbub](https://code.google.com/p/pubsubhubbub/) for instant notifications from compatible Web sites. * Official website: http://freshrss.org * Demo: http://demo.freshrss.org/ @@ -14,28 +15,25 @@ It is a multi-user application with an anonymous reading mode. ![FreshRSS logo](http://marienfressinaud.fr/data/images/freshrss/freshrss_title.png) # Note on branches -**This application is still in development!** Please use the branch that suits your needs: +**This application is under continuous development!** Please use the branch that suits your needs: * Use [the master branch](https://github.com/FreshRSS/FreshRSS/tree/master/) if you need a stable version. * [The beta branch](https://github.com/FreshRSS/FreshRSS/tree/beta) is the default branch: new features are added on a monthly basis. -* For developers and tech savvy persons, [the dev branch](https://github.com/FreshRSS/FreshRSS/tree/dev) is waiting for you! +* For developers and tech savvy persons willing to help testing the latest features, [the dev branch](https://github.com/FreshRSS/FreshRSS/tree/dev) is waiting for you! # Disclaimer -This application was developed to fulfill personal needs not professional needs. -There is no guarantee neither on its security nor its proper functioning. -If there is feature requests which I think are good for the project, I'll do my best to include them. -The best way is to open issues on GitHub -(https://github.com/FreshRSS/FreshRSS/issues). +This application was developed to fulfil personal needs primarily, and comes with absolutely no warranty. +Feature requests, bug reports, and other contributions are welcome. The best way is to [open issues on GitHub](https://github.com/FreshRSS/FreshRSS/issues). # Requirements * Light server running Linux or Windows * It even works on Raspberry Pi with response time under a second (tested with 150 feeds, 22k articles, or 32Mo of compressed data) -* A web server: Apache2 (recommanded), nginx, lighttpd (not tested on others) -* PHP 5.2.1+ (PHP 5.3.7+ recommanded) +* A web server: Apache2 (recommended), nginx, lighttpd (not tested on others) +* PHP 5.2.1+ (PHP 5.3.7+ recommended) * Required extensions: [PDO_MySQL](http://php.net/pdo-mysql) or [PDO_SQLite](http://php.net/pdo-sqlite), [cURL](http://php.net/curl), [GMP](http://php.net/gmp) (for API access on platforms < 64 bits), [IDN](http://php.net/intl.idn) (for Internationalized Domain Names) - * Recommanded extensions : [JSON](http://php.net/json), [mbstring](http://php.net/mbstring), [zlib](http://php.net/zlib), [Zip](http://php.net/zip) -* MySQL 5.0.3+ (recommanded) or SQLite 3.7.4+ -* A recent browser like Firefox 4+, Chrome, Opera, Safari, Internet Explorer 9+ + * Recommended extensions: [JSON](http://php.net/json), [mbstring](http://php.net/mbstring), [zlib](http://php.net/zlib), [Zip](http://php.net/zip) +* MySQL 5.0.3+ (recommended) or SQLite 3.7.4+ +* A recent browser like Firefox, Chrome, Opera, Safari. [Internet Explorer currently not supported, but support will come back](https://github.com/FreshRSS/FreshRSS/issues/772). * Works on mobile ![FreshRSS screenshot](http://marienfressinaud.fr/data/images/freshrss/freshrss_default-design.png) @@ -45,7 +43,7 @@ The best way is to open issues on GitHub 2. Dump the application on your server (expose only the `./p/` folder) 3. Add write access on `./data/` folder to the webserver user 4. Access FreshRSS with your browser and follow the installation process -5. Every thing should be working :) If you encounter any problem, feel free to contact me. +5. Everything should be working :) If you encounter any problem, feel free to contact me. 6. Advanced configuration settings can be seen in [config.php](./data/config.default.php). # Access control @@ -59,18 +57,18 @@ It is needed for the multi-user mode to limit access to FreshRSS. You can: # Automatic feed update * You can add a Cron job to launch the update script. Check the Cron documentation related to your distribution ([Debian/Ubuntu](https://help.ubuntu.com/community/CronHowto), [Red Hat/Fedora](https://fedoraproject.org/wiki/Administration_Guide_Draft/Cron), [Slackware](http://docs.slackware.com/fr:slackbook:process_control?#cron), [Gentoo](https://wiki.gentoo.org/wiki/Cron), [Arch Linux](https://wiki.archlinux.org/index.php/Cron)…). -It’s a good idea to use the web server user . +It’s a good idea to use the Web server user. For example, if you want to run the script every hour: ``` -7 * * * * php /chemin/vers/FreshRSS/app/actualize_script.php > /tmp/FreshRSS.log 2>&1 +7 * * * * php /your-path/FreshRSS/app/actualize_script.php > /tmp/FreshRSS.log 2>&1 ``` # Advices * For a better security, expose only the `./p/` folder on the web. * Be aware that the `./data/` folder contains all personal data, so it is a bad idea to expose it. * The `./constants.php` file defines access to application folder. If you want to customize your installation, every thing happens here. -* If you encounter any problem, logs are accessibles from the interface or manually in `./data/log/*.log` files. +* If you encounter any problem, logs are accessible from the interface or manually in `./data/log/*.log` files. # Backup * You need to keep `./data/config.php`, `./data/*_user.php` and `./data/persona/` files diff --git a/app/Controllers/feedController.php b/app/Controllers/feedController.php index ab73879d0..dfdf0dc16 100755 --- a/app/Controllers/feedController.php +++ b/app/Controllers/feedController.php @@ -268,7 +268,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { * If id and url are not specified, all the feeds are actualized. But if force is * false, process stops at 10 feeds to avoid time execution problem. */ - public function actualizeAction($simplePie = null) { + public function actualizeAction($simplePiePush = null) { @set_time_limit(300); $feedDAO = FreshRSS_Factory::createFeedDao(); @@ -295,10 +295,16 @@ class FreshRSS_feed_Controller extends Minz_ActionController { // Calculate date of oldest entries we accept in DB. $nb_month_old = max(FreshRSS_Context::$user_conf->old_entries, 1); $date_min = time() - (3600 * 24 * 30 * $nb_month_old); + $pshbMinAge = time() - (3600 * 24); //TODO: Make a configuration. $updated_feeds = 0; $is_read = FreshRSS_Context::$user_conf->mark_when['reception'] ? 1 : 0; foreach ($feeds as $feed) { + $pubSubHubbubEnabled = $feed->pubSubHubbubEnabled(); + if ((!$simplePiePush) && (!$id) && (!$force) && $pubSubHubbubEnabled && ($feed->lastUpdate() > $pshbMinAge)) { + continue; //When PubSubHubbub is used, do not pull refresh so often + } + if (!$feed->lock()) { Minz_Log::notice('Feed already being actualized: ' . $feed->url()); continue; @@ -306,8 +312,8 @@ class FreshRSS_feed_Controller extends Minz_ActionController { $url = $feed->url(); //For detection of HTTP 301 try { - if ($simplePie) { - $feed->loadEntries($simplePie); //Used by PubSubHubbub + if ($simplePiePush) { + $feed->loadEntries($simplePiePush); //Used by PubSubHubbub } else { $feed->load(false); } @@ -374,6 +380,14 @@ class FreshRSS_feed_Controller extends Minz_ActionController { continue; } + if ($pubSubHubbubEnabled && !$simplePiePush) { //We use push, but have discovered an article by pull! + $text = 'An article was discovered by pull although we use PubSubHubbub!: Feed ' . $url . ' GUID ' . $entry->guid(); + file_put_contents(USERS_PATH . '/_/log_pshb.txt', date('c') . "\t" . $text . "\n", FILE_APPEND); + Minz_Log::warning($text); + $pubSubHubbubEnabled = false; + $feed->pubSubHubbubEnabled(false); //To force the renewal of our lease + } + if (!$entryDAO->hasTransaction()) { $entryDAO->beginTransaction(); } @@ -423,15 +437,13 @@ class FreshRSS_feed_Controller extends Minz_ActionController { $feedDAO->updateFeed($feed->id(), array('url' => $feed->url())); } - if ($simplePie === null) { - $feed->faviconPrepare(); - if (in_array($feed->url(), array('http://push-pub.appspot.com/feed'))) { //TODO: Remove white-list after testing - Minz_Log::debug('PubSubHubbub match ' . $feed->url()); - if ($feed->pubSubHubbubPrepare()) { - Minz_Log::notice('PubSubHubbub subscribe ' . $feed->url()); - if (!$feed->pubSubHubbubSubscribe(true)) { //Subscribe - Minz_Log::warning('Error while PubSubHubbub subscribing to ' . $feed->url()); - } + $feed->faviconPrepare(); + if (in_array($feed->url(), array('http://push-pub.appspot.com/feed'))) { //TODO: Remove white-list after testing + Minz_Log::debug('PubSubHubbub match ' . $feed->url()); + if ($feed->pubSubHubbubPrepare()) { + Minz_Log::notice('PubSubHubbub subscribe ' . $feed->url()); + if (!$feed->pubSubHubbubSubscribe(true)) { //Subscribe + Minz_Log::warning('Error while PubSubHubbub subscribing to ' . $feed->url()); } } } diff --git a/app/Models/Feed.php b/app/Models/Feed.php index d2b552265..7bc60dfc9 100644 --- a/app/Models/Feed.php +++ b/app/Models/Feed.php @@ -104,6 +104,16 @@ class FreshRSS_Feed extends Minz_Model { public function ttl() { return $this->ttl; } + // public function ttlExpire() { + // $ttl = $this->ttl; + // if ($ttl == -2) { //Default + // $ttl = FreshRSS_Context::$user_conf->ttl_default; + // } + // if ($ttl == -1) { //Never + // $ttl = 64000000; //~2 years. Good enough for PubSubHubbub logic + // } + // return $this->lastUpdate + $ttl; + // } public function nbEntries() { if ($this->nbEntries < 0) { $feedDAO = FreshRSS_Factory::createFeedDao(); @@ -349,18 +359,42 @@ class FreshRSS_Feed extends Minz_Model { // + function pubSubHubbubEnabled($keep = true) { + $url = $this->selfUrl ? $this->selfUrl : $this->url; + $hubFilename = PSHB_PATH . '/feeds/' . base64url_encode($url) . '/!hub.json'; + if ($hubFile = @file_get_contents($hubFilename)) { + $hubJson = json_decode($hubFile, true); + if (!$keep) { + $hubJson['lease_end'] = time() - 60; + file_put_contents($hubFilename, json_encode($hubJson)); + file_put_contents(USERS_PATH . '/_/log_pshb.txt', date('c') . "\t" + . 'Force expire lease for ' . $url . "\n", FILE_APPEND); + } elseif ($hubJson && (empty($hubJson['lease_end']) || $hubJson['lease_end'] > time())) { + return true; + } + } + return false; + } + function pubSubHubbubPrepare() { $key = ''; if (FreshRSS_Context::$system_conf->base_url && $this->hubUrl && $this->selfUrl) { $path = PSHB_PATH . '/feeds/' . base64url_encode($this->selfUrl); - if ($hubFile = @file_get_contents($path . '/!hub.json')) { + $hubFilename = $path . '/!hub.json'; + if ($hubFile = @file_get_contents($hubFilename)) { $hubJson = json_decode($hubFile, true); if (!$hubJson || empty($hubJson['key']) || !ctype_xdigit($hubJson['key'])) { - Minz_Log::warning('Invalid JSON for PubSubHubbub: ' . $this->url); + $text = 'Invalid JSON for PubSubHubbub: ' . $this->url; + Minz_Log::warning($text); + file_put_contents(USERS_PATH . '/_/log_pshb.txt', date('c') . "\t" . $text . "\n", FILE_APPEND); return false; } - if (empty($hubJson['lease_end']) || $hubJson['lease_end'] <= time()) { - Minz_Log::warning('PubSubHubbub lease expired: ' . $this->url); + if (empty($hubJson['lease_end']) || ($hubJson['lease_end'] <= (time() + (3600 * 24)))) { //TODO: Make a better policy + $text = 'PubSubHubbub lease ends at ' + . date('c', empty($hubJson['lease_end']) ? time() : $hubJson['lease_end']) + . ' and needs renewal: ' . $this->url; + Minz_Log::warning($text); + file_put_contents(USERS_PATH . '/_/log_pshb.txt', date('c') . "\t" . $text . "\n", FILE_APPEND); $key = $hubJson['key']; //To renew our lease } } else { @@ -370,12 +404,12 @@ class FreshRSS_Feed extends Minz_Model { 'hub' => $this->hubUrl, 'key' => $key, ); - file_put_contents($path . '/!hub.json', json_encode($hubJson)); + file_put_contents($hubFilename, json_encode($hubJson)); @mkdir(PSHB_PATH . '/keys/'); file_put_contents(PSHB_PATH . '/keys/' . $key . '.txt', base64url_encode($this->selfUrl)); - Minz_Log::debug('PubSubHubbub prepared for ' . $this->url); - file_put_contents(USERS_PATH . '/_/log_pshb.txt', date('c') . "\t" . - 'PubSubHubbub prepared for ' . $this->url . "\n", FILE_APPEND); + $text = 'PubSubHubbub prepared for ' . $this->url; + Minz_Log::debug($text); + file_put_contents(USERS_PATH . '/_/log_pshb.txt', date('c') . "\t" . $text . "\n", FILE_APPEND); } $currentUser = Minz_Session::param('currentUser'); if (ctype_alnum($currentUser) && !file_exists($path . '/' . $currentUser . '.txt')) { @@ -388,7 +422,8 @@ class FreshRSS_Feed extends Minz_Model { //Parameter true to subscribe, false to unsubscribe. function pubSubHubbubSubscribe($state) { if (FreshRSS_Context::$system_conf->base_url && $this->hubUrl && $this->selfUrl) { - $hubFile = @file_get_contents(PSHB_PATH . '/feeds/' . base64url_encode($this->selfUrl) . '/!hub.json'); + $hubFilename = PSHB_PATH . '/feeds/' . base64url_encode($this->selfUrl) . '/!hub.json'; + $hubFile = @file_get_contents($hubFilename); if ($hubFile === false) { Minz_Log::warning('JSON not found for PubSubHubbub: ' . $this->url); return false; @@ -421,6 +456,12 @@ class FreshRSS_Feed extends Minz_Model { file_put_contents(USERS_PATH . '/_/log_pshb.txt', date('c') . "\t" . 'PubSubHubbub ' . ($state ? 'subscribe' : 'unsubscribe') . ' to ' . $this->selfUrl . ' with callback ' . $callbackUrl . ': ' . $info['http_code'] . ' ' . $response . "\n", FILE_APPEND); + + if (!$state) { //unsubscribe + $hubJson['lease_end'] = time() - 60; + file_put_contents($hubFilename, json_encode($hubJson)); + } + return substr($info['http_code'], 0, 1) == '2'; } return false; diff --git a/app/i18n/cz/conf.php b/app/i18n/cz/conf.php index 29fb1e4d4..9518df66d 100644 --- a/app/i18n/cz/conf.php +++ b/app/i18n/cz/conf.php @@ -84,6 +84,7 @@ return array( 'articles_per_page' => 'Počet článků na stranu', 'auto_load_more' => 'Načítat další články dole na stránce', 'auto_remove_article' => 'Po přečtení články schovat', + 'mark_updated_article_unread' => 'Označte aktualizované položky jako nepřečtené', 'confirm_enabled' => 'Vyžadovat potvrzení pro akci “označit vše jako přečtené”', 'display_articles_unfolded' => 'Ve výchozím stavu zobrazovat články otevřené', 'display_categories_unfolded' => 'Ve výchozím stavu zobrazovat kategorie zavřené', diff --git a/app/i18n/cz/sub.php b/app/i18n/cz/sub.php index 78712506c..cea0541e3 100644 --- a/app/i18n/cz/sub.php +++ b/app/i18n/cz/sub.php @@ -37,6 +37,7 @@ return array( 'url' => 'URL kanálu', 'validator' => 'Zkontrolovat platnost kanálu', 'website' => 'URL webové stránky', + 'pubsubhubbub' => 'Okamžité oznámení s PubSubHubbub', ), 'import_export' => array( 'export' => 'Export', diff --git a/app/i18n/de/sub.php b/app/i18n/de/sub.php index 0479b8f46..7433bd61c 100644 --- a/app/i18n/de/sub.php +++ b/app/i18n/de/sub.php @@ -37,6 +37,7 @@ return array( 'url' => 'Feed-URL', 'validator' => 'Überprüfen Sie die Gültigkeit des Feeds', 'website' => 'Webseiten-URL', + 'pubsubhubbub' => 'Sofortige Benachrichtigung mit PubSubHubbub', ), 'import_export' => array( 'export' => 'Exportieren', diff --git a/app/i18n/en/sub.php b/app/i18n/en/sub.php index 2b62e4775..d8b5ced04 100644 --- a/app/i18n/en/sub.php +++ b/app/i18n/en/sub.php @@ -37,6 +37,7 @@ return array( 'url' => 'Feed URL', 'validator' => 'Check the validity of the feed', 'website' => 'Website URL', + 'pubsubhubbub' => 'Instant notification with PubSubHubbub', ), 'import_export' => array( 'export' => 'Export', diff --git a/app/i18n/fr/sub.php b/app/i18n/fr/sub.php index a3f7c4d6d..0a1a03e41 100644 --- a/app/i18n/fr/sub.php +++ b/app/i18n/fr/sub.php @@ -37,6 +37,7 @@ return array( 'url' => 'URL du flux', 'validator' => 'Vérifier la valididé du flux', 'website' => 'URL du site', + 'pubsubhubbub' => 'Notification instantanée par PubSubHubbub', ), 'import_export' => array( 'export' => 'Exporter', diff --git a/app/views/helpers/feed/update.phtml b/app/views/helpers/feed/update.phtml index 0b08d036c..b2cf9f93c 100644 --- a/app/views/helpers/feed/update.phtml +++ b/app/views/helpers/feed/update.phtml @@ -126,6 +126,14 @@ ?>
+
+ +
+ +
+
diff --git a/data/users/_/config.default.php b/data/users/_/config.default.php index bf74ca1de..8f8ff528c 100644 --- a/data/users/_/config.default.php +++ b/data/users/_/config.default.php @@ -25,7 +25,7 @@ return array ( # In the case an article has changed (e.g. updated content): # Set to `true` to mark it unread, or `false` to leave it as-is. - 'mark_updated_article_unread' => false, + 'mark_updated_article_unread' => false, //TODO: -1 => ignore, 0 => update, 1 => update and mark as unread 'sort_order' => 'DESC', 'anon_access' => false, diff --git a/p/api/pshb.php b/p/api/pshb.php index 6280c04ac..2f7f48cd8 100644 --- a/p/api/pshb.php +++ b/p/api/pshb.php @@ -57,8 +57,10 @@ if (!empty($_REQUEST['hub_mode']) && $_REQUEST['hub_mode'] === 'subscribe') { $leaseSeconds = empty($_REQUEST['hub_lease_seconds']) ? 0 : intval($_REQUEST['hub_lease_seconds']); if ($leaseSeconds > 60) { $hubJson['lease_end'] = time() + $leaseSeconds; - file_put_contents('./!hub.json', json_encode($hubJson)); + } else { + unset($hubJson['lease_end']); } + file_put_contents('./!hub.json', json_encode($hubJson)); exit(isset($_REQUEST['hub_challenge']) ? $_REQUEST['hub_challenge'] : ''); } @@ -84,7 +86,7 @@ $self = isset($links[0]) ? $links[0] : null; if ($self !== base64url_decode($canonical64)) { //header('HTTP/1.1 422 Unprocessable Entity'); - logMe('Warning: Self URL ' . $self . ' does not match registered canonical URL!: ' . base64url_decode($canonical64)); + logMe('Warning: Self URL [' . $self . '] does not match registered canonical URL!: ' . base64url_decode($canonical64)); //die('Self URL does not match registered canonical URL!'); $self = base64url_decode($canonical64); } @@ -120,5 +122,5 @@ if ($nb === 0) { die('Nobody is subscribed to this feed anymore after all!'); } -logMe($self . ' done: ' . $nb); +logMe('PubSubHubbub ' . $self . ' done: ' . $nb); exit('Done: ' . $nb . "\n"); -- cgit v1.2.3 From c1548e732d7472c40473b3d99858059333a05eae Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sun, 31 Jul 2016 14:58:19 +0200 Subject: Remove Mozilla Persona login https://github.com/FreshRSS/FreshRSS/issues/1052 --- README.fr.md | 3 +- README.md | 3 +- app/Controllers/authController.php | 152 +------------------------------- app/Controllers/userController.php | 25 ------ app/FreshRSS.php | 8 -- app/Models/Auth.php | 18 +--- app/Models/ConfigurationSetter.php | 7 +- app/i18n/cz/admin.php | 6 -- app/i18n/cz/conf.php | 1 - app/i18n/cz/feedback.php | 1 - app/i18n/cz/gen.php | 3 - app/i18n/cz/install.php | 6 -- app/i18n/de/admin.php | 6 -- app/i18n/de/conf.php | 1 - app/i18n/de/feedback.php | 1 - app/i18n/de/gen.php | 3 - app/i18n/de/install.php | 6 -- app/i18n/en/admin.php | 6 -- app/i18n/en/conf.php | 1 - app/i18n/en/feedback.php | 1 - app/i18n/en/gen.php | 3 - app/i18n/en/install.php | 6 -- app/i18n/fr/admin.php | 6 -- app/i18n/fr/conf.php | 1 - app/i18n/fr/feedback.php | 1 - app/i18n/fr/gen.php | 3 - app/i18n/fr/install.php | 6 -- app/i18n/it/admin.php | 6 -- app/i18n/it/conf.php | 1 - app/i18n/it/feedback.php | 1 - app/i18n/it/gen.php | 3 - app/i18n/it/install.php | 6 -- app/i18n/nl/admin.php | 6 -- app/i18n/nl/conf.php | 1 - app/i18n/nl/feedback.php | 1 - app/i18n/nl/gen.php | 3 - app/i18n/nl/install.php | 6 -- app/i18n/ru/admin.php | 6 -- app/i18n/ru/conf.php | 1 - app/i18n/ru/feedback.php | 1 - app/i18n/ru/gen.php | 3 - app/i18n/ru/install.php | 6 -- app/i18n/tr/admin.php | 6 -- app/i18n/tr/conf.php | 1 - app/i18n/tr/feedback.php | 1 - app/i18n/tr/gen.php | 3 - app/i18n/tr/install.php | 6 -- app/install.php | 45 +--------- app/views/auth/index.phtml | 3 +- app/views/auth/personaLogin.phtml | 28 ------ app/views/auth/register.phtml | 5 -- app/views/auth/reset.phtml | 33 ------- app/views/helpers/javascript_vars.phtml | 2 - app/views/user/manage.phtml | 8 -- app/views/user/profile.phtml | 9 -- data/config.default.php | 1 - data/users/_/config.default.php | 1 - lib/lib_rss.php | 1 - p/scripts/install.js | 8 +- p/scripts/persona.js | 76 ---------------- 60 files changed, 11 insertions(+), 561 deletions(-) delete mode 100644 app/views/auth/personaLogin.phtml delete mode 100644 app/views/auth/reset.phtml delete mode 100644 p/scripts/persona.js (limited to 'data/users/_') diff --git a/README.fr.md b/README.fr.md index fd01a507b..067d6d1a1 100644 --- a/README.fr.md +++ b/README.fr.md @@ -89,7 +89,6 @@ sudo chmod -R g+w ./data/ # Contrôle d’accès Il est requis pour le mode multi-utilisateur, et recommandé dans tous les cas, de limiter l’accès à votre FreshRSS. Au choix : * En utilisant l’identification par formulaire (requiert JavaScript, et PHP 5.3.7+ recommandé – fonctionne avec certaines versions de PHP 5.3.3+) -* En utilisant l’identification par [Mozilla Persona](https://login.persona.org/about) incluse dans FreshRSS * En utilisant un contrôle d’accès HTTP défini par votre serveur Web * Voir par exemple la [documentation d’Apache sur l’authentification](http://httpd.apache.org/docs/trunk/howto/auth.html) * Créer dans ce cas un fichier `./p/i/.htaccess` avec un fichier `.htpasswd` correspondant. @@ -111,7 +110,7 @@ Par exemple, pour exécuter le script toutes les heures : * En cas de problème, les logs peuvent être utile à lire, soit depuis l’interface de FreshRSS, soit manuellement depuis `./data/log/*.log`. # Sauvegarde -* Il faut conserver vos fichiers `./data/config.php` ainsi que `./data/*_user.php` et éventuellement `./data/persona/` +* Il faut conserver vos fichiers `./data/config.php` ainsi que `./data/*_user.php` * Vous pouvez exporter votre liste de flux depuis FreshRSS au format OPML * Pour sauvegarder les articles eux-mêmes, vous pouvez utiliser [phpMyAdmin](http://www.phpmyadmin.net) ou les outils de MySQL : diff --git a/README.md b/README.md index a0d22a75c..76975adbd 100644 --- a/README.md +++ b/README.md @@ -89,7 +89,6 @@ sudo chmod -R g+w ./data/ # Access control It is needed for the multi-user mode to limit access to FreshRSS. You can: * use form authentication (need JavaScript and PHP 5.3.7+, works with some PHP 5.3.3+) -* use [Mozilla Persona](https://login.persona.org/about) authentication included in FreshRSS * use HTTP authentication supported by your web server * See [Apache documentation](http://httpd.apache.org/docs/trunk/howto/auth.html) * In that case, create a `./p/i/.htaccess` file with a matching `.htpasswd` file. @@ -111,7 +110,7 @@ For example, if you want to run the script every hour: * If you encounter any problem, logs are accessible from the interface or manually in `./data/log/*.log` files. # Backup -* You need to keep `./data/config.php`, `./data/*_user.php` and `./data/persona/` files +* You need to keep `./data/config.php`, and `./data/*_user.php` files * You can export your feed list in OPML format from FreshRSS * To save articles, you can use [phpMyAdmin](http://www.phpmyadmin.net) or MySQL tools: diff --git a/app/Controllers/authController.php b/app/Controllers/authController.php index f58b008de..9decba431 100644 --- a/app/Controllers/authController.php +++ b/app/Controllers/authController.php @@ -70,7 +70,7 @@ class FreshRSS_auth_Controller extends Minz_ActionController { /** * This action handles the login page. * - * It forwards to the correct login page (form or Persona) or main page if + * It forwards to the correct login page (form) or main page if * the user is already connected. */ public function loginAction() { @@ -83,9 +83,6 @@ class FreshRSS_auth_Controller extends Minz_ActionController { case 'form': Minz_Request::forward(array('c' => 'auth', 'a' => 'formLogin')); break; - case 'persona': - Minz_Request::forward(array('c' => 'auth', 'a' => 'personaLogin')); - break; case 'http_auth': case 'none': // It should not happened! @@ -188,81 +185,6 @@ class FreshRSS_auth_Controller extends Minz_ActionController { } } - /** - * This action handles Persona login page. - * - * If this action is reached through a POST request, assertion from Persona - * is verificated and user connected if all is ok. - * - * Parameter is: - * - assertion (default: false) - * - * @todo: Persona system should be moved to a plugin - */ - public function personaLoginAction() { - $this->view->res = false; - - if (Minz_Request::isPost()) { - $this->view->_useLayout(false); - - $assert = Minz_Request::param('assertion'); - $url = 'https://verifier.login.persona.org/verify'; - $params = 'assertion=' . $assert . '&audience=' . - urlencode(Minz_Url::display(null, 'php', true)); - $ch = curl_init(); - $options = array( - CURLOPT_URL => $url, - CURLOPT_RETURNTRANSFER => TRUE, - CURLOPT_POST => 2, - CURLOPT_POSTFIELDS => $params - ); - curl_setopt_array($ch, $options); - $result = curl_exec($ch); - curl_close($ch); - - $res = json_decode($result, true); - - $login_ok = false; - $reason = ''; - if ($res['status'] === 'okay') { - $email = filter_var($res['email'], FILTER_VALIDATE_EMAIL); - if ($email != '') { - $persona_file = DATA_PATH . '/persona/' . $email . '.txt'; - if (($current_user = @file_get_contents($persona_file)) !== false) { - $current_user = trim($current_user); - $conf = get_user_configuration($current_user); - if (!is_null($conf)) { - $login_ok = strcasecmp($email, $conf->mail_login) === 0; - } else { - $reason = 'Invalid configuration for user ' . - '[' . $current_user . ']'; - } - } - } else { - $reason = 'Invalid email format [' . $res['email'] . ']'; - } - } else { - $reason = $res['reason']; - } - - if ($login_ok) { - Minz_Session::_param('currentUser', $current_user); - Minz_Session::_param('mail', $email); - FreshRSS_Auth::giveAccess(); - invalidateHttpCache(); - } else { - Minz_Log::warning($reason); - - $res = array(); - $res['status'] = 'failure'; - $res['reason'] = _t('feedback.auth.login.invalid'); - } - - header('Content-Type: application/json; charset=UTF-8'); - $this->view->res = $res; - } - } - /** * This action removes all accesses of the current user. */ @@ -273,78 +195,6 @@ class FreshRSS_auth_Controller extends Minz_ActionController { array('c' => 'index', 'a' => 'index')); } - /** - * This action resets the authentication system. - * - * After reseting, form auth is set by default. - */ - public function resetAction() { - Minz_View::prependTitle(_t('admin.auth.title_reset') . ' · '); - - Minz_View::appendScript(Minz_Url::display( - '/scripts/bcrypt.min.js?' . @filemtime(PUBLIC_PATH . '/scripts/bcrypt.min.js') - )); - - $this->view->no_form = false; - // Enable changement of auth only if Persona! - if (FreshRSS_Context::$system_conf->auth_type != 'persona') { - $this->view->message = array( - 'status' => 'bad', - 'title' => _t('gen.short.damn'), - 'body' => _t('feedback.auth.not_persona') - ); - $this->view->no_form = true; - return; - } - - $conf = get_user_configuration(FreshRSS_Context::$system_conf->default_user); - if (is_null($conf)) { - return; - } - - // Admin user must have set its master password. - if (!$conf->passwordHash) { - $this->view->message = array( - 'status' => 'bad', - 'title' => _t('gen.short.damn'), - 'body' => _t('feedback.auth.no_password_set') - ); - $this->view->no_form = true; - return; - } - - invalidateHttpCache(); - - if (Minz_Request::isPost()) { - $nonce = Minz_Session::param('nonce'); - $username = Minz_Request::param('username', ''); - $challenge = Minz_Request::param('challenge', ''); - - $ok = FreshRSS_FormAuth::checkCredentials( - $username, $conf->passwordHash, $nonce, $challenge - ); - - if ($ok) { - FreshRSS_Context::$system_conf->auth_type = 'form'; - $ok = FreshRSS_Context::$system_conf->save(); - - if ($ok) { - Minz_Request::good(_t('feedback.auth.form.set')); - } else { - Minz_Request::bad(_t('feedback.auth.form.not_set'), - array('c' => 'auth', 'a' => 'reset')); - } - } else { - Minz_Log::warning('Password mismatch for' . - ' user=' . $username . - ', nonce=' . $nonce . - ', c=' . $challenge); - Minz_Request::bad(_t('feedback.auth.login.invalid'), - array('c' => 'auth', 'a' => 'reset')); - } - } - } - /** * This action gives possibility to a user to create an account. */ diff --git a/app/Controllers/userController.php b/app/Controllers/userController.php index 1c7d621f1..0521bc008 100644 --- a/app/Controllers/userController.php +++ b/app/Controllers/userController.php @@ -64,21 +64,8 @@ class FreshRSS_user_Controller extends Minz_ActionController { FreshRSS_Context::$user_conf->apiPasswordHash = $passwordHash; } - // TODO: why do we need of hasAccess here? - if (FreshRSS_Auth::hasAccess('admin')) { - FreshRSS_Context::$user_conf->mail_login = Minz_Request::param('mail_login', '', true); - } - $email = FreshRSS_Context::$user_conf->mail_login; - Minz_Session::_param('mail', $email); - $ok &= FreshRSS_Context::$user_conf->save(); - if ($email != '') { - $personaFile = DATA_PATH . '/persona/' . $email . '.txt'; - @unlink($personaFile); - $ok &= (file_put_contents($personaFile, Minz_Session::param('currentUser', '_')) !== false); - } - if ($ok) { Minz_Request::good(_t('feedback.profile.updated'), array('c' => 'user', 'a' => 'profile')); @@ -119,7 +106,6 @@ class FreshRSS_user_Controller extends Minz_ActionController { * - new_user_language * - new_user_name * - new_user_passwordPlain - * - new_user_email * - r (i.e. a redirection url, optional) * * @todo clean up this method. Idea: write a method to init a user with basic information. @@ -168,22 +154,12 @@ class FreshRSS_user_Controller extends Minz_ActionController { if (empty($passwordHash)) { $passwordHash = ''; } - - $new_user_email = filter_var($_POST['new_user_email'], FILTER_VALIDATE_EMAIL); - if (empty($new_user_email)) { - $new_user_email = ''; - } else { - $personaFile = join_path(DATA_PATH, 'persona', $new_user_email . '.txt'); - @unlink($personaFile); - $ok &= (file_put_contents($personaFile, $new_user_name) !== false); - } } if ($ok) { mkdir(join_path(DATA_PATH, 'users', $new_user_name)); $config_array = array( 'language' => $new_user_language, 'passwordHash' => $passwordHash, - 'mail_login' => $new_user_email, ); $ok &= (file_put_contents($configPath, "deleteUser($username); $ok &= recursive_unlink($user_data); - //TODO: delete Persona file } if ($ok && $self_deletion) { FreshRSS_Auth::removeAccess(); diff --git a/app/FreshRSS.php b/app/FreshRSS.php index 4933892bc..20640266e 100644 --- a/app/FreshRSS.php +++ b/app/FreshRSS.php @@ -98,14 +98,6 @@ class FreshRSS extends Minz_FrontController { Minz_View::appendScript(Minz_Url::display('/scripts/jquery.min.js?' . @filemtime(PUBLIC_PATH . '/scripts/jquery.min.js'))); Minz_View::appendScript(Minz_Url::display('/scripts/shortcut.js?' . @filemtime(PUBLIC_PATH . '/scripts/shortcut.js'))); Minz_View::appendScript(Minz_Url::display('/scripts/main.js?' . @filemtime(PUBLIC_PATH . '/scripts/main.js'))); - - if (FreshRSS_Context::$system_conf->auth_type === 'persona') { - // TODO move it in a plugin - // Needed for login AND logout with Persona. - Minz_View::appendScript('https://login.persona.org/include.js'); - $file_mtime = @filemtime(PUBLIC_PATH . '/scripts/persona.js'); - Minz_View::appendScript(Minz_Url::display('/scripts/persona.js?' . $file_mtime)); - } } private static function loadNotifications() { diff --git a/app/Models/Auth.php b/app/Models/Auth.php index 4e7a71947..d689f7cdb 100644 --- a/app/Models/Auth.php +++ b/app/Models/Auth.php @@ -60,16 +60,6 @@ class FreshRSS_Auth { Minz_Session::_param('currentUser', $current_user); } return $login_ok; - case 'persona': - $email = filter_var(Minz_Session::param('mail'), FILTER_VALIDATE_EMAIL); - $persona_file = DATA_PATH . '/persona/' . $email . '.txt'; - if (($current_user = @file_get_contents($persona_file)) !== false) { - $current_user = trim($current_user); - Minz_Session::_param('currentUser', $current_user); - Minz_Session::_param('mail', $email); - return true; - } - return false; case 'none': return true; default: @@ -93,9 +83,6 @@ class FreshRSS_Auth { case 'http_auth': self::$login_ok = strcasecmp($current_user, httpAuthUser()) === 0; break; - case 'persona': - self::$login_ok = strcasecmp(Minz_Session::param('mail'), $user_conf->mail_login) === 0; - break; case 'none': self::$login_ok = true; break; @@ -143,9 +130,6 @@ class FreshRSS_Auth { Minz_Session::_param('passwordHash'); FreshRSS_FormAuth::deleteCookie(); break; - case 'persona': - Minz_Session::_param('mail'); - break; case 'http_auth': case 'none': // Nothing to do... @@ -170,7 +154,7 @@ class FreshRSS_Auth { public static function accessNeedsAction() { $conf = Minz_Configuration::get('system'); $auth_type = $conf->auth_type; - return $auth_type === 'form' || $auth_type === 'persona'; + return $auth_type === 'form'; } } diff --git a/app/Models/ConfigurationSetter.php b/app/Models/ConfigurationSetter.php index 250c14c39..e472b1e7f 100644 --- a/app/Models/ConfigurationSetter.php +++ b/app/Models/ConfigurationSetter.php @@ -95,11 +95,6 @@ class FreshRSS_ConfigurationSetter { $data['language'] = $value; } - private function _mail_login(&$data, $value) { - $value = filter_var($value, FILTER_VALIDATE_EMAIL); - $data['mail_login'] = $value ? $value : ''; - } - private function _old_entries(&$data, $value) { $value = intval($value); $data['old_entries'] = $value > 0 ? $value : 3; @@ -278,7 +273,7 @@ class FreshRSS_ConfigurationSetter { private function _auth_type(&$data, $value) { $value = strtolower($value); - if (!in_array($value, array('form', 'http_auth', 'persona', 'none'))) { + if (!in_array($value, array('form', 'http_auth', 'none'))) { $value = 'none'; } $data['auth_type'] = $value; diff --git a/app/i18n/cz/admin.php b/app/i18n/cz/admin.php index 342ac7ccd..881c02fc6 100644 --- a/app/i18n/cz/admin.php +++ b/app/i18n/cz/admin.php @@ -8,7 +8,6 @@ return array( 'form' => 'Webový formulář (tradiční, vyžaduje JavaScript)', 'http' => 'HTTP (pro pokročilé uživatele s HTTPS)', 'none' => 'Žádný (nebezpečné)', - 'persona' => 'Mozilla Persona (moderní, vyžaduje JavaScript)', 'title' => 'Přihlášení', 'title_reset' => 'Reset přihlášení', 'token' => 'Authentizační token', @@ -75,10 +74,6 @@ return array( 'nok' => 'Nemáte PDO nebo některý z podporovaných ovladačů (pdo_mysql, pdo_sqlite).', 'ok' => 'Máte PDO a alespoň jeden z podporovaných ovladačů (pdo_mysql, pdo_sqlite).', ), - 'persona' => array( - 'nok' => 'Zkontrolujte oprávnění adresáře ./data/persona. HTTP server musí mít do tohoto adresáře práva zápisu', - 'ok' => 'Oprávnění adresáře Mozilla Persona jsou v pořádku.', - ), 'php' => array( '_' => 'PHP instalace', 'nok' => 'Vaše verze PHP je %s, ale FreshRSS vyžaduje alespoň verzi %s.', @@ -169,7 +164,6 @@ return array( 'user' => array( 'articles_and_size' => '%s článků (%s)', 'create' => 'Vytvořit nového uživatele', - 'email_persona' => 'Email pro přihlášení
(pro Mozilla Persona)', 'language' => 'Jazyk', 'number' => 'Zatím je vytvořen %d účet', 'numbers' => 'Zatím je vytvořeno %d účtů', diff --git a/app/i18n/cz/conf.php b/app/i18n/cz/conf.php index 823ab1ea3..ec25f988c 100644 --- a/app/i18n/cz/conf.php +++ b/app/i18n/cz/conf.php @@ -76,7 +76,6 @@ return array( '_' => 'Smazání účtu', 'warn' => 'Váš účet bude smazán spolu se všemi souvisejícími daty', ), - 'email_persona' => 'Email pro přihlášení
(pro Mozilla Persona)', 'password_api' => 'Password API
(tzn. pro mobilní aplikace)', 'password_form' => 'Heslo
(pro přihlášení webovým formulářem)', 'password_format' => 'Alespoň 7 znaků', diff --git a/app/i18n/cz/feedback.php b/app/i18n/cz/feedback.php index b75a4a15a..81302afca 100644 --- a/app/i18n/cz/feedback.php +++ b/app/i18n/cz/feedback.php @@ -21,7 +21,6 @@ return array( 'success' => 'Jste odhlášen', ), 'no_password_set' => 'Heslo administrátora nebylo nastaveno. Tato funkce není k dispozici.', - 'not_persona' => 'Resetovat lze pouze systém Persona.', ), 'conf' => array( 'error' => 'Během ukládání nastavení došlo k chybě', diff --git a/app/i18n/cz/gen.php b/app/i18n/cz/gen.php index 5e15ae6f9..e73325c55 100644 --- a/app/i18n/cz/gen.php +++ b/app/i18n/cz/gen.php @@ -24,8 +24,6 @@ return array( 'email' => 'Email', 'keep_logged_in' => 'Zapamatovat přihlášení (1 měsíc)', 'login' => 'Login', - 'login_persona' => 'Přihlášení pomocí Persona', - 'login_persona_problem' => 'Problém s připojením k Persona?', 'logout' => 'Odhlášení', 'password' => array( '_' => 'Heslo', @@ -42,7 +40,6 @@ return array( 'admin' => 'Název administrátorského účtu', 'format' => 'maximálně 16 alfanumerických znaků', ), - 'will_reset' => 'Přihlašovací systém bude vyresetován: místo sytému Persona bude použito přihlášení formulářem.', ), 'date' => array( 'Apr' => '\\D\\u\\b\\e\\n', diff --git a/app/i18n/cz/install.php b/app/i18n/cz/install.php index bc3e01992..6b94c0d4b 100644 --- a/app/i18n/cz/install.php +++ b/app/i18n/cz/install.php @@ -9,13 +9,11 @@ return array( 'reinstall' => 'Reinstalovat FreshRSS', ), 'auth' => array( - 'email_persona' => 'Email pro přihlášení
(pro Mozilla Persona)', 'form' => 'Webový formulář (tradiční, vyžaduje JavaScript)', 'http' => 'HTTP (pro pokročilé uživatele s HTTPS)', 'none' => 'Žádný (nebezpečné)', 'password_form' => 'Heslo
(pro přihlášení webovým formulářem)', 'password_format' => 'Alespoň 7 znaků', - 'persona' => 'Mozilla Persona (moderní, vyžaduje JavaScript)', 'type' => 'Způsob přihlášení', ), 'bdd' => array( @@ -78,10 +76,6 @@ return array( 'nok' => 'Nemáte PDO nebo některý z podporovaných ovladačů (pdo_mysql, pdo_sqlite).', 'ok' => 'Máte PDO a alespoň jeden z podporovaných ovladačů (pdo_mysql, pdo_sqlite).', ), - 'persona' => array( - 'nok' => 'Zkontrolujte oprávnění adresáře ./data/persona. HTTP server musí mít do tohoto adresáře práva zápisu', - 'ok' => 'Oprávnění adresáře Mozilla Persona jsou v pořádku.', - ), 'php' => array( 'nok' => 'Vaše verze PHP je %s, ale FreshRSS vyžaduje alespoň verzi %s.', 'ok' => 'Vaše verze PHP je %s a je kompatibilní s FreshRSS.', diff --git a/app/i18n/de/admin.php b/app/i18n/de/admin.php index 6e6cc0956..7b75fe5f4 100644 --- a/app/i18n/de/admin.php +++ b/app/i18n/de/admin.php @@ -8,7 +8,6 @@ return array( 'form' => 'Webformular (traditionell, benötigt JavaScript)', 'http' => 'HTTP (HTTPS für erfahrene Benutzer)', 'none' => 'Keine (gefährlich)', - 'persona' => 'Mozilla Persona (modern, benötigt JavaScript)', 'title' => 'Authentifizierung', 'title_reset' => 'Zurücksetzen der Authentifizierung', 'token' => 'Authentifizierungs-Token', @@ -75,10 +74,6 @@ return array( 'nok' => 'Ihnen fehlt PDO oder einer der unterstützten Treiber (pdo_mysql, pdo_sqlite).', 'ok' => 'Sie haben PDO und mindestens einen der unterstützten Treiber (pdo_mysql, pdo_sqlite).', ), - 'persona' => array( - 'nok' => 'Überprüfen Sie die Berechtigungen des Verzeichnisses ./data/persona. Der HTTP-Server muss Schreibrechte besitzen.', - 'ok' => 'Die Berechtigungen des Verzeichnisses ./data/persona sind in Ordnung.', - ), 'php' => array( '_' => 'PHP-Installation', 'nok' => 'Ihre PHP-Version ist %s aber FreshRSS benötigt mindestens Version %s.', @@ -169,7 +164,6 @@ return array( 'user' => array( 'articles_and_size' => '%s Artikel (%s)', 'create' => 'Neuen Benutzer erstellen', - 'email_persona' => 'Anmelde-E-Mail-Adresse
(für Mozilla Persona)', 'language' => 'Sprache', 'number' => 'Es wurde bis jetzt %d Account erstellt', 'numbers' => 'Es wurden bis jetzt %d Accounts erstellt', diff --git a/app/i18n/de/conf.php b/app/i18n/de/conf.php index c1a762f12..7c57d5655 100644 --- a/app/i18n/de/conf.php +++ b/app/i18n/de/conf.php @@ -76,7 +76,6 @@ return array( '_' => 'Accountlöschung', 'warn' => 'Dein Account und alle damit bezogenen Daten werden gelöscht.', ), - 'email_persona' => 'Anmelde-E-Mail-Adresse
(für Mozilla Persona)', 'password_api' => 'Passwort-API
(z. B. für mobile Anwendungen)', 'password_form' => 'Passwort
(für die Anmeldemethode per Webformular)', 'password_format' => 'mindestens 7 Zeichen', diff --git a/app/i18n/de/feedback.php b/app/i18n/de/feedback.php index 4c15aadc3..f93992982 100644 --- a/app/i18n/de/feedback.php +++ b/app/i18n/de/feedback.php @@ -21,7 +21,6 @@ return array( 'success' => 'Sie sind abgemeldet', ), 'no_password_set' => 'Administrator-Passwort ist nicht gesetzt worden. Dieses Feature ist nicht verfügbar.', - 'not_persona' => 'Nur das Persona-System kann zurückgesetzt werden.', ), 'conf' => array( 'error' => 'Während der Speicherung der Konfiguration trat ein Fehler auf', diff --git a/app/i18n/de/gen.php b/app/i18n/de/gen.php index 4b85c722a..c6e7f1ef3 100644 --- a/app/i18n/de/gen.php +++ b/app/i18n/de/gen.php @@ -24,8 +24,6 @@ return array( 'email' => 'E-Mail-Adresse', 'keep_logged_in' => 'Eingeloggt bleiben (1 Monat)', 'login' => 'Anmelden', - 'login_persona' => 'Anmelden mit Persona', - 'login_persona_problem' => 'Verbindungsproblem mit Persona?', 'logout' => 'Abmelden', 'password' => array( '_' => 'Passwort', @@ -42,7 +40,6 @@ return array( 'admin' => 'Administrator-Nutzername', 'format' => 'maximal 16 alphanumerische Zeichen', ), - 'will_reset' => 'Authentifikationssystem wird zurückgesetzt: ein Formular wird anstelle von Persona benutzt.', ), 'date' => array( 'Apr' => '\\A\\p\\r\\i\\l', diff --git a/app/i18n/de/install.php b/app/i18n/de/install.php index d16496818..a77822e7b 100644 --- a/app/i18n/de/install.php +++ b/app/i18n/de/install.php @@ -9,13 +9,11 @@ return array( 'reinstall' => 'Neuinstallation von FreshRSS', ), 'auth' => array( - 'email_persona' => 'Anmelde-E-Mail-Adresse
(für Mozilla Persona)', 'form' => 'Webformular (traditionell, benötigt JavaScript)', 'http' => 'HTTP (HTTPS für erfahrene Benutzer)', 'none' => 'Keine (gefährlich)', 'password_form' => 'Passwort
(für die Anmeldemethode per Webformular)', 'password_format' => 'mindestens 7 Zeichen', - 'persona' => 'Mozilla Persona (modern, benötigt JavaScript)', 'type' => 'Authentifizierungsmethode', ), 'bdd' => array( @@ -78,10 +76,6 @@ return array( 'nok' => 'Ihnen fehlt PDO oder einer der unterstützten Treiber (pdo_mysql, pdo_sqlite).', 'ok' => 'Sie haben PDO und mindestens einen der unterstützten Treiber (pdo_mysql, pdo_sqlite).', ), - 'persona' => array( - 'nok' => 'Überprüfen Sie die Berechtigungen des Verzeichnisses ./data/persona. Der HTTP-Server muss Schreibrechte besitzen.', - 'ok' => 'Die Berechtigungen des Verzeichnisses ./data/persona sind in Ordnung.', - ), 'php' => array( 'nok' => 'Ihre PHP-Version ist %s aber FreshRSS benötigt mindestens Version %s.', 'ok' => 'Ihre PHP-Version ist %s, welche kompatibel mit FreshRSS ist.', diff --git a/app/i18n/en/admin.php b/app/i18n/en/admin.php index a58771edf..a88552087 100644 --- a/app/i18n/en/admin.php +++ b/app/i18n/en/admin.php @@ -8,7 +8,6 @@ return array( 'form' => 'Web form (traditional, requires JavaScript)', 'http' => 'HTTP (for advanced users with HTTPS)', 'none' => 'None (dangerous)', - 'persona' => 'Mozilla Persona (modern, requires JavaScript)', 'title' => 'Authentication', 'title_reset' => 'Authentication reset', 'token' => 'Authentication token', @@ -75,10 +74,6 @@ return array( 'nok' => 'You lack PDO or one of the supported drivers (pdo_mysql, pdo_sqlite).', 'ok' => 'You have PDO and at least one of the supported drivers (pdo_mysql, pdo_sqlite).', ), - 'persona' => array( - 'nok' => 'Check permissions on ./data/persona directory. HTTP server must have rights to write into', - 'ok' => 'Permissions on Mozilla Persona directory are good.', - ), 'php' => array( '_' => 'PHP installation', 'nok' => 'Your PHP version is %s but FreshRSS requires at least version %s.', @@ -169,7 +164,6 @@ return array( 'user' => array( 'articles_and_size' => '%s articles (%s)', 'create' => 'Create new user', - 'email_persona' => 'Login mail address
(for Mozilla Persona)', 'language' => 'Language', 'number' => 'There is %d account created yet', 'numbers' => 'There are %d accounts created yet', diff --git a/app/i18n/en/conf.php b/app/i18n/en/conf.php index 38e9197e9..b5ab73510 100644 --- a/app/i18n/en/conf.php +++ b/app/i18n/en/conf.php @@ -76,7 +76,6 @@ return array( '_' => 'Account deletion', 'warn' => 'Your account and all the related data will be deleted.', ), - 'email_persona' => 'Login email address
(for Mozilla Persona)', 'password_api' => 'API password
(e.g., for mobile apps)', 'password_form' => 'Password
(for the Web-form login method)', 'password_format' => 'At least 7 characters', diff --git a/app/i18n/en/feedback.php b/app/i18n/en/feedback.php index c9189c0d0..7ce2ae9cf 100644 --- a/app/i18n/en/feedback.php +++ b/app/i18n/en/feedback.php @@ -21,7 +21,6 @@ return array( 'success' => 'You are disconnected', ), 'no_password_set' => 'Administrator password hasn’t been set. This feature isn’t available.', - 'not_persona' => 'Only Persona system can be reset.', ), 'conf' => array( 'error' => 'An error occurred during configuration saving', diff --git a/app/i18n/en/gen.php b/app/i18n/en/gen.php index ba4e2f86c..17b47ba2f 100644 --- a/app/i18n/en/gen.php +++ b/app/i18n/en/gen.php @@ -24,8 +24,6 @@ return array( 'email' => 'Email address', 'keep_logged_in' => 'Keep me logged in (1 month)', 'login' => 'Login', - 'login_persona' => 'Login with Persona', - 'login_persona_problem' => 'Connection problem with Persona?', 'logout' => 'Logout', 'password' => array( '_' => 'Password', @@ -42,7 +40,6 @@ return array( 'admin' => 'Administrator username', 'format' => 'maximum 16 alphanumeric characters', ), - 'will_reset' => 'Authentication system will be reset: a form will be used instead of Persona.', ), 'date' => array( 'Apr' => '\\A\\p\\r\\i\\l', diff --git a/app/i18n/en/install.php b/app/i18n/en/install.php index 4b5bbc62e..d1c5f37c8 100644 --- a/app/i18n/en/install.php +++ b/app/i18n/en/install.php @@ -9,13 +9,11 @@ return array( 'reinstall' => 'Reinstall FreshRSS', ), 'auth' => array( - 'email_persona' => 'Login email address
(for Mozilla Persona)', 'form' => 'Web form (traditional, requires JavaScript)', 'http' => 'HTTP (for advanced users with HTTPS)', 'none' => 'None (dangerous)', 'password_form' => 'Password
(for the Web-form login method)', 'password_format' => 'At least 7 characters', - 'persona' => 'Mozilla Persona (modern, requires JavaScript)', 'type' => 'Authentication method', ), 'bdd' => array( @@ -78,10 +76,6 @@ return array( 'nok' => 'You lack PDO or one of the supported drivers (pdo_mysql, pdo_sqlite).', 'ok' => 'You have PDO and at least one of the supported drivers (pdo_mysql, pdo_sqlite).', ), - 'persona' => array( - 'nok' => 'Check permissions on ./data/persona directory. HTTP server must have rights to write into', - 'ok' => 'Permissions on Mozilla Persona directory are good.', - ), 'php' => array( 'nok' => 'Your PHP version is %s but FreshRSS requires at least version %s.', 'ok' => 'Your PHP version is %s, which is compatible with FreshRSS.', diff --git a/app/i18n/fr/admin.php b/app/i18n/fr/admin.php index f4f267306..c359e9d24 100644 --- a/app/i18n/fr/admin.php +++ b/app/i18n/fr/admin.php @@ -8,7 +8,6 @@ return array( 'form' => 'Formulaire (traditionnel, requiert JavaScript)', 'http' => 'HTTP (pour utilisateurs avancés avec HTTPS)', 'none' => 'Aucune (dangereux)', - 'persona' => 'Mozilla Persona (moderne, requiert JavaScript)', 'title' => 'Authentification', 'title_reset' => 'Réinitialisation de l’authentification', 'token' => 'Jeton d’identification', @@ -75,10 +74,6 @@ return array( 'nok' => 'Vous ne disposez pas de PDO ou d’un des drivers supportés (pdo_mysql, pdo_sqlite).', 'ok' => 'Vous disposez de PDO et d’au moins un des drivers supportés (pdo_mysql, pdo_sqlite).', ), - 'persona' => array( - 'nok' => 'Veuillez vérifier les droits sur le répertoire ./data/persona. Le serveur HTTP doit être capable d’écrire dedans', - 'ok' => 'Les droits sur le répertoire de Mozilla Persona sont bons.', - ), 'php' => array( '_' => 'Installation de PHP', 'nok' => 'Votre version de PHP est la %s mais FreshRSS requiert au moins la version %s.', @@ -169,7 +164,6 @@ return array( 'user' => array( 'articles_and_size' => '%s articles (%s)', 'create' => 'Créer un nouvel utilisateur', - 'email_persona' => 'Adresse courriel de connexion
(pour Mozilla Persona)', 'language' => 'Langue', 'number' => '%d compte a déjà été créé', 'numbers' => '%d comptes ont déjà été créés', diff --git a/app/i18n/fr/conf.php b/app/i18n/fr/conf.php index 6193b7a01..7a6d12e17 100644 --- a/app/i18n/fr/conf.php +++ b/app/i18n/fr/conf.php @@ -76,7 +76,6 @@ return array( '_' => 'Suppression du compte', 'warn' => 'Le compte et toutes les données associées vont être supprimées.', ), - 'email_persona' => 'Adresse courriel de connexion
(pour Mozilla Persona)', 'password_api' => 'Mot de passe API
(ex. : pour applis mobiles)', 'password_form' => 'Mot de passe
(pour connexion par formulaire)', 'password_format' => '7 caractères minimum', diff --git a/app/i18n/fr/feedback.php b/app/i18n/fr/feedback.php index e2364a251..15f3ab859 100644 --- a/app/i18n/fr/feedback.php +++ b/app/i18n/fr/feedback.php @@ -21,7 +21,6 @@ return array( 'success' => 'Vous avez été déconnecté', ), 'no_password_set' => 'Aucun mot de passe administrateur n’a été précisé. Cette fonctionnalité n’est pas disponible.', - 'not_persona' => 'Seul le système d’authentification Persona peut être réinitialisé.', ), 'conf' => array( 'error' => 'Une erreur est survenue durant la sauvegarde de la configuration', diff --git a/app/i18n/fr/gen.php b/app/i18n/fr/gen.php index 031098aa2..d61a716a7 100644 --- a/app/i18n/fr/gen.php +++ b/app/i18n/fr/gen.php @@ -24,8 +24,6 @@ return array( 'email' => 'Adresse courriel', 'keep_logged_in' => 'Rester connecté (1 mois)', 'login' => 'Connexion', - 'login_persona' => 'Connexion avec Persona', - 'login_persona_problem' => 'Problème de connexion à Persona ?', 'logout' => 'Déconnexion', 'password' => array( '_' => 'Mot de passe', @@ -42,7 +40,6 @@ return array( 'admin' => 'Nom d’utilisateur administrateur', 'format' => '16 caractères alphanumériques maximum', ), - 'will_reset' => 'Le système d’authentification va être réinitialisé : un formulaire sera utilisé à la place de Persona.', ), 'date' => array( 'Apr' => '\\a\\v\\r\\i\\l', diff --git a/app/i18n/fr/install.php b/app/i18n/fr/install.php index 91dfbbb09..946a210ee 100644 --- a/app/i18n/fr/install.php +++ b/app/i18n/fr/install.php @@ -9,13 +9,11 @@ return array( 'reinstall' => 'Réinstaller FreshRSS', ), 'auth' => array( - 'email_persona' => 'Adresse courriel de connexion
(pour Mozilla Persona)', 'form' => 'Formulaire (traditionnel, requiert JavaScript)', 'http' => 'HTTP (pour utilisateurs avancés avec HTTPS)', 'none' => 'Aucune (dangereux)', 'password_form' => 'Mot de passe
(pour connexion par formulaire)', 'password_format' => '7 caractères minimum', - 'persona' => 'Mozilla Persona (moderne, requiert JavaScript)', 'type' => 'Méthode d’authentification', ), 'bdd' => array( @@ -78,10 +76,6 @@ return array( 'nok' => 'Vous ne disposez pas de PDO ou d’un des drivers supportés (pdo_mysql, pdo_sqlite).', 'ok' => 'Vous disposez de PDO et d’au moins un des drivers supportés (pdo_mysql, pdo_sqlite).', ), - 'persona' => array( - 'nok' => 'Veuillez vérifier les droits sur le répertoire ./data/persona. Le serveur HTTP doit être capable d’écrire dedans', - 'ok' => 'Les droits sur le répertoire de Mozilla Persona sont bons.', - ), 'php' => array( 'nok' => 'Votre version de PHP est la %s mais FreshRSS requiert au moins la version %s.', 'ok' => 'Votre version de PHP est la %s, qui est compatible avec FreshRSS.', diff --git a/app/i18n/it/admin.php b/app/i18n/it/admin.php index 94b2d6762..4eea158f6 100644 --- a/app/i18n/it/admin.php +++ b/app/i18n/it/admin.php @@ -8,7 +8,6 @@ return array( 'form' => 'Web form (tradizionale, richiede JavaScript)', 'http' => 'HTTP (per gli utenti avanzati con HTTPS)', 'none' => 'Nessuno (pericoloso)', - 'persona' => 'Mozilla Persona (moderno, richiede JavaScript)', 'title' => 'Autenticazione', 'title_reset' => 'Reset autenticazione', 'token' => 'Token di autenticazione', @@ -75,10 +74,6 @@ return array( 'nok' => 'Manca PDO o uno degli altri driver supportati (pdo_mysql, pdo_sqlite).', 'ok' => 'PDO e altri driver supportati (pdo_mysql, pdo_sqlite).', ), - 'persona' => array( - 'nok' => 'Verifica i permessi sulla cartella ./data/persona. Il server HTTP deve avere i permessi per scriverci dentro', - 'ok' => 'I permessi sulla cartella Mozilla Persona sono corretti.', - ), 'php' => array( '_' => 'Installazione PHP', 'nok' => 'Versione PHP %s FreshRSS richiede almeno la versione %s.', @@ -169,7 +164,6 @@ return array( 'user' => array( 'articles_and_size' => '%s articoli (%s)', 'create' => 'Crea nuovo utente', - 'email_persona' => 'Indirizzo mail
(Login Mozilla Persona)', 'language' => 'Lingua', 'number' => ' %d profilo utente creato', 'numbers' => 'Sono presenti %d profili utente', diff --git a/app/i18n/it/conf.php b/app/i18n/it/conf.php index b757b3210..19b62c9a7 100644 --- a/app/i18n/it/conf.php +++ b/app/i18n/it/conf.php @@ -76,7 +76,6 @@ return array( '_' => 'Cancellazione account', 'warn' => 'Il tuo account e tutti i dati associati saranno cancellati.', ), - 'email_persona' => 'Indirizzo email
(Login Mozilla Persona)', 'password_api' => 'Password API
(e.g., per applicazioni mobili)', 'password_form' => 'Password
(per il login classico)', 'password_format' => 'Almeno 7 caratteri', diff --git a/app/i18n/it/feedback.php b/app/i18n/it/feedback.php index caf1cd2b4..f217586b0 100644 --- a/app/i18n/it/feedback.php +++ b/app/i18n/it/feedback.php @@ -21,7 +21,6 @@ return array( 'success' => 'Disconnessione effettuata', ), 'no_password_set' => 'Password di amministrazione non impostata. Opzione non disponibile.', - 'not_persona' => 'Solo il sistema Mozilla Persona può essere resettato.', ), 'conf' => array( 'error' => 'Si è verificato un errore durante il salvataggio della configurazione', diff --git a/app/i18n/it/gen.php b/app/i18n/it/gen.php index d24377593..c02ddd13a 100644 --- a/app/i18n/it/gen.php +++ b/app/i18n/it/gen.php @@ -24,8 +24,6 @@ return array( 'email' => 'Indirizzo email', 'keep_logged_in' => 'Ricorda i dati (1 mese)', 'login' => 'Accedi', - 'login_persona' => 'Accedi con Mozilla Persona', - 'login_persona_problem' => 'Problemi di connessione con Mozilla Persona?', 'logout' => 'Esci', 'password' => array( '_' => 'Password', @@ -42,7 +40,6 @@ return array( 'admin' => 'Username amministratore', 'format' => 'massimo 16 caratteri alfanumerici', ), - 'will_reset' => 'Il sistema di autenticazione verrà resettato: un form verrà usato per Mozilla Persona.', ), 'date' => array( 'Apr' => '\\A\\p\\r\\i\\l\\e', diff --git a/app/i18n/it/install.php b/app/i18n/it/install.php index 8f5300bd5..a60dd4523 100644 --- a/app/i18n/it/install.php +++ b/app/i18n/it/install.php @@ -9,13 +9,11 @@ return array( 'reinstall' => 'Reinstalla FreshRSS', ), 'auth' => array( - 'email_persona' => 'Indirizzo mail
(per Mozilla Persona)', 'form' => 'Web form (tradizionale, richiede JavaScript)', 'http' => 'HTTP (per gli utenti avanzati con HTTPS)', 'none' => 'Nessuno (pericoloso)', 'password_form' => 'Password
(per il login tramite Web-form tradizionale)', 'password_format' => 'Almeno 7 caratteri', - 'persona' => 'Mozilla Persona (moderno, richiede JavaScript)', 'type' => 'Metodo di autenticazione', ), 'bdd' => array( @@ -78,10 +76,6 @@ return array( 'nok' => 'Manca PDO o uno degli altri driver supportati (pdo_mysql, pdo_sqlite).', 'ok' => 'PDO e altri driver supportati (pdo_mysql, pdo_sqlite).', ), - 'persona' => array( - 'nok' => 'Verifica i permessi sulla cartella ./data/persona. Il server HTTP deve avere i permessi per scriverci dentro', - 'ok' => 'I permessi sulla cartella Mozilla Persona sono corretti.', - ), 'php' => array( '_' => 'Installazione PHP', 'nok' => 'Versione di PHP %s FreshRSS richiede almeno la versione %s.', diff --git a/app/i18n/nl/admin.php b/app/i18n/nl/admin.php index bd7d63b6a..9f05d69b1 100644 --- a/app/i18n/nl/admin.php +++ b/app/i18n/nl/admin.php @@ -8,7 +8,6 @@ return array( 'form' => 'Web formulier (traditioneel, benodigd JavaScript)', 'http' => 'HTTP (voor geavanceerde gebruikers met HTTPS)', 'none' => 'Geen (gevaarlijk)', - 'persona' => 'Mozilla Persona (modern, benodigd JavaScript)', 'title' => 'Authenticatie', 'title_reset' => 'Authenticatie terugzetten', 'token' => 'Authenticatie teken', @@ -75,10 +74,6 @@ return array( 'nok' => 'U mist PDO of een van de ondersteunde drivers (pdo_mysql, pdo_sqlite).', 'ok' => 'U hebt PDO en ten minste één van de ondersteunde drivers (pdo_mysql, pdo_sqlite).', ), - 'persona' => array( - 'nok' => 'Controleer de permissies op de ./data/persona map. HTTP server moet rechten hebben om hierin te schrijven', - 'ok' => 'Permissies op de Mozilla Persona map zijn goed.', - ), 'php' => array( '_' => 'PHP installatie', 'nok' => 'Uw PHP versie is %s maar FreshRSS benodigd tenminste versie %s.', @@ -169,7 +164,6 @@ return array( 'user' => array( 'articles_and_size' => '%s artikelen (%s)', 'create' => 'Creëer nieuwe gebruiker', - 'email_persona' => 'Log in mail adres
(voor Mozilla Persona)', 'language' => 'Taal', 'number' => 'Er is %d accounts gemaakt', 'numbers' => 'Er zijn %d accounts gemaakt', diff --git a/app/i18n/nl/conf.php b/app/i18n/nl/conf.php index 9b0aff793..573dabf45 100644 --- a/app/i18n/nl/conf.php +++ b/app/i18n/nl/conf.php @@ -76,7 +76,6 @@ return array( '_' => 'Account verwijderen', 'warn' => 'Uw account en alle gerelateerde gegvens worden verwijderd.', ), - 'email_persona' => 'Log in mail adres
(voor Mozilla Persona)', 'password_api' => 'Wachtwoord API
(e.g., voor mobiele apps)', 'password_form' => 'Wachtwoord
(voor de Web-formulier log in methode)', 'password_format' => 'Ten minste 7 tekens', diff --git a/app/i18n/nl/feedback.php b/app/i18n/nl/feedback.php index 54d84f7d6..b703c43cf 100644 --- a/app/i18n/nl/feedback.php +++ b/app/i18n/nl/feedback.php @@ -21,7 +21,6 @@ return array( 'success' => 'U bent uitgelogd', ), 'no_password_set' => 'Administrateur wachtwoord is niet ingesteld. Deze mogelijkheid is niet beschikbaar.', - 'not_persona' => 'Alleen Persona systeem kan worden gereset.', ), 'conf' => array( 'error' => 'Er is een fout opgetreden tijdens het opslaan van de configuratie', diff --git a/app/i18n/nl/gen.php b/app/i18n/nl/gen.php index 24cba574e..7e03229c9 100644 --- a/app/i18n/nl/gen.php +++ b/app/i18n/nl/gen.php @@ -24,8 +24,6 @@ return array( 'email' => 'Email adres', 'keep_logged_in' => 'Ingelogd blijven voor (1 maand)', 'login' => 'Log in', - 'login_persona' => 'Login met Persona', - 'login_persona_problem' => 'Connectiviteits problemen met Persona', 'logout' => 'Log uit', 'password' => array( '_' => 'Wachtwoord', @@ -42,7 +40,6 @@ return array( 'admin' => 'Administrator gebruikersnaam', 'format' => 'maximaal 16 alphanumerieke tekens', ), - 'will_reset' => 'Het authenticatie system zal worden gereset: een formulier zal worden gebruikt in plaats van Persona.', ), 'date' => array( 'Apr' => '\\A\\p\\r\\i\\l', diff --git a/app/i18n/nl/install.php b/app/i18n/nl/install.php index d16dda4ca..77783cd48 100644 --- a/app/i18n/nl/install.php +++ b/app/i18n/nl/install.php @@ -9,13 +9,11 @@ return array( 'reinstall' => 'Installeer FreshRSS opnieuw', ), 'auth' => array( - 'email_persona' => 'Log in mail adres
(voor Mozilla Persona)', 'form' => 'Web formulier (traditioneel, benodigd JavaScript)', 'http' => 'HTTP (voor geavanceerde gebruikers met HTTPS)', 'none' => 'Geen (gevaarlijk)', 'password_form' => 'Wachtwoord
(voor de Web-formulier log in methode)', 'password_format' => 'Tenminste 7 tekens', - 'persona' => 'Mozilla Persona (modern, benodigd JavaScript)', 'type' => 'Authenticatie methode', ), 'bdd' => array( @@ -78,10 +76,6 @@ return array( 'nok' => 'U mist PDO of één van de ondersteunde (pdo_mysql, pdo_sqlite).', 'ok' => 'U hebt PDO en ten minste één van de ondersteunde drivers (pdo_mysql, pdo_sqlite).', ), - 'persona' => array( - 'nok' => 'Controleer permissies van de ./data/persona map. HTTP server moet rechten hebben om er in te kunnen schrijven', - 'ok' => 'Permissies van de Mozilla Persona map zijn goed.', - ), 'php' => array( 'nok' => 'Uw PHP versie is %s maar FreshRSS benodigd tenminste versie %s.', 'ok' => 'Uw PHP versie is %s, welke compatibel is met FreshRSS.', diff --git a/app/i18n/ru/admin.php b/app/i18n/ru/admin.php index dfea5b3cb..caea627f3 100644 --- a/app/i18n/ru/admin.php +++ b/app/i18n/ru/admin.php @@ -8,7 +8,6 @@ return array( 'form' => 'На основе веб-формы (традиционный, необходим JavaScript)', 'http' => 'HTTP (для продвинутых пользователей - по HTTPS)', 'none' => 'Без аутентификации (небезопасный)', - 'persona' => 'Mozilla Persona (новый, необходим JavaScript)', 'title' => 'Аутентификации', 'title_reset' => 'Сброс аутентицикации', 'token' => 'Токен аутентификации', @@ -75,10 +74,6 @@ return array( 'nok' => 'У вас не установлен PDO или один из необходимых драйверов (pdo_mysql, pdo_sqlite).', 'ok' => 'У вас установлен PDO и как минимум один из поддерживаемых драйверов (pdo_mysql, pdo_sqlite).', ), - 'persona' => array( - 'nok' => 'Проверьте права доступа к папке ./data/persona . Сервер HTTP должен иметь права на запись в эту папку.', - 'ok' => 'Права на папку Mozilla Persona в порядке.', - ), 'php' => array( '_' => 'PHP installation', 'nok' => 'У вас установлен PHP версии %s, но FreshRSS необходима версия не ниже %s.', @@ -169,7 +164,6 @@ return array( 'user' => array( 'articles_and_size' => '%s статей (%s)', 'create' => 'Создать нового пользователя', - 'email_persona' => 'Адрес электронной почты для входа
(for Mozilla Persona)', 'language' => 'Язык', 'number' => 'На данный момент создан %d аккаунт', 'numbers' => 'На данный момент аккаунтов создано: %d', diff --git a/app/i18n/ru/conf.php b/app/i18n/ru/conf.php index e502e9a43..557fbe369 100644 --- a/app/i18n/ru/conf.php +++ b/app/i18n/ru/conf.php @@ -76,7 +76,6 @@ return array( '_' => 'Account deletion', 'warn' => 'Your account and all the related data will be deleted.', ), - 'email_persona' => 'Login email address
(for Mozilla Persona)', 'password_api' => 'Password API
(e.g., for mobile apps)', 'password_form' => 'Password
(for the Web-form login method)', 'password_format' => 'At least 7 characters', diff --git a/app/i18n/ru/feedback.php b/app/i18n/ru/feedback.php index c9189c0d0..7ce2ae9cf 100644 --- a/app/i18n/ru/feedback.php +++ b/app/i18n/ru/feedback.php @@ -21,7 +21,6 @@ return array( 'success' => 'You are disconnected', ), 'no_password_set' => 'Administrator password hasn’t been set. This feature isn’t available.', - 'not_persona' => 'Only Persona system can be reset.', ), 'conf' => array( 'error' => 'An error occurred during configuration saving', diff --git a/app/i18n/ru/gen.php b/app/i18n/ru/gen.php index b8e8511d9..eecd72749 100644 --- a/app/i18n/ru/gen.php +++ b/app/i18n/ru/gen.php @@ -24,8 +24,6 @@ return array( 'email' => 'Email address', 'keep_logged_in' => 'Keep me logged in (1 month)', 'login' => 'Login', - 'login_persona' => 'Login with Persona', - 'login_persona_problem' => 'Connection problem with Persona?', 'logout' => 'Logout', 'password' => array( '_' => 'Password', @@ -42,7 +40,6 @@ return array( 'admin' => 'Administrator username', 'format' => 'maximum 16 alphanumeric characters', ), - 'will_reset' => 'Authentication system will be reset: a form will be used instead of Persona.', ), 'date' => array( 'Apr' => '\\A\\p\\r\\i\\l', diff --git a/app/i18n/ru/install.php b/app/i18n/ru/install.php index c838b2eba..a52e2959b 100644 --- a/app/i18n/ru/install.php +++ b/app/i18n/ru/install.php @@ -9,13 +9,11 @@ return array( 'reinstall' => 'Переустановить FreshRSS', ), 'auth' => array( - 'email_persona' => 'Почта (логин) для
(for Mozilla Persona)', 'form' => 'Вэб-форма (традиционный, необходим JavaScript)', 'http' => 'HTTP (для продвинутых пользователей с HTTPS)', 'none' => 'Никакого (опасно)', 'password_form' => 'Пароль
(для метода аутентификации на Вэб-формах)', 'password_format' => 'Как минимум 7 букв', - 'persona' => 'Mozilla Persona (современный, необходим JavaScript)', 'type' => 'Метод аутентификации', ), 'bdd' => array( @@ -74,10 +72,6 @@ return array( 'nok' => 'У вас не установлен PDO или один из необходимых драйверов (pdo_mysql, pdo_sqlite).', 'ok' => 'У вас установлен PDO и как минимум один из поддерживаемых драйверов (pdo_mysql, pdo_sqlite).', ), - 'persona' => array( - 'nok' => 'Проверьте права доступа к папке ./data/persona . Сервер HTTP должен иметь права на запись в эту папку.', - 'ok' => 'Права на папку Mozilla Persona в порядке.', - ), 'php' => array( 'nok' => 'У вас установлен PHP версии %s, но FreshRSS необходима версия не ниже %s.', 'ok' => 'У вас установлен PHP версии %s, который совместим с FreshRSS.', diff --git a/app/i18n/tr/admin.php b/app/i18n/tr/admin.php index 3a6f8118e..43f8e23c5 100644 --- a/app/i18n/tr/admin.php +++ b/app/i18n/tr/admin.php @@ -8,7 +8,6 @@ return array( 'form' => 'Web formu (geleneksel, JavaScript gerektirir)', 'http' => 'HTTP (ileri kullanıcılar için, HTTPS)', 'none' => 'Hiçbiri (tehlikeli)', - 'persona' => 'Mozilla Persona (modern, JavaScript gerektirir)', 'title' => 'Kimlik doğrulama', 'title_reset' => 'Kimlik doğrulama sıfırla', 'token' => 'Kimlik doğrulama işareti', @@ -75,10 +74,6 @@ return array( 'nok' => 'PDO veya PDO destekli bir sürücü eksik (pdo_mysql, pdo_sqlite).', 'ok' => 'PDO sorunsuz (pdo_mysql, pdo_sqlite).', ), - 'persona' => array( - 'nok' => './data/persona klasör yetkisini kontrol edin. HTTP yazma yetkisi olmalı', - 'ok' => 'Mozilla Persona klasörü yetkileri sorunsuz.', - ), 'php' => array( '_' => 'PHP kurulumu', 'nok' => 'PHP versiyonunuz %s fakat FreshRSS için gerekli olan en düşük sürüm %s.', @@ -169,7 +164,6 @@ return array( 'user' => array( 'articles_and_size' => '%s makale (%s)', 'create' => 'Yeni kullanıcı oluştur', - 'email_persona' => 'Giriş email adresi
(Mozilla Persona için)', 'language' => 'Dil', 'number' => 'Oluşturulmuş %d hesap var', 'numbers' => 'Oluşturulmuş %d hesap var', diff --git a/app/i18n/tr/conf.php b/app/i18n/tr/conf.php index d9e275b21..2fdc248e4 100644 --- a/app/i18n/tr/conf.php +++ b/app/i18n/tr/conf.php @@ -76,7 +76,6 @@ return array( '_' => 'Hesap silme', 'warn' => 'Hesabınız ve tüm verileriniz silinecek.', ), - 'email_persona' => 'Giriş email adresi
(Mozilla Persona için)', 'password_api' => 'API Şifresi
(ör. mobil uygulamalar için)', 'password_form' => 'Şifre
(Tarayıcı girişi için)', 'password_format' => 'En az 7 karakter', diff --git a/app/i18n/tr/feedback.php b/app/i18n/tr/feedback.php index 0572c6da1..a53316206 100644 --- a/app/i18n/tr/feedback.php +++ b/app/i18n/tr/feedback.php @@ -21,7 +21,6 @@ return array( 'success' => 'Bağlantı koptu', ), 'no_password_set' => 'Yönetici şifresi ayarlanmadı. Bu özellik kullanıma uygun değil.', - 'not_persona' => 'Sadece Persona sistem sıfırlanabilir.', ), 'conf' => array( 'error' => 'Yapılandırma ayarları kaydedilirken hata oluştu', diff --git a/app/i18n/tr/gen.php b/app/i18n/tr/gen.php index 492e2cb9b..865dbd4e2 100644 --- a/app/i18n/tr/gen.php +++ b/app/i18n/tr/gen.php @@ -24,8 +24,6 @@ return array( 'email' => 'Email adresleri', 'keep_logged_in' => '(1 ay) oturumu açık tut', 'login' => 'Giriş', - 'login_persona' => 'Persona ile giriş yap', - 'login_persona_problem' => 'Persona ile bağlantı sorununuz mu var ?', 'logout' => 'Çıkış', 'password' => array( '_' => 'Şifre', @@ -42,7 +40,6 @@ return array( 'admin' => 'Yönetici kullanıcı adı', 'format' => 'en fazla 16 alfanümerik karakter', ), - 'will_reset' => 'Kimlik doğrulama sistemi sıfırlanacak: Persone yerine bir form kullanılacak.', ), 'date' => array( 'Apr' => '\\N\\i\\s\\a\\n', diff --git a/app/i18n/tr/install.php b/app/i18n/tr/install.php index 85134845b..951a7c5fd 100644 --- a/app/i18n/tr/install.php +++ b/app/i18n/tr/install.php @@ -9,13 +9,11 @@ return array( 'reinstall' => 'FreshRSS i yeniden yükle', ), 'auth' => array( - 'email_persona' => 'Giriş email adresi
(Mozilla Persona için)', 'form' => 'Web formu (geleneksel, JavaScript gerektirir)', 'http' => 'HTTP (ileri kullanıcılar için, HTTPS)', 'none' => 'Hiçbiri (tehlikeli)', 'password_form' => 'Şifre
(Tarayıcı girişi için)', 'password_format' => 'En az 7 karakter', - 'persona' => 'Mozilla Persona (modern, JavaScript gerektirir)', 'type' => 'Kimlik doğrulama yöntemi', ), 'bdd' => array( @@ -78,10 +76,6 @@ return array( 'nok' => 'PDO veya PDO destekli bir sürücü eksik (pdo_mysql, pdo_sqlite).', 'ok' => 'PDO sorunsuz (pdo_mysql, pdo_sqlite).', ), - 'persona' => array( - 'nok' => './data/persona klasör yetkisini kontrol edin. HTTP yazma yetkisi olmalı', - 'ok' => 'Mozilla Persona klasörü yetkileri sorunsuz.', - ), 'php' => array( 'nok' => 'PHP versiyonunuz %s fakat FreshRSS için gerekli olan en düşük sürüm %s.', 'ok' => 'PHP versiyonunuz %s, FreshRSS ile tam uyumlu.', diff --git a/app/install.php b/app/install.php index 062f66814..e73bc9972 100644 --- a/app/install.php +++ b/app/install.php @@ -103,7 +103,6 @@ function saveStep1() { $_SESSION['title'] = $system_conf->title; $_SESSION['auth_type'] = $system_conf->auth_type; $_SESSION['old_entries'] = $user_conf->old_entries; - $_SESSION['mail_login'] = $user_conf->mail_login; $_SESSION['default_user'] = $current_user; $_SESSION['passwordHash'] = $user_conf->passwordHash; @@ -128,7 +127,6 @@ function saveStep2() { $_SESSION['old_entries'] = param('old_entries', $user_default_config->old_entries); $_SESSION['auth_type'] = param('auth_type', 'form'); $_SESSION['default_user'] = substr(preg_replace('/[^a-zA-Z0-9]/', '', param('default_user', '')), 0, 16); - $_SESSION['mail_login'] = filter_var(param('mail_login', ''), FILTER_VALIDATE_EMAIL); $password_plain = param('passwordPlain', false); if ($password_plain !== false && cryptAvailable()) { @@ -146,8 +144,7 @@ function saveStep2() { return false; } - if (($_SESSION['auth_type'] === 'form' && empty($_SESSION['passwordHash'])) || - ($_SESSION['auth_type'] === 'persona' && empty($_SESSION['mail_login']))) { + if ($_SESSION['auth_type'] === 'form' && empty($_SESSION['passwordHash'])) { return false; } @@ -157,15 +154,11 @@ function saveStep2() { } $token = ''; - if ($_SESSION['mail_login']) { - $token = sha1($_SESSION['salt'] . $_SESSION['mail_login']); - } $config_array = array( 'language' => $_SESSION['language'], 'theme' => $user_default_config->theme, 'old_entries' => $_SESSION['old_entries'], - 'mail_login' => $_SESSION['mail_login'], 'passwordHash' => $_SESSION['passwordHash'], 'token' => $token, ); @@ -179,12 +172,6 @@ function saveStep2() { mkdir($user_dir); file_put_contents($user_config_path, " $cache ? 'ok' : 'ko', 'users' => $users ? 'ok' : 'ko', 'favicons' => $favicons ? 'ok' : 'ko', - 'persona' => $persona ? 'ok' : 'ko', 'http_referer' => $http_referer ? 'ok' : 'ko', 'all' => $php && $minz && $curl && $pdo && $pcre && $ctype && $dom && $xml && - $data && $cache && $users && $favicons && $persona && $http_referer ? + $data && $cache && $users && $favicons && $http_referer ? 'ok' : 'ko' ); } @@ -380,7 +365,6 @@ function freshrss_already_installed() { function checkStep2() { $conf = !empty($_SESSION['old_entries']) && - isset($_SESSION['mail_login']) && !empty($_SESSION['default_user']); $form = ( @@ -388,11 +372,6 @@ function checkStep2() { ($_SESSION['auth_type'] != 'form' || !empty($_SESSION['passwordHash'])) ); - $persona = ( - isset($_SESSION['auth_type']) && - ($_SESSION['auth_type'] != 'persona' || !empty($_SESSION['mail_login'])) - ); - $defaultUser = empty($_POST['default_user']) ? null : $_POST['default_user']; if ($defaultUser === null) { $defaultUser = empty($_SESSION['default_user']) ? '' : $_SESSION['default_user']; @@ -402,9 +381,8 @@ function checkStep2() { return array( 'conf' => $conf ? 'ok' : 'ko', 'form' => $form ? 'ok' : 'ko', - 'persona' => $persona ? 'ok' : 'ko', 'data' => $data ? 'ok' : 'ko', - 'all' => $conf && $form && $persona && $data ? 'ok' : 'ko' + 'all' => $conf && $form && $data ? 'ok' : 'ko' ); } @@ -612,12 +590,6 @@ function printStep1() {

- -

- -

- -

@@ -673,12 +645,11 @@ function printStep2() { @@ -697,14 +668,6 @@ function printStep2() {
-
- -
- tabindex="6"/> - -
-
-
diff --git a/app/views/auth/index.phtml b/app/views/auth/index.phtml index 8e4df8c2c..8f81ac856 100644 --- a/app/views/auth/index.phtml +++ b/app/views/auth/index.phtml @@ -10,11 +10,10 @@
diff --git a/app/views/auth/personaLogin.phtml b/app/views/auth/personaLogin.phtml deleted file mode 100644 index c6d738bf6..000000000 --- a/app/views/auth/personaLogin.phtml +++ /dev/null @@ -1,28 +0,0 @@ -res === false) { ?> -
-

- - - - - -

- - -

- - - - - -

- -

-
-res); -} -?> diff --git a/app/views/auth/register.phtml b/app/views/auth/register.phtml index 306679601..0c261319a 100644 --- a/app/views/auth/register.phtml +++ b/app/views/auth/register.phtml @@ -16,11 +16,6 @@
-
- - -
-
-

- - message)) { ?> -

- message['title']; ?>
- message['body']; ?> -

- - - no_form) { ?> - -

-
- -

- -
- - -
-
- - -
- -
-
- -
- - -
diff --git a/app/views/helpers/javascript_vars.phtml b/app/views/helpers/javascript_vars.phtml index 6178cacf2..1aa43a207 100644 --- a/app/views/helpers/javascript_vars.phtml +++ b/app/views/helpers/javascript_vars.phtml @@ -1,6 +1,5 @@ mark_when; -$mail = Minz_Session::param('mail', false); $s = FreshRSS_Context::$user_conf->shortcuts; echo htmlspecialchars(json_encode(array( 'context' => array( @@ -16,7 +15,6 @@ echo htmlspecialchars(json_encode(array( 'sticky_post' => !!FreshRSS_Context::isStickyPostEnabled(), 'html5_notif_timeout' => FreshRSS_Context::$user_conf->html5_notif_timeout, 'auth_type' => FreshRSS_Context::$system_conf->auth_type, - 'current_user_mail' => $mail ? ('"' . $mail . '"') : null, 'current_view' => Minz_Request::actionName(), ), 'shortcuts' => array( diff --git a/app/views/user/manage.phtml b/app/views/user/manage.phtml index fe1b6618b..e48841d9b 100644 --- a/app/views/user/manage.phtml +++ b/app/views/user/manage.phtml @@ -37,14 +37,6 @@
-
- - mail_login; ?> -
- -
-
-
diff --git a/app/views/user/profile.phtml b/app/views/user/profile.phtml index 7ae2c7ede..e96b5aa32 100644 --- a/app/views/user/profile.phtml +++ b/app/views/user/profile.phtml @@ -41,15 +41,6 @@
-
- - mail_login; ?> -
- placeholder="alice@example.net" /> - -
-
-
diff --git a/data/config.default.php b/data/config.default.php index cae15330f..be3fa8ae2 100644 --- a/data/config.default.php +++ b/data/config.default.php @@ -40,7 +40,6 @@ return array( # Login method: # `none` is without password and shows only the default user; # `form` is a conventional Web login form; - # `persona` is the email-based login by Mozilla; # `http_auth` is an access controled by the HTTP Web server (e.g. `/FreshRSS/p/i/.htaccess` for Apache) # if you use `http_auth`, remember to protect only `/FreshRSS/p/i/`, # and in particular not protect `/FreshRSS/p/api/` if you would like to use the API (different login system). diff --git a/data/users/_/config.default.php b/data/users/_/config.default.php index 8f8ff528c..4a3403453 100644 --- a/data/users/_/config.default.php +++ b/data/users/_/config.default.php @@ -5,7 +5,6 @@ return array ( 'old_entries' => 3, 'keep_history_default' => 0, 'ttl_default' => 3600, - 'mail_login' => '', 'token' => '', 'passwordHash' => '', 'apiPasswordHash' => '', diff --git a/lib/lib_rss.php b/lib/lib_rss.php index f89baf9b1..8196f7847 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -440,7 +440,6 @@ function check_install_files() { 'cache' => CACHE_PATH && is_writable(CACHE_PATH), 'users' => USERS_PATH && is_writable(USERS_PATH), 'favicons' => is_writable(DATA_PATH . '/favicons'), - 'persona' => is_writable(DATA_PATH . '/persona'), 'tokens' => is_writable(DATA_PATH . '/tokens'), ); } diff --git a/p/scripts/install.js b/p/scripts/install.js index 9a49e6031..57fc2450a 100644 --- a/p/scripts/install.js +++ b/p/scripts/install.js @@ -24,18 +24,12 @@ function auth_type_change() { var auth_type = document.getElementById('auth_type'); if (auth_type) { var auth_value = auth_type.value, - password_input = document.getElementById('passwordPlain'), - mail_input = document.getElementById('mail_login'); + password_input = document.getElementById('passwordPlain'); if (auth_value === 'form') { password_input.required = true; - mail_input.required = false; - } else if (auth_value === 'persona') { - password_input.required = false; - mail_input.required = true; } else { password_input.required = false; - mail_input.required = false; } } } diff --git a/p/scripts/persona.js b/p/scripts/persona.js deleted file mode 100644 index 63ab43795..000000000 --- a/p/scripts/persona.js +++ /dev/null @@ -1,76 +0,0 @@ -"use strict"; - -function init_persona() { - if (!(navigator.id && window.$ && window.url)) { - if (window.console) { - console.log('FreshRSS (Persona) waiting for JS…'); - } - window.setTimeout(init_persona, 100); - return; - } - - $('a.signin').click(function() { - navigator.id.request(); - return false; - }); - - $('a.signout').click(function() { - navigator.id.logout(); - return false; - }); - - navigator.id.watch({ - loggedInUser: context['current_user_mail'], - - onlogin: function(assertion) { - // A user has logged in! Here you need to: - // 1. Send the assertion to your backend for verification and to create a session. - // 2. Update your UI. - $.ajax ({ - type: 'POST', - url: url['login'], - data: {assertion: assertion}, - success: function(res, status, xhr) { - if (res.status === 'failure') { - openNotification(res.reason, 'bad'); - } else if (res.status === 'okay') { - location.href = url['index']; - } - }, - error: function(res, status, xhr) { - // alert(res); - } - }); - }, - onlogout: function() { - // A user has logged out! Here you need to: - // Tear down the user's session by redirecting the user or making a call to your backend. - // Also, make sure loggedInUser will get set to null on the next page load. - // (That's a literal JavaScript null. Not false, 0, or undefined. null.) - $.ajax ({ - type: 'POST', - url: url['logout'], - success: function(res, status, xhr) { - location.href = url['index']; - }, - error: function(res, status, xhr) { - // alert(res); - } - }); - } - }); -} - -if (document.readyState && document.readyState !== 'loading') { - if (window.console) { - console.log('FreshRSS (Persona) immediate init…'); - } - init_persona(); -} else if (document.addEventListener) { - document.addEventListener('DOMContentLoaded', function () { - if (window.console) { - console.log('FreshRSS (Persona) waiting for DOMContentLoaded…'); - } - init_persona(); - }, false); -} -- cgit v1.2.3 From 2a5aa34ad2796df00fa09de41361c20764ccdfa8 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sun, 11 Sep 2016 15:06:33 +0200 Subject: Better control of number of entries per page or RSS feed https://github.com/FreshRSS/FreshRSS/issues/1249 * Since X hours: `https://freshrss.example/i/?a=rss&hours=3` * Explicit number: `https://freshrss.example/i/?a=rss&nb=10` * Limited by `min_posts_per_rss` and `max_posts_per_rss` in user config --- CHANGELOG.md | 4 ++++ app/Controllers/indexController.php | 39 +++++++++++++++++++++++++++++++------ app/Models/Context.php | 1 + app/layout/layout.phtml | 3 +++ app/layout/nav_menu.phtml | 3 +++ app/views/auth/index.phtml | 2 +- data/users/_/config.default.php | 3 +++ 7 files changed, 48 insertions(+), 7 deletions(-) (limited to 'data/users/_') diff --git a/CHANGELOG.md b/CHANGELOG.md index b3c46bdb6..f82f68fff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,10 @@ ## 2016-XX-XX FreshRSS 1.6.0-dev * Features + * Better control of number of entries per page or RSS feed [#1249](https://github.com/FreshRSS/FreshRSS/issues/1249) + * Since X hours: `https://freshrss.example/i/?a=rss&hours=3` + * Explicit number: `https://freshrss.example/i/?a=rss&nb=10` + * Limited by `min_posts_per_rss` and `max_posts_per_rss` in user config * Support custom ports `localhost:3306` for database servers [#1241](https://github.com/FreshRSS/FreshRSS/issues/1241) * Security * Prevent `` attacks with `window.opener` [#1245](https://github.com/FreshRSS/FreshRSS/issues/1245) diff --git a/app/Controllers/indexController.php b/app/Controllers/indexController.php index 2332d225d..4e2717920 100755 --- a/app/Controllers/indexController.php +++ b/app/Controllers/indexController.php @@ -34,7 +34,9 @@ class FreshRSS_index_Controller extends Minz_ActionController { $this->view->callbackBeforeContent = function($view) { try { + FreshRSS_Context::$number++; //+1 for pagination $entries = FreshRSS_index_Controller::listEntriesByContext(); + FreshRSS_Context::$number--; $nb_entries = count($entries); if ($nb_entries > FreshRSS_Context::$number) { @@ -154,6 +156,7 @@ class FreshRSS_index_Controller extends Minz_ActionController { * - order (default: conf->sort_order) * - nb (default: conf->posts_per_page) * - next (default: empty string) + * - hours (default: 0) */ private function updateContext() { // Update number of read / unread variables. @@ -180,10 +183,14 @@ class FreshRSS_index_Controller extends Minz_ActionController { FreshRSS_Context::$order = Minz_Request::param( 'order', FreshRSS_Context::$user_conf->sort_order ); - FreshRSS_Context::$number = Minz_Request::param( - 'nb', FreshRSS_Context::$user_conf->posts_per_page - ); + FreshRSS_Context::$number = intval(Minz_Request::param('nb', FreshRSS_Context::$user_conf->posts_per_page)); + if (FreshRSS_Context::$number > FreshRSS_Context::$user_conf->max_posts_per_rss) { + FreshRSS_Context::$number = max( + FreshRSS_Context::$user_conf->max_posts_per_rss, + FreshRSS_Context::$user_conf->posts_per_page); + } FreshRSS_Context::$first_id = Minz_Request::param('next', ''); + FreshRSS_Context::$sinceHours = intval(Minz_Request::param('hours', 0)); } /** @@ -201,11 +208,31 @@ class FreshRSS_index_Controller extends Minz_ActionController { $id = ''; } - return $entryDAO->listWhere( + $limit = FreshRSS_Context::$number; + + $date_min = 0; + if (FreshRSS_Context::$sinceHours) { + $date_min = time() - (FreshRSS_Context::$sinceHours * 3600); + $limit = FreshRSS_Context::$user_conf->max_posts_per_rss; + } + + $entries = $entryDAO->listWhere( $type, $id, FreshRSS_Context::$state, FreshRSS_Context::$order, - FreshRSS_Context::$number + 1, FreshRSS_Context::$first_id, - FreshRSS_Context::$search + $limit, FreshRSS_Context::$first_id, + FreshRSS_Context::$search, $date_min ); + + if (FreshRSS_Context::$sinceHours && (count($entries) < FreshRSS_Context::$user_conf->min_posts_per_rss)) { + $date_min = 0; + $limit = FreshRSS_Context::$user_conf->min_posts_per_rss; + $entries = $entryDAO->listWhere( + $type, $id, FreshRSS_Context::$state, FreshRSS_Context::$order, + $limit, FreshRSS_Context::$first_id, + FreshRSS_Context::$search, $date_min + ); + } + + return $entries; } /** diff --git a/app/Models/Context.php b/app/Models/Context.php index 2a58bd4ba..33e65a619 100644 --- a/app/Models/Context.php +++ b/app/Models/Context.php @@ -35,6 +35,7 @@ class FreshRSS_Context { public static $first_id = ''; public static $next_id = ''; public static $id_max = ''; + public static $sinceHours = 0; /** * Initialize the context. diff --git a/app/layout/layout.phtml b/app/layout/layout.phtml index 4d9ad5458..1f11e0af1 100644 --- a/app/layout/layout.phtml +++ b/app/layout/layout.phtml @@ -42,6 +42,9 @@ } if (isset($this->rss_title)) { $url_rss = $url_base; $url_rss['a'] = 'rss'; + if (FreshRSS_Context::$user_conf->since_hours_posts_per_rss) { + $url_rss['params']['hours'] = FreshRSS_Context::$user_conf->since_hours_posts_per_rss; + } ?> allow_robots) { ?> diff --git a/app/layout/nav_menu.phtml b/app/layout/nav_menu.phtml index d77c1abf9..c02232242 100644 --- a/app/layout/nav_menu.phtml +++ b/app/layout/nav_menu.phtml @@ -151,6 +151,9 @@ if (FreshRSS_Context::$user_conf->token) { $url_output['params']['token'] = FreshRSS_Context::$user_conf->token; } + if (FreshRSS_Context::$user_conf->since_hours_posts_per_rss) { + $url_output['params']['hours'] = FreshRSS_Context::$user_conf->since_hours_posts_per_rss; + } ?> diff --git a/app/views/auth/index.phtml b/app/views/auth/index.phtml index 74e692ec5..7195bab5d 100644 --- a/app/views/auth/index.phtml +++ b/app/views/auth/index.phtml @@ -60,7 +60,7 @@ data-leave-validation=""/> - array('output' => 'rss', 'token' => $token)), 'html', true); ?> + array('output' => 'rss', 'token' => $token, 'hours' => FreshRSS_Context::$user_conf->since_hours_posts_per_rss)), 'html', true); ?>
diff --git a/data/users/_/config.default.php b/data/users/_/config.default.php index 4a3403453..2c56d5f45 100644 --- a/data/users/_/config.default.php +++ b/data/users/_/config.default.php @@ -9,6 +9,9 @@ return array ( 'passwordHash' => '', 'apiPasswordHash' => '', 'posts_per_page' => 20, + 'since_hours_posts_per_rss' => 168, + 'min_posts_per_rss' => 2, + 'max_posts_per_rss' => 400, 'view_mode' => 'normal', 'default_view' => 'adaptive', 'default_state' => FreshRSS_Entry::STATE_NOT_READ, -- cgit v1.2.3 From 9291748c4745ff8f4be2beaa2998869fd26e907e Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Mon, 26 Sep 2016 10:44:44 +0200 Subject: API implement user-info and fix edits https://github.com/FreshRSS/FreshRSS/issues/1254 https://github.com/jangernert/FeedReader/issues/59#issuecomment-249491580 --- app/Controllers/feedController.php | 20 +++++++++++----- app/Models/CategoryDAO.php | 3 +++ data/users/_/config.default.php | 1 + p/api/greader.php | 47 ++++++++++++++++++++++++++++++-------- 4 files changed, 55 insertions(+), 16 deletions(-) (limited to 'data/users/_') diff --git a/app/Controllers/feedController.php b/app/Controllers/feedController.php index faf670e6e..ca7a818c6 100755 --- a/app/Controllers/feedController.php +++ b/app/Controllers/feedController.php @@ -473,17 +473,25 @@ class FreshRSS_feed_Controller extends Minz_ActionController { return $feedDAO->updateFeed($feed_id, array('name' => $feed_name)); } - public static function moveFeed($feed_id, $cat_id) { + public static function moveFeed($feed_id, $cat_id, $new_cat_name = '') { if ($feed_id <= 0) { return false; } - if ($cat_id <= 0) { - // If category was not given get the default one. - $catDAO = new FreshRSS_CategoryDAO(); + + $catDAO = new FreshRSS_CategoryDAO(); + if ($cat_id > 0) { + $cat = $catDAO->searchById($cat_id); + $cat_id = $cat == null ? 0 : $cat->id(); + } + if ($cat_id <= 1 && $new_cat_name != '') { + $cat_id = $catDAO->addCategory(array('name' => $new_cat_name)); + } + if ($cat_id <= 1) { $catDAO->checkDefault(); - $def_cat = $catDAO->getDefault(); - $cat_id = $def_cat->id(); + $cat = $catDAO->getDefault(); + $cat_id = $cat->id(); } + $feedDAO = FreshRSS_Factory::createFeedDao(); return $feedDAO->updateFeed($feed_id, array('category' => $cat_id)); } diff --git a/app/Models/CategoryDAO.php b/app/Models/CategoryDAO.php index fc431553e..c103163a1 100644 --- a/app/Models/CategoryDAO.php +++ b/app/Models/CategoryDAO.php @@ -50,6 +50,9 @@ class FreshRSS_CategoryDAO extends Minz_ModelPdo implements FreshRSS_Searchable } public function deleteCategory($id) { + if ($id <= 1) { + return false; + } $sql = 'DELETE FROM `' . $this->prefix . 'category` WHERE id=?'; $stm = $this->bd->prepare($sql); diff --git a/data/users/_/config.default.php b/data/users/_/config.default.php index 2c56d5f45..6e1d497bc 100644 --- a/data/users/_/config.default.php +++ b/data/users/_/config.default.php @@ -5,6 +5,7 @@ return array ( 'old_entries' => 3, 'keep_history_default' => 0, 'ttl_default' => 3600, + 'mail_login' => '', 'token' => '', 'passwordHash' => '', 'apiPasswordHash' => '', diff --git a/p/api/greader.php b/p/api/greader.php index e2d7dc039..8b1e0ffb1 100644 --- a/p/api/greader.php +++ b/p/api/greader.php @@ -222,6 +222,17 @@ function checkToken($conf, $token) { unauthorized(); } +function userInfo() { //https://github.com/theoldreader/api#user-info + //logMe("userInfo()"); + $user = Minz_Session::param('currentUser', '_'); + exit(json_encode(array( + 'userId' => $user, + 'userName' => $user, + 'userProfileId' => $user, + 'userEmail' => FreshRSS_Context::$user_conf->mail_login, + ))); +} + function tagList() { //logMe("tagList()"); header('Content-Type: application/json; charset=UTF-8'); @@ -299,14 +310,24 @@ function subscriptionEdit($streamNames, $titles, $action, $add = '', $remove = ' $categoryDAO = new FreshRSS_CategoryDAO(); } $c_name = ''; - if ($add != '' && strpos($add, 'user/-/label/') === 0) { //user/-/label/Example - $c_name = substr($add, 13); + if ($add != '' && strpos($add, 'user/') === 0) { //user/-/label/Example ; user/username/label/Example + if (strpos($add, 'user/-/label/') === 0) { + $c_name = substr($add, 13); + } else { + $user = Minz_Session::param('currentUser', '_'); + $prefix = 'user/' . $user . '/label/'; + if (strpos($add, $prefix) === 0) { + $c_name = substr($add, strlen($prefix)); + } else { + $c_name = ''; + } + } $cat = $categoryDAO->searchByName($c_name); $addCatId = $cat == null ? -1 : $cat->id(); } else if ($remove != '' && strpos($remove, 'user/-/label/')) { $addCatId = 1; //Default category } - if ($addCatId <= 0 && $c_name = '') { + if ($addCatId <= 0 && $c_name == '') { $addCatId = 1; //Default category } $feedDAO = FreshRSS_Factory::createFeedDao(); @@ -345,9 +366,7 @@ function subscriptionEdit($streamNames, $titles, $action, $add = '', $remove = ' break; case 'edit': if ($feedId > 0) { - if ($addCatId > 0) { - FreshRSS_feed_Controller::moveFeed($feedId, $addCatId); - } + FreshRSS_feed_Controller::moveFeed($feedId, $addCatId, $c_name); if ($title != '') { FreshRSS_feed_Controller::renameFeed($feedId, $title); } @@ -633,8 +652,8 @@ function renameTag($s, $dest) { badRequest(); } -function disableTag($s, $dest) { - //logMe("renameTag()"); +function disableTag($s) { + //logMe("disableTag($s)"); if ($s != '' && strpos($s, 'user/-/label/') === 0) { $s = substr($s, 13); $categoryDAO = new FreshRSS_CategoryDAO(); @@ -642,6 +661,9 @@ function disableTag($s, $dest) { if ($cat != null) { $feedDAO = FreshRSS_Factory::createFeedDao(); $feedDAO->changeCategory($cat->id(), 0); + if ($cat->id() > 1) { + $categoryDAO->deleteCategory($cat->id()); + } exit('OK'); } } @@ -798,8 +820,10 @@ elseif ($pathInfos[1] === 'reader' && $pathInfos[2] === 'api' && isset($pathInfo case 'disable-tag': //https://github.com/theoldreader/api $token = isset($_POST['T']) ? trim($_POST['T']) : ''; checkToken(FreshRSS_Context::$user_conf, $token); - $s = isset($_POST['s']) ? $_POST['s'] : ''; //user/-/label/Folder - disableTag($s); + $s_s = multiplePosts('s'); + foreach ($s_s as $s) { + disableTag($s); //user/-/label/Folder + } break; case 'mark-all-as-read': $token = isset($_POST['T']) ? trim($_POST['T']) : ''; @@ -814,6 +838,9 @@ elseif ($pathInfos[1] === 'reader' && $pathInfos[2] === 'api' && isset($pathInfo case 'token': token(FreshRSS_Context::$user_conf); break; + case 'user-info': + userInfo(); + break; } } elseif ($pathInfos[1] === 'check' && $pathInfos[2] === 'compatibility') { checkCompatibility(); -- cgit v1.2.3 From 44a57ba12db39439f6cc43fe7542efd92cf402bb Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Fri, 30 Sep 2016 23:30:16 +0200 Subject: Change default value for keep history Larger value by default, for limiting the risk of re-adding an article previously purged, e.g. with feeds which do not have good dates, which do not update so often, and for which the list of articles is not so stable. --- data/users/_/config.default.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'data/users/_') diff --git a/data/users/_/config.default.php b/data/users/_/config.default.php index 6e1d497bc..280b13422 100644 --- a/data/users/_/config.default.php +++ b/data/users/_/config.default.php @@ -3,7 +3,7 @@ return array ( 'language' => 'en', 'old_entries' => 3, - 'keep_history_default' => 0, + 'keep_history_default' => 50, 'ttl_default' => 3600, 'mail_login' => '', 'token' => '', -- cgit v1.2.3 From 3366945a90b58929cc3b9e980ce9a52027151556 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Fri, 14 Oct 2016 17:49:33 +0200 Subject: Default option mark as read during scroll --- CHANGELOG.md | 1 + data/users/_/config.default.php | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'data/users/_') diff --git a/CHANGELOG.md b/CHANGELOG.md index 3178e6ae7..a21e4a093 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ * Experimental support for PostgreSQL [#1195](https://github.com/FreshRSS/FreshRSS/pull/1195) * New client supporting FreshRSS on Linux: FeedReader 2.0+ [#1252](https://github.com/FreshRSS/FreshRSS/issues/1252) * Features + * Rework the “mark as read during scroll” option, now enabled by default [#1258](https://github.com/FreshRSS/FreshRSS/issues/1258), [#1309](https://github.com/FreshRSS/FreshRSS/pull/1309) * Better control of number of entries per page or RSS feed [#1249](https://github.com/FreshRSS/FreshRSS/issues/1249) * Since X hours: `https://freshrss.example/i/?a=rss&hours=3` * Explicit number: `https://freshrss.example/i/?a=rss&nb=10` diff --git a/data/users/_/config.default.php b/data/users/_/config.default.php index 280b13422..f28ef9724 100644 --- a/data/users/_/config.default.php +++ b/data/users/_/config.default.php @@ -35,7 +35,7 @@ return array ( 'mark_when' => array ( 'article' => true, 'site' => true, - 'scroll' => false, + 'scroll' => true, 'reception' => false, ), 'theme' => 'Origine', -- cgit v1.2.3