External Authenticator

From the module README:
----------------------------------
This module enables you to use external authentication sources for password
verification. At the moment this module has 2 drivers. One for LDAP and
one for IMAP which also supports POP3. TLS/SSL are supported for both drivers.

When you use this module you will still need to create accounts within
SilverStripe. There will be an extra field for each account, specifying the
username in the external authentication source.

If you run your website at your ISP which also hosts your mailbox, you can use
the ISP's IMAP/POP3 server to validate your logon. Other users at the ISP
cannot login when you do that, because the accounts also need to be registered
within SilverStripe.
---------------------------------

This topic is continued from the "LDAP Support for SilverStripe" thread from 'Contributions'.

This module was originally released as an LDAP authenticator and then renamed to Simple Authenticator when IMAP/POP3 capabilities were added. Since the name was confusing, it is now renamed to External Authenticator. Updates with respect to the previous version:
- Renamed the module
- Added internationalization
- Code layout cleanup

I had a quick look at your code! Looks good... great work man! I found 2 small Ã¢â‚¬Å“bugsÃ¢â‚¬Â:

* In drivers/IMAP.php line 38 a Ã¢â‚¬Å“)Ã¢â‚¬Â is missing
* In _config.php you first add Ã¢â‚¬Å“ExternalAuthenticatedRoleÃ¢â‚¬Â to the Member object and then
you register the ExternalAuthenticator. You donÃ¢â‚¬â„¢t need to call DataObject::add_extension() there. ItÃ¢â‚¬â„¢s called automatically in ExternalAuthenticator::on_register().

Now I understood why you had those naming Ã¢â‚¬Å“problemsÃ¢â‚¬Â but I think thatÃ¢â‚¬â„¢s actually a bigger problem. By swapping out the code in Ã¢â‚¬Å“driversÃ¢â‚¬Â you prevent a user from using for example IMAP and LDAP authentication at the same time. Not really a problem with those two authentication mechanisms but you maybe you want to have a Ã¢â‚¬Å“backup systemÃ¢â‚¬Â if the other one is offline!?

I think it would be much better to create to different modules so that they could also be used concurrently. Maybe we should refactor the LoginForm and Authenticator class to prevent that we have a lot of code redundancies.

Thanks for the bug report. Missed that one in all the _t function calls. Updated source is available.

As for being not able to do LDAP and IMAP. I wonder how many installations actually use more than one authentication source. I like the suggestion of stacking drivers for redundancy, that should not be difficult to add. However stacking modules for different authentication sources is not wise, but that's a documentation issue.

All the code excluding the driver files could be added to the core code. Even OpenID could be implemented in a driver file, the Authenticator, AuthenticatedRole and LoginForm were largely copied from the OpenID code.

> I wonder how many installations actually use more than one authentication source.

Well.. since it is a brand-new feature I think that most sites at the moment don't use it at all, but we shouldn't restrict it's future use.

> I like the suggestion of stacking drivers for redundancy, that should not be difficult to
> add. However stacking modules for different authentication sources is not, but that's a
> documentation issue.

I'm not sure if you understood me. What I wanted to say was that at the moment all authentication methods share a lot of code within their LoginForms and their Authenticator classes. Maybe we should refactor them so that different authentication methods don't need to copy that code. That's exactly the reason why you created drivers and used ExternalAuthenticator and ExternalLoginForm for both drivers.
But stacking drivers is also a good idea :-)

> All the code excluding the driver files could be added to the core code. Even OpenID
> could be implemented in a driver file, the Authenticator, AuthenticatedRole and LoginForm > were largely copied from the OpenID code.

That was exactly what I meant! We should build an infrastructure were we can simple add a driver (one file!?) without creating a special LoginForm and Authenticator class.
Of course OpenID plays a special role since it uses redirects to another server (not just entering some kind of username and password) and so we have to design the Authenticator class flexible enough (just think about CardSpace, Google Account Authentication, LID, ...)

I would also expand the driver mechanism to the user administration itself. e.g. LDAP or AD (SilverStripe could use the standard POSIX scheme) can handle the user accounts as well as the database can. You might even want to use another database away from the SilverStripe database.

I haven't read enough of the SilverStripe code to see the implications, but the implications are not limited to the authentication mechanism.

> I would also expand the driver mechanism to the user administration itself.
> e.g. LDAP or AD (SilverStripe could use the standard POSIX scheme) can handle the user
> accounts as well as the database can. You might even want to use another database
> away from the SilverStripe database.

While this would be a desirable feature for enterprise applications I think it's too much abstraction for a simple CMS. Also it would require a lot of work to implement such a feature.
But you could of build a bridge or proxy to support that :-)