I imagine a plugin that modifies the login screen to use <http://recaptcha.net/>. You would then be required to fill in the captcha as well as log in in the normal way.
+-- [[users/Will]]
+
> I hate CAPTCHAs with a passion. Someone else is welcome to write such a
> plugin.
>
>>> (Openid delegation makes it a bit harder than just looking at the
>>> openid url though.) --[[Joey]]
+>>>> Well, OpenID only addresses authentication issues, not authorisation issues.
+>>>> Given that it is trivial to set up your own OpenID provider (a full provider, not
+>>>> just a forward to another provider), I can't see a
+>>>> blacklist working in the long term (it would be like blacklisting email).
+>>>> A whitelist might work (it would not be quite as bad as whitelisting email). In any case,
+>>>> there is now a captcha plugin for those that want it. It is accessible
+>>>> (there is an audio option) and serves a social purpose along with
+>>>> keeping bots out (the captcha is used to help digitise hard to read
+>>>> words in books for [Carnegie Mellon University](http://www.cs.cmu.edu/) and
+>>>> [The Internet Archive](http://www.archive.org/) ). Finally, because the actual captcha is outsourced
+>>>> it means that someone else is taking care of keeping it ahead of
+>>>> the bot authors.
+
+>> As [[spam_fighting]] shows, OpenID spam is now real. Yahoo, at least, would need to be blocked, according to the above, which seems like a bold move. --[[anarcat]]
+
Okie - I have a first pass of this. There are still some issues.
Currently the code verifies the CAPTCHA. If you get it right then you're fine.
> This is still not fixed. I would have thought the following patch would
> have fixed this second issue, but it doesn't.
---- a/IkiWiki/Plugin/openid.pm
-+++ b/IkiWiki/Plugin/openid.pm
-@@ -61,6 +61,7 @@ sub formbuilder_setup (@) { #{{{
- # Skip all other required fields in this case.
- foreach my $field ($form->field) {
- next if $field eq "openid_url";
-+ next if $field eq "recaptcha";
- $form->field(name => $field, required => 0,
- validate => '/.*/');
- }
+(code snipped as a working [[patch]] is below)
>> What seems to be happing here is that the openid plugin defines a
>> validate hook for openid_url that calls validate(). validate() in turn
>> just flag it as invalid and let formbuilder handle that. Instead, you'd
>> have to hack something in to redisplay the captcha by hand. --[[Joey]]
+>>> Fixed this. I just modified the OpenID plugin to check if the captcha
+>>> succeeded or failed. Seeing as the OpenID plugin is the one that is
+>>> abusing the normal validate method, I figured it was best to keep
+>>> the fix in the same place. I also added a config switch so you can set if
+>>> the captcha is needed for OpenID logins. OpenID defaults to ignoring
+>>> the captcha.
+>>> Patch is inline below.
+>>> I think this whole thing is working now.
+
+>>>> Ok, glad it's working. Not thrilled that it needs to modify the
+>>>> openid plugin, especially as I'm not sure if i I will integrate the
+>>>> captcha plugin into mainline. Also because it's not very clean to have
+>>>> the oprnid plugin aware of another plugin like that. I'd like to
+>>>> prusue my idea of not doing the captcha validation in the validate
+>>>> hook.
+
+[[!format diff """
+--- a/IkiWiki/Plugin/openid.pm
++++ b/IkiWiki/Plugin/openid.pm
+@@ -18,6 +18,7 @@ sub getopt () {
+ error($@) if $@;
+ Getopt::Long::Configure('pass_through');
+ GetOptions("openidsignup=s" => \$config{openidsignup});
++ GetOptions("openidneedscaptcha=s" => \$config{openidneedscaptcha});
+ }
+
+ sub formbuilder_setup (@) {
+@@ -61,6 +62,7 @@ sub formbuilder_setup (@) {
+ # Skip all other required fields in this case.
+ foreach my $field ($form->field) {
+ next if $field eq "openid_url";
++ next if $config{openidneedscaptcha} && $field eq "recaptcha";
+ $form->field(name => $field, required => 0,
+ validate => '/.*/');
+ }
+@@ -96,6 +98,18 @@ sub validate ($$$;$) {
+ }
+ }
+
++ if ($config{openidneedscaptcha} && defined $form->field("recaptcha")) {
++ foreach my $field ($form->field) {
++ next unless ($field eq "recaptcha");
++ if (! $field->validate) {
++ # if they didn't get the captcha right,
++ # then just claim we validated ok so the
++ # captcha can cause a fail
++ return 1;
++ }
++ }
++ }
++
+ my $check_url = $claimed_identity->check_url(
+ return_to => IkiWiki::cgiurl(do => "postsignin"),
+ trust_root => $config{cgiurl},
+
+"""]]
+
Instructions
=====
You need to go to <http://recaptcha.net/api/getkey> and get a key set.
The keys are added as options.
- reCaptchaPubKey => "LONGPUBLICKEYSTRING",
- reCaptchaPrivKey => "LONGPRIVATEKEYSTRING",
+[[!format perl """
+reCaptchaPubKey => "LONGPUBLICKEYSTRING",
+reCaptchaPrivKey => "LONGPRIVATEKEYSTRING",
+"""]]
You can also use "signInSSL" if you're using ssl for your login screen.
----------
+[[!format perl """
#!/usr/bin/perl
# Ikiwiki password authentication.
package IkiWiki::Plugin::recaptcha;
use strict;
use IkiWiki 2.00;
-sub import { #{{{
+sub import {
hook(type => "formbuilder_setup", id => "recaptcha", call => \&formbuilder_setup);
-} # }}}
+}
-sub getopt () { #{{{
+sub getopt () {
eval q{use Getopt::Long};
error($@) if $@;
Getopt::Long::Configure('pass_through');
GetOptions("reCaptchaPubKey=s" => \$config{reCaptchaPubKey});
GetOptions("reCaptchaPrivKey=s" => \$config{reCaptchaPrivKey});
-} #}}}
+}
-sub formbuilder_setup (@) { #{{{
+sub formbuilder_setup (@) {
my %params=@_;
my $form=$params{form};
});
}
}
-} # }}}
+}
# The following function is borrowed from
# Captcha::reCAPTCHA by Andy Armstrong and are under the PERL Artistic License
}
1;
-
+"""]]