Mike November

Phonetic alphabet for my initials, k?

Viewing entries posted in October 2010

Using dependency injection in SilverStripe

Posted by Marcus Nyeholt on 26 October 2010 | 0 Comments

Tags: , ,

I've been toying with a simple dependency injector for the last few days, and have started to think about ways in which it (or another dependency injector) could benefit SilverStripe. Some ideas I've been toying with

  • Put in authentication / authorization as part of the pre request dispatch.
  • Refactor authentication methods to be injected services linked in
  • Refactor persistence and data loading away from DataObject class directly
  • Using non* SQL based datastores
  • Refactor to use PDO or something with proper prepared statements
  • PermissionService * for sites that don't need complex permissions, have something that returns true, for those that do configure to use something else
  • VersionService
  • WorkflowService
  • SearchService
  • Aop filters for some things
    • Auditing method calls
    • Access restriction on method calls (force developers to think before calling * >write())
    • Would almost work as a replacement to $this* >extend('augmentXXX') type functionality

Along the lines of the first point, I put some code together to see how it works


// injector configuration
Injector::inst(array(
    array(
        'class' => 'RequestProcessor',
        'properties' => array(
            'preFilters' => array(
                '#$AuthenticationFilter',
                '#$AuthorisationFilter',
            )
        ),
    ),
    'AuthenticationFilter',
    'AuthorisationFilter',
    array(
        'class' => 'AuthenticationService',
        'properties' => array(
            'authenticators' => array(
                '#$DbAuthenticationProvider',
            )
        ),
    ),
    'DbAuthenticationProvider',
);

And then adding a hook in before the Director dispatches the request


Injector::inst()->get('RequestProcessor')->preFilter($req, $session); // $session required to get around a SS quirk

The 'grunt' work comes in the AuthneticationFilter


class AuthenticationFilter implements RequestFilter {
    /**
     * Automatically injected based on convention
     */
    public $authenticationService;
    
    public function preRequest(SS_HTTPRequest $request, Session $session) {
        // lets try authenticating
        if (isset($_REQUEST['auth']) || isset($_REQUEST['action_dologin'])) {
            $email = $request->postVar('Email');
            $pass = $request->postVar('Password');

            $member = $this->authenticationService->authenticate($email, $pass);
            if ($member) {
                $member->logIn($request->postVar('Remember'));
                
                // dirty hack for now...
                $session->inst_set('loggedInAs', $member->ID);
            }

            // because we have the request here, we can do a bunch of redirects or
            // whatever we like - but this is just a poc for now so we won't bother with
            // anything else. 
        }
    }

    public function postRequest(SS_HTTPRequest $request, SS_HTTPResponse $response) {

    }
}

So the actual 'authenticate' work is done via an authentication service, which in turn has registered within it a bunch of AuthenticationProvider implementors - in this case I only have one (DbAuthenticationProvider) which simply calls MemberAuthenticator::authenticate(). I could quite easily add on any number of other providers (LDAP, OpenID, etc etc) in a chain, and let the user login via the first that succeeds. Makes for an elegant way to have a single login form.

The next step is to add some logic to the AuthorisationFilter to prevent requests to certain URLs continuing if the user is not authorized (I'm looking at you /dev requests). This stops unauthorised requests very early in the request cycle, and help centralise the logic for this for a single maintainable area for developers to refer to. But that's for another day...

0 comments | Read the full post

Another new blog

Posted by Marcus on 25 October 2010 | 0 Comments

Another year another new blog. It's almost like a new years resolution or something like that.

Anyway, this time around it will be focused mostly on SilverStripe development. Largely on the backend code that goes into modules, but also touching on some parts of the core, and what I actually do for SilverStripe.

0 comments | Read the full post