Skip to content

Commit

Permalink
fix(cnic registrar module): patched url forwarding bug and improved u…
Browse files Browse the repository at this point in the history
…ser experience
  • Loading branch information
AsifNawaz-cnic committed Nov 8, 2024
1 parent 0dc6980 commit a012a91
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 67 deletions.
37 changes: 37 additions & 0 deletions .github/linters/phpstan.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
parameters:
level: 5
#phpVersion: 80100
#treatPhpDocTypesAsCertain: false
fileExtensions:
- php
- module
- inc
paths:
- ../../components/modules/cnr
excludePaths:
- ../../components/modules/cnr/apis/vendor
scanDirectories:
# - /usr/share/rtldev-middleware-blesta/compon
ents
- /var/www/html/blesta
bootstrapFiles:
- /var/www/html/blesta/lib/init.php
#- /var/www/html/blesta/vendors/autoload.php
ignoreErrors:
#- "#^Access to an undefined property WHMCS\\\\Domain\\\\Domain::\\$.*.$#"
#- "#^Call to an undefined static method WHMCS\\\\Domain\\\\Domain::.+\\(\\).$#"
#- "#^Method WHMCS\\\\View\\\\Menu\\\\Item::getChild\\(\\) invoked with 1 parameter, 2 required.$#"
#-
# message: '#Access to an undefined property [a-zA-Z0-9\\_]+::\$(autosetup|code|status|remoteid|id|gid)#'
# paths:
# - ../../modules/addons/cnicssl_addon/cnicssl_addon.php
# - ../../modules/servers/cnicssl/cnicssl.php
# - ../../modules/servers/cnicssl/lib/SSLHelper.php
#- '#Function [a-zA-Z0-9\\_]+ not found.#'
#- '#Variable \$[a-zA-Z0-9\\_]+ might not be defined.#'
#- '#Undefined variable: \$[a-zA-Z0-9\\_]+#'
#- '#Access to an undefined property object::#'
#- '#Parameter \#2 \$callback of function array_walk expects callable#'
parallel:
maximumNumberOfProcesses: 1000
tmpDir: /tmp/phpstan
10 changes: 4 additions & 6 deletions components/modules/cnr/cnr.php
Original file line number Diff line number Diff line change
Expand Up @@ -593,7 +593,7 @@ public function getExpirationDate($service, $format = 'Y-m-d H:i:s')
Loader::loadHelpers($this, ['Date']);

$domain = $this->getServiceDomain($service);
$row = $this->getModuleRow($service->module_row_id ?? $service->module_row);
$row = $this->getModuleRow($service->module_row_id ?? $service->module_row) ?? $this->getModuleRows()[0];
Base::setModule($row);
Base::moduleInstance($this);

Expand Down Expand Up @@ -667,7 +667,6 @@ public function addPackage(array $vars = null)
];
}
}

return $meta;
}

Expand Down Expand Up @@ -1273,7 +1272,7 @@ public function getAdminEditFields($package, $vars = null)

$fields = new ModuleFields();

Base::setModule($this->getModuleRow($package->module_row));
Base::setModule($this->getModuleRow($package->module_row) ?? $this->getModuleRows()[0]);
Base::moduleInstance($this);

if ($package->meta->type === "domain" && $_SERVER["REQUEST_METHOD"] === "GET") {
Expand Down Expand Up @@ -1955,10 +1954,9 @@ private function manageSettings(
if ($zoneInfo->addons->IDProtection) {
$vars->whois_privacy = (int)($r["PROPERTY"]["X-WHOIS-PRIVACY"][0] ?? 0);
}

// check if id_protection is enabled for the domain
$vars->whois_privacy = !$this->featureServiceEnabled('id_protection', $service) ? "disabled" : $vars->whois_privacy;

// To get epp/auth code
if (isset($post["request_epp"])) {
// Expiring Authorization Codes
Expand Down Expand Up @@ -2205,7 +2203,7 @@ public function getServiceDomain($service)
*/
public function getTldPricing($module_row_id = null)
{
$this->getFilteredTldPricing($module_row_id);
return $this->getFilteredTldPricing($module_row_id);
}

/**
Expand Down
10 changes: 6 additions & 4 deletions components/modules/cnr/lib/AdditionalFields.php
Original file line number Diff line number Diff line change
Expand Up @@ -209,9 +209,7 @@ private function getTranslation($parameter, $value, $default, $isrequired = true
* @param bool $replaceComma to get comma replaced by "⸴" (option labels as comma means start with new option)
* @return string
*/
public function getCountryTranslation($parameter, $value, $default, $isrequired = true, $replaceComma = false)
{
}
public function getCountryTranslation($parameter, $value, $default, $isrequired = true, $replaceComma = false) {}

/**
* Get the Translation Key for given Parameter
Expand Down Expand Up @@ -239,7 +237,11 @@ private function getDropdownOptions($name, $values, $labels, $required)
// } elseif ($name === "X-EU-REGISTRANT-CITIZENSHIP") {
// $options[$val] = $val . "|" . Language::_($val, $labels[$idx], true); // todo, fallback logic to translation file
// } else {
$options[$val] = $val . "|" . $this->getTranslation($name, $val, $labels[$idx], true, true);
$options[$val] = $val;
$valTranslation = $this->getTranslation($name, $val, $labels[$idx], true, true);
if ($val !== $valTranslation) {
$options[$val] = $val . "|" . $valTranslation;
}
// }
}
}
Expand Down
18 changes: 16 additions & 2 deletions components/modules/cnr/lib/DomainManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -228,18 +228,32 @@ public function getZoneInfo($domains)
public function addDNS($domain, $postData)
{
$record = Helper::getResourceRecord($postData, $domain);
if (array_key_exists("record_type", $record) && in_array($record["record_type"], ["RD", "MRD"])) {
return $this->call([
"COMMAND" => "AddWebFwd",
"source" => $record["hostname"],
"target" => $record["address"],
"type" => $record["record_type"]
]);
}
return $this->call([
"COMMAND" => "ModifyDNSZone",
"DNSZONE" => "{$domain}",
"ADDRR0" => "{$record}"
]);
}

public function deleteDNS($dns, $postData)
public function deleteDNS($domain, $postData)
{
if ($postData["raw_record"] == "URL" || $postData["raw_record"] == "FRAME") {
return $this->call([
"COMMAND" => "DeleteWebFwd",
"source" => $domain
]);
}
return $this->call([
"COMMAND" => "ModifyDNSZone",
"DNSZONE" => "{$dns}",
"DNSZONE" => "{$domain}",
"DELRR0" => "{$postData['raw_record']}"
]);
}
Expand Down
120 changes: 67 additions & 53 deletions components/modules/cnr/lib/Helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,39 @@
use CNR\MODULE\LIB\Base;
use CNIC\IDNA\Factory\ConverterFactory;

define("CNIC_TLD_CACHE", "1 day");
if (!defined("CNIC_TLD_CACHE")) {
define("CNIC_TLD_CACHE", "1 day");
}

class Helper
{
public static function getResourceRecord($record, $domain = "")
/**
* Retrieves the resource record for a given domain.
*
* @param array $record resource record with their respective data.
* @param string $domain The domain name for which to retrieve the resource record. Default is an empty string.
* @return mixed The resource record data for the specified domain and record type.
*/
public static function getResourceRecord(array $record, string $domain = "")
{
// hostname ttl IN record_type priority address
// $record = $data['hostname'] . " " . $data['ttl'] . " IN " . $data['record_type'];
// if (isset($data['priority']) && !empty($data['priority']) && ($data['record_type'] == 'MX' || $data['record_type'] == 'MXE' || $data['record_type'] == 'SRV')) {
// $record .= " " . $data['priority'];
// }
// $record .= " " . $data['address'];

// Determine record to add
$zone = [];
$ttl = $record["ttl"] ?? "3600";
if (!is_numeric($ttl)) {
$ttl = "3600";
}
if (!$record['hostname'] || (isset($domain) && $record['hostname'] === $domain)) {

if (!$record['hostname'] || (!empty($domain) && $record['hostname'] === $domain)) {
$record['hostname'] = "@";
}

switch ($record['record_type']) {
case "URL":
case "FRAME":
$record["hostname"] = ($record["hostname"] == "@") ? $domain : $record["hostname"] . "." . $domain;
$record["record_type"] = $record["record_type"] == "URL" ? "RD" : "MRD";
$zone[] = $record;
break;
case "MXE":
$address = $record["address"];
$mxpref = is_numeric($record["priority"]) ? $record["priority"] : "100";
Expand Down Expand Up @@ -61,7 +70,14 @@ public static function getResourceRecord($record, $domain = "")
return $zone;
}

public static function errorHandler($response, $successCodes = "/^200$/")
/**
* Handles errors based on the response and success codes.
*
* @param array|\stdClass|null $response The response to be evaluated. Expected to be an associative array or an object with a 'CODE' key and optionally an 'error' key.
* @param string $successCodes A regex pattern representing the success codes. Defaults to "/^200$/".
* @return boolean
*/
public static function errorHandler(array|\stdClass|null $response, string $successCodes = "/^200$/")
{
if ($response instanceof \stdClass) {
$response = json_decode(json_encode($response), true);
Expand Down Expand Up @@ -93,7 +109,7 @@ public static function errorHandler($response, $successCodes = "/^200$/")
* @param string $domain
* @return array
*/
public static function getResourceRecords($resourceRecords, $domain = "")
public static function getResourceRecords(array $resourceRecords, string $domain = "")
{
if (empty($resourceRecords)) {
return [];
Expand All @@ -119,61 +135,49 @@ public static function getResourceRecords($resourceRecords, $domain = "")
continue;
}

if ((bool)preg_match("/^(A|AAAA|CNAME)$/", $rrtype)) {
if (
$rrtype !== "A" ||
!preg_match("/^mxe-host-for-ip-(\d+)-(\d+)-(\d+)-(\d+)$/i", $domain, $m)
) {
$hostrecords[$i] = [
"hostname" => $name,
"ttl" => $ttl,
"record_type" => $rrtype,
"address" => $content
];
$hostrecords[$i]["raw_record"] = Helper::getResourceRecord($hostrecords[$i]);
continue;
if ($resourceRecords['LOCKED'][$i] == 1) {
$fwdtype = "URL";
if (strtolower($rrtype) == "mrd") {
$fwdtype = "FRAME";
}
}

if ($rrtype === "SRV" || $rrtype === "MX") {
$hostrecords[$i] = [
"hostname" => $name,
"ttl" => $ttl,
"record_type" => $rrtype,
"address" => $content,
"priority" => $priority
'hostname' => $name,
'record_type' => $fwdtype,
'address' => $content
];
$hostrecords[$i]["raw_record"] = Helper::getResourceRecord($hostrecords[$i]);
$hostrecords[$i]["raw_record"] = $fwdtype;
continue;
}

if ($rrtype === "X-HTTP") {
if ($rrtype === "REDIRECT") {
$url_type = "URL";
if ($rrtype == 'MX') {
if ($content == $priority) {
continue;
}
if (substr($content, 0, strlen($priority)) === $priority) {
$content = substr($content, strlen($priority) + 1);
}

$hostrecords[$i] = [
"hostname" => $name,
"ttl" => $ttl,
"record_type" => $url_type,
"address" => $content
];
$hostrecords[$i]["raw_record"] = Helper::getResourceRecord($hostrecords[$i]);
continue;
}


// TXT or other records
$hostrecords[$i] = [
"hostname" => $name,
"ttl" => $ttl,
"record_type" => $rrtype,
"address" => $content
];
$hostrecords[$i]["raw_record"] = Helper::getResourceRecord($hostrecords[$i]);
$hostrecords[$i]["raw_record"] = Helper::getResourceRecord($hostrecords[$i], $domain);
}
return $hostrecords;
}

/**
* Retrieves the supported Resource Record (RR) types.
*
* This method returns an array of supported DNS Resource Record types.
*
* @return array An array of supported RR types.
*/
public static function getSupportedRRTypes()
{
return [
Expand All @@ -192,17 +196,19 @@ public static function getSupportedRRTypes()
"SRV",
"TXT",
"TLSA",
"X-HTTP"
"URL",
"FRAME"
];
}

/**
* Builds and returns the rules required to add/edit a module row
*
* @param array $vars An array of key/value data pairs
* @param int|null $module_row_id The module row ID to validate against
* @return array An array of Input rules suitable for Input::setRules()
*/
public static function getRowRules(&$vars, $module_row_id = null)
public static function getRowRules(array &$vars, $module_row_id = null)
{
$instance = Base::moduleInstance();
return [
Expand Down Expand Up @@ -238,6 +244,7 @@ public static function getRowRules(&$vars, $module_row_id = null)
* retrieve data from cache if available.
*
* @param string $keyName The key name for the cache.
* @param bool $returnAsArray Whether to return the cached data as an array.
* @return mixed|false The cached data or false if caching is disabled or an error occurs.
*/
public static function hasCache(string $keyName, bool $returnAsArray = false)
Expand Down Expand Up @@ -266,6 +273,7 @@ public static function hasCache(string $keyName, bool $returnAsArray = false)
*
* @param string $keyName The key name for the cache.
* @param object|array $cacheData The data to store in cache.
* @param int|null $ttl The time-to-live for the cache data. Default is null.
* @return bool True if the data was successfully cached, false otherwise.
*/
public static function setCache(string $keyName, object|array $cacheData, $ttl = null)
Expand Down Expand Up @@ -297,15 +305,21 @@ public static function setCache(string $keyName, object|array $cacheData, $ttl =
return self::hasCache($keyName);
}

/**
* Clears the cache for the given key name.
*
* @param string $keyName The name of the cache key to clear.
* @return void
*/
public static function clearCache(string $keyName)
{
// If cache is disabled or key name is empty, return false
if (!\Configure::get("Caching.on") || empty($keyName)) {
return false;
return;
}

// Clear the cache
return \Cache::clearCache(
\Cache::clearCache(
$keyName,
\Configure::get("Blesta.company_id") . \DS . "modules" . \DS . "cnr" . \DS
);
Expand All @@ -317,7 +331,7 @@ public static function clearCache(string $keyName)
* @param array|string $periods Periods data from API response.
* @return array Parsed periods.
*/
public static function parsePeriods($periods)
public static function parsePeriods(array|string $periods)
{
return array_values(array_unique( // unique values, re-indexed
array_map( // convert strings to ints
Expand All @@ -340,7 +354,7 @@ public static function parsePeriods($periods)
* @param array $domains list of domain names (or tlds)
* @return array
*/
public static function IDNConvert($data)
public static function IDNConvert(array $data)
{
return ConverterFactory::convert($data);
}
Expand Down
Loading

0 comments on commit a012a91

Please sign in to comment.