Permalink
Browse files

Merged revisions 1546-1548,1550,1557 via svnmerge from svn://svn.mong…

…ueurs.net/act/trunk

........
  r1546 | eric | 2007-07-12 14:01:45 -0700 (Thu, 12 Jul 2007) | 4 lines

  Make twostep more generic:
   twostep form and email templates, getting the email,
   getting twostep form errors, are supplied by calling handler
........
  r1547 | eric | 2007-07-12 17:34:53 -0700 (Thu, 12 Jul 2007) | 1 line

  Act::Form ordered global validation
........
  r1548 | eric | 2007-07-13 14:09:48 -0700 (Fri, 13 Jul 2007) | 2 lines

  change password in two steps replaces reset password
........
  r1557 | eric | 2007-07-26 23:47:53 -0700 (Thu, 26 Jul 2007) | 1 line

  resetpassword error message fixup
........


git-svn-id: svn://svn.mongueurs.net/act/branches/stable@1559 67b57a05-4208-db11-a765-00306e02d86a
  • Loading branch information...
1 parent 1b0f572 commit 3f55908295338805c5fc6109d2166069dc5380d7 Éric Cholet committed Jul 27, 2007
View
@@ -247,6 +247,7 @@ CREATE TABLE twostep
(
token char(32) NOT NULL PRIMARY KEY,
email text NOT NULL,
- datetime timestamp without time zone
+ datetime timestamp without time zone,
+ data text,
);
EOF
View
@@ -124,8 +124,6 @@ your own version of F<talk/schedule>.
=item * B<F<user/stats>>
-=item * B<F<user/resetpassword>>
-
=item * B<F<user/purchase>>
=item * B<F<user/change>>
View
@@ -28,11 +28,11 @@
use Act::Handler::Track::Edit;
use Act::Handler::Track::List;
use Act::Handler::User::Change;
+use Act::Handler::User::ChangePassword;
use Act::Handler::User::Main;
use Act::Handler::User::Photo;
use Act::Handler::User::Purchase;
use Act::Handler::User::Register;
-use Act::Handler::User::ResetPassword;
use Act::Handler::User::Rights;
use Act::Handler::User::Search;
use Act::Handler::User::Show;
View
@@ -13,7 +13,11 @@ my @SCHEMA_UPDATES = (
alter table orders add column type text;
",
#3
- "alter table users rename civility to salutation;"
+ "alter table users rename civility to salutation;
+ ",
+#4
+ "alter table twostep add column data text;
+ ",
);
# returns ( current database schema version, required version )
@@ -17,12 +17,12 @@ use constant DEFAULT_PAGE => 'index.html';
# main dispatch table
my %public_handlers = (
atom => 'Act::Handler::News::Atom',
+ changepwd => 'Act::Handler::User::ChangePassword',
event => 'Act::Handler::Event::Show',
events => 'Act::Handler::Event::List',
login => 'Act::Handler::Login',
news => 'Act::Handler::News::List',
register => 'Act::Handler::User::Register',
- resetpw => 'Act::Handler::User::ResetPassword',
schedule => 'Act::Handler::Talk::Schedule',
search => 'Act::Handler::User::Search',
stats => 'Act::Handler::User::Stats',
@@ -34,7 +34,6 @@ my %public_handlers = (
);
my %private_handlers = (
change => 'Act::Handler::User::Change',
- changepwd => 'Act::Handler::User::ChangePassword',
create => 'Act::Handler::User::Create',
csv => 'Act::Handler::CSV',
editevent => 'Act::Handler::Event::Edit',
View
@@ -64,6 +64,15 @@ sub validate
or $self->{invalid}{$field} = $type;
}
}
+ # global validation
+ if ($self->{profile}{global}) {
+ for my $g ( @{ $self->{profile}{global} } ) {
+ unless ($g->( $self->{fields} )) {
+ $self->{invalid}{global} = 1;
+ last;
+ }
+ }
+ }
# return true if validation successful
return 0 == keys %{$self->{invalid}};
}
@@ -1,7 +1,8 @@
package Act::Handler::User::ChangePassword;
use strict;
-
+
+use Act::Auth;
use Act::Config;
use Act::Form;
use Act::Template::HTML;
@@ -15,6 +16,44 @@ my $form = Act::Form->new(
newpassword2 => sub { lc shift },
},
);
+# twostep form
+my $twostep_form = Act::Form->new(
+ optional => [qw(login email)],
+ filters => {
+ login => sub { lc shift },
+ email => sub { lc shift },
+ },
+ constraints => {
+ email => 'email',
+ },
+ global => [ sub {
+ my $fields = shift;
+ # exactly one of the fields must be provided
+ my %key;
+ for my $f (qw(login email)) {
+ if ($fields->{$f}) {
+ if (%key) {
+ %key = ();
+ last;
+ }
+ %key = ($f => $fields->{$f});
+ }
+ }
+ unless (%key) {
+ $fields->{error} = 'ERR_LOGIN_OR_EMAIL';
+ return;
+ }
+ # search for user
+ $fields->{user} = Act::User->new(%key);
+ unless ($fields->{user}) {
+ $fields->{error} = 'ERR_USER_NOT_FOUND';
+ return;
+ }
+ return 1;
+ } ],
+);
+# twostep template
+my $twostep_template = 'user/twostep_change_password';
sub handler
{
@@ -24,6 +63,13 @@ sub handler
# form has been submitted
my @errors;
+ # must have a valid twostep token if not logged in
+ my ($token, $token_data);
+ unless ($Request{user}) {
+ ($token, $token_data) = Act::TwoStep::verify_form()
+ or return;
+ }
+
# validate form fields
my $ok = $form->validate($Request{args});
$fields = $form->{fields};
@@ -35,10 +81,19 @@ sub handler
}
if ($ok) {
+ # remove token and authenticate user if twostep
+ unless ($Request{user}) {
+ my $user = Act::User->new(user_id => $token_data)
+ or die "unknown user_id: $token_data\n";
+ my $sid = Act::Util::create_session($user);
+ Act::Auth->send_cookie($sid);
+ Act::TwoStep::remove($token);
+ }
# update user
$Request{user}->update(
passwd => Act::Util::crypt_password( $fields->{newpassword1} )
);
+
# redirect to user's main page
return Act::Util::redirect(make_uri('main'));
}
@@ -50,6 +105,29 @@ sub handler
}
$template->variables(errors => \@errors);
}
+ elsif ($Request{args}{twostepsubmit}) { # two-step form has been submitted
+ # validate form and create a new token
+ if (Act::TwoStep::create(
+ $twostep_template, $twostep_form,
+ 'user/twostep_change_password_email_subject', 'user/twostep_change_password_email_body',
+ sub { $twostep_form->{fields}{user}{email} },
+ sub { my @errors;
+ $twostep_form->{invalid}{global} && push @errors, $twostep_form->{fields}{error};
+ $twostep_form->{invalid}{email} eq 'email' && push @errors, 'ERR_EMAIL_SYNTAX';
+ return \@errors;
+ },
+ sub { $twostep_form->{fields}{user}{user_id} },
+ )) {
+ # twostep form is valid, display confirmation page
+ $template->process('user/twostep_change_password_ok');
+ }
+ return;
+ }
+ elsif (!$Request{user}) { # user not logged in
+ # do we have a twostep token in the uri?
+ Act::TwoStep::verify_uri($twostep_template)
+ or return;
+ }
# display form
$template->process('user/change_password');
}
@@ -13,6 +13,16 @@ use Apache::Constants qw(FORBIDDEN);
use DateTime;
use DateTime::Format::Pg;
+# twostep form
+my $twostep_form = Act::Form->new(
+ required => [qw(email)],
+ filters => { email => sub { lc shift } },
+ constraints => { email => 'email' },
+);
+
+# twostep template filename
+my $twostep_template = 'user/twostep_add';
+
# registration form
my $form = Act::Form->new(
required => [qw(login first_name last_name email country tshirt )],
@@ -70,12 +80,11 @@ sub handler
my $template = Act::Template::HTML->new();
my $fields = {};
my $duplicates = [];
- my $token;
if ($Request{args}{join}) { # registration form has been submitted
# must have a valid twostep token
- $token = Act::TwoStep::verify_form()
+ (my $token) = Act::TwoStep::verify_form()
or return;
my @errors;
@@ -152,12 +161,24 @@ sub handler
}
elsif ($Request{args}{twostepsubmit}) { # two-step form has been submitted
# validate form and create a new token
- Act::TwoStep::create();
+ if (Act::TwoStep::create(
+ $twostep_template, $twostep_form,
+ 'user/twostep_add_email_subject', 'user/twostep_add_email_body',
+ sub { $twostep_form->{fields}{email} },
+ sub { my @errors;
+ $twostep_form->{invalid}{email} eq 'required' && push @errors, 'ERR_EMAIL';
+ $twostep_form->{invalid}{email} eq 'email' && push @errors, 'ERR_EMAIL_SYNTAX';
+ return \@errors;
+ },
+ )) {
+ $template->variables(email => $twostep_form->{fields}{email});
+ $template->process('user/twostep_add_ok');
+ }
return;
}
else {
# do we have a twostep token in the uri?
- $token = Act::TwoStep::verify_uri()
+ Act::TwoStep::verify_uri($twostep_template)
or return;
}
# display the registration form
@@ -1,126 +0,0 @@
-package Act::Handler::User::ResetPassword;
-
-use strict;
-
-use Act::Config;
-use Act::Email;
-use Act::Form;
-use Act::Template::HTML;
-use Act::User;
-use Act::Util;
-
-# reset password form
-my $form = Act::Form->new(
- optional => [qw(login email)],
- filters => {
- login => sub { lc shift },
- email => sub { lc shift },
- },
- constraints => {
- email => 'email',
- }
-);
-
-sub handler
-{
- my $template = Act::Template::HTML->new();
- my $fields;
-
- if ($Request{args}{ok}) {
- # form has been submitted
- my @errors;
-
- # validate form fields
- my $ok = $form->validate($Request{args});
- $fields = $form->{fields};
-
- # exactly one of the fields must be provided
- my %key;
- if ($ok) {
- for my $f (qw(login email)) {
- if ($fields->{$f}) {
- if (%key) {
- $ok = 0;
- last;
- }
- else {
- %key = ($f => $fields->{$f});
- }
- }
- }
- unless ($ok && %key) {
- $ok = 0;
- push @errors, 'ERR_LOGIN_OR_EMAIL';
- }
- }
- if ($ok) {
-
- # look for user
- my $user = Act::User->new(%key);
-
- if ($user) {
- # reset password
- my ($clear_passwd, $crypt_passwd) = Act::Util::gen_password();
-
- # update user
- $user->update(passwd => $crypt_passwd);
-
- # mail new password to user
- _send_email($user, $clear_passwd);
-
- # thanks for playing
- $template->variables(reset => 1);
- }
- else {
- push @errors, 'ERR_USER_NOT_FOUND';
- }
- }
- else {
- $form->{invalid}{email} eq 'email' && push @errors, 'ERR_EMAIL_SYNTAX';
- }
- $template->variables(errors => \@errors);
- }
- else {
- $fields = {};
- }
- # display form
- $template->variables(
- %$fields
- );
- $template->process('user/resetpassword');
-}
-
-sub _send_email
-{
- my ($user, $clear_passwd) = @_;
-
- # generate subject and body from templates
- my $template = Act::Template->new;
- my %output;
- for my $slot (qw(subject body)) {
- $template->variables(
- user => $user,
- passwd => $clear_passwd,
- );
- $template->process("user/reset_password_$slot", \$output{$slot});
- }
- # send the notification email
- Act::Email::send(
- from => $Config->email_sender_address,
- to => $user->email,
- %output,
- );
-}
-
-1;
-__END__
-
-=head1 NAME
-
-Act::Handler::User::ResetPassword - reset a user's password
-
-=head1 DESCRIPTION
-
-See F<DEVDOC> for a complete discussion on handlers.
-
-=cut
Oops, something went wrong.

0 comments on commit 3f55908

Please sign in to comment.