Ejemplo n.º 1
0
 /**
  * Affiche un élément graphique situé dans APP./views/helpers/
  * @param $helper l'élément à afficher
  */
 public function renderHelper($helper)
 {
     $fic_helper = APP_PATH . '/views/helpers/' . $helper . '.phtml';
     if ((include $fic_helper) === false) {
         Minz_Log::record('File not found: `' . $fic_helper . '`', Minz_Log::WARNING);
     }
 }
Ejemplo n.º 2
0
 public function nonceAction()
 {
     header('Content-Type: application/json; charset=UTF-8');
     header('Last-Modified: ' . gmdate('D, d M Y H:i:s \\G\\M\\T'));
     header('Expires: 0');
     header('Cache-Control: private, no-cache, no-store, must-revalidate');
     header('Pragma: no-cache');
     $user = isset($_GET['user']) ? $_GET['user'] : '';
     if (ctype_alnum($user)) {
         try {
             $salt = FreshRSS_Context::$system_conf->salt;
             $conf = get_user_configuration($user);
             $s = $conf->passwordHash;
             if (strlen($s) >= 60) {
                 $this->view->salt1 = substr($s, 0, 29);
                 //CRYPT_BLOWFISH Salt: "$2a$", a two digit cost parameter, "$", and 22 characters from the alphabet "./0-9A-Za-z".
                 $this->view->nonce = sha1($salt . uniqid(mt_rand(), true));
                 Minz_Session::_param('nonce', $this->view->nonce);
                 return;
                 //Success
             }
         } catch (Minz_Exception $me) {
             Minz_Log::warning('Nonce failure: ' . $me->getMessage());
         }
     } else {
         Minz_Log::notice('Nonce failure due to invalid username!');
     }
     //Failure: Return random data.
     $this->view->salt1 = sprintf('$2a$%02d$', FreshRSS_user_Controller::BCRYPT_COST);
     $alphabet = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
     for ($i = 22; $i > 0; $i--) {
         $this->view->salt1 .= $alphabet[rand(0, 63)];
     }
     $this->view->nonce = sha1(rand());
 }
Ejemplo n.º 3
0
 public function postUpdateHook()
 {
     $res = $this->install();
     if ($res !== true) {
         Minz_Log::warning('Problem during TTRSS API extension post update: ' . $res);
     }
 }
Ejemplo n.º 4
0
 public function nonceAction()
 {
     header('Content-Type: application/json; charset=UTF-8');
     header('Last-Modified: ' . gmdate('D, d M Y H:i:s \\G\\M\\T'));
     header('Expires: 0');
     header('Cache-Control: private, no-cache, no-store, must-revalidate');
     header('Pragma: no-cache');
     $user = isset($_GET['user']) ? $_GET['user'] : '';
     if (ctype_alnum($user)) {
         try {
             $conf = new FreshRSS_Configuration($user);
             $s = $conf->passwordHash;
             if (strlen($s) >= 60) {
                 $this->view->salt1 = substr($s, 0, 29);
                 //CRYPT_BLOWFISH Salt: "$2a$", a two digit cost parameter, "$", and 22 characters from the alphabet "./0-9A-Za-z".
                 $this->view->nonce = sha1(Minz_Configuration::salt() . uniqid(mt_rand(), true));
                 Minz_Session::_param('nonce', $this->view->nonce);
                 return;
                 //Success
             }
         } catch (Minz_Exception $me) {
             Minz_Log::record('Nonce failure: ' . $me->getMessage(), Minz_Log::WARNING);
         }
     }
     $this->view->nonce = '';
     //Failure
     $this->view->salt1 = '';
 }
Ejemplo n.º 5
0
 public function deleteCategory($id)
 {
     $sql = 'DELETE FROM `' . $this->prefix . 'category` WHERE id=?';
     $stm = $this->bd->prepare($sql);
     $values = array($id);
     if ($stm && $stm->execute($values)) {
         return $stm->rowCount();
     } else {
         $info = $stm->errorInfo();
         Minz_Log::record('SQL error : ' . $info[2], Minz_Log::ERROR);
         return false;
     }
 }
Ejemplo n.º 6
0
 public function updateCachedValues()
 {
     //For one single feed, call updateLastUpdate($id)
     $sql = 'UPDATE `' . $this->prefix . 'feed` ' . 'SET cache_nbEntries=(SELECT COUNT(e1.id) FROM `' . $this->prefix . 'entry` e1 WHERE e1.id_feed=`' . $this->prefix . 'feed`.id),' . 'cache_nbUnreads=(SELECT COUNT(e2.id) FROM `' . $this->prefix . 'entry` e2 WHERE e2.id_feed=`' . $this->prefix . 'feed`.id AND e2.is_read=0)';
     $stm = $this->bd->prepare($sql);
     if ($stm && $stm->execute()) {
         return $stm->rowCount();
     } else {
         $info = $stm == null ? array(2 => 'syntax error') : $stm->errorInfo();
         Minz_Log::error('SQL error updateCachedValues: ' . $info[2]);
         return false;
     }
 }
Ejemplo n.º 7
0
 public function deleteCategory($id)
 {
     $sql = 'DELETE FROM `' . $this->prefix . 'category` WHERE id=?';
     $stm = $this->bd->prepare($sql);
     $values = array($id);
     if ($stm && $stm->execute($values)) {
         return $stm->rowCount();
     } else {
         $info = $stm == null ? array(2 => 'syntax error') : $stm->errorInfo();
         Minz_Log::error('SQL error deleteCategory: ' . $info[2]);
         return false;
     }
 }
Ejemplo n.º 8
0
 public function deleteUser($username)
 {
     require_once APP_PATH . '/sql.php';
     $db = Minz_Configuration::dataBase();
     $sql = sprintf(SQL_DROP_TABLES, $db['prefix'] . $username . '_');
     $stm = $this->bd->prepare($sql);
     if ($stm && $stm->execute()) {
         return true;
     } else {
         $info = $stm->errorInfo();
         Minz_Log::record('SQL error : ' . $info[2], Minz_Log::ERROR);
         return false;
     }
 }
Ejemplo n.º 9
0
 /**
  * Démarre l'application (lance le dispatcher et renvoie la réponse)
  */
 public function run()
 {
     try {
         $this->dispatcher->run();
     } catch (Minz_Exception $e) {
         try {
             Minz_Log::error($e->getMessage());
         } catch (Minz_PermissionDeniedException $e) {
             $this->killApp($e->getMessage());
         }
         if ($e instanceof Minz_FileNotExistException || $e instanceof Minz_ControllerNotExistException || $e instanceof Minz_ControllerNotActionControllerException || $e instanceof Minz_ActionException) {
             Minz_Error::error(404, array('error' => array($e->getMessage())), true);
         } else {
             $this->killApp();
         }
     }
 }
Ejemplo n.º 10
0
 public function deleteUser($username)
 {
     $db = FreshRSS_Context::$system_conf->db;
     require_once APP_PATH . '/SQL/install.sql.' . $db['type'] . '.php';
     if ($db['type'] === 'sqlite') {
         return unlink(join_path(DATA_PATH, 'users', $username, 'db.sqlite'));
     } else {
         $userPDO = new Minz_ModelPdo($username);
         $sql = sprintf(SQL_DROP_TABLES, $db['prefix'] . $username . '_');
         $stm = $userPDO->bd->prepare($sql);
         if ($stm && $stm->execute()) {
             return true;
         } else {
             $info = $stm == null ? array(2 => 'syntax error') : $stm->errorInfo();
             Minz_Log::error('SQL error : ' . $info[2]);
             return false;
         }
     }
 }
Ejemplo n.º 11
0
 public function checkAction()
 {
     $this->view->change_view('update', 'index');
     if (file_exists(UPDATE_FILENAME)) {
         // There is already an update file to apply: we don't need to check
         // the webserver!
         // Or if already check during the last hour, do nothing.
         Minz_Request::forward(array('c' => 'update'), true);
         return;
     }
     $auto_update_url = FreshRSS_Context::$system_conf->auto_update_url . '?v=' . FRESHRSS_VERSION;
     $c = curl_init($auto_update_url);
     curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
     curl_setopt($c, CURLOPT_SSL_VERIFYPEER, true);
     curl_setopt($c, CURLOPT_SSL_VERIFYHOST, 2);
     $result = curl_exec($c);
     $c_status = curl_getinfo($c, CURLINFO_HTTP_CODE);
     $c_error = curl_error($c);
     curl_close($c);
     if ($c_status !== 200) {
         Minz_Log::warning('Error during update (HTTP code ' . $c_status . '): ' . $c_error);
         $this->view->message = array('status' => 'bad', 'title' => _t('gen.short.damn'), 'body' => _t('feedback.update.server_not_found', $auto_update_url));
         return;
     }
     $res_array = explode("\n", $result, 2);
     $status = $res_array[0];
     if (strpos($status, 'UPDATE') !== 0) {
         $this->view->message = array('status' => 'bad', 'title' => _t('gen.short.damn'), 'body' => _t('feedback.update.none'));
         @touch(join_path(DATA_PATH, 'last_update.txt'));
         return;
     }
     $script = $res_array[1];
     if (file_put_contents(UPDATE_FILENAME, $script) !== false) {
         $version = explode(' ', $status, 2);
         $version = $version[1];
         @file_put_contents(join_path(DATA_PATH, 'last_update.txt'), $version);
         Minz_Request::forward(array('c' => 'update'), true);
     } else {
         $this->view->message = array('status' => 'bad', 'title' => _t('gen.short.damn'), 'body' => _t('feedback.update.error', 'Cannot save the update script'));
     }
 }
Ejemplo n.º 12
0
 /**
  * This action changes the category of a feed.
  *
  * This page must be reached by a POST request.
  *
  * Parameters are:
  *   - f_id (default: false)
  *   - c_id (default: false)
  * If c_id is false, default category is used.
  *
  * @todo should handle order of the feed inside the category.
  */
 public function moveAction()
 {
     if (!Minz_Request::isPost()) {
         Minz_Request::forward(array('c' => 'subscription'), true);
     }
     $feed_id = Minz_Request::param('f_id');
     $cat_id = Minz_Request::param('c_id');
     if ($cat_id === false) {
         // If category was not given get the default one.
         $catDAO = new FreshRSS_CategoryDAO();
         $catDAO->checkDefault();
         $def_cat = $catDAO->getDefault();
         $cat_id = $def_cat->id();
     }
     $feedDAO = FreshRSS_Factory::createFeedDao();
     $values = array('category' => $cat_id);
     $feed = $feedDAO->searchById($feed_id);
     if ($feed && ($feed->category() == $cat_id || $feedDAO->updateFeed($feed_id, $values))) {
         // TODO: return something useful
     } else {
         Minz_Log::warning('Cannot move feed `' . $feed_id . '` ' . 'in the category `' . $cat_id . '`');
         Minz_Error::error(404);
     }
 }
Ejemplo n.º 13
0
 /**
  * This method import a JSON-based feed (Google Reader format).
  *
  * @param array $origin represents a feed.
  * @param boolean $google_compliant takes care of some specific values if true.
  * @return FreshRSS_Feed if feed is in database at the end of the process,
  *         else null.
  */
 private function addFeedJson($origin, $google_compliant)
 {
     $default_cat = $this->catDAO->getDefault();
     $return = null;
     $key = $google_compliant ? 'htmlUrl' : 'feedUrl';
     $url = $origin[$key];
     $name = $origin['title'];
     $website = $origin['htmlUrl'];
     try {
         // Create a Feed object and add it in database.
         $feed = new FreshRSS_Feed($url);
         $feed->_category($default_cat->id());
         $feed->_name($name);
         $feed->_website($website);
         // Call the extension hook
         $feed = Minz_ExtensionManager::callHook('feed_before_insert', $feed);
         if (!is_null($feed)) {
             // addFeedObject checks if feed is already in DB so nothing else to
             // check here.
             $id = $this->feedDAO->addFeedObject($feed);
             if ($id !== false) {
                 $feed->_id($id);
                 $return = $feed;
             }
         }
     } catch (FreshRSS_Feed_Exception $e) {
         Minz_Log::warning($e->getMessage());
     }
     return $return;
 }
Ejemplo n.º 14
0
 /**
  * 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'));
         }
     }
 }
Ejemplo n.º 15
0
 public function cleanOldEntries($id, $date_min, $keep = 15)
 {
     //Remember to call updateLastUpdate($id) or updateCachedValues() just after
     $sql = 'DELETE FROM ' . $this->prefix . 'entry ' . 'WHERE id_feed=:id_feed AND id<=:id_max ' . 'AND is_favorite=false ' . 'AND lastSeen < (SELECT maxLastSeen FROM (SELECT (MAX(e3.lastSeen)-99) AS maxLastSeen FROM ' . $this->prefix . 'entry e3 WHERE e3.id_feed=:id_feed) recent) ' . 'AND id NOT IN (SELECT id FROM (SELECT e2.id FROM ' . $this->prefix . 'entry e2 WHERE e2.id_feed=:id_feed ORDER BY id DESC LIMIT :keep) keep)';
     //Double select: MySQL doesn't support 'LIMIT & IN/ALL/ANY/SOME subquery'
     $stm = $this->bd->prepare($sql);
     if ($stm) {
         $id_max = intval($date_min) . '000000';
         $stm->bindParam(':id_feed', $id, PDO::PARAM_INT);
         $stm->bindParam(':id_max', $id_max, PDO::PARAM_STR);
         $stm->bindParam(':keep', $keep, PDO::PARAM_INT);
     }
     if ($stm && $stm->execute()) {
         return $stm->rowCount();
     } else {
         $info = $stm == null ? array(2 => 'syntax error') : $stm->errorInfo();
         Minz_Log::error('SQL error cleanOldEntries: ' . $info[2]);
         return false;
     }
 }
Ejemplo n.º 16
0
 /**
  * Translate a key into its corresponding value based on selected language.
  * @param $key the key to translate.
  * @param additional parameters for variable keys.
  * @return the value corresponding to the key.
  *         If no value is found, return the key itself.
  */
 public static function t($key)
 {
     $group = explode('.', $key);
     if (count($group) < 2) {
         Minz_Log::debug($key . ' is not in a valid format');
         $top_level = 'gen';
     } else {
         $top_level = array_shift($group);
     }
     // If $translates[$top_level] is null it means we have to load the
     // corresponding files.
     if (!isset(self::$translates[$top_level]) || is_null(self::$translates[$top_level])) {
         $res = self::loadKey($top_level);
         if (!$res) {
             return $key;
         }
     }
     // Go through the i18n keys to get the correct translation value.
     $translates = self::$translates[$top_level];
     $size_group = count($group);
     $level_processed = 0;
     $translation_value = $key;
     foreach ($group as $i18n_level) {
         $level_processed++;
         if (!isset($translates[$i18n_level])) {
             Minz_Log::debug($key . ' is not a valid key');
             return $key;
         }
         if ($level_processed < $size_group) {
             $translates = $translates[$i18n_level];
         } else {
             $translation_value = $translates[$i18n_level];
         }
     }
     if (is_array($translation_value)) {
         if (isset($translation_value['_'])) {
             $translation_value = $translation_value['_'];
         } else {
             Minz_Log::debug($key . ' is not a valid key');
             return $key;
         }
     }
     // Get the facultative arguments to replace i18n variables.
     $args = func_get_args();
     unset($args[0]);
     return vsprintf($translation_value, $args);
 }
Ejemplo n.º 17
0
 /**
  * This action displays the RSS feed of FreshRSS.
  */
 public function rssAction()
 {
     $allow_anonymous = FreshRSS_Context::$system_conf->allow_anonymous;
     $token = FreshRSS_Context::$user_conf->token;
     $token_param = Minz_Request::param('token', '');
     $token_is_ok = $token != '' && $token === $token_param;
     // Check if user has access.
     if (!FreshRSS_Auth::hasAccess() && !$allow_anonymous && !$token_is_ok) {
         Minz_Error::error(403);
     }
     try {
         $this->updateContext();
     } catch (FreshRSS_Context_Exception $e) {
         Minz_Error::error(404);
     }
     try {
         $this->view->entries = $this->listEntriesByContext();
     } catch (FreshRSS_EntriesGetter_Exception $e) {
         Minz_Log::notice($e->getMessage());
         Minz_Error::error(404);
     }
     // No layout for RSS output.
     $this->view->url = empty($_SERVER['QUERY_STRING']) ? '' : '?' . $_SERVER['QUERY_STRING'];
     $this->view->rss_title = FreshRSS_Context::$name . ' | ' . Minz_View::title();
     $this->view->_useLayout(false);
     header('Content-Type: application/rss+xml; charset=utf-8');
 }
Ejemplo n.º 18
0
 function pubSubHubbubSubscribe($state)
 {
     if (FreshRSS_Context::$system_conf->base_url && $this->hubUrl && $this->selfUrl) {
         $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;
         }
         $hubJson = json_decode($hubFile, true);
         if (!$hubJson || empty($hubJson['key']) || !ctype_xdigit($hubJson['key'])) {
             Minz_Log::warning('Invalid JSON for PubSubHubbub: ' . $this->url);
             return false;
         }
         $callbackUrl = checkUrl(FreshRSS_Context::$system_conf->base_url . 'api/pshb.php?k=' . $hubJson['key']);
         if ($callbackUrl == '') {
             Minz_Log::warning('Invalid callback for PubSubHubbub: ' . $this->url);
             return false;
         }
         $ch = curl_init();
         curl_setopt_array($ch, array(CURLOPT_URL => $this->hubUrl, CURLOPT_FOLLOWLOCATION => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_USERAGENT => _t('gen.freshrss') . '/' . FRESHRSS_VERSION . ' (' . PHP_OS . '; ' . FRESHRSS_WEBSITE . ')', CURLOPT_POSTFIELDS => 'hub.verify=sync' . '&hub.mode=' . ($state ? 'subscribe' : 'unsubscribe') . '&hub.topic=' . urlencode($this->selfUrl) . '&hub.callback=' . urlencode($callbackUrl)));
         $response = curl_exec($ch);
         $info = curl_getinfo($ch);
         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));
         }
         if (substr($info['http_code'], 0, 1) == '2') {
             return true;
         } else {
             $hubJson['lease_start'] = time();
             //Prevent trying again too soon
             $hubJson['error'] = true;
             file_put_contents($hubFilename, json_encode($hubJson));
             return false;
         }
     }
     return false;
 }
Ejemplo n.º 19
0
/**
 * Register and return the configuration for a given user.
 *
 * Note this function has been created to generate temporary configuration
 * objects. If you need a long-time configuration, please don't use this function.
 *
 * @param $username the name of the user of which we want the configuration.
 * @return a Minz_Configuration object, null if the configuration cannot be loaded.
 */
function get_user_configuration($username)
{
    $namespace = 'user_' . $username;
    try {
        Minz_Configuration::register($namespace, join_path(USERS_PATH, $username, 'config.php'), join_path(USERS_PATH, '_', 'config.default.php'));
    } catch (Minz_ConfigurationNamespaceException $e) {
        // namespace already exists, do nothing.
    } catch (Minz_FileNotExistException $e) {
        Minz_Log::warning($e->getMessage());
        return null;
    }
    return Minz_Configuration::get($namespace);
}
Ejemplo n.º 20
0
#
# ***** 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.';
    }
}
Ejemplo n.º 21
0
 private function accessControl($currentUser)
 {
     if ($currentUser == '') {
         switch (Minz_Configuration::authType()) {
             case 'form':
                 $currentUser = Minz_Configuration::defaultUser();
                 Minz_Session::_param('passwordHash');
                 $loginOk = false;
                 break;
             case 'http_auth':
                 $currentUser = httpAuthUser();
                 $loginOk = $currentUser != '';
                 break;
             case 'persona':
                 $loginOk = false;
                 $email = filter_var(Minz_Session::param('mail'), FILTER_VALIDATE_EMAIL);
                 if ($email != '') {
                     //TODO: Remove redundancy with indexController
                     $personaFile = DATA_PATH . '/persona/' . $email . '.txt';
                     if (($currentUser = @file_get_contents($personaFile)) !== false) {
                         $currentUser = trim($currentUser);
                         $loginOk = true;
                     }
                 }
                 if (!$loginOk) {
                     $currentUser = Minz_Configuration::defaultUser();
                 }
                 break;
             case 'none':
                 $currentUser = Minz_Configuration::defaultUser();
                 $loginOk = true;
                 break;
             default:
                 $currentUser = Minz_Configuration::defaultUser();
                 $loginOk = false;
                 break;
         }
     } else {
         $loginOk = true;
     }
     if (!ctype_alnum($currentUser)) {
         Minz_Session::_param('currentUser', '');
         die('Invalid username [' . $currentUser . ']!');
     }
     try {
         $this->conf = new FreshRSS_Configuration($currentUser);
         Minz_View::_param('conf', $this->conf);
         Minz_Session::_param('currentUser', $currentUser);
     } catch (Minz_Exception $me) {
         $loginOk = false;
         try {
             $this->conf = new FreshRSS_Configuration(Minz_Configuration::defaultUser());
             Minz_Session::_param('currentUser', Minz_Configuration::defaultUser());
             Minz_View::_param('conf', $this->conf);
             $notif = array('type' => 'bad', 'content' => 'Invalid configuration for user [' . $currentUser . ']!');
             Minz_Session::_param('notification', $notif);
             Minz_Log::record($notif['content'] . ' ' . $me->getMessage(), Minz_Log::WARNING);
             Minz_Session::_param('currentUser', '');
         } catch (Exception $e) {
             die($e->getMessage());
         }
     }
     if ($loginOk) {
         switch (Minz_Configuration::authType()) {
             case 'form':
                 $loginOk = Minz_Session::param('passwordHash') === $this->conf->passwordHash;
                 break;
             case 'http_auth':
                 $loginOk = strcasecmp($currentUser, httpAuthUser()) === 0;
                 break;
             case 'persona':
                 $loginOk = strcasecmp(Minz_Session::param('mail'), $this->conf->mail_login) === 0;
                 break;
             case 'none':
                 $loginOk = true;
                 break;
             default:
                 $loginOk = false;
                 break;
         }
     }
     Minz_View::_param('loginOk', $loginOk);
     return $loginOk;
 }
Ejemplo n.º 22
0
 /**
  * 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
  */
 public function param($key, $default = null)
 {
     if (isset($this->data[$key])) {
         return $this->data[$key];
     } elseif (!is_null($default)) {
         return $default;
     } else {
         Minz_Log::warning($key . ' does not exist in configuration');
         return null;
     }
 }
Ejemplo n.º 23
0
 public function importExportAction()
 {
     require_once LIB_PATH . '/lib_opml.php';
     $catDAO = new FreshRSS_CategoryDAO();
     $this->view->categories = $catDAO->listCategories();
     $this->view->req = Minz_Request::param('q');
     if ($this->view->req == 'export') {
         Minz_View::_title('freshrss_feeds.opml');
         $this->view->_useLayout(false);
         header('Content-Type: application/xml; charset=utf-8');
         header('Content-disposition: attachment; filename=freshrss_feeds.opml');
         $feedDAO = new FreshRSS_FeedDAO();
         $catDAO = new FreshRSS_CategoryDAO();
         $list = array();
         foreach ($catDAO->listCategories() as $key => $cat) {
             $list[$key]['name'] = $cat->name();
             $list[$key]['feeds'] = $feedDAO->listByCategory($cat->id());
         }
         $this->view->categories = $list;
     } elseif ($this->view->req == 'import' && Minz_Request::isPost()) {
         if ($_FILES['file']['error'] == 0) {
             invalidateHttpCache();
             // on parse le fichier OPML pour récupérer les catégories et les flux associés
             try {
                 list($categories, $feeds) = opml_import(file_get_contents($_FILES['file']['tmp_name']));
                 // On redirige vers le controller feed qui va se charger d'insérer les flux en BDD
                 // les flux sont mis au préalable dans des variables de Request
                 Minz_Request::_param('q', 'null');
                 Minz_Request::_param('categories', $categories);
                 Minz_Request::_param('feeds', $feeds);
                 Minz_Request::forward(array('c' => 'feed', 'a' => 'massiveImport'));
             } catch (FreshRSS_Opml_Exception $e) {
                 Minz_Log::record($e->getMessage(), Minz_Log::WARNING);
                 $notif = array('type' => 'bad', 'content' => Minz_Translate::t('bad_opml_file'));
                 Minz_Session::_param('notification', $notif);
                 Minz_Request::forward(array('c' => 'configure', 'a' => 'importExport'), true);
             }
         }
     }
     $feedDAO = new FreshRSS_FeedDAO();
     $this->view->feeds = $feedDAO->listFeeds();
     // au niveau de la vue, permet de ne pas voir un flux sélectionné dans la liste
     $this->view->flux = false;
     Minz_View::prependTitle(Minz_Translate::t('import_export_opml') . ' · ');
 }
Ejemplo n.º 24
0
#
# ***** END LICENSE BLOCK *****
if (file_exists('install.php')) {
    require 'install.php';
} else {
    require '../../constants.php';
    require LIB_PATH . '/lib_rss.php';
    //Includes class autoloader
    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(LOG_PATH . '/' . $currentUser . '.log'), @filemtime(DATA_PATH . '/config.php'));
        if (httpConditional($dateLastModification, 0, 0, false, false, 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::record($e->getMessage(), Minz_Log::ERROR);
        echo 'See logs files.';
    }
}
Ejemplo n.º 25
0
function clientLogin($email, $pass)
{
    //http://web.archive.org/web/20130604091042/http://undoc.in/clientLogin.html
    logMe('clientLogin(' . $email . ")\n");
    if (ctype_alnum($email)) {
        if (!function_exists('password_verify')) {
            include_once LIB_PATH . '/password_compat.php';
        }
        $conf = get_user_configuration($email);
        if (is_null($conf)) {
            Minz_Log::warning('Invalid API user ' . $email . ': configuration cannot be found.');
            unauthorized();
        }
        if ($conf->apiPasswordHash != '' && password_verify($pass, $conf->apiPasswordHash)) {
            header('Content-Type: text/plain; charset=UTF-8');
            $system_conf = Minz_Configuration::get('system');
            $auth = $email . '/' . sha1($system_conf->salt . $email . $conf->apiPasswordHash);
            echo 'SID=', $auth, "\n", 'Auth=', $auth, "\n";
            exit;
        } else {
            Minz_Log::warning('Password API mismatch for user ' . $email);
            unauthorized();
        }
    } else {
        badRequest();
    }
    die;
}
Ejemplo n.º 26
0
 public function cleanOldEntries($id, $date_min, $keep = 15)
 {
     //Remember to call updateLastUpdate($id) just after
     $sql = 'DELETE e.* FROM `' . $this->prefix . 'entry` e ' . 'WHERE e.id_feed = :id_feed AND e.id <= :id_max AND e.is_favorite = 0 AND e.id NOT IN ' . '(SELECT id FROM (SELECT e2.id FROM `' . $this->prefix . 'entry` e2 WHERE e2.id_feed = :id_feed ORDER BY id DESC LIMIT :keep) keep)';
     //Double select because of: MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
     $stm = $this->bd->prepare($sql);
     $id_max = intval($date_min) . '000000';
     $stm->bindParam(':id_feed', $id, PDO::PARAM_INT);
     $stm->bindParam(':id_max', $id_max, PDO::PARAM_INT);
     $stm->bindParam(':keep', $keep, PDO::PARAM_INT);
     if ($stm && $stm->execute()) {
         return $stm->rowCount();
     } else {
         $info = $stm->errorInfo();
         Minz_Log::record('SQL error : ' . $info[2], Minz_Log::ERROR);
         return false;
     }
 }
Ejemplo n.º 27
0
 /**
  * Load the extension source code based on info metadata.
  *
  * @param $info an array containing information about extension.
  * @return an extension inheriting from Minz_Extension.
  */
 public static function load($info)
 {
     $entry_point_filename = $info['path'] . '/' . self::$ext_entry_point;
     $ext_class_name = $info['entrypoint'] . 'Extension';
     include_once $entry_point_filename;
     // Test if the given extension class exists.
     if (!class_exists($ext_class_name)) {
         Minz_Log::warning('`' . $ext_class_name . '` cannot be found in `' . $entry_point_filename . '`');
         return null;
     }
     // Try to load the class.
     $extension = null;
     try {
         $extension = new $ext_class_name($info);
     } catch (Minz_ExtensionException $e) {
         // We cannot load the extension? Invalid!
         Minz_Log::warning('In `' . $metadata_filename . '`: ' . $e->getMessage());
         return null;
     }
     // Test if class is correct.
     if (!$extension instanceof Minz_Extension) {
         Minz_Log::warning('`' . $ext_class_name . '` is not an instance of `Minz_Extension`');
         return null;
     }
     return $extension;
 }
Ejemplo n.º 28
0
 public function updateLastSeen($id_feed, $guids)
 {
     if (count($guids) < 1) {
         return 0;
     }
     $sql = 'UPDATE `' . $this->prefix . 'entry` SET lastSeen=? WHERE id_feed=? AND guid IN (' . str_repeat('?,', count($guids) - 1) . '?)';
     $stm = $this->bd->prepare($sql);
     $values = array(time(), $id_feed);
     $values = array_merge($values, $guids);
     if ($stm && $stm->execute($values)) {
         return $stm->rowCount();
     } else {
         $info = $stm == null ? array(0 => '', 1 => '', 2 => 'syntax error') : $stm->errorInfo();
         if ($this->autoAddColumn($info)) {
             return $this->updateLastSeen($id_feed, $guids);
         }
         Minz_Log::error('SQL error updateLastSeen: ' . $info[0] . ': ' . $info[1] . ' ' . $info[2] . ' while updating feed ' . $id_feed);
         return false;
     }
 }
Ejemplo n.º 29
0
 /**
  * Mark all the articles in a category as read.
  * There is a fail safe to prevent to mark as read articles that are
  * loaded during the mark as read action. Then the cache is updated.
  *
  * If $idMax equals 0, a deprecated debug message is logged
  *
  * @param integer $id category ID
  * @param integer $idMax fail safe article ID
  * @return integer affected rows
  */
 public function markReadCat($id, $idMax = 0)
 {
     if ($idMax == 0) {
         $idMax = time() . '000000';
         Minz_Log::debug('Calling markReadCat(0) is deprecated!');
     }
     $sql = 'UPDATE `' . $this->prefix . 'entry` ' . 'SET is_read=1 ' . 'WHERE is_read=0 AND id <= ? AND ' . 'id_feed IN (SELECT f.id FROM `' . $this->prefix . 'feed` f WHERE f.category=?)';
     $values = array($idMax, $id);
     $stm = $this->bd->prepare($sql);
     if (!($stm && $stm->execute($values))) {
         $info = $stm == null ? array(2 => 'syntax error') : $stm->errorInfo();
         Minz_Log::error('SQL error markReadCat: ' . $info[2]);
         return false;
     }
     $affected = $stm->rowCount();
     if ($affected > 0 && !$this->updateCacheUnreads($id, false)) {
         return false;
     }
     return $affected;
 }
Ejemplo n.º 30
0
 public function purgeAction()
 {
     @set_time_limit(300);
     $nb_month_old = max($this->view->conf->old_entries, 1);
     $date_min = time() - 3600 * 24 * 30 * $nb_month_old;
     $feedDAO = new FreshRSS_FeedDAO();
     $feeds = $feedDAO->listFeedsOrderUpdate();
     $nbTotal = 0;
     invalidateHttpCache();
     foreach ($feeds as $feed) {
         $feedHistory = $feed->keepHistory();
         if ($feedHistory == -2) {
             //default
             $feedHistory = $this->view->conf->keep_history_default;
         }
         if ($feedHistory >= 0) {
             $nb = $feedDAO->cleanOldEntries($feed->id(), $date_min, $feedHistory);
             if ($nb > 0) {
                 $nbTotal += $nb;
                 Minz_Log::record($nb . ' old entries cleaned in feed [' . $feed->url() . ']', Minz_Log::DEBUG);
                 $feedDAO->updateLastUpdate($feed->id());
             }
         }
     }
     invalidateHttpCache();
     $notif = array('type' => 'good', 'content' => Minz_Translate::t('purge_completed', $nbTotal));
     Minz_Session::_param('notification', $notif);
     Minz_Request::forward(array('c' => 'configure', 'a' => 'archiving'), true);
 }