diff --git a/cp/app/Controllers/HostsController.php b/cp/app/Controllers/HostsController.php index 811a158..3eda138 100644 --- a/cp/app/Controllers/HostsController.php +++ b/cp/app/Controllers/HostsController.php @@ -11,8 +11,236 @@ class HostsController extends Controller { public function view(Request $request, Response $response) { - $hostsModel = new Host($this->container->get('db')); - $hosts = $hostsModel->getAllHost(); - return view($response,'admin/hosts/index.twig', compact('hosts')); - } + return view($response,'admin/hosts/view.twig'); + } + + public function create(Request $request, Response $response) + { + if ($request->getMethod() === 'POST') { + // Retrieve POST data + $data = $request->getParsedBody(); + $db = $this->container->get('db'); + $hostName = $data['hostname'] ?? null; + $ipv4 = $data['ipv4'] ?? null; + $ipv6 = $data['ipv6'] ?? null; + $registrar_id = $data['registrar'] ?? null; + $registrars = $db->select("SELECT id, clid, name FROM registrar"); + + if ($hostName) { + $hostModel = new Host($this->container->get('db')); + + if (preg_match('/^([A-Z0-9]([A-Z0-9-]{0,61}[A-Z0-9]){0,1}\.){1,125}[A-Z0-9]([A-Z0-9-]{0,61}[A-Z0-9])$/i', $hostName) && strlen($hostName) < 254) { + $host_id_already_exist = $hostModel->getHostByNom($hostName); + if ($host_id_already_exist) { + return view($response, 'admin/hosts/create.twig', [ + 'hostName' => $hostName, + 'error' => 'host name already exists', + 'registrars' => $registrars, + ]); + } + } else { + return view($response, 'admin/hosts/create.twig', [ + 'hostName' => $hostName, + 'error' => 'Invalid host name', + 'registrars' => $registrars, + ]); + } + + $result = $db->select('SELECT registrar_id FROM registrar_users WHERE user_id = ?', [$_SESSION['auth_user_id']]); + + if (is_array($result)) { + $clid = $result['registrar_id']; + } else if (is_object($result) && method_exists($result, 'fetch')) { + $clid = $result->fetch(); + } else { + $clid = $registrar_id; + } + + if ($ipv4) { + $ipv4 = normalize_v4_address($ipv4); + if (!filter_var($ipv4, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { + return view($response, 'admin/hosts/create.twig', [ + 'hostName' => $hostName, + 'error' => 'Invalid host addr v4', + 'registrars' => $registrars, + ]); + } + } + + if ($ipv6) { + $ipv6 = normalize_v6_address($ipv6); + if (!filter_var($ipv6, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { + return view($response, 'admin/hosts/create.twig', [ + 'hostName' => $hostName, + 'error' => 'Invalid host addr v6', + 'registrars' => $registrars, + ]); + } + } + + $internal_host = false; + + $query = "SELECT tld FROM domain_tld"; + $result = $db->select($query); + + foreach ($result as $row) { + if (preg_match("/" . preg_quote(strtoupper($row['tld']), '/') . "$/i", $hostName)) { + $internal_host = true; + break; + } + } + + if ($internal_host) { + $domain_exist = false; + $clid_domain = 0; + $superordinate_dom = 0; + + $result = $db->select("SELECT id, clid, name FROM domain"); + + foreach ($result as $row) { + if (strpos($hostName, $row['name']) !== false) { + $domain_exist = true; + $clid_domain = $row['clid']; + $superordinate_dom = $row['id']; + break; + } + } + + if (!$domain_exist) { + return view($response, 'admin/hosts/create.twig', [ + 'hostName' => $hostName, + 'error' => 'A host name object can NOT be created in a repository for which no superordinate domain name object exists', + 'registrars' => $registrars, + ]); + } + + if ($_SESSION['auth_roles'] !== 0) { + if ($clid != $clid_domain) { + return view($response, 'admin/hosts/create.twig', [ + 'hostName' => $hostName, + 'error' => 'The domain name belongs to another registrar, you are not allowed to create hosts for it', + 'registrars' => $registrars, + ]); + } + } + + $db->beginTransaction(); + + try { + $db->insert( + 'host', + [ + 'name' => $hostName, + 'domain_id' => $superordinate_dom, + 'clid' => $clid, + 'crid' => $clid, + 'crdate' => date('Y-m-d H:i:s') + ] + ); + $host_id = $db->getLastInsertId(); + + if (!$ipv4 && !$ipv6) { + return view($response, 'admin/hosts/create.twig', [ + 'hostName' => $hostName, + 'error' => 'At least one of IPv4 or IPv6 must be provided', + 'registrars' => $registrars, + ]); + } + + if ($ipv4) { + $ipv4 = normalize_v4_address($ipv4); + $db->insert( + 'host_addr', + [ + 'host_id' => $host_id, + 'addr' => $ipv4, + 'ip' => 'v4' + ] + ); + } + + if ($ipv6) { + $ipv6 = normalize_v6_address($ipv6); + $db->insert( + 'host_addr', + [ + 'host_id' => $host_id, + 'addr' => $ipv6, + 'ip' => 'v6' + ] + ); + } + + $host_status = 'ok'; + $db->insert( + 'host_status', + [ + 'host_id' => $host_id, + 'status' => $host_status + ] + ); + + $db->commit(); + } catch (Exception $e) { + $db->rollBack(); + return view($response, 'admin/hosts/create.twig', [ + 'hostName' => $hostName, + 'error' => $e->getMessage(), + 'registrars' => $registrars, + ]); + } + + $crdate = $db->selectValue( + "SELECT crdate FROM host WHERE name = ? LIMIT 1", + [$hostName] + ); + + return view($response, 'admin/hosts/create.twig', [ + 'hostName' => $hostName, + 'crdate' => $crdate, + 'registrars' => $registrars, + ]); + } else { + $db->insert( + 'host', + [ + 'name' => $hostName, + 'clid' => $clid, + 'crid' => $clid, + 'crdate' => date('Y-m-d H:i:s') + ] + ); + $host_id = $db->getLastInsertId(); + + $host_status = 'ok'; + $db->insert( + 'host_status', + [ + 'host_id' => $host_id, + 'status' => $host_status + ] + ); + + $crdate = $db->selectValue( + "SELECT crdate FROM host WHERE name = ? LIMIT 1", + [$hostName] + ); + + return view($response, 'admin/hosts/create.twig', [ + 'hostName' => $hostName, + 'crdate' => $crdate, + 'registrars' => $registrars, + ]); + } + } + } + + $db = $this->container->get('db'); + $registrars = $db->select("SELECT id, clid, name FROM registrar"); + + // Default view for GET requests or if POST data is not set + return view($response,'admin/hosts/create.twig', [ + 'registrars' => $registrars, + ]); + } } \ No newline at end of file diff --git a/cp/app/Models/Host.php b/cp/app/Models/Host.php index 52cd51c..ff52b2c 100644 --- a/cp/app/Models/Host.php +++ b/cp/app/Models/Host.php @@ -50,7 +50,20 @@ class Host return $this->db->select($sql, [$id])->fetch(); } + + public function getHostByNom($name) + { + $result = $this->db->select('SELECT id FROM host WHERE name = ?', [$name]); + + if (is_array($result)) { + return $result; + } else if (is_object($result) && method_exists($result, 'fetch')) { + return $result->fetch(); + } + return null; + } + public function deleteHost($id) { $this->db->delete('DELETE FROM host WHERE id = ?', [$id]); diff --git a/cp/resources/views/admin/hosts/create.twig b/cp/resources/views/admin/hosts/create.twig new file mode 100644 index 0000000..80f1321 --- /dev/null +++ b/cp/resources/views/admin/hosts/create.twig @@ -0,0 +1,108 @@ +{% extends "layouts/app.twig" %} + +{% block title %}{{ __('Create Host') }}{% endblock %} + +{% block content %} +
+ + + +
+
+
+
+
+
+ {{ csrf.field | raw }} +
+ + +
+ + {% if registrars %} +
+ + +
+ {% endif %} + +
+ + + Please enter a valid IPv4 address. +
+ +
+ + + Please enter a valid IPv6 address. +
+ + +
+ {% if hostName is defined and crdate is defined %} + + {% elseif error is defined %} + + {% endif %} +
+
+
+
+
+
+ + +{% endblock %} \ No newline at end of file diff --git a/cp/resources/views/admin/hosts/index.twig b/cp/resources/views/admin/hosts/view.twig similarity index 97% rename from cp/resources/views/admin/hosts/index.twig rename to cp/resources/views/admin/hosts/view.twig index 7f15c8e..53d1a2c 100644 --- a/cp/resources/views/admin/hosts/index.twig +++ b/cp/resources/views/admin/hosts/view.twig @@ -59,9 +59,9 @@ - -
-
+
+
+
diff --git a/cp/resources/views/layouts/app.twig b/cp/resources/views/layouts/app.twig index 292e207..04e293c 100644 --- a/cp/resources/views/layouts/app.twig +++ b/cp/resources/views/layouts/app.twig @@ -222,7 +222,7 @@ -
  • +
  • {{ __('List Hosts') }} - + {{ __('Create Host') }} diff --git a/cp/routes/web.php b/cp/routes/web.php index 99e264d..052e29e 100644 --- a/cp/routes/web.php +++ b/cp/routes/web.php @@ -43,7 +43,10 @@ $app->group('', function ($route) { $route->map(['GET', 'POST'], '/domain/check', DomainsController::class . ':check')->setName('domaincheck'); $route->get('/contacts', ContactsController::class .':view')->setName('contacts'); + $route->get('/hosts', HostsController::class .':view')->setName('hosts'); + $route->map(['GET', 'POST'], '/host/create', HostsController::class . ':create')->setName('hostcreate'); + $route->get('/registrars', RegistrarsController::class .':view')->setName('registrars'); $route->get('/logs', LogsController::class .':view')->setName('logs'); $route->get('/reports', ReportsController::class .':view')->setName('reports');