diff --git a/Web/lib/MJB/Web.pm b/Web/lib/MJB/Web.pm index fc51ac8..62a0ba5 100644 --- a/Web/lib/MJB/Web.pm +++ b/Web/lib/MJB/Web.pm @@ -181,10 +181,21 @@ sub startup ($self) { $blog->post( '/page/remove' )->to('Dashboard#do_blog_page_remove' )->name('do_dashboard_blog_page_remove' ); # Blog Creation - $auth->get ( '/blog' )->to('Blog#create' )->name('show_blog_create' ); - $auth->post( '/blog' )->to('Blog#do_create' )->name('do_blog_create' ); - $auth->get ( '/blog/:id/settings' )->to('Blog#settings' )->name('show_blog_settings' ); - $auth->post( '/blog/:id/settings' )->to('Blog#do_settings' )->name('do_blog_settings' ); + $auth->get ( '/blog' )->to('Blog#index' )->name('show_blog' ); + $auth->get ( '/blog/domain/hosted' )->to('Blog#domain_hosted' )->name('show_blog_domain_hosted' ); + $auth->post( '/blog/domain/hosted' )->to('Blog#do_domain_hosted' )->name('do_blog_domain_hosted' ); + $auth->get ( '/blog/domain/owned' )->to('Blog#domain_owned' )->name('show_blog_domain_owned' ); + $auth->post( '/blog/domain/owned' )->to('Blog#do_domain_owned' )->name('do_blog_domain_owned' ); + $auth->get ( '/blog/initialize' )->to('Blog#do_initialize' )->name('do_blog_initialize' ); + $auth->get ( '/blog/:id/settings' )->to('Blog#settings' )->name('show_blog_settings' ); + $auth->post( '/blog/:id/settings' )->to('Blog#do_settings' )->name('do_blog_settings' ); + # + # + # + #$auth->get ( '/blog' )->to('Blog#create' )->name('show_blog_create' ); + #$auth->post( '/blog' )->to('Blog#do_create' )->name('do_blog_create' ); + #$auth->get ( '/blog/:id/settings' )->to('Blog#settings' )->name('show_blog_settings' ); + #$auth->post( '/blog/:id/settings' )->to('Blog#do_settings' )->name('do_blog_settings' ); # Admin Dashboard $admin->get ( '/admin' )->to('Admin#index' )->name('show_admin' ); diff --git a/Web/lib/MJB/Web/Controller/Blog.pm b/Web/lib/MJB/Web/Controller/Blog.pm index ce8f259..b96cf2f 100644 --- a/Web/lib/MJB/Web/Controller/Blog.pm +++ b/Web/lib/MJB/Web/Controller/Blog.pm @@ -2,43 +2,86 @@ package MJB::Web::Controller::Blog; use Mojo::Base 'Mojolicious::Controller', -signatures; use Try::Tiny; -sub create ($c) { +# Blog Create Work Flow: +# 1. Choose Domain +# 2. Choose Blog Settings +# 3. Information Page For Initial Instructions +sub index ( $c ) { + $c->redirect_to( 'show_blog_domain_hosted' ); } -sub do_create ($c) { - $c->stash->{template} = 'blog/create'; +# Initial blog creation entry point when the user +# wants to use one of the domains that we provide. +sub domain_hosted ( $c ) { + push @{$c->stash->{errors}}, $c->flash('error_message') + if $c->flash('error_message'); - my $domain_type = $c->stash->{form_domain_type} = $c->param('domain_type'); - my $domain = $c->stash->{form_owned_domain} = $c->param('owned_domain'); - my $subdomain = $c->stash->{form_hosted_subdomain} = $c->param('hosted_subdomain'); +} - push @{$c->stash->{errors}}, "Unknown domain type submitted." - unless $domain_type eq 'owned' or $domain_type eq 'hosted'; +sub do_domain_hosted ( $c ) { + my $sub_domain = $c->param('subdomain'); + my $top_domain = $c->db->hosted_domain( $c->param('hosted_domain_id') ); - if ( $domain_type eq 'hosted' ) { - push @{$c->stash->{errors}}, "You must enter a subdomain." - unless $subdomain; + push @{$c->stash->{errors}}, "Please select a domain from the drop down menu." + unless $top_domain; - $subdomain = lc($subdomain); + push @{$c->stash->{errors}}, "Please enter a value for the subdomain." + unless $sub_domain; - push @{$c->stash->{errors}}, "Your subdomain may only contain letters, numbers and hypens." - unless $subdomain =~ /^[a-z0-9-]+$/; + push @{$c->stash->{errors}}, "That domain name is already being used." + unless $c->db->domains( { name => $sub_domain . '.' . $top_domain->name } )->count == 0; - } elsif ( $domain_type eq 'owned' ) { - push @{$c->stash->{errors}}, "You must enter a domain." - unless $domain; + if ( $c->stash->{errors} ) { + $c->flash( errors => $c->stash->{errors} ); + $c->redirect_to( $c->url_for( 'show_blog_domain_hosted' ) ); + return; } + $c->redirect_to( $c->url_for( 'do_blog_initialize' )->query( + domain => $sub_domain . '.' . $top_domain->name, + )); +} + +# Initial blog creation entry point when the user +# wants to use a domain that they own. +sub domain_owned ( $c ) { + $c->stash->{dns_record} = 'external.' . $c->db->hosted_domains->first->name; + +} + +sub do_domain_owned ( $c ) { + my $domain_name = $c->param('domain_name'); + + push @{$c->stash->{errors}}, "Please enter a value for the domain name." + unless $domain_name; + + push @{$c->stash->{errors}}, "That domain name is already being used." + unless $c->db->domains( { name => $domain_name } )->count == 0; - return if $c->stash->{errors}; + if ( $c->stash->{errors} ) { + $c->flash( errors => $c->stash->{errors} ); + $c->redirect_to( $c->url_for( 'show_blog_domain_owned' ) ); + return; + } - $domain = $domain ? $domain : $subdomain . '.' . $c->config->{customer_domain}; + $c->redirect_to( $c->url_for( 'do_blog_initialize' )->query( + domain => $domain_name + )); +} + +# This is a special exception, it's actually a get request, because we want it +# forwarded from the domain_hosted / domain_owned requests, and redirecting to +# a post doesn't work. However, since we're doing things rather than displaying +# things, it'll be named with the do_ +sub do_initialize ( $c ) { + my $domain = $c->param('domain'); # Do we already have this domain name? if ( $c->db->domain( { name => $domain } ) ) { - push @{$c->stash->{errors}}, "That domain name has been taken."; + $c->flash( errors => [ 'That domain name is already being hosted.' ] ); + $c->redirect_to( $c->url_for( 'show_blog_domain_hosted' ) ); return; } @@ -66,12 +109,15 @@ sub do_create ($c) { return $blog; }); } catch { - push @{$c->stash->{errors}}, "Account could not be created: $_"; + push @{$c->stash->{errors}}, "Blog could not be created: $_"; }; - # Choose a web server to deploy to - return if $c->stash->{errors}; - + if ( $c->stash->{errors} ) { + $c->flash( errors => $c->stash->{errors} ); + $c->redirect_to( $c->url_for( 'show_blog_domain_hosted' ) ); + return; + } + # Schedule a job to deploy the website my $ssl_job_id = $c->minion->enqueue( 'create_ssl_cert', [ $blog->id ], { notes => { '_bid_' . $blog->id => 1 }, @@ -81,7 +127,6 @@ sub do_create ($c) { $blog->create_related( 'builds', { job_id => $ssl_job_id } ); $c->redirect_to( $c->url_for( 'show_blog_settings', { id => $blog->id } ) ); - } sub settings ( $c ) { diff --git a/Web/lib/MJB/Web/Task/InitializeBlog.pm b/Web/lib/MJB/Web/Task/InitializeBlog.pm new file mode 100644 index 0000000..8ff52ed --- /dev/null +++ b/Web/lib/MJB/Web/Task/InitializeBlog.pm @@ -0,0 +1,60 @@ +package MJB::Web::Task::InitializeBlog; +use Mojo::Base 'MJB::Web::Task', -signatures; +use Mojo::File qw( curfile ); +use File::Copy::Recursive qw( dircopy ); +use IPC::Run3; + +# This needs to do all of the things: +# 1 - Make nginx config +# 2 - Whatever the ansible deploy-site thing does. +# + + +sub run ( $job, $blog_id ) { + $job->note( _mds_template => 'build_static' ); + + my $build_dir = $job->checkout_repo( $blog_id ); + my $blog = $job->app->db->blog( $blog_id ); + + $job->note( is_clone_complete => 1 ); + + # Show the user the commit we're on. + $job->system_command( [ 'git', '-C', $build_dir->child('src')->to_string, 'log', '-1' ] ); + + $build_dir->child('build')->make_path; + + + $job->system_command( [qw( podman run -ti --rm -v .:/srv/jekyll -e JEKYLL_ROOTLESS=1 docker.io/jekyll/jekyll jekyll build ) ], { + chdir => $build_dir->child('src')->to_string, + }); + + $job->process_webroot( + $blog, + $build_dir->child('src')->child('_site')->to_string, + $build_dir->child('build')->to_string + ); + + #== + # Build Site Config + #== TODO: There is two different files made here, one is done by ansible -- pick one, + # probably this one. + Mojo::File->new($build_dir)->child('build')->child('site.yml')->spurt( + YAML::Dump({ + domain => $blog->domain->name, + www_dir => "$build_dir/build/", + }) + ); + + $job->note( is_build_complete => 1 ); + + # Go to the build directory and make $build_dir/. + $ENV{MARKDOWNSITE_CONFIG} = Mojo::File->new($build_dir->to_string)->child('build')->child('site.yml'); + $job->system_command( [ 'ansible-playbook', '/etc/ansible/deploy-website.yml' ] ); + + + $job->note( is_deploy_complete => 1 ); + $job->finish( ); + +} + +1; diff --git a/Web/templates/_base/error_window.html.ep b/Web/templates/_base/error_window.html.ep deleted file mode 100644 index 84fdeb2..0000000 --- a/Web/templates/_base/error_window.html.ep +++ /dev/null @@ -1,10 +0,0 @@ -% if ( $c->stash->{errors} ) { -
The first step of creating your new blog is to choose a domain name.
+ +You can host your blog on a sub domain we provide for free, without any additional configuration. Enter the sub domain you'd like below and press continue.
+ +If you own your own domain name and would like to use that, please click here to continue.
+ +%= include '_base/status_window'; + + diff --git a/Web/templates/blog/domain_owned.html.ep b/Web/templates/blog/domain_owned.html.ep new file mode 100644 index 0000000..52280e3 --- /dev/null +++ b/Web/templates/blog/domain_owned.html.ep @@ -0,0 +1,38 @@ +% layout 'standard', title => 'Create Blog', sb_active => 'dashboard'; + +The first step of creating your new blog is to choose a domain name.
+ +To use your own domain name, you'll need to set the a CNAME record on your domain to point to <%= $dns_record %>. Until this record exists, your blog will not be accessable from the Internet.
+ +If you would like to use a domain name we provide, please click here to go back.
+ +%= include '_base/status_window'; + + diff --git a/Web/templates/dashboard/index.html.ep b/Web/templates/dashboard/index.html.ep index f401cc3..2f50bf2 100644 --- a/Web/templates/dashboard/index.html.ep +++ b/Web/templates/dashboard/index.html.ep @@ -9,7 +9,7 @@