Monthly Archives: June 2008

symfony’s sfGuard plugin and LDAP

A while ago I needed to hook up symfony’s excellent sfGuard plugin to some LDAP functionality. There are a couple of issues with the plugin and the readme which I think need fixing. In particular, there is no support for checking both LDAP and standard sfGuard passwords. This is absolutely essential (eg an admin user or guest users who aren’t in LDAP), and I’m somewhat amazed that there’s no provision for this. Moreover, the plugin structure generally makes it seemingly impossible (or if it is possible it’s just too horrible to contemplate) to write your own checkPassword() which does do both sorts of checking.

Anyway this post is partly an attempt for me to get my head round something which I’ve either totally misunderstood, or just isn’t well documented.

 

Confusing README

The README file that comes with the plugin is great, but it’s a little confusing for explaining how you might override its own way of checking passwords with something that’s LDAP-based. It’s really very simple to do when written out in plain English:

1. Make a file called myLDAP.class.php in your application’s lib folder. Put this in it:

class myLDAP extends sfGuardSecurityUser
{
}

2. Now put a method inside the class you just created:
public static function checkLDAPPassword($username, $password)
{
// put your preferred LDAP-checking code in here
// should return true or false
}

3. Add this to your application’s app.yml file:

all:
  sf_guard_plugin:
    check_password_callable: [myLDAP, checkLDAPPassword]

where myLDAP is the file called myLDAP.class.php that you created in step 1 above. checkLDAPPassword is the method you made inside myLDAP.class.php that you made in step 2.

And there you have it. Basic LDAP password checking.

 

How does checkPassword() actually work?

The above code is all very well, but what’s really going on?

Well, there are a couple of steps which I managed to work out:

1. sfGuardUserValidator contains a call to $user->checkPassword($password) where $user is a result of sfGuardUserPeer::retrieveByUsername($username)

2. PluginsfGuardUser (extends BasesfGuardUser) has a method called checkPassword() too. This calls the method you listed in your app.yml file (checkLDAPPassword in this case), or does a standard sfGuard password check (checkPasswordByGuard) if you didn’t specify anything:

public function checkPassword($password)
{
if ($callable = sfConfig::get('app_sf_guard_plugin_check_password_callable'))
{
return call_user_func_array($callable, array($this->getUsername(), $password));
}
else
{
return $this->checkPasswordByGuard($password);
}
}

Which it does depends on how you set up your app.yml file (see Step 3 above).

At this point, if you set up your app.yml correctly you’ll be in your custom checkLDAPPassword() method, which will do whatever you want it to do to check LDAP passwords. So long as it returns true or false depending on whether the check was successful or not, you’ll be ok.

Note that sfGuardSecurityUser class also contains a checkPassword() method. This basically does the same thing as the in sfGuardUserValidator, but in a slightly different way, and allows access to checkPassword() in templates and controllers through the $sf_user object. The important thing to realise is that both pieces of code end up calling the same checkPassword() method in PluginsfGuardUser.

 

So how about LDAP and sfGuard checking?

Now the fun begins. The problem is that it’s seemingly impossible to call checkPasswordByGuard() yourself from inside your custom-built checkLDAPPassword() method. Why would you want to do this? Because that way you can do some standard password checking first to see if your user is in fact a sfGuard user and not an LDAP user. Only if that failed would you do LDAP checking (I suppose you could do it the other way round if you wanted.) Even better, you wouldn’t need to alter checkPasswordByGuard().

So why is it impossible to call checkPasswordByGuard() ‘by hand’? As far as I can see, it assumes that you’re not in a static context, and that you have some kind of user object available. But of course, my checkLDAPPassword() is in a static context. It had to be that way because it was called by call_user_func_array() which uses the output of sfConfig::get() as an argument.

Sigh…

If you find a way of doing this, please let me know. Losing the will to live is merely one of the symptoms of battling with this sort of thing. I have a life to live.

All I can suggest to you in the meantime is to modify your copy of PluginsfGuardUser.php to allow both sorts of password checking. That’s what I did and it worked for me. It’s just a pity that you can’t override the checkPasswordByGuard() method in some way without changing the core of the plugin.

Matrix GUI, asset builders (and mums)

After fun and a few frustrations sorting out designs in MySource Matrix in my last post (probably mostly caused by me not knowing what I was doing, and with limited time to sort things out), I’ve been looking at the overall user interface for editors.

The interface is possibly a tad intimidating for some (could you imagine your mum using it?), but the great thing about the system is that it’s flexible enough that you can build your own very simple content edit interfaces.

Lots of buttons and flashing lights…

The thing to remember here is that MySource Matrix is a powerful system, with all kinds of features on all kinds of screens. Tickboxes, drop-downs, options, buttons all over the place. It’s great, but it’s complex. And as we all know, making something easy to use is a real trick. Just think back (if you can) to the days of video recorders that no one knew how to use because they made actually fairly simple things seem very hard to do. It’s the kind of thing companies like Apple have spent decades trying to perfect.

Actually the developers of Matrix have done a reasonable job, and in any case much of the interface is only for system administrators (like me) setting the thing up.

But if all you want to do is make a new page with some text, images, and links in it (this must be like 95% of all web pages) you don’t need or want to know about all the fancy stuff in the backend, all the different types of assets, etc, etc. You probably don’t even want to know what an asset is. You just want a nice box you can type stuff into, press a button, and away you go. You want something like wordpress with all its web 2.0 goodness.

Asset builders and simple edit

Thankfully Matrix has two features which you can get to work together to build a simple editing interface the way you want it.

The simple edit interface is basically a way of allowing users to edit a page without all that backend admin stuff. On its own it’s a nice feature, but not much use if you actually want to make a new page. Asset builders are really the other side of the coin, because they give you the flexibility to allow any user to add in whatever new assets you want them to add.

So, make a new page with asset builder. Edit it with simple edit.

I have to say that I haven’t tried getting them to work together yet. I don’t even know to what extent that’s possible. What would be nice is to be able to make a new page and edit it at the same time, then either publish it or save it for later if I don’t want it to go live. That’s what I’m doing now in wordpress. That’s what google docs does. It’s intuitive and quick. That said, I’m probably hoping for too much, because bolting something that simple onto what can often be a considerably more complex process (think workflows, nested content, etc) is a real problem.

Summary

Matrix offers a very comprehensive and rich backend interface. If you want something easier for your users you can build your own very simple frontend new page/edit interface, which is a really nice feature. Users still have to go into the admin interface to delete or move those pages, and do other fairly simple operations.

I’d love to see a friendlier backend interface to Matrix, and I have no idea if that’s planned for Matrix 4 (due out sometime next year apparently). Sprucing it up somewhat would certainly turn it into a pretty much unrivalled open source CMS.

MySource Matrix design

I’ve been playing around with mysource matrix on my laptop recently, as an early development stage to our pilot while we’re waiting for the server hardware to be set up.

One of the first things I’ve been looking at has been setting up designs, and I have to admit it’s been a somewhat mysterious process.

OK so I haven’t been on Squiz’s design training course, but I have taken a long hard look at the 94-page design manual (to their credit, Squiz have about 1300 pages of documentation, most of which is freely available.)

Part of the problem is our pretty complex set of css files. The other part of the problem seems to be the way mysource matrix deals with links to images in css files. Suffice to say that getting an existing design into mysource matrix isn’t much fun. Once you’ve got over that hurdle, performance seems to be an issue.

A far easier option is just to lift your static template, pointing to all those static css files and images sitting on your live webserver. In fact this works just great, and it’s what I’m now doing. But something makes me feel it’s not the ‘right’ way to do things. I should point out that I may have misunderstood something in how to set things up, so this review may not be entirely fair. Apologies in advance it that’s the case.

If you enjoy pain, and want to share some of mine, read on…

Getting Started

Let’s say you have an image that you want to call from a css file with something like

background-image:url(images/snap.gif)

How does matrix know where images/snap.gif lives? Unless it’s living somewhere on a publicly accessible web server, it has to be uploaded into matrix. You can then refer to it as mysource_files/snap.gif, and the system will know what you mean.

If this sounds simple enough, then wait. There’s much more. By the end of this you’ll think having teeth pulled is a fun experience. Read on…

CSS Files

You first have to tell matrix that each css file which has a url() is an asset, not just some static text file sitting there. OK, so I go through all 30 of my css files that are like this, creating them as children to my main design. Something is making me feel uneasy about this, but I carry on anyway.

Images

Right, now I have to make all the images that are referred to in each css file children of the corresponding css file. Ugh. Yep, well I don’t have anything better to do, so I reorganise all my images according to the css file they appear in. Some images in more than one place, but oh well I guess I could make them as copies if only I could remember which css file I already uploaded them to. Whatever. I battle on.

The process continues for some time…

Cool. It was painful, but now I have all my css files uploaded, with all their corresponding images. I’ve changed the css files to refer to mysource_files/imagename.gif rather than their original url.

Now I need to link these files into the main design. It turns out that I can’t actually do this directly. I have to create special design areas in the main design which point to the css files.

OK, not too bad? Erm, well it’s not that simple. I actually also need to put in what’s called a customization which acts as a bridge between design and css files, and it’s that thing which point to the css assets themselves. This feels very wrong, but I carry on.

Too slooowww…

Hoorah! Now after a few hours persistence I have a working design. I test it out. After about 8 seconds, my page loads with the correct design. Hoorah again!

Then I stop and think what’s just happened. 8 seconds? Hmmm, ok well I know this is just on my macbook, but that’s really a tad slow isn’t it?

At that point I realised that there’s a lot going on here. You can cache the css files, although that threw an error when I tried it. I eventually fixed that ‘feature’ temporarily, and it’s true things did start to speed up a lot.

But at that point I pretty much gave up. Life’s too short. The option to point all urls at the currently live designs was just too alluring. Anyway it was all a useful experience, if only to tell me that getting a design to work properly and load quickly in MySource Matrix isn’t a quick or simple procedure.

 

 

mini symfony

I recently read this post by Francois Zaninotto (recently an ex-core symfony developer) about modifying symfony to make it lightweight enough for ajax calls. As he puts it:

That’s when the idea of a “small symfony” comes. Wouldn’t it be great if you could get access to the model layer, the configuration, the autoloading, the user object, the helpers, and keep a MVC separation, without initializing the whole framework?

As symfony stands, it’s sometimes just a tad too bloated for the kinds of really fast responses needed to make ajax applications work. Francois came up with this solution, which is to cut out the call to sfController::dispatch()

But you still get enough to make use of things like the basic MVC design, autoloading, and helpers. I still haven’t tried it myself, but it seems like a really nice idea. Just a shame he’s no longer in the core team…