Securing Demo-Installations of CakePHP Apps

Securing Demo-Installations of CakePHP Apps

When you first start-out developing web-apps for a marketplace such as CodeCanyon, one of the most important things you need to do is create a demo-version of your system. After all, seeing the real thing in action is the top-priority for potential buyers.

Now, if you are working with a PHP MVC framework such as CakePHP, creating such a demo-system with limited functionality is very simple. So let me go ahead and outline the few simple changes you need to do in order to create a demo-mode which you can easily toggle as per your needs. Personally, I use a similar approach in all of my apps, such as VisitorChat (a PHP live chat) or the Project Platform (a PHP project management script).

You can view a live-demo of this concept here:

 

First of all, let’s look at a check-list of what needs to be restricted on the demo system:

  1. Disable deleting records
  2. Disable the ability to edit records
  3. Restrict the creation of records
  4. Disable any specific functionality

 

First of all, let us add the following code to our core.php file:

1
Configure::write('demo', true);

Now, you can use this configuration setting within your code to conditionally grant or deny access to the app’s functionality. At the most basic level, you can apply 90% of your logic to the AppModel and, therefore, the entire app at once.

Simply add the following code to your AppModel’s beforeFind and beforeDelete methods:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    public function beforeSave($options = array())
    {
        if (Configure::read('demo') === true && AppController::$demoBlockIgnore === false)
        {
            AppController::$demoBlocked = true;
            return false;
        }
    }
 
    public function beforeDelete($cascade = true)
    {
        if (Configure::read('demo') === true && AppController::$demoBlockIgnore === false)
        {
            AppController::$demoBlocked = true;
            return false;
        }
    }

This simply returns a false if the system is in demo mode and voilá: nobody will be able to create, update or delete anything. However, simply returning false will only cause confusion for your users who are wondering why their changes are not being accepted.

Therefore, let’s look at adding a notice that tell’s them what’s going on. Ideally, we would do this in the AppController. Firstly, though, add the following static class members which I like to use to control some of the logic:

1
2
3
4
5
6
7
8
9
10
11
    /**
     * Indicates whether a saving operation was blocked due to the system being in demo-mode
     * @var boolean
     */
    public static $demoBlocked = false;
 
    /**
     * Indicates whether the demo-block should be ignored for the current operation
     * @var boolean
     */
    public static $demoBlockIgnore = false;

The member demoBlocked is set by the AppModel and will, later, be used to determine whether to render a flash message or not. The demoBlockIgnore member can be used to allow a range of particular operations that should be done even in the demo system.

So, let’s start displaying our messages:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    public function beforeRender()
    {
        if (self::$demoBlocked === true)
        {
            $this->Session->setFlash(__('You cannot perform any changes in the demonstration system'));
        }
    }
    public function beforeRedirect($url, $status = null, $exit = true)
    {
        if (self::$demoBlocked === true)
        {
            $this->Session->setFlash(__('You cannot perform any changes in the demonstration system'));
        }
    }

This simply tells your app to set a flash message if the AppModel decided not to allow a particular action.

Finally, let’s go back to the demoBlockIgnore variable. For example, in my demo system, I do not want any of the default demo-users to be changes. However, those who are interested, can create their own, private account which is fully functional and without restrictions.
To do this, I simply created a new config-variable called “demo_users” and loaded it with an array containing the primary keys of the restricted default-users: everyone else shall be able to use the app without restrictions.

Here is how I achieved this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    public function __construct($request = null, $response = null)
    {
        /**
         * Deactivate demo-restrictions for newly created users
         */
        if (Configure::read('demo') === true && is_array(Configure::read('demo_users')))
        {
            if (!in_array(AppAuth::user('id'), Configure::read('demo_users')))
            {
                self::$demoBlockIgnore = true;
            }
        }
 
        parent::__construct($request, $response);
    }

Essentially, we are checking whether the currently logged-in user is one of the default users, if the user is indeed a default user: restrict his access. Please note that “AppAuth” is my own alias for the “AuthComponent” and that you will need to change this in your own app.

So, I hope this helps give a few of you an idea of how to quickly create a demo-system for your application. If you have any questions, just give me a shout in the comments-section below!

No comments

Leave a reply

Your email is never published nor shared. Required fields are marked *

Security Question * Time limit is exhausted. Please reload CAPTCHA.