Tag: patterns

Simple PHP MVC

One of the much talked about patterns of the moment is the model-view-controller or model-view-presenter or any of the undoubtedly thousands of variants thereof. Here’s a deliberately really simple one to illustrate the pattern. If you can read it and understand it I hope its useful to you.

Interestingly a vague attempt at inversion of control, another design pattern which IMHO is more of a guide line, is in play here. It is done specifically to allow good component separation and useful test patterns. Hence as long as you have a class that fits the dependency obligations you can use it with the ones given here.

Now for the seriously crazy bit, the code on this page has not been tested to work. Its just here to give you some idea of what the model-view-controller pattern and how it could be implemented.

mvc.controller.php

Overview:

At the heart of each variant implementation of the model view controller pattern is the controller. A controller basically directs requests to the appropriate model or view processing functionality. In the case below it only makes the distinction between the two types and not the instances of functionality.

Some controllers combine a lot more but its not actually necessary and generally ends up making the controller very configuration and platform specific. By keeping configuration out of the controller we make it as general as it can be.

Notes:

Note that there is no exception handling here either. It is not wanted. Consider for a moment that if an exception was not caught, there would be no response to the client, which is a security requirement in many instances. However it there would be a log to trace to the point of failure because of the log entry call.

If exception handling were introduced it would compromise the generic nature of the controller as the controller would need to know what type of response to send to the client. For example if the error was thrown before the content of the request could be analysed and what data would you respond to the request with? HTML? XML? A media stream? A GIF? A JPG? The rule of thumb here is only respond if you know what language to talk in, if you don’t know the requested format you can’t even use clever configuration to determine how respond to a request.

Documented dependencies:

  • class ‘Model’ : method ‘process_request’ : parameters ‘request to process’ : returns ‘new request for either model processing or view generation’
  • class ‘View’ : method ‘process_request’ : parameters ‘request to process’ : returns ‘a view generated from the accumulated data in the request’

Undocumented dependencies:

  • class ‘Log’ : method ‘writestr’ : parameters ‘string to log’, ‘name of log level to record string at’ : returns ‘nothing’
  • class ‘Log’ : method ‘writereq’ : parameters ‘request to log’, ‘name of log level to record string at’ : returns ‘nothing’
  • class ‘Request’ : method ‘is_a_model_request’ : parameters ‘none’ : returns ‘true if the request is to be processed by the model’

Listing:


<?php

Log::getInstance()->writestr( "file:".__FILE__.":loaded", "debug" );

class Controller {

  private $model;

  private $view;

 /*

  * build this controller object

  */

  public function __Construct ( $model, $view ) {

    $this->model = $model;

    $this->view = $view;

  }

 /*

  * process a request

  */

  public function process_request ( $request ) {

    Log::getInstance()->writestr( 

      "class:".__CLASS__.":process_request", "debug" );

    Log::getInstance()->writereq( $request, "debug" );

   /*

    * first process the model request

    */

    $new_request = $this->model->process_request( $request );

   /*

    * if this request results in another model request

    */

    if ( $new_request->is_a_model_request( ) )

      return $this->process_request( $new_request );

   /*

    * otherwise generate view

    */ 

    return $this->view->process_request( $new_request );

  }

}

?>

mvc.model.php

Overview:

A model is responsible for the production of data for the view. Essentially it contains access points to the various methods of the underlying application called actions. In this case it simply has a list of actions that it locates and then executes the action sending the results back to the caller.

Notes:

As with the controller (see above) the model does little more than the basics leaving other classes that know what they are doing to handle the specifics of content. In line with this the model simply logs progress and fails silently.

Undocumented dependencies:

  • class ‘Log’ : method ‘writestr’ : parameters ‘string to log’, ‘name of log level to record string at’ : returns ‘nothing’
  • class ‘Log’ : method ‘writereq’ : parameters ‘request to log’, ‘name of log level to record string at’ : returns ‘nothing’
  • class ‘Actions’ : method ‘find_requested_action’ : parameters ‘request to locate action for’ : returns ‘an Action object’
  • class ‘Action’ : method ‘process_request’ : parameters ‘request to process’ : returns ‘new request for either model processing or view generation’

Listing:


<?php

Log::getInstance()->writestr( "file:".__FILE__.":loaded", "debug" );

class Model {

  private $actions;

 /*

  * build this model object

  */

  public function __Construct ( $actions ) {

    $this->actions = $actions;

  }

 /*

  * process a request

  */

  public function process_request ( $request ) {

    Log::getInstance()->writestr( 

      "class:".__CLASS__.":process_request", "debug" );

    Log::getInstance()->writereq( $request, "debug" );

   /*

    * find the action from the list of actions

    */

    $action = $this->actions->find_requested_action( $request );

   /*

    * run the action and return the resulting request

    */

    return $action->process_request( $request );

  }

}

?>

mvc.view.php

Overview:

A view is called to format the data retrieved from the model into the format that the original client requested. Essentially it contains access points to the various view methods of the underlying application. In this case it simply has a list of views that it locates and then executes sending the results back to the caller.

Notes:

Now those sharp of eye will realise something; this looks pretty much like the model class above, and you’d be right. Apart from a a simple renaming of a few items the code is the same. In practice both the above model class and this view class would be implemented as a single class and simply configured differently. They are only provided in their separate formats here to highlight the model-view-controller form.

Undocumented dependencies:

  • class ‘Log’ : method ‘writestr’ : parameters ‘string to log’, ‘name of log level to record string at’ : returns ‘nothing’
  • class ‘Log’ : method ‘writereq’ : parameters ‘request to log’, ‘name of log level to record string at’ : returns ‘nothing’
  • class ‘Views’ : method ‘find_requested_view’ : parameters ‘request to locate view for’ : returns ‘an View object’
  • class ‘View’ : method ‘process_request’ : parameters ‘request to process’ : returns ‘the final generated view’

Listing:


<?php

Log::getInstance()->writestr( "file:".__FILE__.":loaded", "debug" );

class View {

  private $views;

 /*

  * build this view object

  */

  public function __Construct ( $views ) {

    $this->views = $views;

  }

 /*

  * process a request

  */

  public function process_request ( $request ) {

    Log::getInstance()->writestr( 

      "class:".__CLASS__.":process_request", "debug" );

    Log::getInstance()->writereq( $request, "debug" );

   /*

    * find the view from the list of views

    */

    $view = $this->views->find_requested_view( $request );

   /*

    * process the request and return the resulting view

    */

    return $view->process_request( $request );

  }

}

?>

Pattern: Web Application Security Filter

Pattern Name: Web Application Security Filter

Classification: Structural Filter

Intent:

Isolates authentication and authorisation from the application by filtering requests before they are received by the application so that authentication and authorisation may be easily applied to existing applications and managed seperately from other aplication concerns.

Motivation:

Incorporating authentication and authorisation security protocols into an Internet application is generally complex and when done improperly can lead to significant exposure to abuse and maluse. Due to the complex nature of implementing these security features significant risk is encountered when security code is combined with application code. This pattern is based on the generic filter and observer patterns allowing the seperation of security concerns from the development and management of the application and hopefully providing a better quality of service.

Filters provide an excellent opportunity for seperating security concerns from your web application. Because they intercept the incoming requests to your site before the site even sees them you can even apply the same filter pattern to existing sites without too much alteration. Combined with the power of directory services the pattern can be applied to both authentication and authorisation.

A filter is a special type of the decorator pattern because it allows the data being transmitted not only to be decorated but altered or even replaced altogether. Security functions naturall lend themselves to filter type implementations, perhaps the most well known type of filter implented today is the NetFilter or firewall. Network filters while suitable for addressing network traffic issues are not really suitable for application security, which after the network and operating system produce the most opportunities for security breaches.

Also Known As:

No alternate designs or implementations meeting the pattern are currently known

Applicability:

Any hosted application has the potential to bennefit from deployment of an implementation of this pattern. Also due to the generic nature of this pattern it would suit almost any web aplication container where the container supports filtered access to its hosted applications.

In addition to the basic objectives this security filter pattern can be used to address any olf the following requirements:

  • When security is required to be handled external to the application.
  • Where it is advantageous to have the same security implementation across multiple applications.
  • If security factors need to be isolated to demonstrate security processes for audit.

Structure: A graphical representation of the pattern. Class diagrams and Interaction diagrams can be used for this purpose.

security filter class diagram

Participants: A listing of the classes and objects used in this pattern and their roles in the design.

Collaboration: Describes how classes and objects used in the pattern interact with each other.

Consequences: This section describes the results, side effects, and trade offs caused by using this pattern.

Implementation: This section describes the implementation of the pattern, and represents the solution part of the pattern. It provides the techniques used in implementing this pattern, and suggests ways for this implementation.

Sample Code:

This section has a deliberately brief snip of a filter and its associated filter classes. This is an example of simplified function to higlight the general idea and not how it would be implemented for real. In reality the application container that you are using will already have something to base this on like javax.servlet.Filter so try and use that or something similar.


/*

 * Filter.java

 *

 * @author Michael Chester

 * @date 2007-03-09

 *

 * Filter interface used to chain filters, and eventually an 

 * application adapter.

 *

 * Filter class used to illustrate a simple interpretation on the 

 * securilty filter pattern, a factory should initialise the 

 * private attributes.

 */

public interface FilterInterface {

        public void doProcess(Session session, Request request,

            Response response);

}

public class EntryGate implements FilterInterface {

    /**

     * doProcess the filter action

     *

     * @param session for the current request

     * @param request the request that was sent through

     * @param response to fill out if authorisation fails

     *

     * @returns nothing

     */

    public void doProcess(Session session, Request request,

            Response response) {

        response.setResponse("performing filter");

        if(authorisor.isAuthorised(session, request, response))

            if(validator.isValidated(session, request, response))

                filter.doProcess(session, request, response);

    }

    /**

     * Holds value of property validator.

     */

    private Validator validator;

    /**

     * Holds value of property authority.

     */

    private Authorisor authorisor;

    /**

     * Holds value of property filter.

     */

    private FilterInterface filter;

}

/*

 * Authorisor.java

 *

 * @author Michael Chester

 * @date 2007-03-09

 *

 * Authorisor interface and class used to illustrate the role and

 * function of the authorisation concrete class.

 */

public interface Authorisor {

    public boolean isAuthorised(Session session, Request request,

            Response response);

}

public class AuthorisorExample implements Authorisor {

    /**

     * isAuthorised verifies the identity of the requestor

     *

     * @param session for the current request

     * @param request the request that was sent through

     * @param response to fill out if authorisation fails

     *

     * @returns true if authorised, false otherwise

     */

    public boolean isAuthorised(Session session, Request request,

            Response response) {

        /* authenticate on token */

        if(session.getAuthenticationToken() != null)

            if(session.getAuthenticationToken().equals("validToken"))

                return true;

        /* or authenticate on identity */

        if(request.getIdentity() != null)

            if(request.getIdentity().equals("validUser")) {

            /* and set a token to validate on next request */

            session.setAuthenticationToken("validToken");

            return true;

            }

        /* otherwise the identity is not authorised */

        response.setResponse("user not authorised");

        return false;

    }

}

/*

 * Validator.java

 *

 * @author Michael Chester

 * @date 2007-03-09

 *

 * Validator interface and class used to illustrate the role and

 * function of the validation concrete class.

 */

public interface Validator {

    public boolean isValidated(Session session, Request request,

            Response response);

}

public class ValidatorExample implements Validator {

    /**

     * example of a request validator, put your code here

     *

     * @param session for the current request

     * @param request the request that was sent through

     * @param response to fill out if authorisation fails

     *

     * @returns true if authorised, false otherwise

     */

    public boolean isValidated(Session session, Request request,

            Response response) {

        /* return true if the task matches */

        if(request.getTask() != null)

            if(request.getTask().equals("validTask")) return true;

        /* false otherwise */

        response.setResponse("request is not valid for user");

        return false;

    }

}

Known Uses:

Due to the nature of security applications and the way that this pattern is applied no implemented uses are mentioned here. However a number of applications are currently using this pattern hosted on the Apache Tomcat Servlet Container engine using implementations based on extending Tomcat’s own filter implementation.

Related Patterns:

This pattern is essentially an extension to or application of the already existing generic filter patterns.


Copyright © 1996-2010 Code Snips. All rights reserved.
iDream theme by Templates Next | Powered by WordPress