Skip to content
This repository has been archived by the owner on Sep 6, 2024. It is now read-only.

Commit

Permalink
Add ability to launch sites with SSL (#96)
Browse files Browse the repository at this point in the history
* Add settings for including SSL certificate

* Rename ssl feature to auto_ssl and enable_ssl to enable_auto_ssl

* Add ability to launch with ssl

* Bump version to 2.1
  • Loading branch information
oskosk authored Feb 18, 2018
1 parent 0224e43 commit f976b8b
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 8 deletions.
2 changes: 1 addition & 1 deletion jurassic.ninja.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
/*
* Plugin Name: Jurassic Ninja
* Description: Launch ephemeral instances of WordPress + Jetpack using ServerPilot and an Ubuntu Box.
* Version: 2.0
* Version: 2.1
* Author: Osk
**/

Expand Down
13 changes: 11 additions & 2 deletions lib/rest-api-stuff.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ function add_rest_api_endpoints() {
'woocommerce' => (bool) settings( 'add_woocommerce_by_default', false ),
'wp-debug-log' => (bool) settings( 'set_wp_debug_log_by_default', false ),
'shortlife' => false,
'ssl' => (bool) settings( 'ssl_use_custom_certificate', false ),
];
$json_params = $request->get_json_params();

Expand Down Expand Up @@ -90,7 +91,9 @@ function add_rest_api_endpoints() {
]
);
}
$url = 'http://' . figure_out_main_domain( $data->domains );
// See note in launch_wordpress() about why we can't launch subdomain_multisite with ssl.
$schema = $features['ssl'] && ! $features['subdomain_multisite'] ? 'https' : 'http';
$url = "$schema://" . figure_out_main_domain( $data->domains );

$output = [
'url' => $url,
Expand All @@ -100,7 +103,11 @@ function add_rest_api_endpoints() {

add_post_endpoint( 'specialops/create', function ( $request ) {
$json_params = $request->get_json_params();
$defaults = [
'ssl' => (bool) settings( 'ssl_use_custom_certificate', false ),
];
$features = $json_params && is_array( $json_params ) ? $json_params : [];
$features = array_merge( $defaults, $features );
if ( ! settings( 'enable_launching', true ) ) {
return new \WP_Error( 'site_launching_disabled', __( 'Site launching is disabled right now' ), [
'status' => 503,
Expand All @@ -117,7 +124,9 @@ function add_rest_api_endpoints() {
]
);
}
$url = 'http://' . figure_out_main_domain( $data->domains );
// See note in launch_wordpress() about why we can't launch subdomain_multisite with ssl.
$schema = $features['ssl'] && ! $features['subdomain_multisite'] ? 'https' : 'http';
$url = "$schema://" . figure_out_main_domain( $data->domains );

$output = [
'url' => $url,
Expand Down
45 changes: 43 additions & 2 deletions lib/serverpilot-stuff.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,15 +81,15 @@ function delete_sp_sysuser( $id ) {
}

/**
* Tries to enable SSL on a ServerPilot app
* Tries to enable auto SSL on a ServerPilot app
* This is currently not working so well due to the amount
* of instances created by ServerPilot and the throttling mechanism
* enforced by Let's Encrypt.
*
* @param string $app_id The ServerPilot id for the app
* @return [type] [description]
*/
function enable_ssl( $app_id ) {
function enable_auto_ssl( $app_id ) {
try {
$data = sp()->ssl_auto( $app_id );
wait_for_serverpilot_action( $data->actionid );
Expand All @@ -99,6 +99,47 @@ function enable_ssl( $app_id ) {
}
}

/**
* Enable SSL on a ServerPilot app according to the configured certificate
* in Jurassic Ninja settings.
*
* @param string $app_id The ServerPilot id for the app
* @return [type] [description]
*/
function enable_ssl( $app_id ) {
$private_key = settings( 'ssl_private_key' );
$certificate = settings( 'ssl_certificate' );
$ca_certificates = settings( 'ssl_ca_certificates', null );

if ( ! $private_key || ! $certificate ) {
return new \WP_Error( 'ssl_settings_not_present', __( 'Certificate or Private key are not configured' ) );
}

if ( ! $ca_certificates ) {
debug( 'No CA certificates configured in settings. This may take a little bit longer to launch' );
}

try {
// Add certificate
$data = sp()->ssl_add( $app_id, $private_key, $certificate, $ca_certificates );
/**
* NOTE: Here it would make sense to wait for this action to finish.
* IRL: It talkes tooooo long before the action is in a success state AND
* without the wait, the SSL provisioning still works fine.
* Tested a few sites and nothing broke.
* Leaving it commented in case something breaks eventually.
*/
// wait_for_serverpilot_action( $data->actionid );

// Enable redirection from https to http
$data = sp()->ssl_force( $app_id, true );
wait_for_serverpilot_action( $data->actionid );
return $data;
} catch ( \ServerPilotException $e ) {
return new \WP_Error( $e->getCode(), $e->getMessage() );
}
}

/**
* Returns an array of apps as reported by ServerPilot's API
* @return Array The PHP apps that ServerPilot knows about.
Expand Down
30 changes: 30 additions & 0 deletions lib/settings-stuff.php
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,36 @@ function add_settings_page() {
),
),
),
'ssl' => array(
'title' => __( 'SSL Configuration', 'jurassic-ninja' ),
'text' => '<p>' . __( 'Pase a wildcard SSL certificate and the private key used to generate it.' ) . '</p>',
'fields' => array(
'ssl_use_custom_certificate' => array(
'id' => 'ssl_use_custom_certificate',
'title' => __( 'Use custom SSL certificate', 'jurassic-ninja' ),
'type' => 'checkbox',
'checked' => false,
),
'ssl_certificate' => array(
'id' => 'ssl_certificate',
'title' => __( 'SSL certificate', 'jurassic-ninja' ),
'text' => __( 'Paste the text here.' ),
'type' => 'textarea',
),
'ssl_private_key' => array(
'id' => 'ssl_private_key',
'title' => __( 'The private key used to create the certificate', 'jurassic-ninja' ),
'text' => __( 'Paste the text here.' ),
'type' => 'textarea',
),
'ssl_ca_certificates' => array(
'id' => 'ssl_ca_certificates',
'title' => __( 'CA certificates', 'jurassic-ninja' ),
'text' => __( 'Paste the text here.' ),
'type' => 'textarea',
),
),
),
),
),
] );
Expand Down
28 changes: 25 additions & 3 deletions lib/stuff.php
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,8 @@ function add_wp_log_viewer_plugin() {
* @param String $runtime The PHP runtime versino to run the app on.
* @param Array $features Array of features to enable
* boolean config-constants Should we add the Config Constants plugin to the site?
* boolean ssl Should we add SSL for the site?
* boolean auto_ssl Should we add Let's Encrypt-based SSL for the site?
* boolean ssl Should we add the configured SSL certificate for the site?
* boolean gutenberg Should we add Gutenberg to the site?
* boolean jetpack Should we add Jetpack to the site?
* boolean jetpack-beta Should we add Jetpack Beta Tester plugin to the site?
Expand All @@ -148,6 +149,7 @@ function launch_wordpress( $runtime = 'php7.0', $requested_features = [] ) {
* @param array $features array of default values for feature flags
*/
$default_features = apply_filters( 'jurassic_ninja_features_default_values', [
'auto_ssl' => false,
'ssl' => false,
'config-constants' => false,
'gutenberg' => false,
Expand Down Expand Up @@ -208,13 +210,33 @@ function launch_wordpress( $runtime = 'php7.0', $requested_features = [] ) {
}
log_new_site( $app->data, $features['shortlife'] );

if ( $features['ssl'] ) {
enable_ssl( $app->data->id );
// Currently not used but the code works.
if ( $features['auto_ssl'] ) {
enable_auto_ssl( $app->data->id );
}
// We can't easily enable SSL for subodmains because
// wildcard certificates don't support multiple levels of subdomains
// and this can result in awful experience.
// Need to explorer a little bit better
if ( $features['ssl'] && ! $features['subdomain_multisite'] ) {
if ( $features['auto_ssl'] ) {
debug( 'Both ssl and auto_ssl features were requested. Ignoring ssl and launching with auto_ssl' );
} else {
debug( '%s: Enabling custom SSL', $domain );
$response = enable_ssl( $app->data->id );
if ( is_wp_error( $response ) ) {
debug( 'Error enabling SSL for %s. Check the next log line for a dump of the WP_Error', $domain );
debug( print_r( $response, true ) );
throw new \Exception( 'Error creating sysuser: ' . $return->get_error_message() );
}
}
}

if ( $features['jetpack'] ) {
debug( '%s: Adding Jetpack', $domain );
add_jetpack();
}

if ( $features['jetpack-beta'] ) {
debug( '%s: Adding Jetpack Beta Tester Plugin', $domain );
add_jetpack_beta_plugin();
Expand Down

0 comments on commit f976b8b

Please sign in to comment.