diff options
author | lpsolit%gmail.com <> | 2006-08-20 01:11:59 +0000 |
---|---|---|
committer | lpsolit%gmail.com <> | 2006-08-20 01:11:59 +0000 |
commit | 59285f71c6ed0d4db7d4b0455902130a2d7c83bd (patch) | |
tree | 49e2e47a53bb4ac31c10d3225b5e0a66edc5c126 | |
parent | 9dfdfd787ff4c0afac28b66e67082712ec2a3d92 (diff) | |
download | bugs-59285f71c6ed0d4db7d4b0455902130a2d7c83bd.tar bugs-59285f71c6ed0d4db7d4b0455902130a2d7c83bd.tar.gz bugs-59285f71c6ed0d4db7d4b0455902130a2d7c83bd.tar.bz2 bugs-59285f71c6ed0d4db7d4b0455902130a2d7c83bd.tar.xz bugs-59285f71c6ed0d4db7d4b0455902130a2d7c83bd.zip |
Bug 87795: Creating an account should send token and wait for confirmation (prevent user account abuse) - Patch by Frédéric Buclin <LpSolit@gmail.com> r=mkanat r=bkor a=myk
-rw-r--r-- | Bugzilla/BugMail.pm | 14 | ||||
-rw-r--r-- | Bugzilla/Constants.pm | 5 | ||||
-rw-r--r-- | Bugzilla/DB/Schema.pm | 2 | ||||
-rw-r--r-- | Bugzilla/Install/DB.pm | 3 | ||||
-rw-r--r-- | Bugzilla/Token.pm | 62 | ||||
-rw-r--r-- | Bugzilla/User.pm | 31 | ||||
-rwxr-xr-x | createaccount.cgi | 19 | ||||
-rw-r--r-- | template/en/default/account/cancel-token.txt.tmpl | 11 | ||||
-rw-r--r-- | template/en/default/account/create.html.tmpl | 34 | ||||
-rw-r--r-- | template/en/default/account/created.html.tmpl | 22 | ||||
-rw-r--r-- | template/en/default/account/email/confirm-new.html.tmpl | 64 | ||||
-rw-r--r-- | template/en/default/account/email/request-new.txt.tmpl | 44 | ||||
-rw-r--r-- | template/en/default/email/password.txt.tmpl | 35 | ||||
-rw-r--r-- | template/en/default/global/messages.html.tmpl | 9 | ||||
-rw-r--r-- | template/en/default/global/user-error.html.tmpl | 13 | ||||
-rwxr-xr-x | token.cgi | 87 | ||||
-rwxr-xr-x | userprefs.cgi | 2 |
17 files changed, 322 insertions, 135 deletions
diff --git a/Bugzilla/BugMail.pm b/Bugzilla/BugMail.pm index 07ebf226b..35b05d231 100644 --- a/Bugzilla/BugMail.pm +++ b/Bugzilla/BugMail.pm @@ -654,20 +654,6 @@ sub sendMail { return 1; } -# Send the login name and password of the newly created account to the user. -sub MailPassword { - my ($login, $password) = (@_); - my $template = Bugzilla->template; - my $vars = { - mailaddress => $login . Bugzilla->params->{'emailsuffix'}, - login => $login, - password => $password }; - my $msg; - $template->process("email/password.txt.tmpl", $vars, \$msg) - || ThrowTemplateError($template->error()); - MessageToMTA($msg); -} - # Get bug comments for the given period and format them to be used in emails. sub get_comments_by_bug { my ($id, $start, $end) = @_; diff --git a/Bugzilla/Constants.pm b/Bugzilla/Constants.pm index 9493ea400..2d6c2f561 100644 --- a/Bugzilla/Constants.pm +++ b/Bugzilla/Constants.pm @@ -120,6 +120,8 @@ use File::Basename; DB_MODULE ROOT_USER ON_WINDOWS + + MAX_TOKEN_AGE ); @Bugzilla::Constants::EXPORT_OK = qw(contenttypes); @@ -295,6 +297,9 @@ use constant SENDMAIL_EXE => '/usr/lib/sendmail.exe'; use constant FIELD_TYPE_UNKNOWN => 0; use constant FIELD_TYPE_FREETEXT => 1; +# The maximum number of days a token will remain valid. +use constant MAX_TOKEN_AGE => 3; + # States that are considered to be "open" for bugs. use constant BUG_STATE_OPEN => ('NEW', 'REOPENED', 'ASSIGNED', 'UNCONFIRMED'); diff --git a/Bugzilla/DB/Schema.pm b/Bugzilla/DB/Schema.pm index 50785c5b7..1888c76c0 100644 --- a/Bugzilla/DB/Schema.pm +++ b/Bugzilla/DB/Schema.pm @@ -715,7 +715,7 @@ use constant ABSTRACT_SCHEMA => { # for these changes. tokens => { FIELDS => [ - userid => {TYPE => 'INT3', NOTNULL => 1} , + userid => {TYPE => 'INT3'}, issuedate => {TYPE => 'DATETIME', NOTNULL => 1} , token => {TYPE => 'varchar(16)', NOTNULL => 1, PRIMARYKEY => 1}, diff --git a/Bugzilla/Install/DB.pm b/Bugzilla/Install/DB.pm index a4ab54260..d34a11f24 100644 --- a/Bugzilla/Install/DB.pm +++ b/Bugzilla/Install/DB.pm @@ -471,6 +471,9 @@ sub update_table_definitions { $dbh->bz_alter_column('keyworddefs', 'id', {TYPE => 'SMALLSERIAL', NOTNULL => 1, PRIMARYKEY => 1}); + # 2006-08-19 LpSolit@gmail.com - Bug 87795 + $dbh->bz_alter_column('tokens', 'userid', {TYPE => 'INT3'}); + ################################################################ # New --TABLE-- changes should go *** A B O V E *** this point # ################################################################ diff --git a/Bugzilla/Token.pm b/Bugzilla/Token.pm index 447d27507..6dd8baa6e 100644 --- a/Bugzilla/Token.pm +++ b/Bugzilla/Token.pm @@ -29,6 +29,7 @@ use strict; # Bundle the functions in this file together into the "Bugzilla::Token" package. package Bugzilla::Token; +use Bugzilla::Constants; use Bugzilla::Error; use Bugzilla::Mailer; use Bugzilla::Util; @@ -37,15 +38,45 @@ use Date::Format; use Date::Parse; ################################################################################ -# Constants +# Public Functions ################################################################################ -# The maximum number of days a token will remain valid. -use constant MAX_TOKEN_AGE => 3; +# Creates and sends a token to create a new user account. +# It assumes that the login has the correct format and is not already in use. +sub issue_new_user_account_token { + my $login_name = shift; + my $dbh = Bugzilla->dbh; + my $template = Bugzilla->template; + my $vars = {}; -################################################################################ -# Public Functions -################################################################################ + # Is there already a pending request for this login name? If yes, do not throw + # an error because the user may have lost his email with the token inside. + # But to prevent using this way to mailbomb an email address, make sure + # the last request is at least 10 minutes old before sending a new email. + trick_taint($login_name); + + my $pending_requests = + $dbh->selectrow_array('SELECT COUNT(*) + FROM tokens + WHERE tokentype = ? + AND ' . $dbh->sql_istrcmp('eventdata', '?') . ' + AND issuedate > NOW() - ' . $dbh->sql_interval(10, 'MINUTE'), + undef, ('account', $login_name)); + + ThrowUserError('too_soon_for_new_token', {'type' => 'account'}) if $pending_requests; + + my ($token, $token_ts) = _create_token(undef, 'account', $login_name); + + $vars->{'email'} = $login_name . Bugzilla->params->{'emailsuffix'}; + $vars->{'token_ts'} = $token_ts; + $vars->{'token'} = $token; + + my $message; + $template->process('account/email/request-new.txt.tmpl', $vars, \$message) + || ThrowTemplateError($template->error()); + + MessageToMTA($message); +} sub IssueEmailChangeToken { my ($userid, $old_email, $new_email) = @_; @@ -106,7 +137,7 @@ sub IssuePasswordToken { WHERE ' . $dbh->sql_istrcmp('login_name', '?'), undef, ('password', $loginname)); - ThrowUserError('too_soon_for_new_token') if $too_soon; + ThrowUserError('too_soon_for_new_token', {'type' => 'password'}) if $too_soon; my ($token, $token_ts) = _create_token($userid, 'password', $::ENV{'REMOTE_ADDR'}); @@ -177,26 +208,25 @@ sub GenerateUniqueToken { sub Cancel { my ($token, $cancelaction, $vars) = @_; my $dbh = Bugzilla->dbh; + my $template = Bugzilla->template; $vars ||= {}; # Get information about the token being cancelled. trick_taint($token); - my ($issuedate, $tokentype, $eventdata, $loginname, $realname) = + my ($issuedate, $tokentype, $eventdata, $loginname) = $dbh->selectrow_array('SELECT ' . $dbh->sql_date_format('issuedate') . ', - tokentype, eventdata, login_name, realname + tokentype, eventdata, login_name FROM tokens - INNER JOIN profiles + LEFT JOIN profiles ON tokens.userid = profiles.userid WHERE token = ?', undef, $token); - # Get the email address of the Bugzilla maintainer. - my $maintainer = Bugzilla->params->{'maintainer'}; - - my $template = Bugzilla->template; - + # If we are cancelling the creation of a new user account, then there + # is no entry in the 'profiles' table. + $loginname ||= $eventdata; $vars->{'emailaddress'} = $loginname . Bugzilla->params->{'emailsuffix'}; - $vars->{'maintainer'} = $maintainer; + $vars->{'maintainer'} = Bugzilla->params->{'maintainer'}; $vars->{'remoteaddress'} = $::ENV{'REMOTE_ADDR'}; $vars->{'token'} = $token; $vars->{'tokentype'} = $tokentype; diff --git a/Bugzilla/User.pm b/Bugzilla/User.pm index 12c680f78..54d84020f 100644 --- a/Bugzilla/User.pm +++ b/Bugzilla/User.pm @@ -1355,9 +1355,8 @@ sub insert_new_user { VALUES (?, ?, NOW(), ?, NOW())', undef, ($user->id, $who, $creation_date_fieldid)); - # Return the password to the calling code so it can be included - # in an email sent to the user. - return $password; + # Return the newly created user account. + return $user; } sub is_available_username { @@ -1377,15 +1376,18 @@ sub is_available_username { # was unsafe and required weird escaping; using substring to pull out # the new/old email addresses and sql_position() to find the delimiter (':') # is cleaner/safer - my $sth = $dbh->prepare( - "SELECT eventdata FROM tokens WHERE tokentype = 'emailold' - AND SUBSTRING(eventdata, 1, (" - . $dbh->sql_position(q{':'}, 'eventdata') . "- 1)) = ? - OR SUBSTRING(eventdata, (" - . $dbh->sql_position(q{':'}, 'eventdata') . "+ 1)) = ?"); - $sth->execute($username, $username); - - if (my ($eventdata) = $sth->fetchrow_array()) { + my $eventdata = $dbh->selectrow_array( + "SELECT eventdata + FROM tokens + WHERE (tokentype = 'emailold' + AND SUBSTRING(eventdata, 1, (" . + $dbh->sql_position(q{':'}, 'eventdata') . "- 1)) = ?) + OR (tokentype = 'emailnew' + AND SUBSTRING(eventdata, (" . + $dbh->sql_position(q{':'}, 'eventdata') . "+ 1)) = ?)", + undef, ($username, $username)); + + if ($eventdata) { # Allow thru owner of token if($old_username && ($eventdata eq "$old_username:$username")) { return 1; @@ -1459,7 +1461,7 @@ Bugzilla::User - Object for a Bugzilla user $user->get_selectable_classifications; # Class Functions - $password = insert_new_user($username, $realname, $password, $disabledtext); + $user = insert_new_user($username, $realname, $password, $disabledtext); =head1 DESCRIPTION @@ -1815,8 +1817,7 @@ Params: $username (scalar, string) - The login name for the new user. be sent depending on the user's email preferences. -Returns: The password for this user, in plain text, so it can be included - in an e-mail sent to the user. +Returns: The Bugzilla::User object representing the new user account. =item C<is_available_username> diff --git a/createaccount.cgi b/createaccount.cgi index ab011f336..6f325347e 100755 --- a/createaccount.cgi +++ b/createaccount.cgi @@ -60,21 +60,13 @@ unless ($createexp) { my $login = $cgi->param('login'); if (defined($login)) { - # We've been asked to create an account. - my $realname = trim($cgi->param('realname')); - validate_email_syntax($login) || ThrowUserError('illegal_email_address', {addr => $login}); $vars->{'login'} = $login; - $dbh->bz_lock_tables('profiles WRITE', 'profiles_activity WRITE', - 'user_group_map WRITE', 'email_setting WRITE', - 'groups READ', 'tokens READ', 'fielddefs READ'); - if (!is_available_username($login)) { # Account already exists - $dbh->bz_unlock_tables(); $template->process("account/exists.html.tmpl", $vars) || ThrowTemplateError($template->error()); exit; @@ -83,17 +75,10 @@ if (defined($login)) { if ($login !~ /$createexp/) { ThrowUserError("account_creation_disabled"); } - - # Create account - my $password = insert_new_user($login, $realname); - - $dbh->bz_unlock_tables(); - # Clear out the login cookies in case the user is currently logged in. - Bugzilla->logout(); + # Create and send a token for this new account. + Bugzilla::Token::issue_new_user_account_token($login); - Bugzilla::BugMail::MailPassword($login, $password); - $template->process("account/created.html.tmpl", $vars) || ThrowTemplateError($template->error()); exit; diff --git a/template/en/default/account/cancel-token.txt.tmpl b/template/en/default/account/cancel-token.txt.tmpl index 5124759ed..f9d310534 100644 --- a/template/en/default/account/cancel-token.txt.tmpl +++ b/template/en/default/account/cancel-token.txt.tmpl @@ -42,7 +42,9 @@ to [% maintainer %] if you suspect foul play. Cancelled Because: [% PROCESS cancelactionmessage %] [% BLOCK subject %] - [% IF tokentype == 'password' %] + [% IF tokentype == 'new_account' %] + User account creation request cancelled + [% ELSIF tokentype == 'password' %] Password change request cancelled [% ELSIF tokentype == 'emailnew' OR tokentype == 'emailold' %] Email change request cancelled @@ -72,6 +74,10 @@ Cancelled Because: [% PROCESS cancelactionmessage %] [% ELSIF cancelaction == 'password_change_cancelled' %] You have requested cancellation. + [% ELSIF cancelaction == 'account_creation_cancelled' %] + The creation of the user account [% emailaddress %] + has been cancelled. + [% ELSIF cancelaction == 'user_logged_in' %] You have logged in. @@ -84,6 +90,9 @@ Cancelled Because: [% PROCESS cancelactionmessage %] [% ELSIF cancelaction == 'wrong_token_for_confirming_email_change' %] You have tried to use the token to confirm the email address change. + [% ELSIF cancelaction == 'wrong_token_for_creating_account' %] + You have tried to use the token to create a user account. + [% ELSE %] [%# Give sensible error if the cancel-token function is used incorrectly. #%] diff --git a/template/en/default/account/create.html.tmpl b/template/en/default/account/create.html.tmpl index 052a2b7fe..2e8739b79 100644 --- a/template/en/default/account/create.html.tmpl +++ b/template/en/default/account/create.html.tmpl @@ -29,47 +29,37 @@ [% PROCESS global/variables.none.tmpl %] [% title = BLOCK %] -Create a new [% terms.Bugzilla %] account + Create a new [% terms.Bugzilla %] account [% END %] -[% PROCESS global/header.html.tmpl %] + +[% PROCESS global/header.html.tmpl + title = title + onload = "document.forms['account_creation_form'].login.focus();" %] <p> - To create a [% terms.Bugzilla %] account, all you need to do is - enter a legitimate e-mail address. The account will be created, and - its password will be mailed to you. <b>You will not be able to log - in until you receive the password.</b> If it doesn't arrive within a + To create a [% terms.Bugzilla %] account, all you need to do is to enter + a legitimate e-mail address. You will receive an email at this address + to confirm the creation of your account. <b>You will not be able to log + in until you receive the email.</b> If it doesn't arrive within a reasonable amount of time, you can contact the maintainer of this [% terms.Bugzilla %] installation at <a href="mailto:[% Param("maintainer") %]">[% Param("maintainer") %]</a>. </p> -<p> - Optionally you may enter your real name as well. -</p> - -<form method="get" action="createaccount.cgi"> +<form id="account_creation_form" method="get" action="createaccount.cgi"> <table> <tr> <td align="right"> <b>E-mail address:</b> </td> <td> - <input size="35" name="login"> + <input size="35" id="login" name="login"> [% Param('emailsuffix') FILTER html %] </td> </tr> - - <tr> - <td align="right"> - <b>Real name:</b> - </td> - <td> - <input size="35" name="realname"> - </td> - </tr> </table> <br> - <input type="submit" id="create" value="Create Account"> + <input type="submit" id="send" value="Send"> </form> [% PROCESS global/footer.html.tmpl %] diff --git a/template/en/default/account/created.html.tmpl b/template/en/default/account/created.html.tmpl index 2d507b4cf..58064f24c 100644 --- a/template/en/default/account/created.html.tmpl +++ b/template/en/default/account/created.html.tmpl @@ -17,26 +17,26 @@ # Rights Reserved. # # Contributor(s): Gervase Markham <gerv@gerv.net> + # Frédéric Buclin <LpSolit@gmail.com> #%] [%# INTERFACE: # login: string. The user's Bugzilla login email address. #%] -[% PROCESS global/header.html.tmpl - title = "Account Created" -%] +[% PROCESS global/variables.none.tmpl %] -<p> - A new account, - <tt>[% login FILTER html %]</tt>, - has been created and a randomly-generated password has been e-mailed - to that address. -</p> +[% title = BLOCK %] + Request for new user account '[% login FILTER html %]' submitted +[% END %] + +[% PROCESS global/header.html.tmpl title = title %] <p> - When the e-mail arrives, - <a href="index.cgi?GoAheadAndLogIn=1">log in here</a>. + To confirm the creation of the user account <tt>[% login FILTER html %]</tt>, + use the URL given in the email you will receive. If you take no action in the + next [% constants.MAX_TOKEN_AGE FILTER html %] days, this request will + automatically be canceled. </p> [% PROCESS global/footer.html.tmpl %] diff --git a/template/en/default/account/email/confirm-new.html.tmpl b/template/en/default/account/email/confirm-new.html.tmpl new file mode 100644 index 000000000..0e9ab98e5 --- /dev/null +++ b/template/en/default/account/email/confirm-new.html.tmpl @@ -0,0 +1,64 @@ +[%# 1.0@bugzilla.org %] +[%# The contents of this file are subject to the Mozilla Public + # License Version 1.1 (the "License"); you may not use this file + # except in compliance with the License. You may obtain a copy of + # the License at http://www.mozilla.org/MPL/ + # + # Software distributed under the License is distributed on an "AS + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + # implied. See the License for the specific language governing + # rights and limitations under the License. + # + # The Original Code is the Bugzilla Bug Tracking System. + # + # Contributor(s): Frédéric Buclin <LpSolit@gmail.com> + #%] + +[%# INTERFACE: + # token: string. The token to be used in the user account creation. + # email: email address of the user account. + # date: creation date of the token. + #%] + +[% title = BLOCK %]Create a new user account for '[% email FILTER html %]'[% END %] +[% PROCESS "global/header.html.tmpl" + title = title + onload = "document.forms['confirm_account_form'].realname.focus();" %] + +[% expiration_ts = date + (constants.MAX_TOKEN_AGE * 86400) %] +<div> + To complete the creation of your user account, you must choose a password in the + form below. You can also enter your real name, which is optional.<p> + If you don't fill this form before + <u>[%+ time2str("%H:%M on the %o of %B, %Y", expiration_ts) %]</u>, the creation + of this account will be automatically cancelled. +</div> + +<form id="confirm_account_form" method="post" action="token.cgi"> + <input type="hidden" name="t" value="[% token FILTER html %]"> + <input type="hidden" name="a" value="confirm_new_account"> + <table> + <tr> + <th align="right">Email Address:</th> + <td>[% email FILTER html %]</td> + </tr> + <tr> + <th align="right"><label for="realname">Real Name</label>:</th> + <td><input type="text" id="realname" name="realname" value=""></td> + </tr> + <tr> + <th align="right"><label for="passwd1">Type your password</label>:</th> + <td><input type="password" id="passwd1" name="passwd1" value=""></td> + </tr> + <tr> + <th align="right"><label for="passwd1">Re-type your password</label>:</th> + <td><input type="password" id="passwd2" name="passwd2" value=""></td> + </tr> + <tr> + <th align="right"> </th> + <td><input type="submit" id="confirm" value="Send"></td> + </tr> + </table> +</form> + +[% PROCESS global/footer.html.tmpl %] diff --git a/template/en/default/account/email/request-new.txt.tmpl b/template/en/default/account/email/request-new.txt.tmpl new file mode 100644 index 000000000..85fdec157 --- /dev/null +++ b/template/en/default/account/email/request-new.txt.tmpl @@ -0,0 +1,44 @@ +[%# 1.0@bugzilla.org %] +[%# The contents of this file are subject to the Mozilla Public + # License Version 1.1 (the "License"); you may not use this file + # except in compliance with the License. You may obtain a copy of + # the License at http://www.mozilla.org/MPL/ + # + # Software distributed under the License is distributed on an "AS + # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + # implied. See the License for the specific language governing + # rights and limitations under the License. + # + # The Original Code is the Bugzilla Bug Tracking System. + # + # Contributor(s): Frédéric Buclin <LpSolit@gmail.com> + #%] + +[%# INTERFACE: + # token: random string used to authenticate the transaction. + # token_ts: creation date of the token. + # email: email address of the new account. + #%] + +[% PROCESS global/variables.none.tmpl %] + +[% expiration_ts = token_ts + (constants.MAX_TOKEN_AGE * 86400) %] +From: bugzilla-admin-daemon +To: [% email %] +Subject: [% terms.Bugzilla %]: confirm account creation + +[%+ terms.Bugzilla %] has received a request to create a user account +using your email address ([% email %]). + +To confirm that you want to create an account using that email address, +visit the following link: + +[%+ Param('urlbase') %]token.cgi?t=[% token FILTER url_quote %]&a=request_new_account + +If you are not the person who made this request, or you wish to cancel +this request, visit the following link: + +[%+ Param('urlbase') %]token.cgi?t=[% token FILTER url_quote %]&a=cancel_new_account + +If you do nothing, the request will lapse after [%+ constants.MAX_TOKEN_AGE %] days +(at precisely [%+ time2str("%H:%M on the %o of %B, %Y", expiration_ts) %]). diff --git a/template/en/default/email/password.txt.tmpl b/template/en/default/email/password.txt.tmpl deleted file mode 100644 index 5993a90f5..000000000 --- a/template/en/default/email/password.txt.tmpl +++ /dev/null @@ -1,35 +0,0 @@ -[%# 1.0@bugzilla.org %] -[%# The contents of this file are subject to the Mozilla Public - # License Version 1.1 (the "License"); you may not use this file - # except in compliance with the License. You may obtain a copy of - # the License at http://www.mozilla.org/MPL/ - # - # Software distributed under the License is distributed on an "AS - # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - # implied. See the License for the specific language governing - # rights and limitations under the License. - # - # The Original Code is the Bugzilla Bug Tracking System. - # - # The Initial Developer of the Original Code is Netscape Communications - # Corporation. Portions created by Netscape are - # Copyright (C) 1998 Netscape Communications Corporation. All - # Rights Reserved. - # - # Contributor(s): Emmanuel Seyman <eseyman@linagora.com> - #%] - -[% PROCESS global/variables.none.tmpl %] - -From: bugzilla-daemon -To: [% mailaddress %] -Subject: Your [% terms.Bugzilla %] password. - -To use the wonders of [% terms.Bugzilla %], you can use the following: - - E-mail address: [% login %] - Password: [% password %] - - To change your password, go to: - [%+ Param("urlbase") %]userprefs.cgi - diff --git a/template/en/default/global/messages.html.tmpl b/template/en/default/global/messages.html.tmpl index 08321ed2c..2e1878b5f 100644 --- a/template/en/default/global/messages.html.tmpl +++ b/template/en/default/global/messages.html.tmpl @@ -38,6 +38,15 @@ [% IF groups.size %] You may want to edit the group settings now, using the form below. [% END %] + [% IF login_info %] + You can now go to the <a href="index.cgi">Log In</a> page to enter + this [% terms.Bugzilla %] installation. + [% END %] + + [% ELSIF message_tag == "account_creation_cancelled" %] + [% title = "User Account Creation Cancelled" %] + The creation of the user account [% account FILTER html %] has been + cancelled. [% ELSIF message_tag == "account_updated" %] [% IF changed_fields.size diff --git a/template/en/default/global/user-error.html.tmpl b/template/en/default/global/user-error.html.tmpl index 53fb3ae27..e67c1a81c 100644 --- a/template/en/default/global/user-error.html.tmpl +++ b/template/en/default/global/user-error.html.tmpl @@ -1318,8 +1318,13 @@ [% ELSIF error == "too_soon_for_new_token" %] [% title = "Too Soon For New Token" %] - You have requested a password token too recently to request - another. Please wait a while and try again. + You have requested + [% IF type == "password" %] + a password + [% ELSIF type == "account" %] + an account + [% END %] + token too recently to request another. Please wait a while and try again. [% ELSIF error == "unknown_keyword" %] [% title = "Unknown Keyword" %] @@ -1398,6 +1403,10 @@ [% title = "Wrong Token" %] That token cannot be used to change your email address. + [% ELSIF error == "wrong_token_for_creating_account" %] + [% title = "Wrong Token" %] + That token cannot be used to create a user account. + [% ELSIF error == "zero_length_file" %] [% title = "File Is Empty" %] The file you are trying to attach is empty! @@ -19,6 +19,7 @@ # Rights Reserved. # # Contributor(s): Myk Melez <myk@mozilla.org> +# Frédéric Buclin <LpSolit@gmail.com> ############################################################################ # Script Initialization @@ -36,6 +37,8 @@ use Bugzilla::Error; use Bugzilla::Token; use Bugzilla::User; +use Date::Parse; + my $dbh = Bugzilla->dbh; local our $cgi = Bugzilla->cgi; local our $template = Bugzilla->template; @@ -87,6 +90,12 @@ if ($cgi->param('t')) { Bugzilla::Token::Cancel($::token, "wrong_token_for_confirming_email_change"); ThrowUserError("wrong_token_for_confirming_email_change"); } + if (($::action =~ /^(request|confirm|cancel)_new_account$/) + && ($tokentype ne 'account')) + { + Bugzilla::Token::Cancel($::token, 'wrong_token_for_creating_account'); + ThrowUserError('wrong_token_for_creating_account'); + } } @@ -147,6 +156,12 @@ if ($::action eq 'reqpw') { cancelChangeEmail(); } elsif ($::action eq 'chgem') { changeEmail(); +} elsif ($::action eq 'request_new_account') { + request_create_account(); +} elsif ($::action eq 'confirm_new_account') { + confirm_create_account(); +} elsif ($::action eq 'cancel_new_account') { + cancel_create_account(); } else { # If the action that the user wants to take (specified in the "a" form field) # is none of the above listed actions, display an error telling the user @@ -333,3 +348,75 @@ sub cancelChangeEmail { || ThrowTemplateError($template->error()); } +sub request_create_account { + my (undef, $date, $login_name) = Bugzilla::Token::GetTokenData($::token); + $vars->{'token'} = $::token; + $vars->{'email'} = $login_name . Bugzilla->params->{'emailsuffix'}; + $vars->{'date'} = str2time($date); + + # We require a HTTPS connection if possible. + if (Bugzilla->params->{'sslbase'} ne '' + && Bugzilla->params->{'ssl'} ne 'never') + { + $cgi->require_https(Bugzilla->params->{'sslbase'}); + } + print $cgi->header(); + + $template->process('account/email/confirm-new.html.tmpl', $vars) + || ThrowTemplateError($template->error()); +} + +sub confirm_create_account { + my (undef, undef, $login_name) = Bugzilla::Token::GetTokenData($::token); + + (defined $cgi->param('passwd1') && defined $cgi->param('passwd2')) + || ThrowUserError('new_password_missing'); + validate_password($cgi->param('passwd1'), $cgi->param('passwd2')); + + my $realname = $cgi->param('realname'); + my $password = $cgi->param('passwd1'); + + $dbh->bz_lock_tables('profiles WRITE', 'profiles_activity WRITE', + 'email_setting WRITE', 'user_group_map WRITE', + 'groups READ', 'tokens READ', 'fielddefs READ'); + + # The email syntax may have changed since the initial creation request. + validate_email_syntax($login_name) + || ThrowUserError('illegal_email_address', {addr => $login_name}); + # Also, maybe that this user account has already been created meanwhile. + is_available_username($login_name) + || ThrowUserError('account_exists', {email => $login_name}); + + # Login and password are validated now, and realname is allowed to + # contain anything. + trick_taint($realname); + trick_taint($password); + + my $otheruser = insert_new_user($login_name, $realname, $password); + $dbh->bz_unlock_tables(); + + # Now delete this token. + Bugzilla::Token::DeleteToken($::token); + + # Let the user know that his user account has been successfully created. + $vars->{'message'} = 'account_created'; + $vars->{'otheruser'} = $otheruser; + $vars->{'login_info'} = 1; + + print $cgi->header(); + + $template->process('global/message.html.tmpl', $vars) + || ThrowTemplateError($template->error()); +} + +sub cancel_create_account { + my (undef, undef, $login_name) = Bugzilla::Token::GetTokenData($::token); + + $vars->{'message'} = 'account_creation_cancelled'; + $vars->{'account'} = $login_name; + Bugzilla::Token::Cancel($::token, $vars->{'message'}); + + print $cgi->header(); + $template->process('global/message.html.tmpl', $vars) + || ThrowTemplateError($template->error()); +} diff --git a/userprefs.cgi b/userprefs.cgi index 2a890f19d..2d7fa4de5 100755 --- a/userprefs.cgi +++ b/userprefs.cgi @@ -53,7 +53,7 @@ sub DoAccount { && Bugzilla->user->authorizer->can_change_email) { my @token = $dbh->selectrow_array( "SELECT tokentype, issuedate + " . - $dbh->sql_interval(3, 'DAY') . ", eventdata + $dbh->sql_interval(MAX_TOKEN_AGE, 'DAY') . ", eventdata FROM tokens WHERE userid = ? AND tokentype LIKE 'email%' |