From 0a59ab33b95ef747faba4c9f3bb7d82af75f844d Mon Sep 17 00:00:00 2001 From: johnnyq Date: Sat, 7 Dec 2024 14:09:15 -0500 Subject: [PATCH] Added setup_cli.php to allow to setup via the command line via interactive prompts and non intertactive by argument switches this allows for better automation of installing itflow in places like docker, ansible, HestiaCP Auto Install scripts etc --- setup_cli.php | 386 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 386 insertions(+) create mode 100644 setup_cli.php diff --git a/setup_cli.php b/setup_cli.php new file mode 100644 index 00000000..580fe552 --- /dev/null +++ b/setup_cli.php @@ -0,0 +1,386 @@ +#!/usr/bin/env php + 'Database host', + 'username' => 'Database username', + 'password' => 'Database password', + 'database' => 'Database name', + 'base-url' => 'Base URL (without protocol, e.g. example.com/itflow)', + 'locale' => 'Locale (e.g. en_US)', + 'timezone' => 'Timezone (e.g. UTC)', + 'currency' => 'Currency code (e.g. USD)', + 'company-name' => 'Company name', + 'country' => 'Company country (e.g. United States)', + 'user-name' => 'Admin user full name', + 'user-email' => 'Admin user email', + 'user-password'=> 'Admin user password (min 8 chars)' +]; + +// Additional optional arguments +// address, city, state, zip, phone, company-email, website +// These are optional and don't need error checks if missing. +$optional_args = [ + 'address' => 'Company address (optional)', + 'city' => 'Company city (optional)', + 'state' => 'Company state (optional)', + 'zip' => 'Company postal code (optional)', + 'phone' => 'Company phone (optional)', + 'company-email' => 'Company email (optional)', + 'website' => 'Company website (optional)' +]; + +// Parse command line options +$shortopts = ""; +$longopts = [ + "help", + "host:", + "username:", + "password:", + "database:", + "base-url:", + "locale:", + "timezone:", + "currency:", + "company-name:", + "country:", + "address::", + "city::", + "state::", + "zip::", + "phone::", + "company-email::", + "website::", + "user-name:", + "user-email:", + "user-password:", + "non-interactive" +]; + +$options = getopt($shortopts, $longopts); + +// If --help is set, print usage and exit +if (isset($options['help'])) { + echo "ITFlow CLI Setup Script\n\n"; + echo "Usage:\n"; + echo " php setup_cli.php [options]\n\n"; + echo "Options:\n"; + foreach ($required_args as $arg => $desc) { + echo " --$arg\t$desc (required)\n"; + } + foreach ($optional_args as $arg => $desc) { + echo " --$arg\t$desc\n"; + } + echo " --non-interactive\tRun in non-interactive mode (fail if required args missing)\n"; + echo " --help\t\tShow this help message\n\n"; + echo "If running interactively (without --non-interactive), any missing required arguments will be prompted.\n"; + echo "If running non-interactively, all required arguments must be provided.\n\n"; + exit(0); +} + +if (file_exists("config.php")) { + include "config.php"; +} + +include "functions.php"; +include "database_version.php"; + +if (!isset($config_enable_setup)) { + $config_enable_setup = 1; +} + +if ($config_enable_setup == 0) { + echo "Setup is disabled. Please delete or modify config.php if you need to re-run the setup.\n"; + exit; +} + +$errorLog = ini_get('error_log') ?: "/var/log/apache2/error.log"; + +$timezones = DateTimeZone::listIdentifiers(); + +function prompt($message) { + echo $message . ": "; + return trim(fgets(STDIN)); +} + +$non_interactive = isset($options['non-interactive']); + +function getOptionOrPrompt($key, $promptMessage, $required = false, $default = '', $optionsGlobal = []) { + global $options, $non_interactive; + if (isset($options[$key])) { + return $options[$key]; + } else { + if ($non_interactive && $required) { + die("Missing required argument: --$key\n"); + } + $val = prompt($promptMessage . (strlen($default) ? " [$default]" : '')); + if (empty($val) && !empty($default)) { + $val = $default; + } + if ($required && empty($val)) { + die("Error: $promptMessage is required.\n"); + } + return $val; + } +} + +// Start setup +echo "Welcome to the ITFlow CLI Setup.\n"; + +// If config exists, abort +if (file_exists('config.php')) { + echo "Database is already configured in config.php.\n"; + echo "To re-run the setup, remove config.php and run this script again.\n"; + exit; +} + +// If non-interactive is set, ensure all required arguments are present +if ($non_interactive) { + foreach (array_keys($required_args) as $arg) { + if (!isset($options[$arg])) { + die("Missing required argument: --$arg\n"); + } + } +} + +// Database Setup +echo "\n=== Database Setup ===\n"; +$database = getOptionOrPrompt('database', "Enter the database name", true); +$host = getOptionOrPrompt('host', "Enter the database host", true, 'localhost'); +if (empty($host)) $host = "localhost"; +$username = getOptionOrPrompt('username', "Enter the database username", true); +$password = getOptionOrPrompt('password', "Enter the database password", true); + +// Base URL +$base_url = getOptionOrPrompt('base-url', "Enter the base URL (e.g. example.com/itflow)", true); +$base_url = rtrim($base_url, '/'); + +// Locale, Timezone, Currency +echo "\n=== Localization ===\n"; +$locale = getOptionOrPrompt('locale', "Enter the locale (e.g. en_US)", true); +$timezone = getOptionOrPrompt('timezone', "Enter the timezone (e.g. UTC)", true); +$currency_code = getOptionOrPrompt('currency', "Enter the currency code (e.g. USD)", true); + +// Company Details +echo "\n=== Company Details ===\n"; +$company_name = getOptionOrPrompt('company-name', "Company Name", true); +$country = getOptionOrPrompt('country', "Country", true); +$address = getOptionOrPrompt('address', "Address (optional)", false); +$city = getOptionOrPrompt('city', "City (optional)", false); +$state = getOptionOrPrompt('state', "State/Province (optional)", false); +$zip = getOptionOrPrompt('zip', "Postal Code (optional)", false); +$phone = getOptionOrPrompt('phone', "Phone (optional)", false); +$phone = preg_replace("/[^0-9]/", '', $phone); +$company_email = getOptionOrPrompt('company-email', "Company Email (optional)", false); +$website = getOptionOrPrompt('website', "Website (optional)", false); + +// User Setup +echo "\n=== Create First User ===\n"; +$user_name = getOptionOrPrompt('user-name', "Full Name", true); +$user_email = getOptionOrPrompt('user-email', "Email Address", true); +while (!filter_var($user_email, FILTER_VALIDATE_EMAIL)) { + echo "Invalid email.\n"; + if ($non_interactive) { + die("Invalid email address: $user_email\n"); + } + $user_email = prompt("Email Address"); +} +$user_password_plain = getOptionOrPrompt('user-password', "Password (at least 8 chars)", true); +if (strlen($user_password_plain) < 8) { + if ($non_interactive) { + die("Password must be at least 8 characters.\n"); + } + while (strlen($user_password_plain) < 8) { + echo "Password too short. Try again.\n"; + $user_password_plain = prompt("Password"); + } +} + +if (!preg_match('/^[a-zA-Z0-9.\-\/]+$/', $host)) { + die("Invalid host format.\n"); +} + +// Test Database +$conn = @mysqli_connect($host, $username, $password, $database); +if (!$conn) { + die("Database connection failed - " . mysqli_connect_error() . "\n"); +} + +$installation_id = randomString(32); + +$new_config = " "$installation_id", + 'company_name' => "$company_name_db", + 'website' => "$website_db", + 'city' => "$city_db", + 'state' => "$state_db", + 'country' => "$country_db", + 'currency' => "$currency_db", + 'comments' => "$comments", + 'collection_method' => 1 + ]); + + $opts = ['http' => + [ + 'method' => 'POST', + 'header' => 'Content-type: application/x-www-form-urlencoded', + 'content' => $postdata + ] + ]; + + $context = stream_context_create($opts); + $result = @file_get_contents('https://telemetry.itflow.org', false, $context); + echo "Telemetry response: $result\n"; + } +} + +// finalize config +$myfile = fopen("config.php", "a"); +$txt = "\$config_enable_setup = 0;\n\n"; +fwrite($myfile, $txt); +fclose($myfile); + +echo "\nSetup complete!\n"; +echo "You can now log in with the user you created at: https://$base_url/login.php\n"; + +exit(0);