/** * Créé la connexion à la base de données à l'aide des variables * HOST, BASE, USER et PASS définies dans le fichier de configuration */ public function __construct() { if (self::$useSharedBd && self::$sharedBd != null) { $this->bd = self::$sharedBd; $this->prefix = self::$sharedPrefix; return; } $db = Minz_Configuration::dataBase(); $driver_options = null; try { $type = $db['type']; if ($type == 'mysql') { $string = $type . ':host=' . $db['host'] . ';dbname=' . $db['base'] . ';charset=utf8'; $driver_options = array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'); } elseif ($type == 'sqlite') { $string = $type . ':/' . DATA_PATH . $db['base'] . '.sqlite'; //TODO: DEBUG UTF-8 http://www.siteduzero.com/forum/sujet/sqlite-connexion-utf-8-18797 } $this->bd = new FreshPDO($string, $db['user'], $db['password'], $driver_options); self::$sharedBd = $this->bd; $this->prefix = $db['prefix'] . Minz_Session::param('currentUser', '_') . '_'; self::$sharedPrefix = $this->prefix; } catch (Exception $e) { throw new Minz_PDOConnectionException($string, $db['user'], Minz_Exception::ERROR); } }
/** * This action is the default one for the controller. * * It is called by Minz_Error::error() method. * * Parameters are passed by Minz_Session to have a proper url: * - error_code (default: 404) * - error_logs (default: array()) */ public function indexAction() { $code_int = Minz_Session::param('error_code', 404); $error_logs = Minz_Session::param('error_logs', array()); Minz_Session::_param('error_code'); Minz_Session::_param('error_logs'); switch ($code_int) { case 200: header('HTTP/1.1 200 OK'); break; case 403: header('HTTP/1.1 403 Forbidden'); $this->view->code = 'Error 403 - Forbidden'; $this->view->errorMessage = _t('feedback.access.denied'); break; case 500: header('HTTP/1.1 500 Internal Server Error'); $this->view->code = 'Error 500 - Internal Server Error'; break; case 503: header('HTTP/1.1 503 Service Unavailable'); $this->view->code = 'Error 503 - Service Unavailable'; break; case 404: default: header('HTTP/1.1 404 Not Found'); $this->view->code = 'Error 404 - Not found'; $this->view->errorMessage = _t('feedback.access.not_found'); } $error_message = trim(implode($error_logs)); if ($error_message !== '') { $this->view->errorMessage = $error_message; } Minz_View::prependTitle($this->view->code . ' · '); }
/** * Enregistre un message dans un fichier de log spécifique * Message non loggué si * - environment = SILENT * - level = WARNING et environment = PRODUCTION * - level = NOTICE et environment = PRODUCTION * @param $information message d'erreur / information à enregistrer * @param $level niveau d'erreur * @param $file_name fichier de log, par défaut LOG_PATH/application.log */ public static function record($information, $level, $file_name = null) { $env = Minz_Configuration::environment(); if (!($env === Minz_Configuration::SILENT || $env === Minz_Configuration::PRODUCTION && $level >= Minz_Log::NOTICE)) { if ($file_name === null) { $file_name = LOG_PATH . '/' . Minz_Session::param('currentUser', '_') . '.log'; } switch ($level) { case Minz_Log::ERROR: $level_label = 'error'; break; case Minz_Log::WARNING: $level_label = 'warning'; break; case Minz_Log::NOTICE: $level_label = 'notice'; break; case Minz_Log::DEBUG: $level_label = 'debug'; break; default: $level_label = 'unknown'; } $log = '[' . date('r') . ']' . ' [' . $level_label . ']' . ' --- ' . $information . "\n"; if (file_put_contents($file_name, $log, FILE_APPEND | LOCK_EX) === false) { throw new Minz_PermissionDeniedException($file_name, Minz_Exception::ERROR); } } }
/** * Enregistre un message dans un fichier de log spécifique * Message non loggué si * - environment = SILENT * - level = WARNING et environment = PRODUCTION * - level = NOTICE et environment = PRODUCTION * @param $information message d'erreur / information à enregistrer * @param $level niveau d'erreur * @param $file_name fichier de log */ public static function record($information, $level, $file_name = null) { try { $conf = Minz_Configuration::get('system'); $env = $conf->environment; } catch (Minz_ConfigurationException $e) { $env = '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'); } switch ($level) { case Minz_Log::ERROR: $level_label = 'error'; break; case Minz_Log::WARNING: $level_label = 'warning'; break; case Minz_Log::NOTICE: $level_label = 'notice'; break; case Minz_Log::DEBUG: $level_label = 'debug'; break; default: $level_label = 'unknown'; } $log = '[' . date('r') . ']' . ' [' . $level_label . ']' . ' --- ' . $information . "\n"; if (file_put_contents($file_name, $log, FILE_APPEND | LOCK_EX) === false) { throw new Minz_PermissionDeniedException($file_name, Minz_Exception::ERROR); } } }
public static function truncate() { file_put_contents(join_path(DATA_PATH, 'users', Minz_Session::param('currentUser', '_'), 'log.txt'), ''); if (FreshRSS_Auth::hasAccess('admin')) { file_put_contents(join_path(DATA_PATH, 'users', '_', 'log.txt'), ''); file_put_contents(join_path(DATA_PATH, 'users', '_', 'log_api.txt'), ''); file_put_contents(join_path(DATA_PATH, 'users', '_', 'log_pshb.txt'), ''); } }
/** * Inclus le fichier de langue qui va bien * l'enregistre dans $translates */ public static function init() { $l = Minz_Configuration::language(); self::$language = Minz_Session::param('language', $l); $l_path = APP_PATH . '/i18n/' . self::$language . '.php'; if (file_exists($l_path)) { self::$translates = (include $l_path); } }
public function __construct($params) { $this->seq = isset($params['seq']) ? $params['seq'] : 0; $this->user = Minz_Session::param('currentUser', ''); $this->method = $params['op']; $this->params = $params; $this->system_conf = Minz_Configuration::get('system'); if ($this->user != '') { $this->user_conf = get_user_configuration($this->user); } }
public function handleConfigureAction() { $this->registerTranslates(); $current_user = Minz_Session::param('currentUser'); $filename = 'style.' . $current_user . '.css'; $filepath = join_path($this->getPath(), 'static', $filename); if (Minz_Request::isPost()) { $css_rules = Minz_Request::param('css-rules', ''); file_put_contents($filepath, $css_rules); } $this->css_rules = ''; if (file_exists($filepath)) { $this->css_rules = file_get_contents($filepath); } }
/** * Créé la connexion à la base de données à l'aide des variables * HOST, BASE, USER et PASS définies dans le fichier de configuration */ public function __construct($currentUser = null) { if (self::$useSharedBd && self::$sharedBd != null && $currentUser === null) { $this->bd = self::$sharedBd; $this->prefix = self::$sharedPrefix; $this->current_user = self::$sharedCurrentUser; return; } $conf = Minz_Configuration::get('system'); $db = $conf->db; if ($currentUser === null) { $currentUser = Minz_Session::param('currentUser', '_'); } $this->current_user = $currentUser; self::$sharedCurrentUser = $currentUser; $driver_options = isset($conf->db['pdo_options']) && is_array($conf->db['pdo_options']) ? $conf->db['pdo_options'] : array(); try { $type = $db['type']; if ($type === 'mysql') { $string = 'mysql:host=' . $db['host'] . ';dbname=' . $db['base'] . ';charset=utf8'; $driver_options[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES utf8'; $this->prefix = $db['prefix'] . $currentUser . '_'; } elseif ($type === 'pgsql') { $string = 'pgsql:host=' . $db['host'] . ';dbname=' . $db['base']; $this->prefix = $db['prefix'] . $currentUser . '_'; } elseif ($type === 'sqlite') { $string = 'sqlite:' . join_path(DATA_PATH, 'users', $currentUser, 'db.sqlite'); //$driver_options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION; $this->prefix = ''; } else { throw new Minz_PDOConnectionException('Invalid database type!', $db['user'], Minz_Exception::ERROR); } self::$sharedDbType = $type; self::$sharedPrefix = $this->prefix; $this->bd = new MinzPDO($string, $db['user'], $db['password'], $driver_options); if ($type === 'sqlite') { $this->bd->exec('PRAGMA foreign_keys = ON;'); } self::$sharedBd = $this->bd; } catch (Exception $e) { throw new Minz_PDOConnectionException($string, $db['user'], Minz_Exception::ERROR); } }
function invalidateHttpCache() { Minz_Session::_param('touch', uTimeString()); return touch(LOG_PATH . '/' . Minz_Session::param('currentUser', '_') . '.log'); }
function invalidateHttpCache() { Minz_Session::_param('touch', uTimeString()); return touch(join_path(DATA_PATH, 'users', Minz_Session::param('currentUser', '_'), 'log.txt')); }
public static function truncate() { file_put_contents(LOG_PATH . '/' . Minz_Session::param('currentUser', '_') . '.log', ''); }
/** * This action displays the user management page. */ public function manageAction() { if (!FreshRSS_Auth::hasAccess('admin')) { Minz_Error::error(403); } Minz_View::prependTitle(_t('admin.user.title') . ' · '); // Get the correct current user. $username = Minz_Request::param('u', Minz_Session::param('currentUser')); if (!FreshRSS_UserDAO::exist($username)) { $username = Minz_Session::param('currentUser'); } $this->view->current_user = $username; // Get information about the current user. $entryDAO = FreshRSS_Factory::createEntryDao($this->view->current_user); $this->view->nb_articles = $entryDAO->count(); $this->view->size_user = $entryDAO->size(); }
public function formLoginAction() { if (Minz_Request::isPost()) { $ok = false; $nonce = Minz_Session::param('nonce'); $username = Minz_Request::param('username', ''); $c = Minz_Request::param('challenge', ''); if (ctype_alnum($username) && ctype_graph($c) && ctype_alnum($nonce)) { if (!function_exists('password_verify')) { include_once LIB_PATH . '/password_compat.php'; } try { $conf = new FreshRSS_Configuration($username); $s = $conf->passwordHash; $ok = password_verify($nonce . $s, $c); if ($ok) { Minz_Session::_param('currentUser', $username); Minz_Session::_param('passwordHash', $s); } else { Minz_Log::record('Password mismatch for user ' . $username . ', nonce=' . $nonce . ', c=' . $c, Minz_Log::WARNING); } } catch (Minz_Exception $me) { Minz_Log::record('Login failure: ' . $me->getMessage(), Minz_Log::WARNING); } } else { Minz_Log::record('Invalid credential parameters: user='******' challenge=' . $c . ' nonce=' . $nonce, Minz_Log::DEBUG); } if (!$ok) { $notif = array('type' => 'bad', 'content' => Minz_Translate::t('invalid_login')); Minz_Session::_param('notification', $notif); } $this->view->_useLayout(false); Minz_Request::forward(array('c' => 'index', 'a' => 'index'), true); } elseif (!Minz_Configuration::canLogIn()) { Minz_Error::error(403, array('error' => array(Minz_Translate::t('access_denied')))); } invalidateHttpCache(); }
/** * Returns if current user has access to the given scope. * * @param string $scope general (default) or admin * @return boolean true if user has corresponding access, false else. */ public static function hasAccess($scope = 'general') { $conf = Minz_Configuration::get('system'); $default_user = $conf->default_user; $ok = self::$login_ok; switch ($scope) { case 'general': break; case 'admin': $ok &= Minz_Session::param('currentUser') === $default_user; break; default: $ok = false; } return $ok; }
/** * This action delete an existing user. * * Request parameter is: * - username * * @todo clean up this method. Idea: create a User->clean() method. */ public function deleteAction() { $username = Minz_Request::param('username'); $redirect_url = urldecode(Minz_Request::param('r', false, true)); if (!$redirect_url) { $redirect_url = array('c' => 'user', 'a' => 'manage'); } $self_deletion = Minz_Session::param('currentUser', '_') === $username; if (Minz_Request::isPost() && (FreshRSS_Auth::hasAccess('admin') || $self_deletion)) { $db = FreshRSS_Context::$system_conf->db; require_once APP_PATH . '/SQL/install.sql.' . $db['type'] . '.php'; $ok = ctype_alnum($username); $user_data = join_path(DATA_PATH, 'users', $username); if ($ok) { $default_user = FreshRSS_Context::$system_conf->default_user; $ok &= strcasecmp($username, $default_user) !== 0; //It is forbidden to delete the default user } if ($ok && $self_deletion) { // We check the password if it's a self-destruction $nonce = Minz_Session::param('nonce'); $challenge = Minz_Request::param('challenge', ''); $ok &= FreshRSS_FormAuth::checkCredentials($username, FreshRSS_Context::$user_conf->passwordHash, $nonce, $challenge); } if ($ok) { $ok &= is_dir($user_data); } if ($ok) { $userDAO = new FreshRSS_UserDAO(); $ok &= $userDAO->deleteUser($username); $ok &= recursive_unlink($user_data); //TODO: delete Persona file } if ($ok && $self_deletion) { FreshRSS_Auth::removeAccess(); $redirect_url = array('c' => 'index', 'a' => 'index'); } invalidateHttpCache(); $notif = array('type' => $ok ? 'good' : 'bad', 'content' => _t('feedback.user.deleted' . (!$ok ? '.error' : ''), $username)); Minz_Session::_param('notification', $notif); } Minz_Request::forward($redirect_url, true); }
public function archivingAction() { if (Minz_Request::isPost()) { $old = Minz_Request::param('old_entries', 3); $keepHistoryDefault = Minz_Request::param('keep_history_default', 0); $this->view->conf->_old_entries($old); $this->view->conf->_keep_history_default($keepHistoryDefault); $this->view->conf->save(); invalidateHttpCache(); $notif = array('type' => 'good', 'content' => Minz_Translate::t('configuration_updated')); Minz_Session::_param('notification', $notif); Minz_Request::forward(array('c' => 'configure', 'a' => 'archiving'), true); } Minz_View::prependTitle(Minz_Translate::t('archiving_configuration') . ' · '); $entryDAO = new FreshRSS_EntryDAO(); $this->view->nb_total = $entryDAO->count(); $this->view->size_user = $entryDAO->size(); if (Minz_Configuration::isAdmin(Minz_Session::param('currentUser', '_'))) { $this->view->size_total = $entryDAO->size(true); } }
function pubSubHubbubPrepare() { $key = ''; if (FreshRSS_Context::$system_conf->base_url && $this->hubUrl && $this->selfUrl && @is_dir(PSHB_PATH)) { $path = PSHB_PATH . '/feeds/' . base64url_encode($this->selfUrl); $hubFilename = $path . '/!hub.json'; if ($hubFile = @file_get_contents($hubFilename)) { $hubJson = json_decode($hubFile, true); if (!$hubJson || empty($hubJson['key']) || !ctype_xdigit($hubJson['key'])) { $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() + 3600 * 23) { //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 } elseif ((!empty($hubJson['error']) || empty($hubJson['lease_end'])) && (empty($hubJson['lease_start']) || $hubJson['lease_start'] < time() - 3600 * 23)) { //Do not renew too often $key = $hubJson['key']; //To renew our lease } } else { @mkdir($path, 0777, true); $key = sha1($path . FreshRSS_Context::$system_conf->salt . uniqid(mt_rand(), true)); $hubJson = array('hub' => $this->hubUrl, 'key' => $key); file_put_contents($hubFilename, json_encode($hubJson)); @mkdir(PSHB_PATH . '/keys/'); file_put_contents(PSHB_PATH . '/keys/' . $key . '.txt', base64url_encode($this->selfUrl)); $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')) { touch($path . '/' . $currentUser . '.txt'); } } return $key; }
/** * 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='******', nonce=' . $nonce . ', c=' . $challenge); Minz_Request::bad(_t('feedback.auth.login.invalid'), array('c' => 'auth', 'a' => 'reset')); } } }
private function loadNotifications() { $notif = Minz_Session::param('notification'); if ($notif) { Minz_View::_param('notification', $notif); Minz_Session::_param('notification'); } }
function checkToken($conf, $token) { //http://code.google.com/p/google-reader-api/wiki/ActionToken $user = Minz_Session::param('currentUser', '_'); logMe('checkToken(' . $token . ")\n"); $system_conf = Minz_Configuration::get('system'); if ($token === str_pad(sha1($system_conf->salt . $user . $conf->apiPasswordHash), 57, 'Z')) { return true; } unauthorized(); }
public function deleteAction() { if (Minz_Request::isPost() && Minz_Configuration::isAdmin(Minz_Session::param('currentUser', '_'))) { require_once APP_PATH . '/sql.php'; $username = Minz_Request::param('username'); $ok = ctype_alnum($username); if ($ok) { $ok &= strcasecmp($username, Minz_Configuration::defaultUser()) !== 0; //It is forbidden to delete the default user } if ($ok) { $configPath = DATA_PATH . '/' . $username . '_user.php'; $ok &= file_exists($configPath); } if ($ok) { $userDAO = new FreshRSS_UserDAO(); $ok &= $userDAO->deleteUser($username); $ok &= unlink($configPath); //TODO: delete Persona file } invalidateHttpCache(); $notif = array('type' => $ok ? 'good' : 'bad', 'content' => Minz_Translate::t($ok ? 'user_deleted' : 'error_occurred', $username)); Minz_Session::_param('notification', $notif); } Minz_Request::forward(array('c' => 'configure', 'a' => 'users'), true); }
# along with this program. If not, see <http://www.gnu.org/licenses/>. # # ***** END LICENSE BLOCK ***** require '../../constants.php'; require LIB_PATH . '/lib_rss.php'; //Includes class autoloader if (file_exists(DATA_PATH . '/do-install.txt')) { require APP_PATH . '/install.php'; } else { session_cache_limiter(''); Minz_Session::init('FreshRSS'); Minz_Session::_param('keepAlive', 1); //For Persona if (!file_exists(DATA_PATH . '/no-cache.txt')) { require LIB_PATH . '/http-conditional.php'; $currentUser = Minz_Session::param('currentUser', ''); $dateLastModification = $currentUser === '' ? time() : max(@filemtime(join_path(USERS_PATH, $currentUser, 'log.txt')), @filemtime(join_path(DATA_PATH, 'config.php'))); if (httpConditional($dateLastModification, 0, 0, false, PHP_COMPRESSION, true)) { exit; //No need to send anything } } try { $front_controller = new FreshRSS(); $front_controller->init(); $front_controller->run(); } catch (Exception $e) { echo '### Fatal error! ###<br />', "\n"; Minz_Log::error($e->getMessage()); echo 'See logs files.'; }
public static function truncate() { file_put_contents(join_path(DATA_PATH, 'users', Minz_Session::param('currentUser', '_'), 'log.txt'), ''); }