diff --git a/cp/app/Controllers/LogsController.php b/cp/app/Controllers/LogsController.php index 8b26f99..d8602cc 100644 --- a/cp/app/Controllers/LogsController.php +++ b/cp/app/Controllers/LogsController.php @@ -13,14 +13,18 @@ class LogsController extends Controller { return view($response,'admin/logs/index.twig'); } - + public function poll(Request $request, Response $response) { return view($response,'admin/logs/poll.twig'); } - + public function log(Request $request, Response $response) { + if ($_SESSION["auth_roles"] != 0) { + return $response->withHeader('Location', '/dashboard')->withStatus(302); + } + return view($response,'admin/logs/log.twig'); } } \ No newline at end of file diff --git a/cp/app/Controllers/RegistrarsController.php b/cp/app/Controllers/RegistrarsController.php index fd25fee..17aad09 100644 --- a/cp/app/Controllers/RegistrarsController.php +++ b/cp/app/Controllers/RegistrarsController.php @@ -12,6 +12,10 @@ class RegistrarsController extends Controller { public function view(Request $request, Response $response) { + if ($_SESSION["auth_roles"] != 0) { + return $response->withHeader('Location', '/dashboard')->withStatus(302); + } + return view($response,'admin/registrars/index.twig'); } @@ -303,7 +307,7 @@ class RegistrarsController extends Controller [ $args ]); if ($registrar) { - // Check if the user is not an admin (assuming role 0 is admin) + // Check if the user is not an admin if ($_SESSION["auth_roles"] != 0) { $userRegistrars = $db->select('SELECT registrar_id FROM registrar_users WHERE user_id = ?', [$_SESSION['auth_user_id']]); @@ -311,7 +315,7 @@ class RegistrarsController extends Controller $userRegistrarIds = array_column($userRegistrars, 'registrar_id'); // Check if the registrar's ID is in the user's list of registrar IDs - if (!in_array($registrars['id'], $userRegistrarIds)) { + if (!in_array($registrar['id'], $userRegistrarIds)) { // Redirect to the registrars view if the user is not authorized for this contact return $response->withHeader('Location', '/registrars')->withStatus(302); } @@ -359,6 +363,58 @@ class RegistrarsController extends Controller } + public function registrar(Request $request, Response $response) + { + $db = $this->container->get('db'); + // Get the current URI + $uri = $request->getUri()->getPath(); + $registrarId = $_SESSION['auth_registrar_id']; + + if (isset($registrarId) && $registrarId !== "") { + $registrar = $db->selectRow('SELECT * FROM registrar WHERE id = ?', + [ $registrarId ]); + + if ($registrar) { + $registrarContact = $db->selectRow('SELECT * FROM registrar_contact WHERE registrar_id = ?', + [ $registrar['id'] ]); + $registrarOte = $db->select('SELECT * FROM registrar_ote WHERE registrar_id = ? ORDER by command', + [ $registrar['id'] ]); + $registrarUsers = $db->selectRow('SELECT user_id FROM registrar_users WHERE registrar_id = ?', + [ $registrar['id'] ]); + $userEmail = $db->selectRow('SELECT email FROM users WHERE id = ?', + [ $registrarUsers['user_id'] ]); + $registrarWhitelist = $db->select('SELECT addr FROM registrar_whitelist WHERE registrar_id = ?', + [ $registrar['id'] ]); + // Check if RegistrarOTE is not empty + if (is_array($registrarOte) && !empty($registrarOte)) { + // Split the results into two groups + $firstHalf = array_slice($registrarOte, 0, 5); + $secondHalf = array_slice($registrarOte, 5); + } else { + // If RegistrarOTE is empty, set both halves to empty arrays + $firstHalf = []; + $secondHalf = []; + } + + return view($response,'admin/registrars/viewRegistrar.twig', [ + 'registrar' => $registrar, + 'registrarContact' => $registrarContact, + 'firstHalf' => $firstHalf, + 'secondHalf' => $secondHalf, + 'userEmail' => $userEmail, + 'registrarWhitelist' => $registrarWhitelist, + 'currentUri' => $uri + ]); + } else { + // Contact does not exist, redirect to the dashboard view + return $response->withHeader('Location', '/dashboard')->withStatus(302); + } + } else { + // Redirect to the registrars view + return $response->withHeader('Location', '/registrars')->withStatus(302); + } + } + public function updateRegistrar(Request $request, Response $response, $args) { $db = $this->container->get('db'); @@ -518,11 +574,6 @@ class RegistrarsController extends Controller try { $currentDateTime = new \DateTime(); $update = $currentDateTime->format('Y-m-d H:i:s.v'); - $characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; - $randomPrefix = ''; - for ($i = 0; $i < 2; $i++) { - $randomPrefix .= $characters[rand(0, strlen($characters) - 1)]; - } $currency = $_SESSION['_currency'] ?? 'USD'; if (empty($data['ianaId']) || !is_numeric($data['ianaId'])) { @@ -667,5 +718,287 @@ class RegistrarsController extends Controller return $response->withHeader('Location', '/registrar/update/'.$registrar)->withStatus(302); } } + + public function editRegistrar(Request $request, Response $response) + { + if ($request->getMethod() === 'POST') { + // Retrieve POST data + $data = $request->getParsedBody(); + $db = $this->container->get('db'); + if (!empty($_SESSION['registrars_to_update'])) { + $registrar = $_SESSION['registrars_to_update'][0]; + } else { + $this->container->get('flash')->addMessage('error', 'No registrar specified for update'); + return $response->withHeader('Location', '/registrars')->withStatus(302); + } + + $data['ipAddress'] = array_filter($data['ipAddress']); + $iso3166 = new ISO3166(); + $countries = $iso3166->all(); + + $ipAddressValidator = v::when( + v::arrayType()->notEmpty(), // Condition: If it's a non-empty array + v::arrayType()->each(v::ip()), // Then: Each element must be a valid IP address + v::equals('') // Else: Allow it to be an empty string + ); + + $data['owner']['cc'] = strtoupper($data['owner']['cc']); + $data['billing']['cc'] = strtoupper($data['billing']['cc']); + $data['abuse']['cc'] = strtoupper($data['abuse']['cc']); + + $phoneValidator = v::regex('/^\+\d{1,3}\.\d{2,12}$/'); + + // Define validation for nested fields + $contactValidator = [ + v::key('first_name', v::stringType()->notEmpty()->length(1, 255), true), + v::key('last_name', v::stringType()->notEmpty()->length(1, 255), true), + v::key('org', v::optional(v::stringType()->length(1, 255)), false), + v::key('street1', v::optional(v::stringType()), false), + v::key('city', v::stringType()->notEmpty(), true), + v::key('sp', v::optional(v::stringType()), false), + v::key('pc', v::optional(v::stringType()), false), + v::key('cc', v::countryCode(), true), + v::key('voice', v::optional($phoneValidator), false), + v::key('fax', v::optional(v::phone()), false), + v::key('email', v::email(), true) + ]; + + $validators = [ + 'name' => v::stringType()->notEmpty()->length(1, 255), + 'ianaId' => v::optional(v::positive()->length(1, 5)), + 'email' => v::email(), + 'owner' => v::optional(v::keySet(...$contactValidator)), + 'billing' => v::optional(v::keySet(...$contactValidator)), + 'abuse' => v::optional(v::keySet(...$contactValidator)), + 'whoisServer' => v::domain(), + 'rdapServer' => v::domain(), + 'url' => v::url(), + 'abuseEmail' => v::email(), + 'abusePhone' => v::optional($phoneValidator), + 'ipAddress' => v::optional($ipAddressValidator) + ]; + + $errors = []; + foreach ($validators as $field => $validator) { + try { + $validator->assert(isset($data[$field]) ? $data[$field] : []); + } catch (\Respect\Validation\Exceptions\NestedValidationException $e) { + $errors[$field] = $e->getMessages(); + } + } + + if (!empty($errors)) { + // Handle errors + $errorText = ''; + + foreach ($errors as $field => $messages) { + $errorText .= ucfirst($field) . ' errors: ' . implode(', ', $messages) . '; '; + } + + // Trim the final semicolon and space + $errorText = rtrim($errorText, '; '); + + $this->container->get('flash')->addMessage('error', $errorText); + return $response->withHeader('Location', '/registrar/edit')->withStatus(302); + } + + if (!empty($_SESSION['registrars_user_email'])) { + $regEmail = $_SESSION['registrars_user_email'][0]; + } else { + $this->container->get('flash')->addMessage('error', 'No email specified for update'); + return $response->withHeader('Location', '/registrar/edit')->withStatus(302); + } + + $db->beginTransaction(); + + try { + $currentDateTime = new \DateTime(); + $update = $currentDateTime->format('Y-m-d H:i:s.v'); + $currency = $_SESSION['_currency'] ?? 'USD'; + + if (empty($data['ianaId']) || !is_numeric($data['ianaId'])) { + $data['ianaId'] = null; + } + + $updateData = [ + 'name' => $data['name'], + 'iana_id' => $data['ianaId'], + 'email' => $data['email'], + 'url' => $data['url'], + 'whois_server' => $data['whoisServer'], + 'rdap_server' => $data['rdapServer'], + 'abuse_email' => $data['abuseEmail'], + 'abuse_phone' => $data['abusePhone'], + 'currency' => $currency, + 'lastupdate' => $crdate + ]; + + if (!empty($data['eppPassword'])) { + $eppPassword = password_hash($data['eppPassword'], PASSWORD_ARGON2ID, ['memory_cost' => 1024 * 128, 'time_cost' => 6, 'threads' => 4]); + $updateData['pw'] = $eppPassword; + } + + $db->update( + 'registrar', + $updateData, + [ + 'clid' => $registrar + ] + ); + $registrar_id = $db->selectValue( + 'SELECT id FROM registrar WHERE clid = ?', + [$registrar] + ); + + $db->update( + 'registrar_contact', + [ + 'first_name' => $data['owner']['first_name'], + 'last_name' => $data['owner']['last_name'], + 'org' => $data['owner']['org'], + 'street1' => $data['owner']['street1'], + 'city' => $data['owner']['city'], + 'sp' => $data['owner']['sp'], + 'pc' => $data['owner']['pc'], + 'cc' => strtolower($data['owner']['cc']), + 'voice' => $data['owner']['voice'], + 'email' => $data['owner']['email'] + ], + [ + 'registrar_id' => $registrar_id, + 'type' => 'owner' + ] + ); + + $db->update( + 'registrar_contact', + [ + 'first_name' => $data['billing']['first_name'], + 'last_name' => $data['billing']['last_name'], + 'org' => $data['billing']['org'], + 'street1' => $data['billing']['street1'], + 'city' => $data['billing']['city'], + 'sp' => $data['billing']['sp'], + 'pc' => $data['billing']['pc'], + 'cc' => strtolower($data['billing']['cc']), + 'voice' => $data['billing']['voice'], + 'email' => $data['billing']['email'] + ], + [ + 'registrar_id' => $registrar_id, + 'type' => 'billing' + ] + ); + + $db->update( + 'registrar_contact', + [ + 'first_name' => $data['abuse']['first_name'], + 'last_name' => $data['abuse']['last_name'], + 'org' => $data['abuse']['org'], + 'street1' => $data['abuse']['street1'], + 'city' => $data['abuse']['city'], + 'sp' => $data['abuse']['sp'], + 'pc' => $data['abuse']['pc'], + 'cc' => strtolower($data['abuse']['cc']), + 'voice' => $data['abuse']['voice'], + 'email' => $data['abuse']['email'] + ], + [ + 'registrar_id' => $registrar_id, + 'type' => 'abuse' + ] + ); + + if (!empty($data['ipAddress'])) { + $db->delete( + 'registrar_whitelist', + [ + 'registrar_id' => $registrar_id + ] + ); + + foreach ($data['ipAddress'] as $ip) { + $db->insert( + 'registrar_whitelist', + [ + 'registrar_id' => $registrar_id, + 'addr' => $ip + ] + ); + } + } + + if ($data['panelPassword']) { + $panelPassword = password_hash($data['panelPassword'], PASSWORD_ARGON2ID, ['memory_cost' => 1024 * 128, 'time_cost' => 6, 'threads' => 4]); + + $db->update( + 'users', + [ + 'password' => $panelPassword, + ], + [ + 'email' => $regEmail + ] + ); + } + + $db->commit(); + } catch (Exception $e) { + $db->rollBack(); + $this->container->get('flash')->addMessage('error', 'Database failure during update: ' . $e->getMessage()); + return $response->withHeader('Location', '/registrar/edit')->withStatus(302); + } + + unset($_SESSION['registrars_to_update']); + unset($_SESSION['registrars_user_email']); + $this->container->get('flash')->addMessage('success', 'Registrar ' . $data['name'] . ' has been updated successfully on ' . $update); + return $response->withHeader('Location', '/registrar/edit')->withStatus(302); + } + + $db = $this->container->get('db'); + $iso3166 = new ISO3166(); + $countries = $iso3166->all(); + // Get the current URI + $uri = $request->getUri()->getPath(); + $registrarId = $_SESSION['auth_registrar_id']; + + if (isset($registrarId) && $registrarId !== "") { + $registrar = $db->selectRow('SELECT * FROM registrar WHERE id = ?', + [ $registrarId ]); + + if ($registrar) { + $contacts = $db->select("SELECT * FROM registrar_contact WHERE registrar_id = ?", + [ $registrar['id'] ]); + $ote = $db->select("SELECT * FROM registrar_ote WHERE registrar_id = ?", + [ $registrar['id'] ]); + $user_id = $db->selectValue("SELECT user_id FROM registrar_users WHERE registrar_id = ?", + [ $registrar['id'] ]); + $user = $db->selectRow("SELECT email FROM users WHERE id = ?", + [ $user_id ]); + $whitelist = $db->select("SELECT * FROM registrar_whitelist WHERE registrar_id = ?", + [ $registrar['id'] ]); + + $_SESSION['registrars_to_update'] = [$registrar['clid']]; + $_SESSION['registrars_user_email'] = [$user['email']]; + + return view($response,'admin/registrars/updateRegistrarUser.twig', [ + 'registrar' => $registrar, + 'contacts' => $contacts, + 'ote' => $ote, + 'user' => $user, + 'whitelist' => $whitelist, + 'currentUri' => $uri, + 'countries' => $countries + ]); + } else { + // Registrar does not exist, redirect to the dashboard view + return $response->withHeader('Location', '/dashboard')->withStatus(302); + } + } else { + // Redirect to the registrars view + return $response->withHeader('Location', '/registrars')->withStatus(302); + } + } } \ No newline at end of file diff --git a/cp/app/Controllers/ReportsController.php b/cp/app/Controllers/ReportsController.php index 7590c56..c27bd7a 100644 --- a/cp/app/Controllers/ReportsController.php +++ b/cp/app/Controllers/ReportsController.php @@ -11,6 +11,10 @@ class ReportsController extends Controller { public function view(Request $request, Response $response) { + if ($_SESSION["auth_roles"] != 0) { + return $response->withHeader('Location', '/dashboard')->withStatus(302); + } + return view($response,'admin/reports/index.twig'); } } \ No newline at end of file diff --git a/cp/app/Controllers/UsersController.php b/cp/app/Controllers/UsersController.php index 9d79c83..999ea70 100644 --- a/cp/app/Controllers/UsersController.php +++ b/cp/app/Controllers/UsersController.php @@ -11,6 +11,10 @@ class UsersController extends Controller { public function listUsers(Request $request, Response $response) { + if ($_SESSION["auth_roles"] != 0) { + return $response->withHeader('Location', '/dashboard')->withStatus(302); + } + $userModel = new User($this->container->get('db')); $users = $userModel->getAllUsers(); return view($response,'admin/users/listUsers.twig', compact('users')); diff --git a/cp/resources/views/admin/registrars/updateRegistrarUser.twig b/cp/resources/views/admin/registrars/updateRegistrarUser.twig new file mode 100644 index 0000000..a31d913 --- /dev/null +++ b/cp/resources/views/admin/registrars/updateRegistrarUser.twig @@ -0,0 +1,574 @@ +{% extends "layouts/app.twig" %} + +{% block title %}{{ __('Update Registrar') }} {{ registrar.name }}{% endblock %} + +{% block content %} +