From 10cd3cffb17e14d23dc95f18ce87cc2b308bcdb0 Mon Sep 17 00:00:00 2001 From: swag Date: Fri, 21 Apr 2023 22:25:05 -0400 Subject: [PATCH] Actions for locking/unlocking accounts --- README.md | 1 - lib/PostText.pm | 9 +++++ lib/PostText/Controller/Moderator.pm | 44 +++++++++++++++++++++++++ lib/PostText/Model/Moderator.pm | 16 +++++++++ t/admin.t | 40 ++++++++++++++++++++-- templates/layouts/default.html.ep | 2 ++ templates/moderator/lock_acct.html.ep | 8 +++++ templates/moderator/unlock_acct.html.ep | 8 +++++ 8 files changed, 125 insertions(+), 3 deletions(-) create mode 100644 templates/moderator/lock_acct.html.ep create mode 100644 templates/moderator/unlock_acct.html.ep diff --git a/README.md b/README.md index c1978bf..7f99141 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,6 @@ Run the tests locally (against development environment): ## TODOs -1. Action for locking/unlocking accounts 1. CSS 1. "All new posts flagged" mode (require approval for new posts) diff --git a/lib/PostText.pm b/lib/PostText.pm index 539e350..718930b 100644 --- a/lib/PostText.pm +++ b/lib/PostText.pm @@ -206,6 +206,15 @@ sub startup($self) { $mod_admin->any([qw{GET POST}], '/reset') ->to('moderator#admin_reset') ->name('admin_reset'); + + # lock() is a builtin so use _acct suffix + $mod_admin->any([qw{GET POST}], '/lock') + ->to('moderator#lock_acct') + ->name('lock_acct'); + + $mod_admin->any([qw{GET POST}], '/unlock') + ->to('moderator#unlock_acct') + ->name('unlock_acct'); } 1; diff --git a/lib/PostText/Controller/Moderator.pm b/lib/PostText/Controller/Moderator.pm index 8d1cff0..d6b26ad 100644 --- a/lib/PostText/Controller/Moderator.pm +++ b/lib/PostText/Controller/Moderator.pm @@ -233,4 +233,48 @@ sub mod_reset($self) { return $self->render; } +sub lock_acct($self) { + my $v; + + $v = $self->validation if $self->req->method eq 'POST'; + + if ($v && $v->has_data) { + $v->required('email'); + + if ($v->has_error) { + $self->stash(status => 400) + } + else { + my $email = $self->param('email'); + + $self->moderator->lock_acct($email); + $self->stash(info => "Account $email has been locked 🔒"); + } + } + + return $self->render; +} + +sub unlock_acct($self) { + my $v; + + $v = $self->validation if $self->req->method eq 'POST'; + + if ($v && $v->has_data) { + $v->required('email'); + + if ($v->has_error) { + $self->stash(status => 400) + } + else { + my $email = $self->param('email'); + + $self->moderator->unlock_acct($email); + $self->stash(info => "Account $email has been unlocked 🔓"); + } + } + + return $self->render; +} + 1; diff --git a/lib/PostText/Model/Moderator.pm b/lib/PostText/Model/Moderator.pm index 847f2f2..1a9f6cc 100644 --- a/lib/PostText/Model/Moderator.pm +++ b/lib/PostText/Model/Moderator.pm @@ -192,4 +192,20 @@ sub mod_reset($self, $mod_id, $password) { END_SQL } +sub lock_acct($self, $email) { + $self->pg->db->query(<<~'END_SQL', $email) + UPDATE moderators + SET lock_status = TRUE + WHERE email_addr = ?; + END_SQL +} + +sub unlock_acct($self, $email) { + $self->pg->db->query(<<~'END_SQL', $email) + UPDATE moderators + SET lock_status = FALSE + WHERE email_addr = ?; + END_SQL +} + 1; diff --git a/t/admin.t b/t/admin.t index 21d2e0d..0e2dce7 100644 --- a/t/admin.t +++ b/t/admin.t @@ -41,6 +41,24 @@ subtest Login => sub { ->status_is(200) ->text_like(h2 => qr/Reset Password/) ->element_exists('a[href*="/moderator/admin/reset"]') + ->element_exists('form input[name="email"]' ) + ->element_exists('form input[name="password"]' ) + }; + + subtest Lock => sub { + $t->get_ok('/moderator/admin/lock') + ->status_is(200) + ->text_like(h2 => qr/Lock Account/) + ->element_exists('a[href*="/moderator/admin/lock"]') + ->element_exists('form input[name="email"]' ) + }; + + subtest Unlock => sub { + $t->get_ok('/moderator/admin/unlock') + ->status_is(200) + ->text_like(h2 => qr/Unlock Account/) + ->element_exists('a[href*="/moderator/admin/unlock"]') + ->element_exists('form input[name="email"]' ) }; # Admin session ends @@ -51,15 +69,33 @@ subtest Login => sub { subtest 'No admin, no buttons', sub { $t->get_ok('/thread/single/1') ->status_is(200) - ->element_exists_not('a[href*="/moderator/admin/create"]'); + ->element_exists_not('a[href*="/moderator/admin/create"]') + ->element_exists_not('a[href*="/moderator/admin/reset"]' ) + ->element_exists_not('a[href*="/moderator/admin/lock"]' ) + ->element_exists_not('a[href*="/moderator/admin/unlock"]'); $t->get_ok('/remark/single/1') ->status_is(200) - ->element_exists_not('a[href*="/moderator/admin/create"]'); + ->element_exists_not('a[href*="/moderator/admin/create"]') + ->element_exists_not('a[href*="/moderator/admin/reset"]' ) + ->element_exists_not('a[href*="/moderator/admin/lock"]' ) + ->element_exists_not('a[href*="/moderator/admin/unlock"]'); $t->get_ok('/moderator/admin/create') ->status_is(302) ->header_like(Location => qr/login/); + + $t->get_ok('/moderator/admin/reset') + ->status_is(302) + ->header_like(Location => qr/login/); + + $t->get_ok('/moderator/admin/lock') + ->status_is(302) + ->header_like(Location => qr/login/); + + $t->get_ok('/moderator/admin/unlock') + ->status_is(302) + ->header_like(Location => qr/login/); }; }; diff --git a/templates/layouts/default.html.ep b/templates/layouts/default.html.ep index 52f846c..20f888e 100644 --- a/templates/layouts/default.html.ep +++ b/templates/layouts/default.html.ep @@ -28,6 +28,8 @@ Admin: <%= link_to Create => 'create_mod' %> <%= link_to Reset => 'admin_reset' %> + <%= link_to Lock => 'lock_acct' %> + <%= link_to Unlock => 'unlock_acct' %> <% } =%> diff --git a/templates/moderator/lock_acct.html.ep b/templates/moderator/lock_acct.html.ep new file mode 100644 index 0000000..a426725 --- /dev/null +++ b/templates/moderator/lock_acct.html.ep @@ -0,0 +1,8 @@ +% layout 'default'; +% title 'Lock Account'; +

<%= title %>

+
+ <%= label_for email => 'Email' %> + <%= email_field 'email' %> + <%= submit_button 'Lock' %> +
diff --git a/templates/moderator/unlock_acct.html.ep b/templates/moderator/unlock_acct.html.ep new file mode 100644 index 0000000..16f4d7f --- /dev/null +++ b/templates/moderator/unlock_acct.html.ep @@ -0,0 +1,8 @@ +% layout 'default'; +% title 'Unlock Account'; +

<%= title %>

+
+ <%= label_for email => 'Email' %> + <%= email_field 'email' %> + <%= submit_button 'Unlock' %> +