Refactored admin controller.

master
Manager Bot 3 years ago
parent 9eaf1d4dff
commit b991658a87
  1. 9
      Web/lib/MJB/Web.pm
  2. 238
      Web/lib/MJB/Web/Controller/Admin.pm

@ -68,13 +68,20 @@ sub startup ($self) {
# Helper to redirect on errors, support setting the form and errors in a flash
# if they exist in the stash.
$self->helper( redirect_error => sub ( $c, $redirect_to, $redirect_args = {} ) {
$self->helper( redirect_error => sub ( $c, $redirect_to, $redirect_args = {}, $errors = [] ) {
push @{$c->stash->{errors}}, @{$errors} if $errors;
$c->flash( form => $c->stash->{form} ) if $c->stash->{form};
$c->flash( errors => $c->stash->{errors} ) if $c->stash->{errors};
$c->redirect_to( $c->url_for( $redirect_to, $redirect_args ) );
});
# Helper to redirect on success, support setting a message and redirecting to a named route.
$self->helper( redirect_success => sub ( $c, $redirect_to, $success_message ) {
$c->flash( confirmation => $success_message );
$c->redirect_to( $c->url_for( $redirect_to ) );
});
# Minion plugin & tasks
$self->plugin( Minion => { Pg => $self->config->{database}->{minion} } );

@ -2,26 +2,30 @@ package MJB::Web::Controller::Admin;
use Mojo::Base 'Mojolicious::Controller', -signatures;
use Try::Tiny;
#==
# GET /admin | show_admin
#
# Redirect to the people listing page.
#==
sub index ( $c ) {
$c->redirect_to( 'show_admin_people' );
}
# POST /admin
#==
# POST /admin | do_admin_become
# uid | A user id, that the admin would like to become
# bid | A blog id, that the admin will go to the manage page for
# url | A URL to return to when the admin logs out of the user account
#
# An admin may inpersonate any other user for technical support purposes,
# this code is called to become another user. Sign out to become your origional
# user again.
#
# INPUT:
# uid | A user id
# bid | A blog id belonging to the user
# url | A URL to return to when the admin logs out of the user account
#
# When given a uid, become that user and go to the user's dashboard.
#
# When given a uid and a bid that the user owns, become that user
# and go to the blog's dashboard.
#
#==
sub do_admin_become ( $c ) {
my ( $uid, $bid, $url ) = ( $c->param('uid'), $c->param('bid'), $c->param('url') );
@ -38,15 +42,31 @@ sub do_admin_become ( $c ) {
}
}
#==
# GET /admin/people | show_admin_people
#
# This route shows people, users, who exist on this system.
#==
sub people ( $c ) {
my $people = $c->stash->{people} = [ $c->db->people->all ];
}
#==
# GET /admin/person/:id | show_admin_person, { id => ? }
#
# This route shows a given person, their blogs, and notes about them.
#==
sub person ( $c ) {
my $profile = $c->stash->{profile} = $c->db->person( $c->param('id') );
my $notes = $c->stash->{notes} = [ $profile->person_note_people->all ];
}
#==
# POST /admin/person/:id/note | do_admin_person_note { id => person.id }
# content | The content of the message about this user.
#
# This route makes a note about a person on their profile page.
#==
sub do_person_note ( $c ) {
my $profile = $c->db->person( $c->param('id') );
my $content = $c->param('content');
@ -58,24 +78,35 @@ sub do_person_note ( $c ) {
$c->flash( confirmation => "Added note to this account." );
$c->redirect_to( $c->url_for( 'show_admin_person', { id => $profile->id } ) );
}
#==
# GET /admin/blogs | show_admin_blogs
#
# This route lists blogs that are hosted on this system.
#==
sub blogs ( $c ) {
my $blogs = $c->stash->{blogs} = [ $c->db->blogs->all ];
}
sub servers ( $c ) {
my $servers = $c->stash->{servers} = [ $c->db->servers->all ];
}
#==
# GET /admin/invites | show_admin_invites
#
# This route shows the invites that currently exist and can be used.
#==
sub invites ( $c ) {
my $invites = $c->stash->{invites} = [ $c->db->invites->all ];
}
#==
# POST /admin/invite | do_admin_invite
# code | The invite code, this is case-sensitive.
# is_multi_use | When true, the code may be used more than once.
#
# This route adds an invite code.
#==
sub do_invite ( $c ) {
my $code = $c->param('code');
my $is_multi_use = $c->param('is_multi_use' );
@ -88,29 +119,50 @@ sub do_invite ( $c ) {
});
});
} catch {
$c->flash( error_message => "Invite Code could not be created: $_" );
push @{$c->stash->{errors}}, "Invite code could not be created: $_";
};
return $c->redirect_error( 'show_admin_invites' )
if $c->stash->{errors};
$c->redirect_to( $c->url_for( 'show_admin_invites' ) );
return;
return $c->redirect_success( 'show_admin_invites', "Added $code to invites." );
}
#==
# POST /admin/invite/remove | do_admin_invite_remove
# iid | The id of the invite code to delete
#
# This route deletes an invite code.
#==
sub do_invite_remove ( $c ) {
my $invite = $c->db->invite($c->param('iid'));
if ( ! $invite ) {
$c->flash( error_message => "Invite could not be removed, because it doesn't exist?" );
$c->redirect_to( $c->url_for( 'show_admin_invites' ) );
return;
}
return $c->redirect_error( 'show_admin_invites', {}, [ 'The invite does not exist' ] )
unless $invite;
my $code = $invite->code;
$invite->delete;
$c->flash( confirmation => "Removed $code from invite pool." );
$c->redirect_to( $c->url_for( 'show_admin_invites' ) );
return $c->redirect_success( 'show_admin_invites', "Removed $code from invite pool." );
}
#==
# GET /admin/servers | show_admin_servers
#
# This route shows servers that blogs are hosted on, and deployed to.
#==
sub servers ( $c ) {
my $servers = $c->stash->{servers} = [ $c->db->servers->all ];
}
#==
# POST /admin/server | do_admin_server
# server_fqdn | The domain name to use for the server, builder and certbot
# servers should have ssh access to these servers.
#
# This route adds a server to the pool for deployment. These servers are used by
# the certbot and builder servers to deploy ssl certs and blogs to.
#==
sub do_server ( $c ) {
my $fqdn = $c->param('server_fqdn');
@ -119,36 +171,53 @@ sub do_server ( $c ) {
$c->db->servers->create({ hostname => $fqdn });
});
} catch {
$c->flash( error_message => "Server could not be created: $_" );
$c->redirect_to( $c->url_for( 'show_admin_servers' ) );
return;
push @{$c->stash->{errors}}, "Server could not be created: $_";
};
return $c->redirect_error( 'show_admin_servers' )
if $c->stash->{errors};
$c->flash( confirmation => "Added $fqdn to server pool." );
$c->redirect_to( $c->url_for( 'show_admin_servers' ) );
return $c->redirect_success( 'show_admin_servers', "Added $fqdn to server pool." );
}
#==
# POST /admin/server/remove | do_admin_server_remove
# sid | The id of the server to remove
#
# This route removes a server from the rotation used for deploying blogs/ssl certs.
#==
sub do_server_remove ( $c ) {
my $server = $c->db->server($c->param('sid'));
if ( ! $server ) {
$c->flash( error_message => "Server could not be removed, because it doesn't exist?" );
$c->redirect_to( $c->url_for( 'show_admin_servers' ) );
return;
}
return $c->redirect_error( 'show_admin_servers', {}, [ 'The server does not exist' ] )
unless $server;
my $hostname = $server->hostname;
$server->delete;
$c->flash( confirmation => "Removed $hostname from server pool." );
$c->redirect_to( $c->url_for( 'show_admin_servers' ) );
return $c->redirect_success( 'show_admin_servers', "Removed $hostname to server pool." );
}
#==
# GET /admin/domains | show_admin_domains
#
# This route shows domains that users can host their blogs under.
#==
sub domains ( $c ) {
my $domains = $c->stash->{domains} = [ $c->db->hosted_domains->all ];
$c->stash->{domains} = [ $c->db->hosted_domains->all ];
}
#==
# POST /admin/domain | do_admin_domain
# domain_fqdn | The fully qualified domain name we will use for hosting (i.e. foobar.net)
# ssl_challenge | The challenge type -- dns-linode or http to use for validating domains
#
# This route will add a domain to use for hosting. For example, if one adds foobar.net, then
# users will be able to host blogs like myblog.foobar.net.
#
# http challenges will use the certbot server and /.well-known/ forwarding for creation/updating w/ --standalone
# dns-linode challenges will use the --dns-linode plugin and credentials expected to be done with ansible.
#==
sub do_domain ( $c ) {
my $fqdn = $c->param('domain_fqdn');
my $ssl = $c->param('ssl_challenge');
@ -158,35 +227,44 @@ sub do_domain ( $c ) {
$c->db->hosted_domains->create({ name => $fqdn, letsencrypt_challenge => $ssl });
});
} catch {
$c->flash( error_message => "domain could not be created: $_" );
$c->redirect_to( $c->url_for( 'show_admin_domains' ) );
return;
push @{$c->stash->{errors}}, "Domain could not be created: $_";
};
return $c->redirect_error( 'show_admin_domains' )
if $c->stash->{errors};
if ( $ssl eq 'dns-linode' ) {
$c->minion->enqueue( 'mk_wildcard_ssl', [ $domain->id ], { queue => 'certbot' } );
}
$c->flash( confirmation => "Added $fqdn to domain pool." );
$c->redirect_to( $c->url_for( 'show_admin_domains' ) );
return $c->redirect_success( 'show_admin_domains', "Added $fqdn to domain pool." );
}
#==
# POST /admin/domain/remove | do_admin_domain_remove
# did | The ID for the domain to remove.
#
# This route will remove a hosted domain by its ID.
#==
sub do_domain_remove ( $c ) {
my $domain = $c->db->hosted_domain($c->param('did'));
if ( ! $domain ) {
$c->flash( error_message => "domain could not be removed, because it doesn't exist?" );
$c->redirect_to( $c->url_for( 'show_admin_domains' ) );
return;
}
return $c->redirect_error( 'show_admin_domains', {}, [ "That domain doesn't seem to exist." ] )
unless $domain;
my $hostname = $domain->name;
$domain->delete;
$c->flash( confirmation => "Removed $hostname from domain pool." );
$c->redirect_to( $c->url_for( 'show_admin_domains' ) );
return $c->redirect_success( 'show_admin_domains', "Removed $hostname from domain pool." );
}
#==
# POST /admin/update_ssl | do_admin_update_ssl
#
# This route will schedule a job for update_ssl SSL certs on
# the certbot server and then sync them with the webserver.
# certbot server to the webservers.
#==
sub do_update_ssl ( $c ) {
my $id = $c->minion->enqueue( 'update_ssl_certs', [ ], {
queue => 'certbot',
@ -194,10 +272,15 @@ sub do_update_ssl ( $c ) {
});
$c->db->admin_jobs->create({ minion_job_id => $id });
$c->flash( confirmation => "Scheduled job to update SSL certs." );
$c->redirect_to( $c->url_for( 'show_admin_jobs' ) );
return $c->redirect_success( 'show_admin_jobs', 'Scheduled job to update SSL certs.' );
}
#==
# POST /admin/sync_ssl | do_admin_sync_ssl
#
# This route will schedule a job for syncing SSL certs from the
# certbot server to the webservers.
#==
sub do_sync_ssl ( $c ) {
my $id = $c->minion->enqueue( 'sync_ssl_certs', [ ], {
queue => 'certbot',
@ -205,58 +288,61 @@ sub do_sync_ssl ( $c ) {
});
$c->db->admin_jobs->create({ minion_job_id => $id });
$c->flash( confirmation => "Scheduled job to sync SSL certs." );
$c->redirect_to( $c->url_for( 'show_admin_jobs' ) );
return $c->redirect_success( 'show_admin_jobs', 'Scheduled job to sync SSL certs.' );
}
#==
# POST /admin/alert/read | do_admin_alert_read
# nid | The ID for the system_note
#
# This route will mark a system_note as read when given the note id.
#==
sub do_alert_read ( $c ) {
my $note = $c->db->system_note( $c->param('nid') );
if ( ! $note ) {
$c->flash( error_message => "Note could not be marked as read, because it doesn't exist?" );
$c->redirect_to( $c->url_for( 'show_admin_alerts' ) );
return;
}
return $c->redirect_error( 'show_admin_alerts', {}, [ "That note doesn't seem to exist." ] )
unless $note;
$note->is_read( 1 );
$note->update;
$c->flash( confirmation => "Note marked as read." );
$c->redirect_to( $c->url_for( 'show_admin_alerts' ) );
return $c->redirect_success( 'show_admin_alerts', 'Note marked as read.' );
}
#==
# POST /admin/alert/unread | do_admin_alert_unread
# nid | The ID for the system_note
#
# This route will mark a system_note as unread when given the note id.
#==
sub do_alert_unread ( $c ) {
my $note = $c->db->system_note( $c->param('nid') );
if ( ! $note ) {
$c->flash( error_message => "Note could not be marked as unread, because it doesn't exist?" );
$c->redirect_to( $c->url_for( 'show_admin_alerts' ) );
return;
}
return $c->redirect_error( 'show_admin_alerts', {}, [ "That note doesn't seem to exist." ] )
unless $note;
$note->is_read( 0 );
$note->update;
$c->flash( confirmation => "Note marked as read." );
$c->redirect_to( $c->url_for( 'show_admin_alerts' ) );
return $c->redirect_success( 'show_admin_alerts', 'Note marked as unread.' );
}
#==
# POST /admin/alert/remove | do_admin_alert_remove
# nid | The ID for the system_note
#
# This route will delete a system_note when given the note id.
#==
sub do_alert_remove ( $c ) {
my $note = $c->db->system_note( $c->param('nid') );
if ( ! $note ) {
$c->flash( error_message => "Note could not be removed, because it doesn't exist?" );
$c->redirect_to( $c->url_for( 'show_admin_alerts' ) );
return;
}
return $c->redirect_error( 'show_admin_alerts', {}, [ "That note doesn't seem to exist." ] )
unless $note;
$note->delete;
$c->flash( confirmation => "Note removed" );
$c->redirect_to( $c->url_for( 'show_admin_alerts' ) );
return $c->redirect_success( 'show_admin_alerts', 'Note removed.' );
}
1;

Loading…
Cancel
Save