Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion Bugzilla/Install/Filesystem.pm
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,8 @@ sub FILESYSTEM {
dirs => DIR_CGI_WRITE },
$assetsdir => { files => WS_SERVE,
dirs => DIR_CGI_OVERWRITE | DIR_ALSO_WS_SERVE },
"$datadir/captcha" => { files => CGI_WRITE,
dirs => DIR_CGI_WRITE },

# Readable directories
"$datadir/mining" => { files => CGI_READ,
Expand Down Expand Up @@ -282,6 +284,7 @@ sub FILESYSTEM {
$extensionsdir => DIR_CGI_READ,
# Directories that cgi scripts can write to.
"$datadir/db" => DIR_CGI_WRITE,
"$datadir/captcha" => DIR_CGI_WRITE,
$attachdir => DIR_CGI_WRITE,
$graphsdir => DIR_CGI_WRITE | DIR_ALSO_WS_SERVE,
$webdotdir => DIR_CGI_WRITE | DIR_ALSO_WS_SERVE,
Expand Down Expand Up @@ -430,7 +433,7 @@ EOT

"$assetsdir/.htaccess" => { perms => WS_SERVE, contents => <<EOT
# Allow access to .css files
<FilesMatch \\.(css|js)\$>
<FilesMatch \\.(css|js|png)\$>
<IfModule mod_version.c>
<IfVersion < 2.4>
Allow from all
Expand Down
5 changes: 5 additions & 0 deletions Bugzilla/Install/Requirements.pm
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,11 @@ sub REQUIRED_MODULES {
# 2.0 is the first version that will work with JSON::RPC.
version => '2.01',
},
{
package => 'Authen-Captcha',
module => 'Authen::Captcha',
version => '1.024',
},
);

if (ON_WINDOWS) {
Expand Down
13 changes: 13 additions & 0 deletions Bugzilla/Template.pm
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,18 @@ sub _concatenate_js {
return [ $file ];
}

sub _captcha_path {
my $token = shift;
return "" unless $token;

my $cgi_path = bz_locations()->{cgi_path};
my $assets_path = bz_locations()->{assetsdir};
my $captcha_path = "$assets_path" . "/$token.png";

$captcha_path =~ s/^\Q$cgi_path\E\///o;
return $captcha_path;
}

# YUI dependency resolution
sub yui_resolve_deps {
my ($yui, $yui_deps) = @_;
Expand Down Expand Up @@ -1112,6 +1124,7 @@ sub create {
'css_files' => \&css_files,
yui_resolve_deps => \&yui_resolve_deps,
concatenate_js => \&_concatenate_js,
captcha_path => \&_captcha_path,

# All classifications (sorted by sortkey, name)
'all_classifications' => sub {
Expand Down
25 changes: 24 additions & 1 deletion createaccount.cgi
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ use Bugzilla::Constants;
use Bugzilla::Error;
use Bugzilla::Token;

use Authen::Captcha;

# Just in case someone already has an account, let them get the correct footer
# on an error message. The user is logged out just after the account is
# actually created.
Expand All @@ -33,13 +35,32 @@ my $login = $cgi->param('login');
my $uid = $cgi->param('uid');

# Modified for Mer to send uid to account creation and to put uid into
# the $vars for the templates
# the $vars for the templates. And added captcha for the robots

my $captcha_data = bz_locations()->{'datadir'} . "/captcha";
my $captcha_output = bz_locations()->{'assetsdir'};
my $captcha = Authen::Captcha->new(
data_folder => $captcha_data,
output_folder => $captcha_output,
);

if (defined($login)) {
# Check the hash token to make sure this user actually submitted
# the create account form.
my $token = $cgi->param('token');
check_hash_token($token, ['create_account']);

my $captcha_token = $cgi->param('captcha_token');
my $captcha_code = $cgi->param('captcha_code');
my $result = $captcha->check_code($captcha_code, $captcha_token);
if ($result == 0) {
ThrowCodeError('captcha_check_error');
} elsif ($result == -1) {
ThrowUserError('captcha_expired');
} elsif ($result < -1 ) {
ThrowUserError('captcha_invalid');
}

$user->check_and_send_account_creation_confirmation($login, $uid);
$vars->{'login'} = $login;
$vars->{'uid'} = $uid;
Expand All @@ -49,6 +70,8 @@ if (defined($login)) {
exit;
}

$vars->{'captcha_token'} = $captcha->generate_code(10);

# Show the standard "would you like to create an account?" form.
$template->process("account/create.html.tmpl", $vars)
|| ThrowTemplateError($template->error());
8 changes: 8 additions & 0 deletions template/en/default/account/create.html.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,14 @@
Username:
</span>
<input size="35" id="uid" name="uid" required>

<br><img src="[% captcha_path(captcha_token) FILTER html %]"><br>
<span class="label">
Enter the above code:
</span>
<input id="captcha_code" name="captcha_code" required>
<input type="hidden" name="captcha_token" value="[% captcha_token FILTER html %]">

<input type="hidden" id="token" name="token" value="[% issue_hash_token(['create_account']) FILTER html %]">
<input type="submit" id="send" value="Send">
</form>
Expand Down
4 changes: 4 additions & 0 deletions template/en/default/global/code-error.html.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,10 @@
Bugzilla does not support the search type
"[% operator.truncate(30, "...") FILTER html %]".

[% ELSIF error == "captcha_check_error" %]
[% title = "Captcha check failed" %]
Checking the captcha code failed.

[% ELSE %]
[%# Try to find hooked error messages %]
[% error_message = Hook.process("errors") %]
Expand Down
8 changes: 8 additions & 0 deletions template/en/default/global/user-error.html.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -1947,6 +1947,14 @@
[% END %]
with the External Login ID "[% extern_id FILTER html %]".

[% ELSIF error == "captcha_expired" %]
[% title = "Invalid captcha" %]
The used captcha has already expired.

[% ELSIF error == "captcha_invalid" %]
[% title = "Invalid captcha" %]
The given captcha code is not correct.

[% ELSE %]

[%# Try to find hooked error messages %]
Expand Down