How can a plugin update the loginname database?
I have a working prototype of general SSL/X.509 identification & authentication for TWiki 4.1.2. Registration data is extracted from the certificate & populates the registration form. The form data populates the user's personal page. The certificate DN populates the .htpasswd file, and (apache) httpd does everything right. Simply browsing to the TWiki gets you logged-in & and associated with your WikiName.
But (you knew something was coming...): there's one little thing...
Making all this work requires mapping the X.509 DN to a more conventional login name. At the end of the registration process, the standard registration code writes the unmapped X.509 DN to the TWikiUsers page.
I have both the DN and the conventional name at the registrationHandler of a plugin. I need to update TWikiUsers, replacing the DN with the conventional login name. I considered the ugly "readTopicText/edit/saveTopicText" approach as a work-around, but it appears that TWikiUsers hasn't been written when the registrationHandler is called.
How can I do this? Is there an existing API that I haven't found? Can one be created?
--
TimotheLitt - 23 Sep 2007
While I'm not quite positive I understand your situation, I am tempated to suggest that you look at writing a
UserMapper for 4.2.0 instead. (heck, even a 4.1.2
UserMapping should work). This is not really the domain of a Plugin - but is why the plugable
UserMapping class was written.
--
SvenDowideit - 24 Sep 2007
4.2? Oh, I see - it's at beta 1.
The precise situation is that I (and from scanning the web, many before me) want TWiki users to be identified by their X.509 certificates. I'm almost there...
X.509 certificates appear as REMOTE_USER environment variables like
/C=US/ST=New York/L=Queens/O=big.co.com/OU=Execs/OU=Bottle Washers/CN=Fred Flightly/emailAddress=bigwig@no-email.net.
For httpd to authenticate, the .htpasswd entry must be that ugly string. However, TWikiUsers, which is used to map REMOTE_USER to the user's TWikiName can't handle the syntax. (Plus, this page is viewed by people.) So, we need a modified version of the string to be stored on the TWikiUsers page. The modified (
mapped) version is created to be unique, readable, and matchable by the existing lookup/update code.
A plugin
almost works, and is something easy to package and contribute. Here's the essence:
sub initializeUserHandler
{
### my ( $loginName, $url, $pathInfo ) = @_; # do not uncomment, use $_[0], $_[1]... instead
my( $sts, $mappedName ) = mapDN( $_[0] );
return $mappedName;
}
sub registrationHandler
{
# my ( $web, $wikiName, $loginName ) = @_; # do not uncomment, use $_[0], $_[1]... instead
# See if the name is mapped
my( $sts, $mappedName ) = mapDN( $_[2] );
return if( $sts );
# Mapped name, update the users topic.
# This doesn't work because at this call-out, the page hasn't been written.
# What we want is to have the current $loginName entered into .htpasswd, bu
# $mappedName written to the TWikiUsers topic.
%GRAY%
my $text = TWiki::Func::readTopicText( 'Main', 'TWikiUsers', undef, 1 );
if( $text =~ /^http.*?\/oops/ ) {
# TWiki::Func::redirectCgiQuery( $query, $text );
return;
}
if( $text !~ s/ - $_[2] - / - $mappedName - /gs ) {
return;
}
my $oopsUrl = TWiki::Func::saveTopicText( 'Main', 'TWikiUsers', $text );
if( $oopsUrl ) {
# TWiki::Func::redirectCgiQuery( $query, $text );
return;
}
%ENDCOLOR%
return;
}
There's some more magic to extract data from the certificate to fill in forms and the like, but that's under control.
--
TimotheLitt - 24 Sep 2007
seriously, it still sounds like code that you should be putting into a trivial
UserMapping and
LoginManager - and they already exist in 4.1.2.
--
SvenDowideit - 25 Sep 2007
--
JoseREMY - 29 Oct 2007
You may also consider to use information coming from X.509 certificate, to search an LDAP directory (see
LdapContrib ), and then map to a correct TWiki user.
--
JoseREMY - 29 Oct 2007