]> git.immae.eu Git - github/wallabag/wallabag.git/commitdiff
#4 - ajout système de connexion (login poche mot de passe poche pour l'instant)
authornicosomb <nicolas@loeuillet.org>
Thu, 18 Apr 2013 13:39:34 +0000 (15:39 +0200)
committernicosomb <nicolas@loeuillet.org>
Thu, 18 Apr 2013 13:39:34 +0000 (15:39 +0200)
15 files changed:
CREDITS
css/style.css
import.php
inc/MyTool.class.php [new file with mode: 0644]
inc/Session.class.php [new file with mode: 0644]
inc/config.php
inc/functions.php
inc/rain.tpl.class.php
index.php
tpl/entries.html
tpl/head.html
tpl/home.html
tpl/login.html [new file with mode: 0644]
tpl/view.html
view.php

diff --git a/CREDITS b/CREDITS
index 31e74bad5daaa8d2a6ef97f8f23765904049e066..c917a012df2b6d8e543d3fdcc2a4d2c334c69da5 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -5,6 +5,7 @@ poche is based on :
 * logo by Brightmix http://www.iconfinder.com/icondetails/43256/128/jeans_monotone_pocket_icon
 * icons http://icomoon.io
 * PHP Simple HTML DOM Parser (for Pocket import) http://simplehtmldom.sourceforge.net/
+* Session https://github.com/tontof/kriss_feed/blob/master/src/class/Session.php
 
 poche is developed by Nicolas Lœuillet under the Do What the Fuck You Want to Public License
 
index cf1ee2f028335f936a0af0e404f05fc309bb0d17..29dca289a25cae99fb21820652f8ce70cd76b5bf 100644 (file)
@@ -62,16 +62,15 @@ header {
     color: #F1F1F1;
 }
 
-/*#content {
-    width: 800px;
-    margin: 0 auto;
-}*/
-
-
 footer {
     text-align: right;
 }
 
+/*** ***/
+/*** LOGIN FORM ***/
+ul#login li {
+    list-style-type: none;
+}
 /*** ***/
 /*** LINKS DISPLAY ***/
 
index 135443c9a4746517b339b07b6df37d9547b75769..72e3eac7696974177e765211d3aadfee25c5c282 100644 (file)
@@ -30,7 +30,7 @@ else {
             $url = $a[0]->href;
 
 
-            action_to_do('add', $url, $token);
+            action_to_do('add', $url);
             if ($read == '1') {
                 $last_id = $db->getHandle()->lastInsertId();
                 $sql_update     = "UPDATE entries SET is_read=~is_read WHERE id=?";
diff --git a/inc/MyTool.class.php b/inc/MyTool.class.php
new file mode 100644 (file)
index 0000000..8206f3f
--- /dev/null
@@ -0,0 +1,256 @@
+<?php
+class MyTool
+{
+    public static function initPhp()
+    {
+        define('START_TIME', microtime(true));
+
+        if (phpversion() < 5) {
+            die("Argh you don't have PHP 5 !");
+        }
+
+        error_reporting(E_ALL);
+
+        function stripslashesDeep($value) {
+            return is_array($value)
+                ? array_map('stripslashesDeep', $value)
+                : stripslashes($value);
+        }
+
+        if (get_magic_quotes_gpc()) {
+            $_POST = array_map('stripslashesDeep', $_POST);
+            $_GET = array_map('stripslashesDeep', $_GET);
+            $_COOKIE = array_map('stripslashesDeep', $_COOKIE);
+        }
+
+        ob_start();
+        register_shutdown_function('ob_end_flush');
+    }
+
+    public static function isUrl($url)
+    {
+        // http://neo22s.com/check-if-url-exists-and-is-online-php/
+        $pattern='|^http(s)?://[a-z0-9-]+(.[a-z0-9-]+)*(:[0-9]+)?(/.*)?$|i';
+
+        return preg_match($pattern, $url);
+    }
+
+    public static function isEmail($email)
+    {
+        $pattern = "/^[A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2, 4}$/i";
+
+        return (preg_match($pattern, $email));
+    }
+
+    public static function formatBBCode($text)
+    {
+        $replace = array(
+            '/\[m\](.+?)\[\/m\]/is'
+            => '/* moderate */',
+            '/\[b\](.+?)\[\/b\]/is'
+            => '<strong>$1</strong>',
+            '/\[i\](.+?)\[\/i\]/is'
+            => '<em>$1</em>',
+            '/\[s\](.+?)\[\/s\]/is'
+            => '<del>$1</del>',
+            '/\[u\](.+?)\[\/u\]/is'
+            => '<span style="text-decoration: underline;">$1</span>',
+            '/\[url\](.+?)\[\/url]/is'
+            => '<a href="$1">$1</a>',
+            '/\[url=(\w+:\/\/[^\]]+)\](.+?)\[\/url]/is'
+            => '<a href="$1">$2</a>',
+            '/\[quote\](.+?)\[\/quote\]/is'
+            => '<blockquote>$1</blockquote>',
+            '/\[code\](.+?)\[\/code\]/is'
+            => '<code>$1</code>',
+            '/\[([^[]+)\|([^[]+)\]/is'
+            => '<a href="$2">$1</a>'
+            );
+        $text = preg_replace(
+            array_keys($replace),
+            array_values($replace),
+            $text
+        );
+
+        return $text;
+    }
+
+    public static function formatText($text)
+    {
+        $text = preg_replace_callback(
+            '/<code_html>(.*?)<\/code_html>/is',
+            create_function(
+                '$matches',
+                'return htmlspecialchars($matches[1]);'
+            ),
+            $text
+        );
+        $text = preg_replace_callback(
+            '/<code_php>(.*?)<\/code_php>/is',
+            create_function(
+                '$matches',
+                'return highlight_string("<?php $matches[1] ?>", true);'
+            ),
+            $text
+        );
+        $text = preg_replace('/<br \/>/is', '', $text);
+
+        $text = preg_replace(
+            '#(^|\s)([a-z]+://([^\s\w/]?[\w/])*)(\s|$)#im',
+            '\\1<a href="\\2">\\2</a>\\4',
+            $text
+        );
+        $text = preg_replace(
+            '#(^|\s)wp:?([a-z]{2}|):([\w]+)#im',
+            '\\1<a href="http://\\2.wikipedia.org/wiki/\\3">\\3</a>',
+            $text
+        );
+        $text = str_replace(
+            'http://.wikipedia.org/wiki/',
+            'http://www.wikipedia.org/wiki/',
+            $text
+        );
+        $text = str_replace('\wp:', 'wp:', $text);
+        $text = str_replace('\http:', 'http:', $text);
+        $text = MyTool::formatBBCode($text);
+        $text = nl2br($text);
+
+        return $text;
+    }
+
+    public static function getUrl()
+    {
+        $https = (!empty($_SERVER['HTTPS'])
+                  && (strtolower($_SERVER['HTTPS']) == 'on'))
+            || (isset($_SERVER["SERVER_PORT"])
+                && $_SERVER["SERVER_PORT"] == '443'); // HTTPS detection.
+        $serverport = (!isset($_SERVER["SERVER_PORT"])
+                       || $_SERVER["SERVER_PORT"] == '80'
+                       || ($https && $_SERVER["SERVER_PORT"] == '443')
+                       ? ''
+                       : ':' . $_SERVER["SERVER_PORT"]);
+
+        $scriptname = str_replace('/index.php', '/', $_SERVER["SCRIPT_NAME"]);
+
+        if (!isset($_SERVER["SERVER_NAME"])) {
+            return $scriptname;
+        }
+
+        return 'http' . ($https ? 's' : '') . '://'
+            . $_SERVER["SERVER_NAME"] . $serverport . $scriptname;
+    }
+
+    public static function rrmdir($dir)
+    {
+        if (is_dir($dir) && ($d = @opendir($dir))) {
+            while (($file = @readdir($d)) !== false) {
+                if ( $file == '.' || $file == '..' ) {
+                    continue;
+                } else {
+                    unlink($dir . '/' . $file);
+                }
+            }
+        }
+    }
+
+    public static function humanBytes($bytes)
+    {
+        $siPrefix = array( 'bytes', 'KB', 'MB', 'GB', 'TB', 'EB', 'ZB', 'YB' );
+        $base = 1024;
+        $class = min((int) log($bytes, $base), count($siPrefix) - 1);
+        $val = sprintf('%1.2f', $bytes / pow($base, $class));
+
+        return $val . ' ' . $siPrefix[$class];
+    }
+
+    public static function returnBytes($val)
+    {
+        $val = trim($val);
+        $last = strtolower($val[strlen($val)-1]);
+        switch($last)
+        {
+        case 'g': $val *= 1024;
+        case 'm': $val *= 1024;
+        case 'k': $val *= 1024;
+        }
+
+        return $val;
+    }
+
+    public static function getMaxFileSize()
+    {
+        $sizePostMax = MyTool::returnBytes(ini_get('post_max_size'));
+        $sizeUploadMax = MyTool::returnBytes(ini_get('upload_max_filesize'));
+
+        // Return the smaller of two:
+        return min($sizePostMax, $sizeUploadMax);
+    }
+
+    public static function smallHash($text)
+    {
+        $t = rtrim(base64_encode(hash('crc32', $text, true)), '=');
+        // Get rid of characters which need encoding in URLs.
+        $t = str_replace('+', '-', $t);
+        $t = str_replace('/', '_', $t);
+        $t = str_replace('=', '@', $t);
+
+        return $t;
+    }
+
+    public static function renderJson($data)
+    {
+        header('Cache-Control: no-cache, must-revalidate');
+        header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
+        header('Content-type: application/json; charset=UTF-8');
+
+        echo json_encode($data);
+        exit();
+    }
+
+    public static function grabToLocal($url, $file, $force = false)
+    {
+        if ((!file_exists($file) || $force) && in_array('curl', get_loaded_extensions())){
+            $ch = curl_init ($url);
+            curl_setopt($ch, CURLOPT_HEADER, false);
+            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+            curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
+            $raw = curl_exec($ch);
+            if (curl_getinfo($ch, CURLINFO_HTTP_CODE) == 200) {
+                $fp = fopen($file, 'x');
+                fwrite($fp, $raw);
+                fclose($fp);
+            }
+            curl_close ($ch);
+        }
+    }
+
+    public static function redirect($rurl = '')
+    {
+        if ($rurl === '') {
+            // if (!empty($_SERVER['HTTP_REFERER']) && strcmp(parse_url($_SERVER['HTTP_REFERER'],PHP_URL_HOST),$_SERVER['SERVER_NAME'])==0)
+            $rurl = (empty($_SERVER['HTTP_REFERER'])?'?':$_SERVER['HTTP_REFERER']);
+            if (isset($_POST['returnurl'])) {
+                $rurl = $_POST['returnurl'];
+            }
+        }
+
+        // prevent loop
+        if (empty($rurl) || parse_url($rurl, PHP_URL_QUERY) === $_SERVER['QUERY_STRING']) {
+            $rurl = MyTool::getUrl();
+        }
+
+        if (substr($rurl, 0, 1) !== '?') {
+            $ref = MyTool::getUrl();
+            if (substr($rurl, 0, strlen($ref)) !== $ref) {
+                $rurl = $ref;
+            }
+        }
+        header('Location: '.$rurl);
+        exit();
+    }
+
+    public static function silence_errors($num, $str)
+    {
+// No-op
+    }
+}
\ No newline at end of file
diff --git a/inc/Session.class.php b/inc/Session.class.php
new file mode 100644 (file)
index 0000000..06fa6a8
--- /dev/null
@@ -0,0 +1,136 @@
+<?php
+/**
+ * Session management class
+ * http://www.developpez.net/forums/d51943/php/langage/sessions/
+ * http://sebsauvage.net/wiki/doku.php?id=php:session
+ * http://sebsauvage.net/wiki/doku.php?id=php:shaarli
+ *
+ * Features:
+ * - Everything is stored on server-side (we do not trust client-side data,
+ *   such as cookie expiration)
+ * - IP addresses + user agent are checked on each access to prevent session
+ *   cookie hijacking (such as Firesheep)
+ * - Session expires on user inactivity (Session expiration date is
+ *   automatically updated everytime the user accesses a page.)
+ * - A unique secret key is generated on server-side for this session
+ *   (and never sent over the wire) which can be used
+ *   to sign forms (HMAC) (See $_SESSION['uid'] )
+ * - Token management to prevent XSRF attacks.
+ *
+ * TODO:
+ * - log login fail
+ * - prevent brute force (ban IP)
+ *
+ * HOWTOUSE:
+ * - Just call Session::init(); to initialize session and
+ *   check if connected with Session::isLogged()
+ */
+
+class Session
+{
+    // If the user does not access any page within this time,
+    // his/her session is considered expired (in seconds).
+    public static $inactivity_timeout = 3600;
+    private static $_instance;
+
+    // constructor
+    private function __construct()
+    {
+        // Use cookies to store session.
+        ini_set('session.use_cookies', 1);
+        // Force cookies for session  (phpsessionID forbidden in URL)
+        ini_set('session.use_only_cookies', 1);
+        if (!session_id()){
+            // Prevent php to use sessionID in URL if cookies are disabled.
+            ini_set('session.use_trans_sid', false);
+            session_start('poche');
+        }
+    }
+
+    // initialize session
+    public static function init()
+    {
+        if (!isset(self::$_instance)) {
+            self::$_instance = new Session();
+        }
+    }
+
+    // Returns the IP address, user agent and language of the client
+    // (Used to prevent session cookie hijacking.)
+    private static function _allInfos()
+    {
+        $infos = $_SERVER["REMOTE_ADDR"];
+        if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
+            $infos.=$_SERVER['HTTP_X_FORWARDED_FOR'];
+        }
+        if (isset($_SERVER['HTTP_CLIENT_IP'])) {
+            $infos.='_'.$_SERVER['HTTP_CLIENT_IP'];
+        }
+        $infos.='_'.$_SERVER['HTTP_USER_AGENT'];
+        $infos.='_'.$_SERVER['HTTP_ACCEPT_LANGUAGE'];
+        return sha1($infos);
+    }
+
+    // Check that user/password is correct and init some SESSION variables.
+    public static function login($login,$password,$login_test,$password_test,
+                                 $pValues = array())
+    {
+        foreach ($pValues as $key => $value) {
+            $_SESSION[$key] = $value;
+        }
+        if ($login==$login_test && $password==$password_test){
+            // generate unique random number to sign forms (HMAC)
+            $_SESSION['uid'] = sha1(uniqid('',true).'_'.mt_rand());
+            $_SESSION['info']=Session::_allInfos();
+            $_SESSION['username']=$login;
+            // Set session expiration.
+            $_SESSION['expires_on']=time()+Session::$inactivity_timeout;
+            return true;
+        }
+        return false;
+    }
+
+    // Force logout
+    public static function logout()
+    {
+        unset($_SESSION['uid'],$_SESSION['info'],$_SESSION['expires_on']);
+    }
+
+    // Make sure user is logged in.
+    public static function isLogged()
+    {
+        if (!isset ($_SESSION['uid'])
+            || $_SESSION['info']!=Session::_allInfos()
+            || time()>=$_SESSION['expires_on']){
+            Session::logout();
+            return false;
+        }
+        // User accessed a page : Update his/her session expiration date.
+        $_SESSION['expires_on']=time()+Session::$inactivity_timeout;
+        return true;
+    }
+
+    // Returns a token.
+    public static function getToken()
+    {
+        if (!isset($_SESSION['tokens'])){
+            $_SESSION['tokens']=array();
+        }
+        // We generate a random string and store it on the server side.
+        $rnd = sha1(uniqid('',true).'_'.mt_rand());
+        $_SESSION['tokens'][$rnd]=1;
+        return $rnd;
+    }
+
+    // Tells if a token is ok. Using this function will destroy the token.
+    // return true if token is ok.
+    public static function isToken($token)
+    {
+        if (isset($_SESSION['tokens'][$token]))
+        {
+            unset($_SESSION['tokens'][$token]); // Token is used: destroy it.
+            return true; // Token is ok.
+        }
+        return false; // Wrong token, or already used.
+    }
+}
\ No newline at end of file
index 386fd0360fb941f193b86ef39aef04a9d8e1410e..403217ce6d95d1defb675909a534cbaf28e29ea3 100644 (file)
@@ -22,10 +22,12 @@ include 'functions.php';
 require_once 'Readability.php';
 require_once 'Encoding.php';
 require_once 'rain.tpl.class.php';
+require_once 'MyTool.class.php';
+require_once 'Session.class.php';
 
 $db = new db(DB_PATH);
 
-# Initialisation de RainTPL
+# initialisation de RainTPL
 raintpl::$tpl_dir   = './tpl/';
 raintpl::$cache_dir = './cache/';
 raintpl::$base_url  = get_poche_url();
@@ -33,13 +35,43 @@ raintpl::configure('path_replace', false);
 raintpl::configure('debug', false);
 $tpl = new raintpl();
 
-# Démarrage session et initialisation du jeton de sécurité
-session_start();
+# initialize session
+Session::init();
+# XSRF protection with token
+if (!empty($_POST)) {
+    if (!Session::isToken($_POST['token'])) {
+        die('Wrong token.');
+    }
+    unset($_SESSION['tokens']);
+}
+
+$ref = empty($_SERVER['HTTP_REFERER']) ? '' : $_SERVER['HTTP_REFERER'];
+
+if (isset($_GET['login'])) {
+    // Login
+    if (!empty($_POST['login']) && !empty($_POST['password'])) {
+        if (Session::login('poche', 'poche', $_POST['login'], $_POST['password'])) {
+            if (!empty($_POST['longlastingsession'])) {
+                $_SESSION['longlastingsession'] = 31536000;
+                $_SESSION['expires_on'] = time() + $_SESSION['longlastingsession'];
+                session_set_cookie_params($_SESSION['longlastingsession']);
+            } else {
+                session_set_cookie_params(0); // when browser closes
+            }
+            session_regenerate_id(true);
 
-if (!isset($_SESSION['token_poche'])) {
-    $token = md5(uniqid(rand(), TRUE));
-    $_SESSION['token_poche'] = $token;
-    $_SESSION['token_time_poche'] = time();
+            MyTool::redirect();
+        }
+        logm('login failed');
+        die("Login failed !");
+    } else {
+        logm('login successful');
+    }
+}
+elseif (isset($_GET['logout'])) {
+    logm('logout');
+    Session::logout();
+    MyTool::redirect();
 }
 
 # Traitement des paramètres et déclenchement des actions
@@ -48,8 +80,12 @@ $action             = (isset ($_REQUEST['action'])) ? htmlentities($_REQUEST['ac
 $_SESSION['sort']   = (isset ($_REQUEST['sort'])) ? htmlentities($_REQUEST['sort']) : 'id';
 $id                 = (isset ($_REQUEST['id'])) ? htmlspecialchars($_REQUEST['id']) : '';
 $url                = (isset ($_GET['url'])) ? $_GET['url'] : '';
-$token              = (isset ($_REQUEST['token'])) ? $_REQUEST['token'] : '';
+
+$tpl->assign('isLogged', Session::isLogged());
+$tpl->assign('referer', $ref);
+$tpl->assign('view', $view);
+$tpl->assign('poche_url', get_poche_url());
 
 if ($action != '') {
-    action_to_do($action, $url, $token, $id);
+    action_to_do($action, $url, $id);
 }
index 936ec6ea8d4f44f7fce3c37c7d57899215792a68..13acd36f30840d88675b0e7144c9df27a5cf0392 100644 (file)
@@ -91,7 +91,7 @@ function get_external_file($url)
 function prepare_url($url)
 {
     $parametres = array();
-    $url    = html_entity_decode(trim($url));
+    $url        = html_entity_decode(trim($url));
 
     // We remove the annoying parameters added by FeedBurner and GoogleFeedProxy (?utm_source=...)
     // from shaarli, by sebsauvage
@@ -99,7 +99,7 @@ function prepare_url($url)
     $i=strpos($url,'?utm_source='); if ($i!==false) $url=substr($url,0,$i);
     $i=strpos($url,'#xtor=RSS-'); if ($i!==false) $url=substr($url,0,$i);
 
-    $title  = $url;
+    $title = $url;
     if (!preg_match('!^https?://!i', $url))
         $url = 'http://' . $url;
 
@@ -230,7 +230,7 @@ function remove_directory($directory)
  * Appel d'une action (mark as fav, archive, delete)
  */
 
-function action_to_do($action, $url, $token, $id = 0)
+function action_to_do($action, $url, $id = 0)
 {
     global $db;
 
@@ -248,29 +248,20 @@ function action_to_do($action, $url, $token, $id = 0)
             logm('add link ' . $url);
             break;
         case 'delete':
-            if (verif_token($token)) {
-                remove_directory(ABS_PATH . $id);
-                $sql_action     = "DELETE FROM entries WHERE id=?";
-                $params_action  = array($id);
-                logm('delete link #' . $id);
-            }
-            else logm('csrf problem while deleting entry');
+            remove_directory(ABS_PATH . $id);
+            $sql_action     = "DELETE FROM entries WHERE id=?";
+            $params_action  = array($id);
+            logm('delete link #' . $id);
             break;
         case 'toggle_fav' :
-            if (verif_token($token)) {
-                $sql_action     = "UPDATE entries SET is_fav=~is_fav WHERE id=?";
-                $params_action  = array($id);
-                logm('mark as favorite link #' . $id);
-            }
-            else logm('csrf problem while fav entry');
+            $sql_action     = "UPDATE entries SET is_fav=~is_fav WHERE id=?";
+            $params_action  = array($id);
+            logm('mark as favorite link #' . $id);
             break;
         case 'toggle_archive' :
-            if (verif_token($token)) {
-                $sql_action     = "UPDATE entries SET is_read=~is_read WHERE id=?";
-                $params_action  = array($id);
-                logm('archive link #' . $id);
-            }
-            else logm('csrf problem while archive entry');
+            $sql_action     = "UPDATE entries SET is_read=~is_read WHERE id=?";
+            $params_action  = array($id);
+            logm('archive link #' . $id);
             break;
         default:
             break;
@@ -305,7 +296,7 @@ function action_to_do($action, $url, $token, $id = 0)
 /**
  * Détermine quels liens afficher : home, fav ou archives
  */
-function display_view($view)
+function get_entries($view)
 {
     global $db;
 
@@ -385,36 +376,6 @@ function get_article($id)
     return $entry;
 }
 
-/**
- * Vérifie si le jeton passé en $_POST correspond à celui en session
- */
-function verif_token($token)
-{
-    if(isset($_SESSION['token_poche']) && isset($_SESSION['token_time_poche']) && isset($token))
-    {
-        if($_SESSION['token_poche'] == $token)
-        {
-            $old_timestamp = time() - (15*60);
-            if($_SESSION['token_time_poche'] >= $old_timestamp)
-            {
-                return TRUE;
-            }
-            else {
-                session_destroy();
-                logm('session expired');
-            }
-        }
-        else {
-            logm('token error : the token is different');
-            return FALSE;
-        }
-    }
-    else {
-        logm('token error : the token is not here');
-        return FALSE;
-    }
-}
-
 function logm($message)
 {
     $t = strval(date('Y/m/d_H:i:s')).' - '.$_SERVER["REMOTE_ADDR"].' - '.strval($message)."\n";
index ea83b2c19ec991946f7571ed4a0b6853896d238a..6522c7985d92de3020e480c3fa23832ff300c332 100644 (file)
@@ -81,18 +81,18 @@ class RainTPL{
                 *
                 */
                static $check_template_update = true;
-                
+
 
                /**
-                * PHP tags <? ?> 
+                * PHP tags <? ?>
                 * True: php tags are enabled into the template
                 * False: php tags are disabled into the template and rendered as html
                 *
                 * @var bool
                 */
-               static $php_enabled = false;
+               static $php_enabled = true;
+
 
-               
                /**
                 * Debug mode flag.
                 * True: debug mode is used, syntax errors are displayed directly in template. Execution of script is not terminated.
@@ -285,7 +285,7 @@ class RainTPL{
        */
        protected function xml_reSubstitution($capture) {
                return "<?php echo '<?xml ".stripslashes($capture[1])." ?>'; ?>";
-       } 
+       }
 
        /**
         * Compile and write the compiled template file
@@ -304,11 +304,11 @@ class RainTPL{
                        $template_code = str_replace( array("<?","?>"), array("&lt;?","?&gt;"), $template_code );
 
                //xml re-substitution
-               $template_code = preg_replace_callback ( "/##XML(.*?)XML##/s", array($this, 'xml_reSubstitution'), $template_code ); 
+               $template_code = preg_replace_callback ( "/##XML(.*?)XML##/s", array($this, 'xml_reSubstitution'), $template_code );
 
                //compile template
                $template_compiled = "<?php if(!class_exists('raintpl')){exit;}?>" . $this->compileTemplate( $template_code, $tpl_basedir );
-               
+
 
                // fix the php-eating-newline-after-closing-tag-problem
                $template_compiled = str_replace( "?>\n", "?>\n\n", $template_compiled );
@@ -413,7 +413,7 @@ class RainTPL{
 
                                // if the cache is active
                                if( isset($code[ 2 ]) ){
-                                       
+
                                        //dynamic include
                                        $compiled_code .= '<?php $tpl = new '.get_class($this).';' .
                                                                 'if( $cache = $tpl->cache( $template = basename("'.$include_var.'") ) )' .
@@ -426,7 +426,7 @@ class RainTPL{
                                                                 '} ?>';
                                }
                                else{
-       
+
                                        //dynamic include
                                        $compiled_code .= '<?php $tpl = new '.get_class($this).';' .
                                                                          '$tpl_dir_temp = self::$tpl_dir;' .
@@ -434,8 +434,8 @@ class RainTPL{
                                                                          ( !$loop_level ? null : '$tpl->assign( "key", $key'.$loop_level.' ); $tpl->assign( "value", $value'.$loop_level.' );' ).
                                                                          '$tpl->draw( dirname("'.$include_var.'") . ( substr("'.$include_var.'",-1,1) != "/" ? "/" : "" ) . basename("'.$include_var.'") );'.
                                                                          '?>';
-                                       
-                                       
+
+
                                }
 
                        }
@@ -548,7 +548,7 @@ class RainTPL{
                                else
                                        // parse the function
                                        $parsed_function = $function . $this->var_replace( $code[ 2 ], $tag_left_delimiter = null, $tag_right_delimiter = null, $php_left_delimiter = null, $php_right_delimiter = null, $loop_level );
-                               
+
                                //if code
                                $compiled_code .=   "<?php echo $parsed_function; ?>";
                        }
@@ -582,8 +582,8 @@ class RainTPL{
                }
                return $compiled_code;
        }
-       
-       
+
+
        /**
         * Reduce a path, eg. www/library/../filepath//file => www/filepath/file
         * @param type $path
@@ -612,7 +612,7 @@ class RainTPL{
                if( self::$path_replace ){
 
                        $tpl_dir = self::$base_url . self::$tpl_dir . $tpl_basedir;
-                       
+
                        // reduce the path
                        $path = $this->reduce_path($tpl_dir);
 
@@ -683,7 +683,7 @@ class RainTPL{
                        $this->function_check( $tag );
 
                        $extra_var = $this->var_replace( $extra_var, null, null, null, null, $loop_level );
-            
+
 
                        // check if there's an operator = in the variable tags, if there's this is an initialization so it will not output any value
                        $is_init_variable = preg_match( "/^(\s*?)\=[^=](.*?)$/", $extra_var );
@@ -712,7 +712,7 @@ class RainTPL{
 
                        //if there's a function
                        if( $function_var ){
-                
+
                 // check if there's a function or a static method and separate, function by parameters
                                $function_var = str_replace("::", "@double_dot@", $function_var );
 
@@ -786,7 +786,7 @@ class RainTPL{
 
                             // check if there's an operator = in the variable tags, if there's this is an initialization so it will not output any value
                             $is_init_variable = preg_match( "/^[a-z_A-Z\.\[\](\-\>)]*=[^=]*$/", $extra_var );
-                            
+
                             //function associate to variable
                             $function_var = ( $extra_var and $extra_var[0] == '|') ? substr( $extra_var, 1 ) : null;
 
@@ -805,16 +805,16 @@ class RainTPL{
 
                             //transform .$variable in ["$variable"] and .variable in ["variable"]
                             $variable_path = preg_replace('/\.(\${0,1}\w+)/', '["\\1"]', $variable_path );
-                            
+
                             // if is an assignment also assign the variable to $this->var['value']
                             if( $is_init_variable )
                                 $extra_var = "=\$this->var['{$var_name}']{$variable_path}" . $extra_var;
 
-                                
+
 
                             //if there's a function
                             if( $function_var ){
-                                
+
                                     // check if there's a function or a static method and separate, function by parameters
                                     $function_var = str_replace("::", "@double_dot@", $function_var );
 
@@ -855,13 +855,13 @@ class RainTPL{
                                             $php_var = '$' . $var_name . $variable_path;
                             }else
                                     $php_var = '$' . $var_name . $variable_path;
-                            
+
                             // compile the variable for php
                             if( isset( $function ) )
                                     $php_var = $php_left_delimiter . ( !$is_init_variable && $echo ? 'echo ' : null ) . ( $params ? "( $function( $php_var, $params ) )" : "$function( $php_var )" ) . $php_right_delimiter;
                             else
                                     $php_var = $php_left_delimiter . ( !$is_init_variable && $echo ? 'echo ' : null ) . $php_var . $extra_var . $php_right_delimiter;
-                            
+
                             $html = str_replace( $tag, $php_var, $html );
 
 
index d0d008ed4799e99c2aba869edb2977f4bfd79e02..995426b456b8b6cdfe33a66c1711a3ce3d452b8f 100644 (file)
--- a/index.php
+++ b/index.php
 
 include dirname(__FILE__).'/inc/config.php';
 
-$entries = display_view($view);
+$entries = get_entries($view);
 
 $tpl->assign('title', 'poche, a read it later open source system');
-$tpl->assign('view', $view);
-$tpl->assign('poche_url', get_poche_url());
 $tpl->assign('entries', $entries);
 $tpl->assign('load_all_js', 1);
-$tpl->assign('token', $_SESSION['token_poche']);
 
 $tpl->draw('head');
-$tpl->draw('home');
-$tpl->draw('entries');
-$tpl->draw('js');
-$tpl->draw('footer');
+if (Session::isLogged()) {
+    $tpl->draw('home');
+    $tpl->draw('entries');
+    $tpl->draw('js');
+}
+else {
+    $tpl->draw('login');
+}
+$tpl->draw('footer');
\ No newline at end of file
index 0d3e6bc0c5f42e617b23bfe7cf9944e62722bd69..c74bc34672054ac69194326a8173cc01a40aae1a 100644 (file)
@@ -6,9 +6,9 @@
                             </h2>
                             <div class="tools">
                                 <ul>
-                                    <li><a title="toggle mark as read" class="tool archive {if="$value.is_read == '0'"}archive-off{/if}" onclick="toggle_archive(this, {$value.id}, '{$token}')"><span></span></a></li>
-                                    <li><a title="toggle favorite" class="tool fav {if="$value.is_fav == '0'"}fav-off{/if}" onclick="toggle_favorite(this, {$value.id}, '{$token}')"><span></span></a></li>
-                                    <li><form method="post" onsubmit="return confirm('Are you sure?')" style="display: inline;"><input type="hidden" name="token" id="token" value="{$token}" /><input type="hidden" id="action" name="action" value="delete" /><input type="hidden" id="id" name="id" value="{$value.id}" /><input type="submit" class="delete" title="toggle delete" /></form></li>
+                                    <li><a title="toggle mark as read" class="tool archive {if="$value.is_read == '0'"}archive-off{/if}" onclick="toggle_archive(this, {$value.id}, '<?php echo Session::getToken(); ?>')"><span></span></a></li>
+                                    <li><a title="toggle favorite" class="tool fav {if="$value.is_fav == '0'"}fav-off{/if}" onclick="toggle_favorite(this, {$value.id}, '<?php echo Session::getToken(); ?>')"><span></span></a></li>
+                                    <li><form method="post" onsubmit="return confirm('Are you sure?')" style="display: inline;"><input type="hidden" name="token" id="token" value="<?php echo Session::getToken(); ?>" /><input type="hidden" id="action" name="action" value="delete" /><input type="hidden" id="id" name="id" value="{$value.id}" /><input type="submit" class="delete" title="toggle delete" /></form></li>
                                 </ul>
                             </div>
                         </span>
index 66150d8f8ffc3243020001f103b87f8e9d4e05bd..6fcf9741967e19ba20b5e060312d6fbbac67526b 100644 (file)
@@ -15,4 +15,9 @@
         <link rel="apple-touch-icon-precomposed" href="./img/apple-touch-icon-precomposed.png">
         <link rel="stylesheet" href="./css/knacss.css" media="all">
         <link rel="stylesheet" href="./css/style.css" media="all">
-    </head>
\ No newline at end of file
+    </head>
+    <body>
+        <header>
+            <h1><img src="./img/logo.png" alt="logo poche" />poche</h1>
+        </header>
+        <div id="main">
\ No newline at end of file
index 568b9274d45f1530ad20426a38cdf9f1c7df2501..216f39b9bec09e12f12d886fb90331ed205adb17 100644 (file)
@@ -1,16 +1,12 @@
-    <body>
-        <header>
-            <h1><img src="./img/logo.png" alt="logo poche" />poche</h1>
-        </header>
-        <div id="main">
             <ul id="links">
                 <li><a href="index.php" {if="$view == 'index'"}class="current"{/if}>home</a></li>
                 <li><a href="?view=fav" {if="$view == 'fav'"}class="current"{/if}>favorites</a></li>
                 <li><a href="?view=archive" {if="$view == 'archive'"}class="current"{/if}>archive</a></li>
                 <li><a style="cursor: move" title="i am a bookmarklet, use me !" href="javascript:(function(){var%20url%20=%20location.href%20||%20url;window.open('{$poche_url}?action=add&url='%20+%20encodeURIComponent(url),'_self');})();">poche it !</a></li>
+                <li><a href="?logout" title="Logout">logout</a></li>
             </ul>
             <ul id="sort">
-                <li><img src="img/up.png" onclick="sort_links('{$view}', 'ia', '{$token}');" title="by date asc" /> by date <img src="img/down.png" onclick="sort_links('{$view}', 'id', '{$token}');" title="by date desc" /></li>
-                <li><img src="img/up.png" onclick="sort_links('{$view}', 'ta', '{$token}');" title="by title asc" /> by title <img src="img/down.png" onclick="sort_links('{$view}', 'td', '{$token}');" title="by title desc" /></li>
+                <li><img src="img/up.png" onclick="sort_links('{$view}', 'ia', '{'<?php echo Session::getToken(); ?>'}');" title="by date asc" /> by date <img src="img/down.png" onclick="sort_links('{$view}', 'id', '<?php echo Session::getToken(); ?>');" title="by date desc" /></li>
+                <li><img src="img/up.png" onclick="sort_links('{$view}', 'ta', '<?php echo Session::getToken(); ?>');" title="by title asc" /> by title <img src="img/down.png" onclick="sort_links('{$view}', 'td', '<?php echo Session::getToken(); ?>');" title="by title desc" /></li>
             </ul>
             <div id="content">
\ No newline at end of file
diff --git a/tpl/login.html b/tpl/login.html
new file mode 100644 (file)
index 0000000..024b3fd
--- /dev/null
@@ -0,0 +1,13 @@
+            <form method="post" action="?login" name="loginform">
+            <fieldset>
+            <h2>login to your poche</h2>
+            <ul id="login">
+                <li><label for="login">Login</label> <input type="text" id="login" name="login" placeholder="Login" tabindex="1"></li>
+                <li><label for="password">Password</label> <input type="password" id="password" name="password" placeholder="Password" tabindex="2"></li>
+                <li><label><input type="checkbox" name="longlastingsession" tabindex="3">&nbsp;Stay signed in (Do not check on public computers)</label></li>
+                <li><button type="submit" tabindex="4">Sign in</button></li>
+            </ul>
+            </fieldset>
+            <input type="hidden" name="returnurl" value="<?php echo htmlspecialchars($referer);?>">
+            <input type="hidden" name="token" value="<?php echo Session::getToken(); ?>">
+            </form>
\ No newline at end of file
index 3a1ba7c6510ab10560c26bad123d2fd394df4379..1191bd8234e8301796e8dc641a213825521ce90d 100644 (file)
@@ -1,4 +1,21 @@
-{include="head"}
+<!DOCTYPE html>
+<!--[if lte IE 6]> <html class="no-js ie6 ie67 ie678" lang="en"> <![endif]-->
+<!--[if lte IE 7]> <html class="no-js ie7 ie67 ie678" lang="en"> <![endif]-->
+<!--[if IE 8]> <html class="no-js ie8 ie678" lang="en"> <![endif]-->
+<!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]-->
+<html>
+    <head>
+        <meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0">
+        <meta charset="utf-8">
+        <meta http-equiv="X-UA-Compatible" content="IE=10">
+        <title>{$title}</title>
+        <link rel="shortcut icon" type="image/x-icon" href="./img/favicon.ico" />
+        <link rel="apple-touch-icon-precomposed" sizes="144x144" href="./img/apple-touch-icon-144x144-precomposed.png">
+        <link rel="apple-touch-icon-precomposed" sizes="72x72" href="./img/apple-touch-icon-72x72-precomposed.png">
+        <link rel="apple-touch-icon-precomposed" href="./img/apple-touch-icon-precomposed.png">
+        <link rel="stylesheet" href="./css/knacss.css" media="all">
+        <link rel="stylesheet" href="./css/style.css" media="all">
+    </head>
     <body class="article">
         <div id="article" class="w600p">
                <div class="backhome">
@@ -6,9 +23,9 @@
                </div>
             <div class="tools">
                 <ul>
-                    <li><a title="toggle mark as read" class="tool archive {if="$is_read == '0'"}archive-off{/if}" onclick="toggle_archive(this, {$id}, '{$token}')"><span></span></a></li>
-                    <li><a title="toggle favorite" class="tool fav {if="$is_fav == '0'"}fav-off{/if}" onclick="toggle_favorite(this, {$id}, '{$token}')"><span></span></a></li>
-                    <li><form method="post" onsubmit="return confirm('Are you sure?')" style="display: inline;" action="index.php"><input type="hidden" name="token" id="token" value="{$token}" /><input type="hidden" id="action" name="action" value="delete" /><input type="hidden" id="id" name="id" value="{$id}" /><input type="submit" class="delete" title="toggle delete" /></form></li>
+                    <li><a title="toggle mark as read" class="tool archive {if="$is_read == '0'"}archive-off{/if}" onclick="toggle_archive(this, {$id}, '<?php echo Session::getToken(); ?>')"><span></span></a></li>
+                    <li><a title="toggle favorite" class="tool fav {if="$is_fav == '0'"}fav-off{/if}" onclick="toggle_favorite(this, {$id}, '<?php echo Session::getToken(); ?>')"><span></span></a></li>
+                    <li><form method="post" onsubmit="return confirm('Are you sure?')" style="display: inline;" action="index.php"><input type="hidden" name="token" id="token" value="<?php echo Session::getToken(); ?>" /><input type="hidden" id="action" name="action" value="delete" /><input type="hidden" id="id" name="id" value="{$id}" /><input type="submit" class="delete" title="toggle delete" /></form></li>
                 </ul>
             </div>
             <header class="mbm">
                 <a href="index.php" title="back to home">&larr;</a>
             </div>
         </div>
-        {include="footer"}
+
         {include="js"}
+
+        <footer class="mr2 mt3 smaller">
+            <p>powered by <a href="http://inthepoche.com">poche</a><br />follow us on <a href="https://twitter.com/getpoche" title="follow us on twitter">twitter</a></p>
+        </footer>
+
     </body>
-</html>
+</html>
\ No newline at end of file
index 9ba6f62dab7049e5f83290b885c42329efcda129..29a5b32456cfe777b9e9389178ddf0e9c2f63caa 100644 (file)
--- a/view.php
+++ b/view.php
@@ -24,7 +24,6 @@ if(!empty($id)) {
         $tpl->assign('is_fav', $entry[0]['is_fav']);
         $tpl->assign('is_read', $entry[0]['is_read']);
         $tpl->assign('load_all_js', 0);
-        $tpl->assign('token', $_SESSION['token_poche']);
         $tpl->draw('view');
     }
     else {