From 9a68e9ec839d43f630667fb8c55bbafc924902a1 Mon Sep 17 00:00:00 2001 From: swag Date: Fri, 21 Apr 2023 23:21:12 -0400 Subject: [PATCH] Actions for promoting/demoting admins --- lib/PostText.pm | 8 +++++ lib/PostText/Controller/Moderator.pm | 44 +++++++++++++++++++++++++ lib/PostText/Model/Moderator.pm | 16 +++++++++ t/admin.t | 44 ++++++++++++++++++++----- templates/layouts/default.html.ep | 10 +++--- templates/moderator/admin_reset.html.ep | 1 - templates/moderator/demote.html.ep | 10 ++++++ templates/moderator/lock_acct.html.ep | 6 ++-- templates/moderator/promote.html.ep | 10 ++++++ templates/moderator/unlock_acct.html.ep | 6 ++-- 10 files changed, 138 insertions(+), 17 deletions(-) create mode 100644 templates/moderator/demote.html.ep create mode 100644 templates/moderator/promote.html.ep diff --git a/lib/PostText.pm b/lib/PostText.pm index 718930b..758df99 100644 --- a/lib/PostText.pm +++ b/lib/PostText.pm @@ -215,6 +215,14 @@ sub startup($self) { $mod_admin->any([qw{GET POST}], '/unlock') ->to('moderator#unlock_acct') ->name('unlock_acct'); + + $mod_admin->any([qw{GET POST}], '/promote') + ->to('moderator#promote') + ->name('promote_mod'); + + $mod_admin->any([qw{GET POST}], '/demote') + ->to('moderator#demote') + ->name('demote_admin'); } 1; diff --git a/lib/PostText/Controller/Moderator.pm b/lib/PostText/Controller/Moderator.pm index d6b26ad..8d3a0b1 100644 --- a/lib/PostText/Controller/Moderator.pm +++ b/lib/PostText/Controller/Moderator.pm @@ -277,4 +277,48 @@ sub unlock_acct($self) { return $self->render; } +sub promote($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 => 404) + } + else { + my $email = $self->param('email'); + + $self->moderator->promote($email); + $self->stash(info => "Account $email has been promoted to admin 🧑‍🎓"); + } + } + + return $self->render; +} + +sub demote($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 => 404) + } + else { + my $email = $self->param('email'); + + $self->moderator->demote($email); + $self->stash(info => "Account $email has been demoted to mod 🧒"); + } + } + + return $self->render; +} + 1; diff --git a/lib/PostText/Model/Moderator.pm b/lib/PostText/Model/Moderator.pm index 1a9f6cc..7dc6b05 100644 --- a/lib/PostText/Model/Moderator.pm +++ b/lib/PostText/Model/Moderator.pm @@ -208,4 +208,20 @@ sub unlock_acct($self, $email) { END_SQL } +sub promote($self, $email) { + $self->pg->db->query(<<~'END_SQL', $email) + UPDATE moderators + SET admin_status = TRUE + WHERE email_addr = ?; + END_SQL +} + +sub demote($self, $email) { + $self->pg->db->query(<<~'END_SQL', $email) + UPDATE moderators + SET admin_status = FALSE + WHERE email_addr = ?; + END_SQL +} + 1; diff --git a/t/admin.t b/t/admin.t index 0e2dce7..f635a22 100644 --- a/t/admin.t +++ b/t/admin.t @@ -61,6 +61,22 @@ subtest Login => sub { ->element_exists('form input[name="email"]' ) }; + subtest Promote => sub { + $t->get_ok('/moderator/admin/promote') + ->status_is(200) + ->text_like(h2 => qr/Promote Moderator/) + ->element_exists('a[href*="/moderator/admin/promote"]') + ->element_exists('form input[name="email"]' ) + }; + + subtest Demote => sub { + $t->get_ok('/moderator/admin/demote') + ->status_is(200) + ->text_like(h2 => qr/Demote Admin/) + ->element_exists('a[href*="/moderator/admin/demote"]') + ->element_exists('form input[name="email"]' ) + }; + # Admin session ends $t->get_ok('/logout') ->status_is(302) @@ -69,17 +85,21 @@ 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/reset"]' ) - ->element_exists_not('a[href*="/moderator/admin/lock"]' ) - ->element_exists_not('a[href*="/moderator/admin/unlock"]'); + ->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"]' ) + ->element_exists_not('a[href*="/moderator/admin/promote"]') + ->element_exists_not('a[href*="/moderator/admin/demote"]' ); $t->get_ok('/remark/single/1') ->status_is(200) - ->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"]'); + ->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"]' ) + ->element_exists_not('a[href*="/moderator/admin/promote"]') + ->element_exists_not('a[href*="/moderator/admin/demote"]' ); $t->get_ok('/moderator/admin/create') ->status_is(302) @@ -96,6 +116,14 @@ subtest Login => sub { $t->get_ok('/moderator/admin/unlock') ->status_is(302) ->header_like(Location => qr/login/); + + $t->get_ok('/moderator/admin/promote') + ->status_is(302) + ->header_like(Location => qr/login/); + + $t->get_ok('/moderator/admin/demote') + ->status_is(302) + ->header_like(Location => qr/login/); }; }; diff --git a/templates/layouts/default.html.ep b/templates/layouts/default.html.ep index 20f888e..dcc580a 100644 --- a/templates/layouts/default.html.ep +++ b/templates/layouts/default.html.ep @@ -26,10 +26,12 @@
<% if (is_admin) { =%> Admin: - <%= link_to Create => 'create_mod' %> - <%= link_to Reset => 'admin_reset' %> - <%= link_to Lock => 'lock_acct' %> - <%= link_to Unlock => 'unlock_acct' %> + <%= link_to Create => 'create_mod' %> + <%= link_to Reset => 'admin_reset' %> + <%= link_to Lock => 'lock_acct' %> + <%= link_to Unlock => 'unlock_acct' %> + <%= link_to Promote => 'promote_mod' %> + <%= link_to Demote => 'demote_admin' %> <% } =%>
diff --git a/templates/moderator/admin_reset.html.ep b/templates/moderator/admin_reset.html.ep index 81f05cb..9ccb05c 100644 --- a/templates/moderator/admin_reset.html.ep +++ b/templates/moderator/admin_reset.html.ep @@ -12,4 +12,3 @@ <%= submit_button 'Reset' %> - diff --git a/templates/moderator/demote.html.ep b/templates/moderator/demote.html.ep new file mode 100644 index 0000000..de9933c --- /dev/null +++ b/templates/moderator/demote.html.ep @@ -0,0 +1,10 @@ +% layout 'default'; +% title 'Demote Admin'; +

<%= title %>

+
+ + <%= submit_button 'Demote' %> +
diff --git a/templates/moderator/lock_acct.html.ep b/templates/moderator/lock_acct.html.ep index a426725..e14e006 100644 --- a/templates/moderator/lock_acct.html.ep +++ b/templates/moderator/lock_acct.html.ep @@ -2,7 +2,9 @@ % title 'Lock Account';

<%= title %>

- <%= label_for email => 'Email' %> - <%= email_field 'email' %> + <%= submit_button 'Lock' %>
diff --git a/templates/moderator/promote.html.ep b/templates/moderator/promote.html.ep new file mode 100644 index 0000000..014c46d --- /dev/null +++ b/templates/moderator/promote.html.ep @@ -0,0 +1,10 @@ +% layout 'default'; +% title 'Promote Moderator'; +

<%= title %>

+
+ + <%= submit_button 'Promote' %> +
diff --git a/templates/moderator/unlock_acct.html.ep b/templates/moderator/unlock_acct.html.ep index 16f4d7f..dcd70f1 100644 --- a/templates/moderator/unlock_acct.html.ep +++ b/templates/moderator/unlock_acct.html.ep @@ -2,7 +2,9 @@ % title 'Unlock Account';

<%= title %>

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