aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Reaction/InterfaceModel/Action/User
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Reaction/InterfaceModel/Action/User')
-rw-r--r--lib/Reaction/InterfaceModel/Action/User/ChangePassword.pm63
-rw-r--r--lib/Reaction/InterfaceModel/Action/User/Login.pm49
-rw-r--r--lib/Reaction/InterfaceModel/Action/User/ResetPassword.pm63
-rw-r--r--lib/Reaction/InterfaceModel/Action/User/Role/ConfirmationCodeSupport.pm44
-rw-r--r--lib/Reaction/InterfaceModel/Action/User/SetPassword.pm69
5 files changed, 288 insertions, 0 deletions
diff --git a/lib/Reaction/InterfaceModel/Action/User/ChangePassword.pm b/lib/Reaction/InterfaceModel/Action/User/ChangePassword.pm
new file mode 100644
index 0000000..fc8ff88
--- /dev/null
+++ b/lib/Reaction/InterfaceModel/Action/User/ChangePassword.pm
@@ -0,0 +1,63 @@
+package Reaction::InterfaceModel::Action::User::ChangePassword;
+
+use Reaction::Class;
+
+class ChangePassword is 'Reaction::InterfaceModel::Action::User::SetPassword', which {
+ has old_password => (isa => 'Password', is => 'rw', lazy_fail => 1);
+
+ around error_for_attribute => sub {
+ my $super = shift;
+ my ($self, $attr) = @_;
+ if ($attr->name eq 'old_password') {
+ return "Old password incorrect"
+ unless $self->verify_old_password;
+ }
+ #return $super->(@_); #commented out because the original didn't super()
+ };
+
+ around can_apply => sub {
+ my $super = shift;
+ my ($self) = @_;
+ return 0 unless $self->verify_old_password;
+ return $super->(@_);
+ };
+
+ implements verify_old_password => as {
+ my $self = shift;
+ return unless $self->has_old_password;
+
+ my $user = $self->target_model;
+ return $user->can("check_password") ?
+ $user->check_password($self->old_password) :
+ $self->old_password eq $user->password;
+ };
+
+};
+
+1;
+
+=head1 NAME
+
+Reaction::InterfaceModel::Action::User::ChangePassword
+
+=head1 DESCRIPTION
+
+=head1 METHODS
+
+=head2 old_password
+
+=head2 verify_old_password
+
+=head1 SEE ALSO
+
+L<Reaction::InterfaceModel::Action::DBIC::User::ChangePassword>
+
+=head1 AUTHORS
+
+See L<Reaction::Class> for authors.
+
+=head1 LICENSE
+
+See L<Reaction::Class> for the license.
+
+=cut
diff --git a/lib/Reaction/InterfaceModel/Action/User/Login.pm b/lib/Reaction/InterfaceModel/Action/User/Login.pm
new file mode 100644
index 0000000..781ec0f
--- /dev/null
+++ b/lib/Reaction/InterfaceModel/Action/User/Login.pm
@@ -0,0 +1,49 @@
+package Reaction::InterfaceModel::Action::User::Login;
+
+use Reaction::Class;
+use aliased 'Reaction::InterfaceModel::Action';
+
+class Login, is Action, which {
+
+ has 'username' => (isa => 'SimpleStr', is => 'rw', lazy_fail => 1);
+ has 'password' => (isa => 'Password', is => 'rw', lazy_fail => 1);
+
+ around error_for_attribute => sub {
+ my $super = shift;
+ my ($self, $attr) = @_;
+ my $result = $super->(@_);
+ my $predicate = $attr->predicate;
+ if (defined $result && $self->$predicate) {
+ return 'Invalid username or password';
+ }
+ return;
+ };
+
+ implements do_apply => as {
+ my $self = shift;
+ my $target = $self->target_model;
+ return $target->login($self->username, $self->password);
+ };
+};
+
+1;
+
+=head1 NAME
+
+Reaction::InterfaceModel::Action::User::Login
+
+=head1 DESCRIPTION
+
+=head2 username
+
+=head2 password
+
+=head1 AUTHORS
+
+See L<Reaction::Class> for authors.
+
+=head1 LICENSE
+
+See L<Reaction::Class> for the license.
+
+=cut
diff --git a/lib/Reaction/InterfaceModel/Action/User/ResetPassword.pm b/lib/Reaction/InterfaceModel/Action/User/ResetPassword.pm
new file mode 100644
index 0000000..3ef645d
--- /dev/null
+++ b/lib/Reaction/InterfaceModel/Action/User/ResetPassword.pm
@@ -0,0 +1,63 @@
+package Reaction::InterfaceModel::Action::User::ResetPassword;
+
+use Reaction::Class;
+use Digest::MD5;
+
+use aliased
+ 'Reaction::InterfaceModel::Action::User::Role::ConfirmationCodeSupport';
+use aliased 'Reaction::InterfaceModel::Action::User::SetPassword';
+
+class ResetPassword is SetPassword, which {
+
+ does ConfirmationCodeSupport;
+
+ has confirmation_code =>
+ (isa => 'NonEmptySimpleStr', is => 'rw', lazy_fail => 1);
+
+ around error_for_attribute => sub {
+ my $super = shift;
+ my ($self, $attr) = @_;
+ if ($attr->name eq 'confirmation_code') {
+ return "Confirmation code incorrect"
+ unless $self->verify_confirmation_code;
+ }
+ #return $super->(@_); #commented out because the original didn't super()
+ };
+
+ implements verify_confirmation_code => as {
+ my $self = shift;
+ return $self->has_confirmation_code
+ && ($self->confirmation_code eq $self->generate_confirmation_code);
+ };
+
+};
+
+1;
+
+=head1 NAME
+
+Reaction::InterfaceModel::Action::User::ResetPassword
+
+=head1 DESCRIPTION
+
+=head2 error_for_attribute
+
+=head2 confirmation_code
+
+=head2 verify_confirmation_code
+
+=head1 SEE ALSO
+
+L<Reaction::InterfaceModel::Action::DBIC::User::ResetPassword>
+
+L<Reaction::InterfaceModel::Action::User::Role::ConfirmationCodeSupport>
+
+=head1 AUTHORS
+
+See L<Reaction::Class> for authors.
+
+=head1 LICENSE
+
+See L<Reaction::Class> for the license.
+
+=cut
diff --git a/lib/Reaction/InterfaceModel/Action/User/Role/ConfirmationCodeSupport.pm b/lib/Reaction/InterfaceModel/Action/User/Role/ConfirmationCodeSupport.pm
new file mode 100644
index 0000000..649f76a
--- /dev/null
+++ b/lib/Reaction/InterfaceModel/Action/User/Role/ConfirmationCodeSupport.pm
@@ -0,0 +1,44 @@
+package Reaction::InterfaceModel::Action::User::Role::ConfirmationCodeSupport;
+
+use Reaction::Role;
+use Digest::MD5;
+
+role ConfirmationCodeSupport, which{
+
+ #requires qw/target_model ctx/;
+
+ implements generate_confirmation_code => as {
+ my $self = shift;
+ my $ident = $self->target_model->identity_string.
+ $self->target_model->password;
+ my $secret = $self->ctx->config->{confirmation_code_secret};
+ die "Application config does not define confirmation_code_secret"
+ unless $secret;
+ return Digest::MD5::md5_hex($secret.$ident);
+ };
+
+};
+
+1;
+
+=head1 NAME
+
+Reaction::InterfaceModel::Action::User::Role::ConfirmationCodeSupport
+
+=head1 DESCRIPTION
+
+=head2 generate_confirmation_code
+
+=head2 meta
+
+Need to define confirmation_code_secret in application config.
+
+=head1 AUTHORS
+
+See L<Reaction::Class> for authors.
+
+=head1 LICENSE
+
+See L<Reaction::Class> for the license.
+
+=cut
diff --git a/lib/Reaction/InterfaceModel/Action/User/SetPassword.pm b/lib/Reaction/InterfaceModel/Action/User/SetPassword.pm
new file mode 100644
index 0000000..fcf922a
--- /dev/null
+++ b/lib/Reaction/InterfaceModel/Action/User/SetPassword.pm
@@ -0,0 +1,69 @@
+package Reaction::InterfaceModel::Action::User::SetPassword;
+
+use Reaction::Class;
+use Reaction::InterfaceModel::Action;
+
+class SetPassword is 'Reaction::InterfaceModel::Action', which {
+
+ has new_password => (isa => 'Password', is => 'rw', lazy_fail => 1);
+ has confirm_new_password =>
+ (isa => 'Password', is => 'rw', lazy_fail => 1);
+
+ around error_for_attribute => sub {
+ my $super = shift;
+ my ($self, $attr) = @_;
+ if ($attr->name eq 'confirm_new_password') {
+ return "New password doesn't match"
+ unless $self->verify_confirm_new_password;
+ }
+ return $super->(@_);
+ };
+
+ around can_apply => sub {
+ my $super = shift;
+ my ($self) = @_;
+ return 0 unless $self->verify_confirm_new_password;
+ return $super->(@_);
+ };
+
+ implements verify_confirm_new_password => as {
+ my $self = shift;
+ return $self->has_new_password && $self->has_confirm_new_password
+ && ($self->new_password eq $self->confirm_new_password);
+ };
+
+};
+
+1;
+
+=head1 NAME
+
+Reaction::InterfaceModel::Action::User::SetPassword
+
+=head1 DESCRIPTION
+
+=head1 ATTRIBUTES
+
+=head2 new_password
+
+=head2 confirm_new_password
+
+=head1 METHODS
+
+=head2 verify_confirm_new_password
+
+Tests to make sure that C<new_password> and C<confirm_new_password> match.
+
+=head1 SEE ALSO
+
+L<Reaction::InterfaceModel::Action::DBIC::User::SetPassword>
+
+=head1 AUTHORS
+
+See L<Reaction::Class> for authors.
+
+=head1 LICENSE
+
+See L<Reaction::Class> for the license.
+
+=cut