Compare commits
50 Commits
Author | SHA1 | Date | |
---|---|---|---|
289e6530a8 | |||
1db989d7c8 | |||
9ed956ad7d | |||
3a29039bde | |||
02cdc70e9b | |||
ac0d8c776e | |||
b147cda096 | |||
17e70f14a2 | |||
bb1a16988d | |||
f04c306f91 | |||
5d2e95ac3d | |||
4e056f6831 | |||
753e96ed85 | |||
d31ee8bdec | |||
26b0b6de6b | |||
efb069eb5a | |||
514c77de55 | |||
7b40624218 | |||
06df37ed3c | |||
c6ece08a0b | |||
0f13e29fe9 | |||
b06128e819 | |||
f25e90f292 | |||
d0224f6746 | |||
71a275198f | |||
578f76426e | |||
96689879c4 | |||
e9b14a11d7 | |||
a312ad9095 | |||
1518deee87 | |||
c9757ead13 | |||
3e591eee9c | |||
94334694d4 | |||
6fc85b8692 | |||
8784acbed9 | |||
cc4bbbecb4 | |||
730ae25d63 | |||
e4f5a4a07e | |||
4f52e99a92 | |||
176bd9dc83 | |||
65ea85da39 | |||
2c65f743e7 | |||
eaa137291b | |||
17535d825d | |||
93e12b9949 | |||
43b8f19a7b | |||
645f3d00fe | |||
fd4175987b | |||
2eb96742bb | |||
8f946d9360 |
3
.gitignore
vendored
3
.gitignore
vendored
@ -14,3 +14,6 @@
|
||||
/config.json.prod
|
||||
keys.txt
|
||||
/.phpunit.cache
|
||||
/var/log/*
|
||||
/public/openapi/bindapi.json
|
||||
/public/openapi/bootstrap.php
|
||||
|
@ -6,9 +6,6 @@
|
||||
6. [DynDNS](#6-dyndns)
|
||||
7. [Conclusion](#7-conclusion)
|
||||
|
||||
Don't use this code right now.
|
||||
You can try 1.0.2, but it's not well tested.
|
||||
|
||||
|
||||
NOTICE: This documentation is not current as of September 2022.
|
||||
After I finished the refactoring I'll upgrade it.
|
||||
|
6
TODO
6
TODO
@ -1,3 +1,7 @@
|
||||
API Endpoint cleanup
|
||||
check keytype of panel
|
||||
check keytype of 1bindApi
|
||||
check:configkey => update config.json
|
||||
more UNIT tests
|
||||
DB migrations
|
||||
|
||||
|
||||
|
@ -10,11 +10,11 @@ if (php_sapi_name() !== 'cli') {
|
||||
|
||||
// check php version (must be >= 8.1)
|
||||
/** @noinspection PhpArgumentWithoutNamedIdentifierInspection */
|
||||
if (version_compare(PHP_VERSION, '8.1.0', '<')) {
|
||||
echo 'This application requires PHP 8.1 or newer. You are running ' . PHP_VERSION . PHP_EOL;
|
||||
echo 'If you are using KeyHelp, use keyhelp-php81 ' . $argv[0] . ' instead.' . PHP_EOL;
|
||||
if (version_compare(PHP_VERSION, '8.2.0', '<')) {
|
||||
echo 'This application requires PHP 8.2 or newer. You are running ' . PHP_VERSION . PHP_EOL;
|
||||
echo 'If you are using KeyHelp, use keyhelp-php82 ' . $argv[0] . ' instead.' . PHP_EOL;
|
||||
exit;
|
||||
}
|
||||
|
||||
/** @noinspection PhpArgumentWithoutNamedIdentifierInspection */
|
||||
require dirname(__DIR__, 1) . '/src/Util/Console.php';
|
||||
require dirname(__DIR__, 1) . '/src/Utilities/Console.php';
|
||||
|
148
bindapi.json
Normal file
148
bindapi.json
Normal file
@ -0,0 +1,148 @@
|
||||
{
|
||||
"openapi": "3.0.0",
|
||||
"info": {
|
||||
"title": "bindAPI",
|
||||
"version": "1.0.9"
|
||||
},
|
||||
"servers": [
|
||||
{
|
||||
"url": "{schema}://{hostname}/api",
|
||||
"description": "The bindAPI URL.",
|
||||
"variables": {
|
||||
"schema": {
|
||||
"enum": [
|
||||
"http",
|
||||
"https"
|
||||
],
|
||||
"default": "https"
|
||||
},
|
||||
"hostname": {
|
||||
"enum": [
|
||||
"ns1.24unix.net",
|
||||
"ns2.24unix.net"
|
||||
],
|
||||
"default": "ns2.24unix.net"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"paths": {
|
||||
"/ping": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"Server"
|
||||
],
|
||||
"description": "Checks for connectivity and valid APIkey",
|
||||
"operationId": "ping",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK"
|
||||
},
|
||||
"401": {
|
||||
"description": "API key is missing or invalid."
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"Authorization": []
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/version": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"Server"
|
||||
],
|
||||
"description": "Check the API version of the nameserver.",
|
||||
"operationId": "version",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "x.y.z, aka major, minor, patch"
|
||||
},
|
||||
"401": {
|
||||
"description": "API key is missing or invalid."
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"Authorization": []
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/domains": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"Domains"
|
||||
],
|
||||
"summary": "List all domains.",
|
||||
"description": "Returns a list of all domains on this server.",
|
||||
"operationId": "getAllDomains",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK"
|
||||
},
|
||||
"401": {
|
||||
"description": "API key is missing or invalid."
|
||||
},
|
||||
"404": {
|
||||
"description": "Domain not found."
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"Authorization": []
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/domains/{name}": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"Domains"
|
||||
],
|
||||
"summary": "Returns a single domain.",
|
||||
"description": "Returns information of a single domain specified by its domain name.",
|
||||
"operationId": "getSingleDomain",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "name",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK"
|
||||
},
|
||||
"401": {
|
||||
"description": "API key is missing or invalid."
|
||||
},
|
||||
"404": {
|
||||
"description": "Domain not found."
|
||||
}
|
||||
},
|
||||
"security": []
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"securitySchemes": {
|
||||
"Authorization": {
|
||||
"type": "apiKey",
|
||||
"description": "Api Authentication",
|
||||
"name": "X-API-Key",
|
||||
"in": "header"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
{
|
||||
"name": "Server"
|
||||
}
|
||||
]
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
{
|
||||
"name": "24unix/bindapi",
|
||||
"description": "manage Bind9 DNS server via REST API",
|
||||
"version": "2023.0.1",
|
||||
"build_number": "333",
|
||||
"name": "tracer/bindapi",
|
||||
"description": "manage Bind9 client zones for KeyHelp",
|
||||
"version": "1.1.2",
|
||||
"build_number": "380",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Micha Espey",
|
||||
@ -23,6 +23,7 @@
|
||||
"ext-posix": "*",
|
||||
"ext-sodium": "*",
|
||||
"arubacao/tld-checker": "^1.2",
|
||||
"bartlett/php-compatinfo": "^7.1",
|
||||
"monolog/monolog": "^3.1",
|
||||
"netresearch/jsonmapper": "^4.4",
|
||||
"php-di/php-di": "^6.3",
|
||||
@ -30,7 +31,7 @@
|
||||
"robmorgan/phinx": "^0.15",
|
||||
"symfony/property-access": "^6.1",
|
||||
"symfony/serializer": "^6.1",
|
||||
"zircote/swagger-php": "^4.2"
|
||||
"zircote/swagger-php": "^4.8"
|
||||
},
|
||||
"config": {
|
||||
"optimize-autoloader": true,
|
||||
|
3099
composer.lock
generated
3099
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@ -1,9 +1,10 @@
|
||||
{
|
||||
"env": "prod",
|
||||
"dbHost": "localhost",
|
||||
"dbPort": 3306,
|
||||
"dbDatabase": "sampledb",
|
||||
"dbUser": "sampleuser",
|
||||
"dbPassword": "secret",
|
||||
"encryptionKey": "12345678901234567890123456789012",
|
||||
"encryptionKey": "1bad::babe",
|
||||
"debug": false
|
||||
}
|
||||
|
33
db/migrations/20240418112243_config_table.php
Normal file
33
db/migrations/20240418112243_config_table.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
use Phinx\Db\Adapter\MysqlAdapter;
|
||||
|
||||
class ConfigTable extends Phinx\Migration\AbstractMigration
|
||||
{
|
||||
public function change()
|
||||
{
|
||||
$this->table('config', [
|
||||
'id' => false,
|
||||
'engine' => 'InnoDB',
|
||||
'encoding' => 'utf8mb4',
|
||||
'collation' => 'utf8mb4_general_ci',
|
||||
'comment' => '',
|
||||
'row_format' => 'DYNAMIC',
|
||||
])
|
||||
->addColumn('name', 'string', [
|
||||
'null' => false,
|
||||
'limit' => 256,
|
||||
'collation' => 'utf8mb4_general_ci',
|
||||
'encoding' => 'utf8mb4',
|
||||
])
|
||||
->addColumn('value', 'string', [
|
||||
'null' => false,
|
||||
'limit' => 256,
|
||||
'collation' => 'utf8mb4_general_ci',
|
||||
'encoding' => 'utf8mb4',
|
||||
'after' => 'name',
|
||||
])
|
||||
->removeColumn('version')
|
||||
->save();
|
||||
}
|
||||
}
|
24
db/migrations/20240418172308_api_key_creation_date.php
Normal file
24
db/migrations/20240418172308_api_key_creation_date.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
use Phinx\Db\Adapter\MysqlAdapter;
|
||||
|
||||
class ApiKeyCreationDate extends Phinx\Migration\AbstractMigration
|
||||
{
|
||||
public function change()
|
||||
{
|
||||
$this->table('apikeys', [
|
||||
'id' => false,
|
||||
'primary_key' => ['id'],
|
||||
'engine' => 'InnoDB',
|
||||
'encoding' => 'utf8mb4',
|
||||
'collation' => 'utf8mb4_unicode_ci',
|
||||
'comment' => '',
|
||||
'row_format' => 'DYNAMIC',
|
||||
])
|
||||
->addColumn('created_at', 'timestamp', [
|
||||
'null' => false,
|
||||
'after' => 'apikey',
|
||||
])
|
||||
->save();
|
||||
}
|
||||
}
|
24
db/migrations/20240419120157_unique_config_values.php
Normal file
24
db/migrations/20240419120157_unique_config_values.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
use Phinx\Db\Adapter\MysqlAdapter;
|
||||
|
||||
class UniqueConfigValues extends Phinx\Migration\AbstractMigration
|
||||
{
|
||||
public function change()
|
||||
{
|
||||
$this->table('config', [
|
||||
'id' => false,
|
||||
'primary_key' => ['name'],
|
||||
'engine' => 'InnoDB',
|
||||
'encoding' => 'utf8mb4',
|
||||
'collation' => 'utf8mb4_general_ci',
|
||||
'comment' => '',
|
||||
'row_format' => 'DYNAMIC',
|
||||
])
|
||||
->addIndex(['name'], [
|
||||
'name' => 'name',
|
||||
'unique' => true,
|
||||
])
|
||||
->save();
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
use Phinx\Db\Adapter\MysqlAdapter;
|
||||
|
||||
class TimeStampDefaultforApiKeys extends Phinx\Migration\AbstractMigration
|
||||
{
|
||||
public function change()
|
||||
{
|
||||
$this->table('apikeys', [
|
||||
'id' => false,
|
||||
'primary_key' => ['id'],
|
||||
'engine' => 'InnoDB',
|
||||
'encoding' => 'utf8mb4',
|
||||
'collation' => 'utf8mb4_unicode_ci',
|
||||
'comment' => '',
|
||||
'row_format' => 'DYNAMIC',
|
||||
])
|
||||
->changeColumn('created_at', 'timestamp', [
|
||||
'null' => true,
|
||||
'default' => 'current_timestamp()',
|
||||
'after' => 'apikey',
|
||||
])
|
||||
->save();
|
||||
}
|
||||
}
|
37
db/migrations/20240427114541_add_self_to_nameservers.php
Normal file
37
db/migrations/20240427114541_add_self_to_nameservers.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
use Phinx\Db\Adapter\MysqlAdapter;
|
||||
|
||||
class AddSelfToNameservers extends Phinx\Migration\AbstractMigration
|
||||
{
|
||||
public function change()
|
||||
{
|
||||
// $this->table('domains', [
|
||||
// 'id' => false,
|
||||
// 'primary_key' => ['id'],
|
||||
// 'engine' => 'InnoDB',
|
||||
// 'encoding' => 'utf8mb4',
|
||||
// 'collation' => 'utf8mb4_unicode_ci',
|
||||
// 'comment' => '',
|
||||
// 'row_format' => 'DYNAMIC',
|
||||
// ])
|
||||
// ->removeColumn('self')
|
||||
// ->save();
|
||||
$this->table('nameservers', [
|
||||
'id' => false,
|
||||
'primary_key' => ['id'],
|
||||
'engine' => 'InnoDB',
|
||||
'encoding' => 'utf8mb4',
|
||||
'collation' => 'utf8mb4_unicode_ci',
|
||||
'comment' => '',
|
||||
'row_format' => 'DYNAMIC',
|
||||
])
|
||||
->addColumn('self', 'enum', [
|
||||
'null' => false,
|
||||
'limit' => 3,
|
||||
'values' => ['yes', 'no'],
|
||||
'after' => 'apikey_prefix',
|
||||
])
|
||||
->save();
|
||||
}
|
||||
}
|
41
db/migrations/20240430111136_u_u_i_d_for_config.php
Normal file
41
db/migrations/20240430111136_u_u_i_d_for_config.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
use Phinx\Db\Adapter\MysqlAdapter;
|
||||
|
||||
class UUIDForConfig extends Phinx\Migration\AbstractMigration
|
||||
{
|
||||
public function change()
|
||||
{
|
||||
$this->table('config', [
|
||||
'id' => false,
|
||||
'primary_key' => ['id'],
|
||||
'engine' => 'InnoDB',
|
||||
'encoding' => 'utf8mb4',
|
||||
'collation' => 'utf8mb4_general_ci',
|
||||
'comment' => '',
|
||||
'row_format' => 'DYNAMIC',
|
||||
])
|
||||
->addColumn('id', 'uuid', [
|
||||
'null' => false,
|
||||
])
|
||||
->changeColumn('name', 'string', [
|
||||
'null' => false,
|
||||
'limit' => 256,
|
||||
'collation' => 'utf8mb4_general_ci',
|
||||
'encoding' => 'utf8mb4',
|
||||
'after' => 'id',
|
||||
])
|
||||
->changeColumn('value', 'string', [
|
||||
'null' => false,
|
||||
'limit' => 256,
|
||||
'collation' => 'utf8mb4_general_ci',
|
||||
'encoding' => 'utf8mb4',
|
||||
'after' => 'name',
|
||||
])
|
||||
->addIndex(['id'], [
|
||||
'name' => 'id',
|
||||
'unique' => true,
|
||||
])
|
||||
->save();
|
||||
}
|
||||
}
|
24
db/migrations/20240430112049_default_u_u_i_dfor_config.php
Normal file
24
db/migrations/20240430112049_default_u_u_i_dfor_config.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
use Phinx\Db\Adapter\MysqlAdapter;
|
||||
|
||||
class DefaultUUIDforConfig extends Phinx\Migration\AbstractMigration
|
||||
{
|
||||
public function change()
|
||||
{
|
||||
$this->table('config', [
|
||||
'id' => false,
|
||||
'primary_key' => ['id'],
|
||||
'engine' => 'InnoDB',
|
||||
'encoding' => 'utf8mb4',
|
||||
'collation' => 'utf8mb4_general_ci',
|
||||
'comment' => '',
|
||||
'row_format' => 'DYNAMIC',
|
||||
])
|
||||
->changeColumn('id', 'uuid', [
|
||||
'null' => false,
|
||||
'default' => 'uuid()',
|
||||
])
|
||||
->save();
|
||||
}
|
||||
}
|
@ -112,23 +112,71 @@ return array (
|
||||
),
|
||||
'columns' =>
|
||||
array (
|
||||
'version' =>
|
||||
'id' =>
|
||||
array (
|
||||
'TABLE_CATALOG' => 'def',
|
||||
'TABLE_NAME' => 'config',
|
||||
'COLUMN_NAME' => 'version',
|
||||
'COLUMN_NAME' => 'id',
|
||||
'ORDINAL_POSITION' => 1,
|
||||
'COLUMN_DEFAULT' => 'uuid()',
|
||||
'IS_NULLABLE' => 'NO',
|
||||
'DATA_TYPE' => 'uuid',
|
||||
'CHARACTER_MAXIMUM_LENGTH' => NULL,
|
||||
'CHARACTER_OCTET_LENGTH' => NULL,
|
||||
'NUMERIC_PRECISION' => NULL,
|
||||
'NUMERIC_SCALE' => NULL,
|
||||
'DATETIME_PRECISION' => NULL,
|
||||
'CHARACTER_SET_NAME' => NULL,
|
||||
'COLLATION_NAME' => NULL,
|
||||
'COLUMN_TYPE' => 'uuid',
|
||||
'COLUMN_KEY' => 'PRI',
|
||||
'EXTRA' => '',
|
||||
'PRIVILEGES' => 'select,insert,update,references',
|
||||
'COLUMN_COMMENT' => '',
|
||||
'IS_GENERATED' => 'NEVER',
|
||||
'GENERATION_EXPRESSION' => NULL,
|
||||
),
|
||||
'name' =>
|
||||
array (
|
||||
'TABLE_CATALOG' => 'def',
|
||||
'TABLE_NAME' => 'config',
|
||||
'COLUMN_NAME' => 'name',
|
||||
'ORDINAL_POSITION' => 2,
|
||||
'COLUMN_DEFAULT' => NULL,
|
||||
'IS_NULLABLE' => 'NO',
|
||||
'DATA_TYPE' => 'varchar',
|
||||
'CHARACTER_MAXIMUM_LENGTH' => 11,
|
||||
'CHARACTER_OCTET_LENGTH' => 44,
|
||||
'CHARACTER_MAXIMUM_LENGTH' => 256,
|
||||
'CHARACTER_OCTET_LENGTH' => 1024,
|
||||
'NUMERIC_PRECISION' => NULL,
|
||||
'NUMERIC_SCALE' => NULL,
|
||||
'DATETIME_PRECISION' => NULL,
|
||||
'CHARACTER_SET_NAME' => 'utf8mb4',
|
||||
'COLLATION_NAME' => 'utf8mb4_general_ci',
|
||||
'COLUMN_TYPE' => 'varchar(11)',
|
||||
'COLUMN_TYPE' => 'varchar(256)',
|
||||
'COLUMN_KEY' => 'UNI',
|
||||
'EXTRA' => '',
|
||||
'PRIVILEGES' => 'select,insert,update,references',
|
||||
'COLUMN_COMMENT' => '',
|
||||
'IS_GENERATED' => 'NEVER',
|
||||
'GENERATION_EXPRESSION' => NULL,
|
||||
),
|
||||
'value' =>
|
||||
array (
|
||||
'TABLE_CATALOG' => 'def',
|
||||
'TABLE_NAME' => 'config',
|
||||
'COLUMN_NAME' => 'value',
|
||||
'ORDINAL_POSITION' => 3,
|
||||
'COLUMN_DEFAULT' => NULL,
|
||||
'IS_NULLABLE' => 'NO',
|
||||
'DATA_TYPE' => 'varchar',
|
||||
'CHARACTER_MAXIMUM_LENGTH' => 256,
|
||||
'CHARACTER_OCTET_LENGTH' => 1024,
|
||||
'NUMERIC_PRECISION' => NULL,
|
||||
'NUMERIC_SCALE' => NULL,
|
||||
'DATETIME_PRECISION' => NULL,
|
||||
'CHARACTER_SET_NAME' => 'utf8mb4',
|
||||
'COLLATION_NAME' => 'utf8mb4_general_ci',
|
||||
'COLUMN_TYPE' => 'varchar(256)',
|
||||
'COLUMN_KEY' => '',
|
||||
'EXTRA' => '',
|
||||
'PRIVILEGES' => 'select,insert,update,references',
|
||||
@ -139,6 +187,60 @@ return array (
|
||||
),
|
||||
'indexes' =>
|
||||
array (
|
||||
'PRIMARY' =>
|
||||
array (
|
||||
1 =>
|
||||
array (
|
||||
'Table' => 'config',
|
||||
'Non_unique' => 0,
|
||||
'Key_name' => 'PRIMARY',
|
||||
'Seq_in_index' => 1,
|
||||
'Column_name' => 'id',
|
||||
'Collation' => 'A',
|
||||
'Sub_part' => NULL,
|
||||
'Packed' => NULL,
|
||||
'Null' => '',
|
||||
'Index_type' => 'BTREE',
|
||||
'Comment' => '',
|
||||
'Index_comment' => '',
|
||||
),
|
||||
),
|
||||
'name' =>
|
||||
array (
|
||||
1 =>
|
||||
array (
|
||||
'Table' => 'config',
|
||||
'Non_unique' => 0,
|
||||
'Key_name' => 'name',
|
||||
'Seq_in_index' => 1,
|
||||
'Column_name' => 'name',
|
||||
'Collation' => 'A',
|
||||
'Sub_part' => NULL,
|
||||
'Packed' => NULL,
|
||||
'Null' => '',
|
||||
'Index_type' => 'BTREE',
|
||||
'Comment' => '',
|
||||
'Index_comment' => '',
|
||||
),
|
||||
),
|
||||
'id' =>
|
||||
array (
|
||||
1 =>
|
||||
array (
|
||||
'Table' => 'config',
|
||||
'Non_unique' => 0,
|
||||
'Key_name' => 'id',
|
||||
'Seq_in_index' => 1,
|
||||
'Column_name' => 'id',
|
||||
'Collation' => 'A',
|
||||
'Sub_part' => NULL,
|
||||
'Packed' => NULL,
|
||||
'Null' => '',
|
||||
'Index_type' => 'BTREE',
|
||||
'Comment' => '',
|
||||
'Index_comment' => '',
|
||||
),
|
||||
),
|
||||
),
|
||||
'foreign_keys' => NULL,
|
||||
),
|
||||
@ -879,6 +981,30 @@ return array (
|
||||
'IS_GENERATED' => 'NEVER',
|
||||
'GENERATION_EXPRESSION' => NULL,
|
||||
),
|
||||
'created_at' =>
|
||||
array (
|
||||
'TABLE_CATALOG' => 'def',
|
||||
'TABLE_NAME' => 'apikeys',
|
||||
'COLUMN_NAME' => 'created_at',
|
||||
'ORDINAL_POSITION' => 5,
|
||||
'COLUMN_DEFAULT' => 'current_timestamp()',
|
||||
'IS_NULLABLE' => 'YES',
|
||||
'DATA_TYPE' => 'timestamp',
|
||||
'CHARACTER_MAXIMUM_LENGTH' => NULL,
|
||||
'CHARACTER_OCTET_LENGTH' => NULL,
|
||||
'NUMERIC_PRECISION' => NULL,
|
||||
'NUMERIC_SCALE' => NULL,
|
||||
'DATETIME_PRECISION' => 0,
|
||||
'CHARACTER_SET_NAME' => NULL,
|
||||
'COLLATION_NAME' => NULL,
|
||||
'COLUMN_TYPE' => 'timestamp',
|
||||
'COLUMN_KEY' => '',
|
||||
'EXTRA' => '',
|
||||
'PRIVILEGES' => 'select,insert,update,references',
|
||||
'COLUMN_COMMENT' => '',
|
||||
'IS_GENERATED' => 'NEVER',
|
||||
'GENERATION_EXPRESSION' => NULL,
|
||||
),
|
||||
),
|
||||
'indexes' =>
|
||||
array (
|
||||
@ -1060,6 +1186,30 @@ return array (
|
||||
'IS_GENERATED' => 'NEVER',
|
||||
'GENERATION_EXPRESSION' => NULL,
|
||||
),
|
||||
'self' =>
|
||||
array (
|
||||
'TABLE_CATALOG' => 'def',
|
||||
'TABLE_NAME' => 'nameservers',
|
||||
'COLUMN_NAME' => 'self',
|
||||
'ORDINAL_POSITION' => 7,
|
||||
'COLUMN_DEFAULT' => NULL,
|
||||
'IS_NULLABLE' => 'NO',
|
||||
'DATA_TYPE' => 'enum',
|
||||
'CHARACTER_MAXIMUM_LENGTH' => 3,
|
||||
'CHARACTER_OCTET_LENGTH' => 12,
|
||||
'NUMERIC_PRECISION' => NULL,
|
||||
'NUMERIC_SCALE' => NULL,
|
||||
'DATETIME_PRECISION' => NULL,
|
||||
'CHARACTER_SET_NAME' => 'utf8mb4',
|
||||
'COLLATION_NAME' => 'utf8mb4_unicode_ci',
|
||||
'COLUMN_TYPE' => 'enum(\'yes\',\'no\')',
|
||||
'COLUMN_KEY' => '',
|
||||
'EXTRA' => '',
|
||||
'PRIVILEGES' => 'select,insert,update,references',
|
||||
'COLUMN_COMMENT' => '',
|
||||
'IS_GENERATED' => 'NEVER',
|
||||
'GENERATION_EXPRESSION' => NULL,
|
||||
),
|
||||
),
|
||||
'indexes' =>
|
||||
array (
|
||||
|
6
dist/systemd/README.md
vendored
Normal file
6
dist/systemd/README.md
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
Copy these files to /etc/systems/system, adapt the path in the service unit and enable the timer by issuing:
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable bindAPI.timer
|
||||
systemctl start bindAPI.timer
|
||||
systemctl list-timers
|
6
dist/systemd/bindAPI.service
vendored
Normal file
6
dist/systemd/bindAPI.service
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
[Unit]
|
||||
Description=BindAPI Service to check zone file and reload configuration
|
||||
|
||||
[Service]
|
||||
User=<paneluser>
|
||||
ExecStart=/home/users/<user>/<bindApi>/bin/console -q cron:run
|
10
dist/systemd/bindAPI.timer
vendored
Normal file
10
dist/systemd/bindAPI.timer
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
[Unit]
|
||||
Description=Runs BindAPI every minute
|
||||
|
||||
[Timer]
|
||||
OnBootSec=1min
|
||||
OnUnitActiveSec=1min
|
||||
Unit=bindAPI.service
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
@ -1,17 +1,20 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use Exception;
|
||||
use App\Service\BindAPI;
|
||||
|
||||
error_reporting(error_level: E_ALL);
|
||||
|
||||
require dirname(path: __DIR__) . '/vendor/autoload.php';
|
||||
|
||||
$uri = parse_url(url: $_SERVER['REQUEST_URI'], component: PHP_URL_PATH);
|
||||
$uri = explode(separator: '/', string: $uri);
|
||||
$parsedUrl = parse_url(url: $_SERVER['REQUEST_URI'], component: PHP_URL_PATH);
|
||||
$uri = explode(separator: '/', string: $parsedUrl);
|
||||
|
||||
if ($uri[1] !== 'api') {
|
||||
$baseRoutes = ['app', 'api'];
|
||||
$uriPrefix = $uriFirstThreeLetters = substr(string: $uri[1], offset: 0, length: 3);
|
||||
|
||||
|
||||
if (!in_array(needle: $uriPrefix, haystack: $baseRoutes)) {
|
||||
// only handle $baseRoutes, elso go to swagger ui
|
||||
$scheme = $_SERVER['REQUEST_SCHEME'];
|
||||
$host = $_SERVER['SERVER_NAME'];
|
||||
$header = "$scheme://$host/openapi/index.html";
|
||||
@ -23,15 +26,22 @@ header(header: "Access-Control-Allow-Origin: *");
|
||||
header(header: "Content-Type: application/json; charset=UTF-8");
|
||||
header(header: "Access-Control-Allow-Methods: OPTIONS,GET,POST,PUT,DELETE");
|
||||
header(header: "Access-Control-Max-Age: 3600");
|
||||
header(header: "Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
|
||||
header(header: "Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With, x-api-key");
|
||||
|
||||
$requestMethod = $_SERVER["REQUEST_METHOD"];
|
||||
|
||||
if ($requestMethod === "OPTIONS") {
|
||||
// Respond with OK status code for preflight requests
|
||||
http_response_code(response_code: 200);
|
||||
exit();
|
||||
}
|
||||
|
||||
try {
|
||||
$app = new BindAPI();
|
||||
$app = new BindAPI(quiet: false);
|
||||
$app->handleRequest(requestMethod: $requestMethod, uri: $uri);
|
||||
} catch (Exception $e) {
|
||||
echo json_encode(value: [
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
}
|
||||
|
||||
|
5
public/openapi/bootstrap.php2
Normal file
5
public/openapi/bootstrap.php2
Normal file
@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
const DEFAULT_NS = 'ns2.24unix.net';
|
||||
|
||||
const NAMESERVERS = ['ns1.24unix.net', 'ns2.24unix.net'];
|
@ -19,7 +19,8 @@
|
||||
<script>
|
||||
window.onload = function () {
|
||||
// Begin Swagger UI call region
|
||||
const ui = SwaggerUIBundle({
|
||||
let ui;
|
||||
ui = SwaggerUIBundle({
|
||||
url: "/openapi/bindapi.json",
|
||||
dom_id: "#swagger-ui",
|
||||
deepLinking: true,
|
||||
|
@ -1,94 +0,0 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
error_reporting(error_level: E_ALL);
|
||||
|
||||
use App\Repository\DomainRepository;
|
||||
use App\Repository\DynDNSRepository;
|
||||
use DI\Container;
|
||||
use DI\ContainerBuilder;
|
||||
use DI\DependencyException;
|
||||
use DI\NotFoundException;
|
||||
use Exception;
|
||||
use Monolog\Formatter\LineFormatter;
|
||||
use Monolog\Handler\StreamHandler;
|
||||
use Monolog\Level;
|
||||
use Monolog\Logger;
|
||||
use function DI\autowire;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class BindAPI
|
||||
{
|
||||
private Logger $logger;
|
||||
private Container $container;
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function __construct(bool $quiet)
|
||||
{
|
||||
// init the logger
|
||||
$dateFormat = "Y:m:d H:i:s";
|
||||
$output = "%datetime% %channel%.%level_name% %message%\n"; // %context% %extra%
|
||||
$formatter = new LineFormatter(format: $output, dateFormat: $dateFormat);
|
||||
|
||||
$debug = (new ConfigController(quiet: $quiet))->getConfig(configKey: 'debug');
|
||||
if ($debug) {
|
||||
$stream = new StreamHandler(stream: dirname(path: __DIR__, levels: 2) . '/bindAPI.log', level: Level::Debug);
|
||||
} else {
|
||||
$stream = new StreamHandler(stream: dirname(path: __DIR__, levels: 2) . '/bindAPI.log', level: Level::Info);
|
||||
}
|
||||
$stream->setFormatter(formatter: $formatter);
|
||||
|
||||
$this->logger = new Logger(name: 'bindAPI');
|
||||
$this->logger->pushHandler(handler: $stream);
|
||||
$this->logger->debug(message: 'bindAPI started');
|
||||
|
||||
|
||||
$containerBuilder = new ContainerBuilder();
|
||||
$containerBuilder->addDefinitions([
|
||||
ConfigController::class => autowire()
|
||||
->constructorParameter(parameter: 'quiet', value: $quiet),
|
||||
CLIController::class => autowire()
|
||||
->constructorParameter(parameter: 'logger', value: $this->logger)
|
||||
->constructorParameter(parameter: 'quiet', value: $quiet),
|
||||
DomainController::class => autowire()
|
||||
->constructorParameter(parameter: 'logger', value: $this->logger)
|
||||
->constructorParameter(parameter: 'quiet', value: $quiet),
|
||||
DomainRepository::class => autowire()
|
||||
->constructorParameter(parameter: 'logger', value: $this->logger),
|
||||
DynDnsRepository::class => autowire()
|
||||
->constructorParameter(parameter: 'logger', value: $this->logger),
|
||||
RequestController::class => autowire()
|
||||
->constructorParameter(parameter: 'logger', value: $this->logger)
|
||||
]);
|
||||
$this->container = $containerBuilder->build();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @throws DependencyException
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function runCommand(array $arguments): void
|
||||
{
|
||||
$this->logger->debug(message: 'runCommand()');
|
||||
$cliController = $this->container->get(name: CLIController::class);
|
||||
$cliController->runCommand(arguments: $arguments);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @throws DependencyException
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function handleRequest(string $requestMethod, array $uri): void
|
||||
{
|
||||
$this->logger->debug(message: 'handleRequest()');
|
||||
$requestController = $this->container->get(name: RequestController::class);
|
||||
$requestController->handleRequest(requestMethod: $requestMethod, uri: $uri);
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -2,6 +2,8 @@
|
||||
|
||||
namespace App\Controller\Commands;
|
||||
|
||||
use App\Utilities\Colors;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@ -31,17 +33,17 @@ class CommandGroup
|
||||
|
||||
public function printCommands(int $longestCommandLength): void
|
||||
{
|
||||
echo COLOR_YELLOW . str_pad(string: $this->name, length: $longestCommandLength + 1) . COLOR_WHITE . $this->description . COLOR_DEFAULT . PHP_EOL;
|
||||
echo Colors::YELLOW . str_pad(string: $this->name, length: $longestCommandLength + 1) . Colors::WHITE . $this->description . Colors::DEFAULT . PHP_EOL;
|
||||
foreach ($this->commands as $command) {
|
||||
echo COLOR_GREEN . str_pad(string: ' ', length: $longestCommandLength + 1, pad_type: STR_PAD_LEFT) . $this->name . ':' . $command->getName();
|
||||
echo Colors::GREEN . str_pad(string: ' ', length: $longestCommandLength + 1, pad_type: STR_PAD_LEFT) . $this->name . ':' . $command->getName();
|
||||
foreach ($command->getMandatoryParameters() as $optionals) {
|
||||
echo ' <' . $optionals . '>';
|
||||
}
|
||||
foreach ($command->getOptionalParameters() as $mandatory) {
|
||||
echo ' {' . $mandatory . '}';
|
||||
}
|
||||
echo COLOR_WHITE . ' ' . $command->getDescription();
|
||||
echo COLOR_DEFAULT . PHP_EOL;
|
||||
echo Colors::WHITE . ' ' . $command->getDescription();
|
||||
echo Colors::DEFAULT . PHP_EOL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
namespace App\Controller\Commands;
|
||||
|
||||
use App\Utilities\Colors;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@ -64,23 +66,23 @@ class CommandGroupContainer
|
||||
if ($group->exec(subcommand: $subcommand)) {
|
||||
exit(0);
|
||||
} else {
|
||||
echo COLOR_DEFAULT . 'Unknown subcommand ' . COLOR_YELLOW . $subcommand . COLOR_DEFAULT .' for ' . COLOR_YELLOW . $command . COLOR_DEFAULT . '.' . PHP_EOL;
|
||||
echo Colors::DEFAULT . 'Unknown subcommand ' . Colors::YELLOW . $subcommand . Colors::DEFAULT .' for ' . Colors::YELLOW . $command . Colors::DEFAULT . '.' . PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
echo COLOR_DEFAULT . 'Unknown subcommand ' . COLOR_YELLOW . $subcommand . COLOR_DEFAULT .' for ' . COLOR_YELLOW . $command . COLOR_DEFAULT . '.' . PHP_EOL;
|
||||
echo Colors::DEFAULT . 'Unknown command group ' . Colors::YELLOW . $command . Colors::DEFAULT . '.' . PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
// check for command group and print available commands
|
||||
foreach ($this->commandGroups as $group) {
|
||||
if ($group->getName() === $command) {
|
||||
echo 'Available subcommands for: ' . COLOR_YELLOW . $group->getName() . COLOR_DEFAULT . ':' . PHP_EOL;
|
||||
echo 'Available subcommands for: ' . Colors::YELLOW . $group->getName() . Colors::DEFAULT . ':' . PHP_EOL;
|
||||
$group->printCommands(strlen(string: $group->getName()));
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
echo COLOR_DEFAULT . 'Unknown command ' . COLOR_YELLOW . $command . COLOR_DEFAULT . '.' . PHP_EOL;
|
||||
echo Colors::DEFAULT . 'Unknown command ' . Colors::YELLOW . $command . Colors::DEFAULT . '.' . PHP_EOL;
|
||||
}
|
||||
}
|
@ -2,14 +2,14 @@
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
use App\Utilities\Colors;
|
||||
|
||||
class ConfigController
|
||||
{
|
||||
private array $config;
|
||||
private static $missingEncryptionShown = false;
|
||||
|
||||
public function __construct(bool $quiet, bool $test = false)
|
||||
public function __construct(private readonly bool $quiet, bool $test = false)
|
||||
{
|
||||
|
||||
if ($test) {
|
||||
@ -38,21 +38,33 @@ class ConfigController
|
||||
}
|
||||
$configJSON = file_get_contents(filename: $configFile);
|
||||
|
||||
if (json_decode(json: $configJSON) === null) {
|
||||
// first check if json is valid, after make the assignment
|
||||
if (json_decode(json: $configJSON, associative: true) === null) {
|
||||
echo 'Config file is not valid JSON.' . PHP_EOL;
|
||||
echo $configJSON . PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$this->config = json_decode(json: $configJSON, associative: true);
|
||||
if (!ConfigController::$missingEncryptionShown) {
|
||||
if (!isset($this->config['encryptionKey']) || ($this->config['encryptionKey'] === '1bad::babe')) {
|
||||
ConfigController::$missingEncryptionShown = true;
|
||||
if (!$this->quiet) {
|
||||
echo Colors::RED . 'Error: ' . Colors::DEFAULT . 'No encryption key, please run ' . Colors::YELLOW . './bin/console check:generatekey' . Colors::DEFAULT . PHP_EOL;
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
$this->config['quiet'] = (bool)$quiet;
|
||||
$this->config['test'] = (bool)$test;
|
||||
}
|
||||
|
||||
public function getConfig(string $configKey): string
|
||||
public function getConfig(string $configKey): ?string
|
||||
{
|
||||
return $this->config[$configKey];
|
||||
if (isset($this->config[$configKey])) {
|
||||
return $this->config[$configKey];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,8 @@ use App\Entity\Domain;
|
||||
use App\Repository\DomainRepository;
|
||||
use App\Repository\NameserverRepository;
|
||||
use App\Repository\PanelRepository;
|
||||
use App\Service\ApiClient;
|
||||
use App\Utilities\Colors;
|
||||
use Monolog\Logger;
|
||||
|
||||
error_reporting(error_level: E_ALL);
|
||||
@ -25,7 +27,7 @@ class DomainController
|
||||
|
||||
public function __construct(
|
||||
private readonly NameserverRepository $nameserverRepository,
|
||||
private readonly ApiController $checkController,
|
||||
private readonly ApiClient $checkController,
|
||||
private readonly DomainRepository $domainRepository,
|
||||
private readonly PanelRepository $panelRepository,
|
||||
private readonly ConfigController $configController,
|
||||
@ -70,28 +72,58 @@ class DomainController
|
||||
|
||||
function updateSlaveZones(): void
|
||||
{
|
||||
$this->logger->debug(message: 'Delete all slave zones');
|
||||
|
||||
$zones = glob(pattern: $this->localZonesDir . '*');
|
||||
foreach ($zones as $zone) {
|
||||
unlink(filename: $zone);
|
||||
}
|
||||
$this->logger->debug(message: 'update slave zones');
|
||||
|
||||
$existingZones = glob(pattern: $this->localZonesDir . '*');
|
||||
|
||||
$domains = $this->domainRepository->findAll();
|
||||
$longestEntry = $this->domainRepository->getLongestEntry('name');
|
||||
|
||||
$longestEntry = $this->domainRepository->getLongestEntry(field: 'name');
|
||||
$self = $this->panelRepository->getSelf();
|
||||
|
||||
foreach ($domains as $domain) {
|
||||
$zoneFile = $this->localZonesDir . $domain->getName();
|
||||
if (!$this->quiet) {
|
||||
echo ' ' . COLOR_YELLOW . str_pad($domain->getName(), $longestEntry + 1, " ", STR_PAD_RIGHT) ;
|
||||
echo ' ' . Colors::YELLOW . str_pad(string: $domain->getName(), length: $longestEntry + 1, pad_string: " ", pad_type: STR_PAD_RIGHT) ;
|
||||
}
|
||||
if ($this->createSlaveZoneFile(domain: $domain)) {
|
||||
|
||||
if (strcmp(string1: $self->getName(), string2: $domain->getPanel()) !== 0) {
|
||||
if (!file_exists(filename: $zoneFile)) {
|
||||
if (!$this->quiet) {
|
||||
echo Colors::GREEN . ' OK' . Colors::DEFAULT . PHP_EOL;
|
||||
}
|
||||
$this->createSlaveZoneFile(domain: $domain);
|
||||
} else {
|
||||
if (($key = array_search(needle: $zoneFile, haystack: $existingZones)) !== false) {
|
||||
if (isset($existingZones[$key])) {
|
||||
unset($existingZones[$key]);
|
||||
}
|
||||
} else {
|
||||
echo 'missing value: ' . $zoneFile;
|
||||
}
|
||||
if (!$this->quiet) {
|
||||
echo Colors::DEFAULT . 'Zone already exists.' . PHP_EOL;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!$this->quiet) {
|
||||
echo COLOR_GREEN . ' OK' . COLOR_DEFAULT . PHP_EOL;
|
||||
echo Colors::DEFAULT . 'We are master for ' . Colors::YELLOW . $domain->getName() . PHP_EOL;
|
||||
}
|
||||
}
|
||||
}
|
||||
// remove stale zones
|
||||
foreach ($existingZones as $zone) {
|
||||
if (!$this->quiet) {
|
||||
echo 'Removing stale zone: ' . Colors::YELLOW . $zone . Colors::DEFAULT . PHP_EOL;
|
||||
}
|
||||
echo $zone . PHP_EOL;
|
||||
unlink(filename: $zone);
|
||||
}
|
||||
|
||||
$this->createIncludeFile();
|
||||
$semaphore = $this->localZonesDir . 'zones.flag';
|
||||
if (file_exists(filename: $semaphore)) {
|
||||
unlink(filename: $semaphore);
|
||||
$this->createIncludeFile();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -159,12 +191,12 @@ class DomainController
|
||||
$uid = posix_geteuid();
|
||||
}
|
||||
if (!$this->quiet) {
|
||||
echo "UID:\t" . COLOR_YELLOW . $uid . PHP_EOL;
|
||||
echo "UID:\t" . Colors::YELLOW . $uid . PHP_EOL;
|
||||
}
|
||||
$pwuid = posix_getpwuid(user_id: $uid);
|
||||
$name = $pwuid['name'];
|
||||
if (!$this->quiet) {
|
||||
echo COLOR_DEFAULT . "Name:\t" . COLOR_YELLOW . $name . PHP_EOL;
|
||||
echo Colors::DEFAULT . "Name:\t" . Colors::YELLOW . $name . PHP_EOL;
|
||||
}
|
||||
|
||||
if (!$bindGroup = posix_getgrnam(name: 'bind')) {
|
||||
@ -173,40 +205,40 @@ class DomainController
|
||||
$members = $bindGroup['members'] ?? [];
|
||||
if (in_array(needle: $name, haystack: $members)) {
|
||||
if (!$this->quiet) {
|
||||
echo "\t✅ $name" . COLOR_DEFAULT . ' is in group ' . COLOR_YELLOW . 'bind' . PHP_EOL;
|
||||
echo "\t✅ $name" . Colors::DEFAULT . ' is in group ' . Colors::YELLOW . 'bind' . PHP_EOL;
|
||||
}
|
||||
} else {
|
||||
$setupIsValid = false;
|
||||
if (!$this->quiet) {
|
||||
echo COLOR_RED . "\t❌$name needs to be in group " . COLOR_YELLOW . 'bind' . COLOR_DEFAULT . '!' . PHP_EOL;
|
||||
echo Colors::RED . "\t❌$name needs to be in group " . Colors::YELLOW . 'bind' . Colors::DEFAULT . '!' . PHP_EOL;
|
||||
}
|
||||
}
|
||||
if (!$this->quiet) {
|
||||
echo COLOR_DEFAULT . 'Checking ' . COLOR_YELLOW . $this->localZoneFile . PHP_EOL;
|
||||
echo Colors::DEFAULT . 'Checking ' . Colors::YELLOW . $this->localZoneFile . PHP_EOL;
|
||||
}
|
||||
$localZoneFilePermissions = @fileperms(filename: $this->localZoneFile);
|
||||
if ($localZoneFilePermissions & 0x0010) {
|
||||
if (!$this->quiet) {
|
||||
echo COLOR_DEFAULT . "\t✅ Group has write access." . PHP_EOL;
|
||||
echo Colors::DEFAULT . "\t✅ Group has write access." . PHP_EOL;
|
||||
}
|
||||
} else {
|
||||
$setupIsValid = false;
|
||||
if (!$this->quiet) {
|
||||
echo COLOR_RED . "\t❌Group needs write permission!" . COLOR_DEFAULT . PHP_EOL;
|
||||
echo Colors::RED . "\t❌Group needs write permission!" . Colors::DEFAULT . PHP_EOL;
|
||||
}
|
||||
}
|
||||
if (!$this->quiet) {
|
||||
echo 'Checking ' . COLOR_YELLOW . $this->namedConfLocalFile . PHP_EOL;
|
||||
echo 'Checking ' . Colors::YELLOW . $this->namedConfLocalFile . PHP_EOL;
|
||||
}
|
||||
if (file_exists(filename: $this->namedConfLocalFile) && $namedConfLocal = file_get_contents(filename: $this->namedConfLocalFile)) {
|
||||
if (!str_contains(haystack: $namedConfLocal, needle: $this->localZoneFile)) {
|
||||
$setupIsValid = false;
|
||||
if (!$this->quiet) {
|
||||
echo "\t❌ $this->localZoneFile" . COLOR_RED . ' needs to be included in ' . COLOR_YELLOW . $this->namedConfLocalFile . PHP_EOL;
|
||||
echo "\t❌ $this->localZoneFile" . Colors::RED . ' needs to be included in ' . Colors::YELLOW . $this->namedConfLocalFile . PHP_EOL;
|
||||
}
|
||||
} else {
|
||||
if (!$this->quiet) {
|
||||
echo "\t✅ $this->localZoneFile" . COLOR_DEFAULT . ' is included in ' . COLOR_YELLOW . $this->namedConfLocalFile . PHP_EOL;
|
||||
echo "\t✅ $this->localZoneFile" . Colors::DEFAULT . ' is included in ' . Colors::YELLOW . $this->namedConfLocalFile . PHP_EOL;
|
||||
}
|
||||
}
|
||||
} else {
|
||||