2021-11-30 11:20:42 +01:00
< ? php
namespace AIO\Data ;
use AIO\Auth\PasswordGenerator ;
use AIO\Controller\DockerController ;
class ConfigurationManager
{
public function GetConfig () : array
{
if ( file_exists ( DataConst :: GetConfigFile ()))
{
$configContent = file_get_contents ( DataConst :: GetConfigFile ());
return json_decode ( $configContent , true );
}
return [];
}
public function GetPassword () : string {
return $this -> GetConfig ()[ 'password' ];
}
public function GetToken () : string {
return $this -> GetConfig ()[ 'AIO_TOKEN' ];
}
public function SetPassword ( string $password ) : void {
$config = $this -> GetConfig ();
$config [ 'password' ] = $password ;
$this -> WriteConfig ( $config );
}
public function GetSecret ( string $secretId ) : string {
$config = $this -> GetConfig ();
if ( ! isset ( $config [ 'secrets' ][ $secretId ])) {
$config [ 'secrets' ][ $secretId ] = bin2hex ( random_bytes ( 24 ));
$this -> WriteConfig ( $config );
}
if ( $secretId === 'BORGBACKUP_PASSWORD' && ! file_exists ( DataConst :: GetBackupSecretFile ())) {
$this -> DoubleSafeBackupSecret ( $config [ 'secrets' ][ $secretId ]);
}
return $config [ 'secrets' ][ $secretId ];
}
2022-03-01 11:44:59 +01:00
private function DoubleSafeBackupSecret ( string $borgBackupPassword ) : void {
2021-11-30 11:20:42 +01:00
file_put_contents ( DataConst :: GetBackupSecretFile (), $borgBackupPassword );
}
public function hasBackupRunOnce () : bool {
if ( ! file_exists ( DataConst :: GetBackupKeyFile ())) {
return false ;
} else {
return true ;
}
}
public function GetLastBackupTime () : string {
if ( ! file_exists ( DataConst :: GetBackupArchivesList ())) {
return '' ;
}
$content = file_get_contents ( DataConst :: GetBackupArchivesList ());
2022-02-16 15:05:04 +01:00
if ( $content === '' ) {
2021-11-30 11:20:42 +01:00
return '' ;
}
$lastBackupLines = explode ( " \n " , $content );
$lastBackupLine = $lastBackupLines [ sizeof ( $lastBackupLines ) - 2 ];
if ( $lastBackupLine === " " ) {
return '' ;
}
$lastBackupTimes = explode ( " , " , $lastBackupLine );
$lastBackupTime = $lastBackupTimes [ 1 ];
if ( $lastBackupTime === " " ) {
return '' ;
}
return $lastBackupTime ;
}
2021-12-07 19:10:05 +01:00
public function GetBackupTimes () : array {
if ( ! file_exists ( DataConst :: GetBackupArchivesList ())) {
2022-02-16 15:05:04 +01:00
return [];
2021-12-07 19:10:05 +01:00
}
$content = file_get_contents ( DataConst :: GetBackupArchivesList ());
2022-02-16 15:05:04 +01:00
if ( $content === '' ) {
return [];
2021-12-07 19:10:05 +01:00
}
2022-02-16 15:05:04 +01:00
$backupLines = explode ( " \n " , $content );
2022-02-16 14:32:57 +01:00
$backupTimes = [];
2021-12-07 19:10:05 +01:00
foreach ( $backupLines as $lines ) {
2022-02-16 15:05:04 +01:00
if ( $lines !== " " ) {
$backupTimesTemp = explode ( ',' , $lines );
$backupTimes [] = $backupTimesTemp [ 1 ];
}
2021-12-07 19:10:05 +01:00
}
2022-03-15 16:02:43 +01:00
// Reverse the array to list newest backup first
$backupTimes = array_reverse ( $backupTimes );
2021-12-07 19:10:05 +01:00
return $backupTimes ;
}
2021-11-30 11:20:42 +01:00
public function wasStartButtonClicked () : bool {
if ( isset ( $this -> GetConfig ()[ 'wasStartButtonClicked' ])) {
return true ;
} else {
return false ;
}
}
2022-03-15 23:46:58 +01:00
public function isx64Platform () : bool {
if ( php_uname ( 'm' ) === 'x86_64' ) {
return true ;
} else {
return false ;
}
}
public function isClamavEnabled () : bool {
$config = $this -> GetConfig ();
if ( isset ( $config [ 'isClamavEnabled' ]) && $config [ 'isClamavEnabled' ] === 1 ) {
return true ;
} else {
return false ;
}
}
public function SetClamavEnabledState ( int $value ) : void {
$config = $this -> GetConfig ();
$config [ 'isClamavEnabled' ] = $value ;
$this -> WriteConfig ( $config );
}
2022-03-17 10:13:21 +01:00
public function isOnlyofficeEnabled () : bool {
$config = $this -> GetConfig ();
if ( isset ( $config [ 'isOnlyofficeEnabled' ]) && $config [ 'isOnlyofficeEnabled' ] === 1 ) {
return true ;
} else {
return false ;
}
}
public function SetOnlyofficeEnabledState ( int $value ) : void {
$config = $this -> GetConfig ();
$config [ 'isOnlyofficeEnabled' ] = $value ;
$this -> WriteConfig ( $config );
}
public function isCollaboraEnabled () : bool {
$config = $this -> GetConfig ();
if ( isset ( $config [ 'isCollaboraEnabled' ]) && $config [ 'isCollaboraEnabled' ] === 0 ) {
return false ;
} else {
return true ;
}
}
public function SetCollaboraEnabledState ( int $value ) : void {
$config = $this -> GetConfig ();
$config [ 'isCollaboraEnabled' ] = $value ;
$this -> WriteConfig ( $config );
}
public function isTalkEnabled () : bool {
$config = $this -> GetConfig ();
if ( isset ( $config [ 'isTalkEnabled' ]) && $config [ 'isTalkEnabled' ] === 0 ) {
return false ;
} else {
return true ;
}
}
public function SetTalkEnabledState ( int $value ) : void {
$config = $this -> GetConfig ();
$config [ 'isTalkEnabled' ] = $value ;
$this -> WriteConfig ( $config );
}
2021-11-30 11:20:42 +01:00
/**
* @ throws InvalidSettingConfigurationException
*/
public function SetDomain ( string $domain ) : void {
2022-03-09 11:59:44 +01:00
// Validate domain
if ( ! filter_var ( $domain , FILTER_VALIDATE_DOMAIN , FILTER_FLAG_HOSTNAME )) {
2022-05-20 14:02:04 +02:00
throw new InvalidSettingConfigurationException ( " Domain is not a valid domain! " );
2021-11-30 11:20:42 +01:00
}
2022-02-23 18:01:56 +01:00
// Validate that it is not an IP-address
if ( filter_var ( $domain , FILTER_VALIDATE_IP )) {
throw new InvalidSettingConfigurationException ( " Please enter a domain and not an IP-address! " );
}
2022-06-30 14:34:36 +02:00
// Skip domain validation if opted in to do so
if ( $this -> shouldDomainValidationBeSkipped ()) {
2021-11-30 11:20:42 +01:00
2022-06-30 14:34:36 +02:00
$dnsRecordIP = gethostbyname ( $domain );
if ( $dnsRecordIP === $domain ) {
$dnsRecordIP = '' ;
2022-06-30 14:47:37 +02:00
}
2022-06-07 00:15:02 +02:00
2022-06-30 14:34:36 +02:00
if ( empty ( $dnsRecordIP )) {
$record = dns_get_record ( $domain , DNS_AAAA );
if ( ! empty ( $record )) {
$dnsRecordIP = $record [ 0 ][ 'ipv6' ];
}
}
2022-06-27 12:20:17 +02:00
2022-06-30 14:34:36 +02:00
// Validate IP
if ( ! filter_var ( $dnsRecordIP , FILTER_VALIDATE_IP )) {
throw new InvalidSettingConfigurationException ( " DNS config is not set for this domain or the domain is not a valid domain! (It was found to be set to ' " . $dnsRecordIP . " ') " );
2022-06-27 12:20:17 +02:00
}
2021-11-30 11:20:42 +01:00
2022-06-30 14:34:36 +02:00
// Get the apache port
$port = $this -> GetApachePort ();
2021-11-30 11:20:42 +01:00
2022-06-30 14:34:36 +02:00
if ( ! filter_var ( $dnsRecordIP , FILTER_VALIDATE_IP , FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE )) {
$errorMessage = " It seems like the ip-address is set to an internal or reserved ip-address. This is not supported. (It was found to be set to ' " . $dnsRecordIP . " ') " ;
if ( $port === '443' ) {
throw new InvalidSettingConfigurationException ( $errorMessage );
} else {
error_log ( $errorMessage );
}
}
2021-11-30 11:20:42 +01:00
2022-06-30 14:34:36 +02:00
// Check if port 443 is open
$connection = @ fsockopen ( $domain , 443 , $errno , $errstr , 10 );
if ( $connection ) {
fclose ( $connection );
} else {
throw new InvalidSettingConfigurationException ( " The server is not reachable on Port 443. You can verify this e.g. with 'https://portchecker.co/' by entering your domain there as ip-address and port 443 as port. " );
}
// Get Instance ID
$instanceID = $this -> GetSecret ( 'INSTANCE_ID' );
2021-12-08 18:12:56 +01:00
2022-06-30 14:34:36 +02:00
// set protocol
if ( $port !== '443' ) {
$protocol = 'https://' ;
} else {
$protocol = 'http://' ;
}
2021-11-30 11:20:42 +01:00
2022-06-30 14:34:36 +02:00
// Check if response is correct
$ch = curl_init ();
$testUrl = $protocol . $domain . ':443' ;
curl_setopt ( $ch , CURLOPT_URL , $testUrl );
curl_setopt ( $ch , CURLOPT_RETURNTRANSFER , true );
$response = ( string ) curl_exec ( $ch );
# Get rid of trailing \n
$response = str_replace ( " \n " , " " , $response );
if ( $response !== $instanceID ) {
error_log ( 'The response of the connection attempt to "' . $testUrl . '" was: ' . $response );
error_log ( 'Expected was: ' . $instanceID );
error_log ( 'The error message was: ' . curl_error ( $ch ));
throw new InvalidSettingConfigurationException ( " Domain does not point to this server or the reverse proxy is not configured correctly. See the mastercontainer logs for more details. ('sudo docker logs -f nextcloud-aio-mastercontainer') " );
}
2021-11-30 11:20:42 +01:00
}
// Write domain
$config = $this -> GetConfig ();
$config [ 'domain' ] = $domain ;
2022-03-21 13:23:17 +01:00
// Reset the borg restore password when setting the domain
$config [ 'borg_restore_password' ] = '' ;
2021-11-30 11:20:42 +01:00
$this -> WriteConfig ( $config );
}
public function GetDomain () : string {
$config = $this -> GetConfig ();
if ( ! isset ( $config [ 'domain' ])) {
$config [ 'domain' ] = '' ;
}
return $config [ 'domain' ];
}
public function GetBackupMode () : string {
$config = $this -> GetConfig ();
if ( ! isset ( $config [ 'backup-mode' ])) {
$config [ 'backup-mode' ] = '' ;
}
return $config [ 'backup-mode' ];
}
2021-12-07 19:10:05 +01:00
public function GetSelectedRestoreTime () : string {
$config = $this -> GetConfig ();
if ( ! isset ( $config [ 'selected-restore-time' ])) {
$config [ 'selected-restore-time' ] = '' ;
}
return $config [ 'selected-restore-time' ];
}
2021-11-30 11:20:42 +01:00
public function GetAIOURL () : string {
$config = $this -> GetConfig ();
if ( ! isset ( $config [ 'AIO_URL' ])) {
$config [ 'AIO_URL' ] = '' ;
}
return $config [ 'AIO_URL' ];
}
/**
* @ throws InvalidSettingConfigurationException
*/
public function SetBorgBackupHostLocation ( string $location ) : void {
$isValidPath = false ;
2022-05-06 12:17:56 +02:00
if ( str_starts_with ( $location , '/' ) && ! str_ends_with ( $location , '/' )) {
$isValidPath = true ;
2022-05-23 17:19:23 +02:00
} elseif ( $location === 'nextcloud_aio_backupdir' ) {
$isValidPath = true ;
2021-11-30 11:20:42 +01:00
}
2022-05-06 12:17:56 +02:00
if ( ! $isValidPath ) {
throw new InvalidSettingConfigurationException ( " The path must start with '/', and must not end with '/'! " );
2021-11-30 11:20:42 +01:00
}
$config = $this -> GetConfig ();
$config [ 'borg_backup_host_location' ] = $location ;
$this -> WriteConfig ( $config );
}
2022-03-21 13:23:17 +01:00
/**
* @ throws InvalidSettingConfigurationException
*/
public function SetBorgRestoreHostLocationAndPassword ( string $location , string $password ) : void {
if ( $location === '' ) {
throw new InvalidSettingConfigurationException ( " Please enter a path! " );
}
$isValidPath = false ;
if ( str_starts_with ( $location , '/' ) && ! str_ends_with ( $location , '/' )) {
$isValidPath = true ;
2022-05-23 17:19:23 +02:00
} elseif ( $location === 'nextcloud_aio_backupdir' ) {
$isValidPath = true ;
2022-03-21 13:23:17 +01:00
}
2022-05-06 12:17:56 +02:00
if ( ! $isValidPath ) {
throw new InvalidSettingConfigurationException ( " The path must start with '/', and must not end with '/'! " );
2022-03-21 13:23:17 +01:00
}
if ( $password === '' ) {
throw new InvalidSettingConfigurationException ( " Please enter the password! " );
}
$config = $this -> GetConfig ();
$config [ 'borg_backup_host_location' ] = $location ;
$config [ 'borg_restore_password' ] = $password ;
2022-04-24 12:57:23 +02:00
$config [ 'instance_restore_attempt' ] = 1 ;
2022-03-21 13:23:17 +01:00
$this -> WriteConfig ( $config );
}
2022-03-08 21:16:33 +01:00
/**
* @ throws InvalidSettingConfigurationException
*/
public function ChangeMasterPassword ( string $currentPassword , string $newPassword ) : void {
if ( $currentPassword === '' ) {
throw new InvalidSettingConfigurationException ( " Please enter your current password. " );
}
if ( $currentPassword !== $this -> GetPassword ()) {
throw new InvalidSettingConfigurationException ( " The entered current password is not correct. " );
}
if ( $newPassword === '' ) {
throw new InvalidSettingConfigurationException ( " Please enter a new password. " );
}
if ( strlen ( $newPassword ) < 24 ) {
throw new InvalidSettingConfigurationException ( " New passwords must be >= 24 digits. " );
}
if ( ! preg_match ( " #^[a-zA-Z0-9 ]+ $ # " , $newPassword )) {
throw new InvalidSettingConfigurationException ( 'Not allowed characters in the new password.' );
}
// All checks pass so set the password
$this -> SetPassword ( $newPassword );
}
2021-12-08 18:12:56 +01:00
public function GetApachePort () : string {
2022-03-11 17:28:55 +01:00
$envVariableName = 'APACHE_PORT' ;
$configName = 'apache_port' ;
$defaultValue = '443' ;
return $this -> GetEnvironmentalVariableOrConfig ( $envVariableName , $configName , $defaultValue );
2021-12-08 18:12:56 +01:00
}
2021-12-04 11:01:38 +01:00
/**
* @ throws InvalidSettingConfigurationException
*/
2021-11-30 11:20:42 +01:00
public function WriteConfig ( array $config ) : void {
if ( ! is_dir ( DataConst :: GetDataDirectory ())) {
2021-12-04 11:01:38 +01:00
throw new InvalidSettingConfigurationException ( DataConst :: GetDataDirectory () . " does not exist! Something was set up falsely! " );
2021-11-30 11:20:42 +01:00
}
file_put_contents ( DataConst :: GetConfigFile (), json_encode ( $config ));
}
2022-03-11 17:28:55 +01:00
private function GetEnvironmentalVariableOrConfig ( string $envVariableName , string $configName , string $defaultValue ) : string {
$envVariableOutput = getenv ( $envVariableName );
if ( $envVariableOutput === false ) {
$config = $this -> GetConfig ();
if ( ! isset ( $config [ $configName ]) || $config [ $configName ] === '' ) {
$config [ $configName ] = $defaultValue ;
}
return $config [ $configName ];
2022-03-14 14:59:46 +01:00
}
if ( file_exists ( DataConst :: GetConfigFile ())) {
$config = $this -> GetConfig ();
if ( ! isset ( $config [ $configName ])) {
$config [ $configName ] = '' ;
}
if ( $envVariableOutput !== $config [ $configName ]) {
$config [ $configName ] = $envVariableOutput ;
$this -> WriteConfig ( $config );
2022-03-11 17:28:55 +01:00
}
}
2022-03-14 14:59:46 +01:00
return $envVariableOutput ;
2022-03-11 17:28:55 +01:00
}
2021-11-30 11:20:42 +01:00
public function GetBorgBackupHostLocation () : string {
$config = $this -> GetConfig ();
if ( ! isset ( $config [ 'borg_backup_host_location' ])) {
$config [ 'borg_backup_host_location' ] = '' ;
}
return $config [ 'borg_backup_host_location' ];
}
2022-03-21 13:23:17 +01:00
public function GetBorgRestorePassword () : string {
$config = $this -> GetConfig ();
if ( ! isset ( $config [ 'borg_restore_password' ])) {
$config [ 'borg_restore_password' ] = '' ;
}
return $config [ 'borg_restore_password' ];
}
2022-04-24 12:57:23 +02:00
public function isInstanceRestoreAttempt () : bool {
$config = $this -> GetConfig ();
if ( ! isset ( $config [ 'instance_restore_attempt' ])) {
$config [ 'instance_restore_attempt' ] = '' ;
}
if ( $config [ 'instance_restore_attempt' ] === 1 ) {
return true ;
}
return false ;
}
2021-11-30 11:20:42 +01:00
public function GetBorgBackupMode () : string {
$config = $this -> GetConfig ();
if ( ! isset ( $config [ 'backup-mode' ])) {
$config [ 'backup-mode' ] = '' ;
}
return $config [ 'backup-mode' ];
}
2022-02-21 17:31:05 +01:00
public function GetNextcloudMount () : string {
2022-03-11 17:28:55 +01:00
$envVariableName = 'NEXTCLOUD_MOUNT' ;
$configName = 'nextcloud_mount' ;
$defaultValue = '' ;
return $this -> GetEnvironmentalVariableOrConfig ( $envVariableName , $configName , $defaultValue );
2022-02-21 17:31:05 +01:00
}
2022-03-08 16:49:13 +01:00
public function GetNextcloudDatadirMount () : string {
2022-03-11 17:28:55 +01:00
$envVariableName = 'NEXTCLOUD_DATADIR' ;
$configName = 'nextcloud_datadir' ;
$defaultValue = 'nextcloud_aio_nextcloud_data' ;
return $this -> GetEnvironmentalVariableOrConfig ( $envVariableName , $configName , $defaultValue );
2022-03-08 16:49:13 +01:00
}
2022-04-04 19:12:07 +02:00
2022-05-13 18:46:34 +02:00
public function GetDockerSocketPath () : string {
$envVariableName = 'DOCKER_SOCKET_PATH' ;
$configName = 'docker_socket_path' ;
$defaultValue = '/var/run/docker.sock' ;
return $this -> GetEnvironmentalVariableOrConfig ( $envVariableName , $configName , $defaultValue );
}
2022-04-04 19:12:07 +02:00
/**
* @ throws InvalidSettingConfigurationException
*/
public function SetDailyBackupTime ( string $time ) : void {
if ( $time === " " ) {
throw new InvalidSettingConfigurationException ( " The daily backup time must not be empty! " );
}
if ( ! preg_match ( " #^[0-1][0-9]:[0-5][0-9] $ # " , $time ) && ! preg_match ( " #^2[0-3]:[0-5][0-9] $ # " , $time )) {
throw new InvalidSettingConfigurationException ( " You did not enter a correct time! One correct example is '04:00'! " );
}
file_put_contents ( DataConst :: GetDailyBackupTimeFile (), $time );
}
public function GetDailyBackupTime () : string {
if ( ! file_exists ( DataConst :: GetDailyBackupTimeFile ())) {
return '' ;
}
return file_get_contents ( DataConst :: GetDailyBackupTimeFile ());
}
public function DeleteDailyBackupTime () : void {
if ( file_exists ( DataConst :: GetDailyBackupTimeFile ())) {
unlink ( DataConst :: GetDailyBackupTimeFile ());
}
}
public function isDailyBackupRunning () : bool {
if ( file_exists ( DataConst :: GetDailyBackupBlockFile ())) {
return true ;
}
return false ;
}
2022-05-18 18:36:51 +02:00
public function GetTimezone () : string {
$config = $this -> GetConfig ();
if ( ! isset ( $config [ 'timezone' ])) {
$config [ 'timezone' ] = '' ;
}
return $config [ 'timezone' ];
}
2022-05-23 19:55:50 +02:00
/**
* @ throws InvalidSettingConfigurationException
*/
2022-05-18 18:36:51 +02:00
public function SetTimezone ( string $timezone ) : void {
if ( $timezone === " " ) {
throw new InvalidSettingConfigurationException ( " The timezone must not be empty! " );
}
2022-05-23 19:55:50 +02:00
if ( ! preg_match ( " #^[a-zA-Z0-9_ \ - \ / \ +]+ $ # " , $timezone )) {
2022-05-18 18:36:51 +02:00
throw new InvalidSettingConfigurationException ( " The entered timezone does not seem to be a valid timezone! " );
}
$config = $this -> GetConfig ();
$config [ 'timezone' ] = $timezone ;
$this -> WriteConfig ( $config );
}
public function DeleteTimezone () : void {
$config = $this -> GetConfig ();
$config [ 'timezone' ] = '' ;
$this -> WriteConfig ( $config );
}
2022-06-30 14:34:36 +02:00
public function shouldDomainValidationBeSkipped () : bool {
$envVariableOutput = getenv ( 'SKIP_DOMAIN_VALIDATION' );
if ( $envVariableOutput !== false ) {
return true ;
}
return false ;
}
2021-11-30 11:20:42 +01:00
}