Arquivo Eletrônico


2011, Sep-09

Password-Protecting Pages in Stacey

You can use these modifications to password-protect content in your Stacey installation.

  1. Modify the application files to catch our password-protected content and ask for a password.
  2. Add our custom Password class to Stacey’s app folder.
  3. Create a the content and template to display our password form.
  4. Secure the content you want by adding is_secure: true to the text file.

This approach is not 100% secure and won’t stop a determined intruder, but it will work if you need a simple and easy way to keep your content from being easily accessible.

Replace the functions in the following files:

/app/cache.inc.php

Reason: Authentication check added when @is_private variable is set. Also avoid caching of the private page

  function create($route) {
    $page = new Page($route);
    // Private page authentication code
    if($page->data['@is_private']){
        if(!Password::authenticated())
            $page = new Page('password');
    }
    // End of addition
    # start output buffer
    ob_start();
      echo $page->parse_template();
      # if cache folder is writable, write to it
      // The following  line was replaced by the next two lines. Avoid caching when @is_private is set.
      // if(is_writable('./app/_cache') && !$page->data['@bypass_cache']) $this->write_cache();
      if(is_writable('./app/_cache') && !$page->data['@bypass_cache'])
        if (!$page->data['@is_private']) $this->write_cache();
      else if ($this->is_commentable()) echo "\n".$this->comment_tags['begin'].' Stacey('.Stacey::$version.'). '.$this->comment_tags['end'];
    # end buffer
    ob_end_flush();
    return '';
  }

/app/stacey.inc.php

Reason: Moved the etag browser-side caching to after the cache_exired check to avoid client-side caching of private pages.

  function render($file_path, $template_file) {
    $cache = new Cache($file_path, $template_file);        
    # set any custom headers
    $this->set_content_type($template_file);
//    # if etag is still fresh, return 304 and don't render anything
//    if(!$this->etag_expired($cache)) return;
    # if cache has expired
    if($cache->expired()) {
      # render page & create new cache
      echo $cache->create($this->route);
    } else {
      # if etag is still fresh, return 304 and don't render anything
      if(!$this->etag_expired($cache)) return;
      # render the existing cache
      echo $cache->render();
    }
  }

The password checking class

Create a file password.inc.php inside the app folder

/ (root)
+ app
?  + cache.inc.php
?  + helpers.inc.php
?  + password.inc.php
+ content
+ templates

Here is where we define the password to be used. file contents:

<?php
Class Password {

    function get_password(){
        return md5(‘your_password’); //<== Change the password to what you want it to be.
    }

    function authenticated(){
        session_start();
        $password = self::get_password();

        if (isset($_SESSION['stacey_password'])){
            if ($_SESSION['stacey_password'] == $password)
                return true;
        }

        if (isset($_POST['password'])) {
            if (md5($_POST['password'])==$password){
                $_SESSION['stacey_password'] = $password;
                return true;
            }
            return false;
        }
        else{
            return false;
        }
    }

}
?

Create corresponding content and template files

password.txt

Under /content create a folder called ‘password’ and within it a file called ’password.txt’

/ (root)
+ app
+ content
?  + 1.projects
?  ?  password
?      ? password.txt

file contents:

is_private: true
?
page_description: Some secret stuff
?
title: Secret area

password.html

Now, create a new template named ‘password.html’ based on a category template and modify it to include a form with an input area named ‘password’

/ (root)
+ app
+ content
+ templates
?  + category.html
?  + index.html
?  + password.html

file contents:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
  "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
    <title>@ title, @ name's Portfolio </title>
    <link rel="alternate" type="application/atom+xml" href="@ root_path/?/feed/">
    <link rel="stylesheet" href="@ root_path/public/docs/css/screen.css" type="text/css" media="screen"> 
  </head>
  <body>
    <div id="container">
      <h1 class="col three">
        <a href="@ root_path">@ name</a>
        <strong>@ profession</strong>
      </h1>
      <em class="col three">@ email</em>
      <hr>
      : navigation
      <div id="content" class="col eight">
    <form method="post"><p>Please enter your password for access</p>
    <input name="password" type="password" size="25" maxlength="10"><input value="Login" type="submit"></form>
      </div>
      <hr>
      <p id="footer" class="col six">© Copyright @ name @ current_year <a class="atom-rss" href="@ root_path/?/feed/">RSS</a><br>
        <em>Content managed by <a href="http://www.staceyapp.com">stacey</a></em></p>
    </div>
  </body>
</html>

Secure your content

Now all you have to do is to add is_secure: true to your page.txt, project.txt or category.txt file you want it to be password protected and you are done! You may need to clean your cache to avoid displaying the cached copy of the secured page.

is_secure: true
?
title: The Test Project 1
?
date: 2009, Jun—
?
content: 
Lorem ipsum dolor...

7/14