wip yeswiki-installer and yeswiki-remover
This commit is contained in:
parent
12b6a9b0c2
commit
a685758881
9 changed files with 567 additions and 164 deletions
13
.env.example
Normal file
13
.env.example
Normal file
|
@ -0,0 +1,13 @@
|
|||
# Quotas and database models
|
||||
soloquota=1000000
|
||||
solomodel='modele_solo'
|
||||
fermequota=10000000
|
||||
fermemodel='modele_ferme'
|
||||
|
||||
# Server IP addresses in order to check if domain is really pointing to your server
|
||||
ip4='127.0.0.1'
|
||||
ip6='::1'
|
||||
|
||||
# Mysql account with enought privileges to create users and DB
|
||||
mysqluser='root'
|
||||
mysqlpassword='1 very long & secure password or passphrase!'
|
21
README.md
21
README.md
|
@ -1,3 +1,24 @@
|
|||
# yeswiki-installer
|
||||
|
||||
Installer script for YesWiki, working on an opiniated Debian 11 environment.
|
||||
|
||||
## Setup
|
||||
|
||||
- clone this repository on your server
|
||||
- go in the folder `cd yeswiki-installer`
|
||||
- copy .env.example to .env `cp .env.example .env`
|
||||
- edit .env file and change it with your informations
|
||||
- add executable rights to some files `chmod +x yeswiki-installer.php yeswiki-remover.php`
|
||||
- make symlinks if you want to use those commands globally and more easily
|
||||
```
|
||||
sudo ln -s yeswiki.installer.php /usr/local/bin/yeswiki-installer
|
||||
sudo ln -s yeswiki.remover.php /usr/local/bin/yeswiki-remover
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
**You need root acces to use those commands**
|
||||
|
||||
Type `sudo yeswiki-installer` to see all the options for installation of YesWiki.
|
||||
|
||||
Type `sudo yeswiki-remover` to see all the options for removal of YesWiki
|
|
@ -1,5 +1,7 @@
|
|||
{
|
||||
"require": {
|
||||
"league/climate": "^3.8"
|
||||
"league/climate": "^3.8",
|
||||
"devcoder-xyz/php-dotenv": "^1.1",
|
||||
"league/plates": "^3.4"
|
||||
}
|
||||
}
|
||||
|
|
112
composer.lock
generated
112
composer.lock
generated
|
@ -4,8 +4,52 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "7804f603c1e45b579e09b65c72451f75",
|
||||
"content-hash": "de592ca396a34fbfa0f874b18161bb66",
|
||||
"packages": [
|
||||
{
|
||||
"name": "devcoder-xyz/php-dotenv",
|
||||
"version": "1.1.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/devcoder-xyz/php-dotenv.git",
|
||||
"reference": "1f478184b7fd199f5ffb0f89c1547f61c8172042"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/devcoder-xyz/php-dotenv/zipball/1f478184b7fd199f5ffb0f89c1547f61c8172042",
|
||||
"reference": "1f478184b7fd199f5ffb0f89c1547f61c8172042",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.4"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"DevCoder\\": "src",
|
||||
"Test\\DevCoder\\": "tests"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fad M.R",
|
||||
"email": "fadymichel@devcoder.xyz"
|
||||
}
|
||||
],
|
||||
"description": "Parses .env files",
|
||||
"support": {
|
||||
"issues": "https://github.com/devcoder-xyz/php-dotenv/issues",
|
||||
"source": "https://github.com/devcoder-xyz/php-dotenv/tree/1.1.1"
|
||||
},
|
||||
"time": "2021-07-17T21:19:15+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/climate",
|
||||
"version": "3.8.2",
|
||||
|
@ -71,6 +115,70 @@
|
|||
},
|
||||
"time": "2022-06-18T14:42:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/plates",
|
||||
"version": "v3.4.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/plates.git",
|
||||
"reference": "6d3ee31199b536a4e003b34a356ca20f6f75496a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/plates/zipball/6d3ee31199b536a4e003b34a356ca20f6f75496a",
|
||||
"reference": "6d3ee31199b536a4e003b34a356ca20f6f75496a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.0|^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"mikey179/vfsstream": "^1.6",
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"squizlabs/php_codesniffer": "^3.5"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.0-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"League\\Plates\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jonathan Reinink",
|
||||
"email": "jonathan@reinink.ca",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "RJ Garcia",
|
||||
"email": "ragboyjr@icloud.com",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "Plates, the native PHP template system that's fast, easy to use and easy to extend.",
|
||||
"homepage": "https://platesphp.com",
|
||||
"keywords": [
|
||||
"league",
|
||||
"package",
|
||||
"templates",
|
||||
"templating",
|
||||
"views"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/thephpleague/plates/issues",
|
||||
"source": "https://github.com/thephpleague/plates/tree/v3.4.0"
|
||||
},
|
||||
"time": "2020-12-25T05:00:37+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/log",
|
||||
"version": "3.0.0",
|
||||
|
@ -185,5 +293,5 @@
|
|||
"prefer-lowest": false,
|
||||
"platform": [],
|
||||
"platform-dev": [],
|
||||
"plugin-api-version": "2.3.0"
|
||||
"plugin-api-version": "2.2.0"
|
||||
}
|
||||
|
|
64
templates/nginx-yeswiki.pro.php
Normal file
64
templates/nginx-yeswiki.pro.php
Normal file
|
@ -0,0 +1,64 @@
|
|||
# ----------------------------------------------------------------------
|
||||
# | Config file for <?=$this->e($domain)?> host |
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
server {
|
||||
listen [::]:80;
|
||||
listen 80;
|
||||
server_name <?=$this->e($domain)?>;
|
||||
|
||||
return 301 https://<?=$this->e($domain)?>$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen [::]:443 ssl http2;
|
||||
listen 443 ssl http2;
|
||||
|
||||
server_name www.<?=$this->e($domain)?>;
|
||||
|
||||
include h5bp/tls/ssl_engine.conf;
|
||||
include h5bp/tls/certificate_files.conf;
|
||||
include h5bp/tls/policy_strict.conf;
|
||||
|
||||
return 301 $scheme://<?=$this->e($domain)?>$request_uri;
|
||||
}
|
||||
|
||||
|
||||
server {
|
||||
# listen [::]:443 ssl http2 accept_filter=dataready; # for FreeBSD
|
||||
# listen 443 ssl http2 accept_filter=dataready; # for FreeBSD
|
||||
listen [::]:443 ssl http2;
|
||||
listen 443 ssl http2;
|
||||
|
||||
# The host name to respond to
|
||||
server_name <?=$this->e($domain)?>;
|
||||
|
||||
include h5bp/tls/ssl_engine.conf;
|
||||
include h5bp/tls/certificate_files.conf;
|
||||
include h5bp/tls/policy_strict.conf;
|
||||
|
||||
# Path for static files
|
||||
root /home/<?=$this->e($user)?>/<?=$this->e($domain)?>;
|
||||
|
||||
# Custom error pages
|
||||
include h5bp/errors/custom_errors.conf;
|
||||
|
||||
# Include the basic h5bp config set
|
||||
include h5bp/basic.conf;
|
||||
|
||||
access_log /var/log/nginx/<?=$this->e($domain)?>-access.log;
|
||||
error_log /var/log/nginx/<?=$this->e($domain)?>-error.log error;
|
||||
index index.php index.html index.htm;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.php$is_args$args;
|
||||
}
|
||||
|
||||
location ~ \.php$ {
|
||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||
fastcgi_pass unix:/var/run/php-fpm-<?=$this->e($user)?>.sock;
|
||||
fastcgi_index index.php;
|
||||
include fastcgi.conf;
|
||||
}
|
||||
}
|
||||
|
207
utils.inc.php
Normal file
207
utils.inc.php
Normal file
|
@ -0,0 +1,207 @@
|
|||
<?php
|
||||
|
||||
require 'vendor/autoload.php';
|
||||
|
||||
function checkDNS($domain)
|
||||
{
|
||||
if (!preg_match('/(?=^.{4,253}$)(^((?!-)[a-zA-Z0-9-]{0,62}[a-zA-Z0-9]\.)+[a-zA-Z]{2,63}$)/', strtolower($domain))) {
|
||||
throw new Exception('not valid domain : "'.$domain.'".');
|
||||
}
|
||||
$currentip = dns_get_record($domain, DNS_A + DNS_AAAA);
|
||||
if (empty($currentip)) {
|
||||
throw new Exception('the domain '.$domain.' was not found in DNS record.');
|
||||
}
|
||||
if ($currentip[0]['ip'] !== $_SERVER['ip4']) {
|
||||
throw new Exception('the current ip v4 address of '.$domain.' is '.$currentip[0]['ip'].'. it should be '.$_SERVER['ip4']);
|
||||
}
|
||||
if ($currentip[1]['ipv6'] !== $_SERVER['ip6']) {
|
||||
throw new Exception('the current ip v6 address of '.$domain.' is '.$currentip[1]['ipv6'].'. it should be '.$_SERVER['ip6']);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function checkIfInstalled($domain)
|
||||
{
|
||||
exec('find /home/* -maxdepth 1 -type d | grep '.$domain, $output);
|
||||
if (!empty($output)) {
|
||||
throw new Exception('the domain '.$domain.' was already found on the server.');
|
||||
}
|
||||
}
|
||||
|
||||
function checkIfUserExist($user)
|
||||
{
|
||||
exec('cut -d: -f1 /etc/passwd | grep '.$user, $output);
|
||||
return !empty($output);
|
||||
}
|
||||
|
||||
function generateUserFromDomain($domain, $recursive = null)
|
||||
{
|
||||
if ($recursive == 100) {
|
||||
throw new Exception('Too much users found, 100 that is too much for '.$domain);
|
||||
}
|
||||
$user = str_split(str_replace(['yeswiki.pro', '-', '.'], '', $domain), 30)[0].$recursive;
|
||||
// try anthor username if user exists or if reserved name
|
||||
if (checkIfUserExist($user) || in_array($user, ['www', 'stats', 'mail', 'sql', 'cron', 'modelesolo', 'modeleferme'])) {
|
||||
if ($recursive === null) {
|
||||
$recursive = 1;
|
||||
}
|
||||
$user = generateUserFromDomain($domain, $recursive + 1);
|
||||
}
|
||||
return $user;
|
||||
}
|
||||
|
||||
function findUserFromExistingDomain($domain)
|
||||
{
|
||||
exec('find /home/* -maxdepth 1 -type d | grep '.$domain, $output);
|
||||
if (empty($output)) {
|
||||
throw new Exception('the domain '.$domain.' was not found on the server.');
|
||||
} else {
|
||||
return str_replace(['/home/', '/'.$domain], '', $output[0]);
|
||||
}
|
||||
}
|
||||
|
||||
function generatePassword($length = 32, $add_dashes = false, $available_sets = 'luds')
|
||||
{
|
||||
$sets = array();
|
||||
if (strpos($available_sets, 'l') !== false) {
|
||||
$sets[] = 'abcdefghjkmnpqrstuvwxyz';
|
||||
}
|
||||
if (strpos($available_sets, 'u') !== false) {
|
||||
$sets[] = 'ABCDEFGHJKMNPQRSTUVWXYZ';
|
||||
}
|
||||
if (strpos($available_sets, 'd') !== false) {
|
||||
$sets[] = '23456789';
|
||||
}
|
||||
if (strpos($available_sets, 's') !== false) {
|
||||
$sets[] = '!@#$%&*?';
|
||||
}
|
||||
|
||||
$all = '';
|
||||
$password = '';
|
||||
foreach ($sets as $set) {
|
||||
$password .= $set[array_rand(str_split($set))];
|
||||
$all .= $set;
|
||||
}
|
||||
|
||||
$all = str_split($all);
|
||||
for ($i = 0; $i < $length - count($sets); $i++) {
|
||||
$password .= $all[array_rand($all)];
|
||||
}
|
||||
|
||||
$password = str_shuffle($password);
|
||||
|
||||
if (!$add_dashes) {
|
||||
return $password;
|
||||
}
|
||||
|
||||
$dash_len = floor(sqrt($length));
|
||||
$dash_str = '';
|
||||
while (strlen($password) > $dash_len) {
|
||||
$dash_str .= substr($password, 0, $dash_len) . '-';
|
||||
$password = substr($password, $dash_len);
|
||||
}
|
||||
$dash_str .= $password;
|
||||
return $dash_str;
|
||||
}
|
||||
|
||||
function createSQLUserAndDatabase($user)
|
||||
{
|
||||
$pass = generatePassword();
|
||||
exec('mysql -u '.$_SERVER['mysqluser'].' -p'.$_SERVER['mysqlpassword'].' -e \'CREATE DATABASE IF NOT EXISTS '.$user.';\'', $output);
|
||||
exec('mysql -u '.$_SERVER['mysqluser'].' -p'.$_SERVER['mysqlpassword'].' -e "CREATE USER IF NOT EXISTS \''.$user.'\'@\'localhost\' IDENTIFIED BY \''.$pass.'\';"', $output);
|
||||
exec('mysql -u '.$_SERVER['mysqluser'].' -p'.$_SERVER['mysqlpassword'].' -e "GRANT ALL PRIVILEGES ON '.$user.'.* TO \''.$user.'\'@\'localhost\';"', $output);
|
||||
exec('mysql -u '.$_SERVER['mysqluser'].' -p'.$_SERVER['mysqlpassword'].' -e "FLUSH PRIVILEGES;"', $output);
|
||||
return ['database' => $user, 'user' => $user, 'password' => $pass];
|
||||
}
|
||||
|
||||
function removeMySQLUserAndDatabase($user)
|
||||
{
|
||||
exec('mysql -u '.$_SERVER['mysqluser'].' -p'.$_SERVER['mysqlpassword'].' -e \'DROP DATABASE IF EXISTS '.$user.';\'', $output);
|
||||
exec('mysql -u '.$_SERVER['mysqluser'].' -p'.$_SERVER['mysqlpassword'].' -e "DROP USER IF EXISTS \''.$user.'\'@\'localhost\';"', $output);
|
||||
exec('mysql -u '.$_SERVER['mysqluser'].' -p'.$_SERVER['mysqlpassword'].' -e "FLUSH PRIVILEGES;"', $output);
|
||||
return;
|
||||
}
|
||||
|
||||
function createUnixUserWithQuota($user, $quota)
|
||||
{
|
||||
$pass = generatePassword();
|
||||
exec('useradd -m -p "'.$pass.'" '.$user, $output);
|
||||
exec('setquota -u '.$user.' '.$quota.' '.$quota.' 0 0 -a /dev/loop0', $output);
|
||||
// TODO : handle errors
|
||||
return ['user' => $user, 'password' => $pass, 'quota' => $quota];
|
||||
}
|
||||
|
||||
function removeUnixUser($user)
|
||||
{
|
||||
exec('deluser --remove-home '.$user, $output);
|
||||
// TODO : handle errors
|
||||
return;
|
||||
}
|
||||
|
||||
function createNginxConfig($domain, $user, $herseUser, $hersePass)
|
||||
{
|
||||
// Create new Plates instance
|
||||
$templates = new League\Plates\Engine('./templates');
|
||||
|
||||
// Render a template
|
||||
echo $templates->render('nginx-yeswiki.pro', ['domain' => $domain, 'user' => $user]);
|
||||
|
||||
addHerse($nginxFile, $herseUser, $hersePass);
|
||||
}
|
||||
|
||||
function removeNginxConfig($domain, $user)
|
||||
{
|
||||
}
|
||||
|
||||
function createPhpFpmConfig($user)
|
||||
{
|
||||
}
|
||||
|
||||
function removePhpFpmConfig($user)
|
||||
{
|
||||
}
|
||||
|
||||
function copyYesWikiFiles($domain, $user, $type)
|
||||
{
|
||||
$destDir = '/home'.'/'.$user.'/'.$domain;
|
||||
exec('mkdir -p '.$destDir, $output);
|
||||
// TODO : handle errors
|
||||
return;
|
||||
}
|
||||
|
||||
function copyYesWikiDatabase($user, $type)
|
||||
{
|
||||
$databaseModel = ($type === 'solo') ? $_SERVER['solomodel'] : $_SERVER['fermemodel'];
|
||||
exec('mysql -u '.$_SERVER['mysqluser'].' -p'.$_SERVER['mysqlpassword'].' -e "DUPLICATE '.$databaseModel.' TO '.$user.';"', $output);
|
||||
// TODO : handle errors
|
||||
return;
|
||||
}
|
||||
|
||||
function checkHerse($herseUser, $hersePass)
|
||||
{
|
||||
if (empty($herseUser) && empty($hersePass)) {
|
||||
return false; // no herse needed
|
||||
} elseif (empty($herseUser) || empty($hersePass)) {
|
||||
throw new Exception('You need an username AND a password to add a herse.');
|
||||
}
|
||||
return true; // herse needed
|
||||
}
|
||||
|
||||
function addHerse(&$nginxFile, $herseUser, $hersePass)
|
||||
{
|
||||
if (empty($herseUser) && empty($hersePass)) {
|
||||
return ; // no herse needed
|
||||
} elseif (empty($herseUser) || empty($hersePass)) {
|
||||
throw new Exception('You need an username AND a password to add a herse.');
|
||||
} else {
|
||||
//add herse to the domain
|
||||
echo $nginxFile;
|
||||
}
|
||||
}
|
||||
|
||||
function removeYesWiki($domain, $user)
|
||||
{
|
||||
// enlever la db et le user sql
|
||||
// enlever la config nginx et la conf php-fpm
|
||||
// enlever le user unix et son home
|
||||
}
|
|
@ -1,44 +1,101 @@
|
|||
#!/usr/bin/php
|
||||
<?php
|
||||
require_once('vendor/autoload.php');
|
||||
require_once('yeswiki-installer.utils.inc.php');
|
||||
require_once('utils.inc.php');
|
||||
|
||||
$climate = new League\CLImate\CLImate;
|
||||
use DevCoder\DotEnv;
|
||||
|
||||
$climate = new League\CLImate\CLImate();
|
||||
$climate->description('yeswiki-installer, install YesWiki like a professionnal 🌈🦄');
|
||||
$climate->arguments->add([
|
||||
'domain' => [
|
||||
'prefix' => 'd',
|
||||
'longPrefix' => 'domain',
|
||||
'description' => 'Domain name used for installation',
|
||||
'required' => true,
|
||||
'defaultValue' => 'example.com'
|
||||
],
|
||||
'type' => [
|
||||
|
||||
if (0 == posix_getuid()) {
|
||||
$absolutePathToEnvFile = __DIR__ . '/.env';
|
||||
if (file_exists($absolutePathToEnvFile)) {
|
||||
(new DotEnv($absolutePathToEnvFile))->load();
|
||||
} else {
|
||||
$climate->error('ERROR : No .env file found.');
|
||||
exit;
|
||||
}
|
||||
|
||||
$climate->arguments->add([
|
||||
'domain' => [
|
||||
'prefix' => 'd',
|
||||
'longPrefix' => 'domain',
|
||||
'description' => 'Domain name used for installation',
|
||||
'required' => true,
|
||||
'defaultValue' => 'example.com'
|
||||
],
|
||||
'type' => [
|
||||
'prefix' => 't',
|
||||
'longPrefix' => 'type',
|
||||
'description' => 'Type of installation, can be "solo" or "ferme"',
|
||||
'required' => true,
|
||||
'defaultValue' => 'solo'
|
||||
],
|
||||
'quota' => [
|
||||
'quota' => [
|
||||
'prefix' => 'q',
|
||||
'longPrefix' => 'quota',
|
||||
'description' => 'User quota for hard drive space, in bytes',
|
||||
'required' => true,
|
||||
'defaultValue' => 2000000,
|
||||
'castTo' => 'int'
|
||||
'defaultValue' => $_SERVER['soloquota'],
|
||||
'castTo' => 'int'
|
||||
],
|
||||
]);
|
||||
$climate->arguments->parse();
|
||||
$domain = $climate->arguments->get('domain');
|
||||
if (!empty($domain) && $domain !== 'example.com') {
|
||||
$climate->bold()->underline()->out('Installation of YesWiki on '.$domain);
|
||||
$res = installYesWiki($domain, $climate->arguments->get('quota'), $climate->arguments->get('type'));
|
||||
if (!empty($res['error'])) {
|
||||
$climate->error('ERROR : '.$res['error']);
|
||||
} else {
|
||||
$climate->dump($res);
|
||||
}
|
||||
'herseuser' => [
|
||||
'prefix' => 'hu',
|
||||
'longPrefix' => 'herseuser',
|
||||
'description' => 'Username for HTTP auth barrier',
|
||||
],
|
||||
'hersepass' => [
|
||||
'prefix' => 'hp',
|
||||
'longPrefix' => 'hersepass',
|
||||
'description' => 'Password for HTTP auth barrier',
|
||||
],
|
||||
'confirm' => [
|
||||
'prefix' => 'y',
|
||||
'longPrefix' => 'yes',
|
||||
'description' => 'Say yes to every confirmation check (no prompt)',
|
||||
'noValue' => true,
|
||||
],
|
||||
]);
|
||||
$climate->arguments->parse();
|
||||
$domain = $climate->arguments->get('domain');
|
||||
if (!empty($domain) && $domain !== 'example.com') {
|
||||
try {
|
||||
$quota = $climate->arguments->get('quota');
|
||||
$type = $climate->arguments->get('type');
|
||||
$confirm = $climate->arguments->get('confirm');
|
||||
$herseUser = $climate->arguments->get('herseuser');
|
||||
$hersePass = $climate->arguments->get('hersepass');
|
||||
checkDNS($domain);
|
||||
checkIfInstalled($domain);
|
||||
$needHerse = checkHerse($herseUser, $hersePass);
|
||||
$user = generateUserFromDomain($domain);
|
||||
$climate->bold()->underline()->out('Installation of YesWiki');
|
||||
$climate->out('This will install a yeswiki on <bold>'.$domain."</bold>\n".'model <bold>'.$type.'</bold>, <bold>'.str_replace('000000', 'Gb', $quota).' quota</bold>, with the user <bold>'.$user.'</bold>.'."\n".($needHerse ? 'An herse with user <bold>'.$herseUser.'</bold> and password <bold>'.$hersePass.'</bold> will be set up.' : ''));
|
||||
$input = $climate->confirm('Is it all good ?');
|
||||
if ($confirm || $input->confirmed()) {
|
||||
$unixUser = createUnixUserWithQuota($user, $quota);
|
||||
$dbUser = createSQLUserAndDatabase($user);
|
||||
createNginxConfig($domain, $user, $herseUser, $hersePass);
|
||||
createPhpFpmConfig($user);
|
||||
copyYesWikiFiles($domain, $user, $type);
|
||||
copyYesWikiDatabase($user, $type);
|
||||
$climate->shout(
|
||||
'The yeswiki was successfully installed on <bold>'.$domain.'</bold>, congrats ! 🎉'."\n"
|
||||
.' Unix user : <bold>'.$unixUser['user'].'</bold> with password : <bold>'.$unixUser['password'].'</bold> was created.'."\n"
|
||||
.'MySQL user : <bold>'.$dbUser['user'].'</bold> with password : <bold>'.$dbUser['password'].'</bold> was created for database <bold>'.$dbUser['database'].'</bold>.'."\n"
|
||||
);
|
||||
// TODO : send log, send email
|
||||
} else {
|
||||
$climate->info('Ok, let\'s stop here...');
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$climate->error('ERROR : '.$e->getMessage());
|
||||
}
|
||||
} else {
|
||||
$climate->usage();
|
||||
}
|
||||
} else {
|
||||
$climate->usage();
|
||||
$climate->error('ERROR : this script needs root privilege to run.');
|
||||
exit;
|
||||
}
|
||||
|
|
|
@ -1,134 +0,0 @@
|
|||
<?php
|
||||
|
||||
function checkDNS($domain, $ip4 = '138.201.86.17', $ip6 = '2a01:4f8:172:21c9::2') {
|
||||
if (!preg_match('/(?=^.{4,253}$)(^((?!-)[a-zA-Z0-9-]{0,62}[a-zA-Z0-9]\.)+[a-zA-Z]{2,63}$)/', strtolower($domain))) {
|
||||
return ['error' => 'Not valid domain.'];
|
||||
}
|
||||
$currentip = dns_get_record($domain, DNS_A + DNS_AAAA);
|
||||
if ($currentip[0]['ip'] !== $ip4) {
|
||||
return ['error' => 'The current ip v4 address of '.$domain.' is '.$currentip[0]['ip'].'. it should be '.$ip4];
|
||||
}
|
||||
if ($currentip[1]['ipv6'] !== $ip6) {
|
||||
return ['error' => 'The current ip v6 address of '.$domain.' is '.$currentip[1]['ipv6'].'. it should be '.$ip6];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function checkIfInstalled($domain) {
|
||||
return true;
|
||||
}
|
||||
|
||||
function checkIfUserExist($user) {
|
||||
return true;
|
||||
}
|
||||
|
||||
function generateUserFromDomain($domain, $recursive = null) {
|
||||
$user = 'toto';
|
||||
return $user;
|
||||
}
|
||||
|
||||
function generatePassword($length = 32, $add_dashes = false, $available_sets = 'luds') {
|
||||
$sets = array();
|
||||
if(strpos($available_sets, 'l') !== false)
|
||||
$sets[] = 'abcdefghjkmnpqrstuvwxyz';
|
||||
if(strpos($available_sets, 'u') !== false)
|
||||
$sets[] = 'ABCDEFGHJKMNPQRSTUVWXYZ';
|
||||
if(strpos($available_sets, 'd') !== false)
|
||||
$sets[] = '23456789';
|
||||
if(strpos($available_sets, 's') !== false)
|
||||
$sets[] = '!@#$%&*?';
|
||||
|
||||
$all = '';
|
||||
$password = '';
|
||||
foreach($sets as $set)
|
||||
{
|
||||
$password .= $set[array_rand(str_split($set))];
|
||||
$all .= $set;
|
||||
}
|
||||
|
||||
$all = str_split($all);
|
||||
for($i = 0; $i < $length - count($sets); $i++)
|
||||
$password .= $all[array_rand($all)];
|
||||
|
||||
$password = str_shuffle($password);
|
||||
|
||||
if(!$add_dashes)
|
||||
return $password;
|
||||
|
||||
$dash_len = floor(sqrt($length));
|
||||
$dash_str = '';
|
||||
while(strlen($password) > $dash_len)
|
||||
{
|
||||
$dash_str .= substr($password, 0, $dash_len) . '-';
|
||||
$password = substr($password, $dash_len);
|
||||
}
|
||||
$dash_str .= $password;
|
||||
return $dash_str;
|
||||
}
|
||||
|
||||
function createSQLUserAndDatabase($user) {
|
||||
$pass = generatePassword();
|
||||
return ['database' => 'dbtata', 'user' => 'dbtata', 'password' => $pass];
|
||||
}
|
||||
|
||||
function createUnixUserWithQuota($user, $quota) {
|
||||
$pass = generatePassword();
|
||||
return ['user' => 'toto', 'password' => $pass, 'quota' => $quota];
|
||||
}
|
||||
|
||||
function createNginxConfig($domain, $user) {
|
||||
|
||||
}
|
||||
|
||||
function createPhpFpmConfig($user) {
|
||||
|
||||
}
|
||||
|
||||
function copyYesWikiFiles($domain, $user) {
|
||||
|
||||
}
|
||||
|
||||
function copyYesWikiDatabase($databaseModel) {
|
||||
|
||||
}
|
||||
|
||||
function addHerse($id, $pass) {
|
||||
return ['user' => $id, 'password' => $pass];
|
||||
}
|
||||
|
||||
function installYesWiki($domain, $quota, $type) {
|
||||
$res = checkDNS($domain);
|
||||
if (!empty($res['error'])) {
|
||||
return $res;
|
||||
}
|
||||
$res = checkIfInstalled($domain);
|
||||
if (!empty($res['error'])) {
|
||||
return $res;
|
||||
}
|
||||
$user = generateUserFromDomain($domain);
|
||||
$unixUser = createUnixUserWithQuota($user, $quota);
|
||||
$dbUser = createSQLUserAndDatabase($user);
|
||||
createNginxConfig($domain, $user);
|
||||
createPhpFpmConfig($user);
|
||||
copyYesWikiFiles($domain, $user);
|
||||
$databaseModel = ($type === 'solo') ? 'modelesolo' : 'modeleferme' ;
|
||||
copyYesWikiDatabase($databaseModel);
|
||||
|
||||
$herseUser = [];
|
||||
if (!empty($herseId) && !empty($hersePass)) {
|
||||
$herseUser = addHerse($herseId, $hersePass);
|
||||
}
|
||||
return [
|
||||
'domain'=> $domain,
|
||||
'type' => $type,
|
||||
'user' => $unixUser,
|
||||
'db' => $dbUser,
|
||||
'herse' => $herseUser
|
||||
];
|
||||
}
|
||||
|
||||
function removeYesWiki($domain, $user) {
|
||||
// enlever la db et le user sql
|
||||
// enlever la config nginx et la conf php-fpm
|
||||
// enlever le user unix et son home
|
||||
}
|
65
yeswiki-remover.php
Executable file
65
yeswiki-remover.php
Executable file
|
@ -0,0 +1,65 @@
|
|||
#!/usr/bin/php
|
||||
<?php
|
||||
require_once('vendor/autoload.php');
|
||||
require_once('utils.inc.php');
|
||||
|
||||
use DevCoder\DotEnv;
|
||||
|
||||
$climate = new League\CLImate\CLImate();
|
||||
$climate->description('yeswiki-remover, remove a domain used for YesWiki because death is not the end 💀😈');
|
||||
|
||||
if (0 == posix_getuid()) {
|
||||
$absolutePathToEnvFile = __DIR__ . '/.env';
|
||||
if (file_exists($absolutePathToEnvFile)) {
|
||||
(new DotEnv($absolutePathToEnvFile))->load();
|
||||
} else {
|
||||
$climate->error('ERROR : No .env file found.');
|
||||
exit;
|
||||
}
|
||||
|
||||
$climate->arguments->add([
|
||||
'domain' => [
|
||||
'prefix' => 'd',
|
||||
'longPrefix' => 'domain',
|
||||
'description' => 'Domain name that will be removed',
|
||||
'required' => true,
|
||||
'defaultValue' => 'example.com'
|
||||
],
|
||||
'confirm' => [
|
||||
'prefix' => 'y',
|
||||
'longPrefix' => 'yes',
|
||||
'description' => 'Say yes to every confirmation check (no prompt)',
|
||||
'noValue' => true,
|
||||
],
|
||||
]);
|
||||
$climate->arguments->parse();
|
||||
$domain = $climate->arguments->get('domain');
|
||||
if (!empty($domain) && $domain !== 'example.com') {
|
||||
try {
|
||||
$confirm = $climate->arguments->get('confirm');
|
||||
$user = findUserFromExistingDomain($domain);
|
||||
$climate->bold()->underline()->out('Removal of YesWiki');
|
||||
$climate->out('This will remove <bold>'.$domain.'</bold> with the user <bold>'.$user.'</bold>'."\n");
|
||||
$input = $climate->confirm('Shall we really do it ?');
|
||||
if ($confirm || $input->confirmed()) {
|
||||
removeUnixUser($user);
|
||||
removeNginxConfig($domain, $user);
|
||||
removePhpFpmConfig($user);
|
||||
removeMySQLUserAndDatabase($user);
|
||||
$climate->shout(
|
||||
'The yeswiki on <bold>'.$domain.'</bold> was successfully removed, congrats ! 🎉'."\n"
|
||||
);
|
||||
// TODO : send log, send email
|
||||
} else {
|
||||
$climate->info('Ok, let\'s stop here...');
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$climate->error('ERROR : '.$e->getMessage());
|
||||
}
|
||||
} else {
|
||||
$climate->usage();
|
||||
}
|
||||
} else {
|
||||
$climate->error('ERROR : this script needs root privilege to run.');
|
||||
exit;
|
||||
}
|
Loading…
Add table
Reference in a new issue