Basic fee extension support now completed

This commit is contained in:
Pinga 2023-12-20 09:30:24 +02:00
parent 04eac7a648
commit 49d7822d1a
4 changed files with 89 additions and 28 deletions

View file

@ -15,11 +15,7 @@ We're on a mission to make **Namingo** the best it can be, and we need your expe
We've completed the core development of Namingo, including WHOIS, DAS, EPP, RDAP servers, and control panel. The system handles 150,000 domains efficiently (on a VPS with 2 cores, 4GB of RAM, and a 100GB SSD) and has passed basic QA and security tests. We've completed the core development of Namingo, including WHOIS, DAS, EPP, RDAP servers, and control panel. The system handles 150,000 domains efficiently (on a VPS with 2 cores, 4GB of RAM, and a 100GB SSD) and has passed basic QA and security tests.
Current focuses: Our current focus is on implementing the launch phase extension as outlined in RFC8334.
- Fee extension (RFC8748) integration.
- Launch phase extension (RFC8334) implementation.
We're currently in the phase of external testing and are aware that there might be bugs or incomplete features in the project. If you're able to identify and fix any issues, we encourage you to submit a pull request. If you're not sure how to fix an issue, please don't hesitate to report it to us, and we'll work on addressing it. Your contributions and feedback are valuable in helping us improve Namingo. For any inquiries or suggestions, feel free to reach out. We're currently in the phase of external testing and are aware that there might be bugs or incomplete features in the project. If you're able to identify and fix any issues, we encourage you to submit a pull request. If you're not sure how to fix an issue, please don't hesitate to report it to us, and we'll work on addressing it. Your contributions and feedback are valuable in helping us improve Namingo. For any inquiries or suggestions, feel free to reach out.

View file

@ -740,7 +740,6 @@ class EppWriter {
$writer->endElement(); // End of 'fee:period' $writer->endElement(); // End of 'fee:period'
$writer->startElement('fee:fee'); $writer->startElement('fee:fee');
$writer->writeAttribute('description', 'Fee');
$writer->writeAttribute('refundable', 1); $writer->writeAttribute('refundable', 1);
$writer->writeAttribute('grace-period', 'P5D'); $writer->writeAttribute('grace-period', 'P5D');
$writer->text($fee['fee']); $writer->text($fee['fee']);
@ -787,6 +786,27 @@ class EppWriter {
$writer->writeElement('domain:exDate', $exDateFormatted); $writer->writeElement('domain:exDate', $exDateFormatted);
$writer->endElement(); // End of 'domain:creData' $writer->endElement(); // End of 'domain:creData'
$writer->endElement(); // End of 'resData' $writer->endElement(); // End of 'resData'
if (isset($resp['fee_include']) && $resp['fee_include'] == true) {
$writer->startElement('extension');
$writer->startElement('fee:creData');
$writer->writeAttribute('xmlns:fee', 'urn:ietf:params:xml:ns:epp:fee-1.0');
$writer->writeElement('fee:currency', 'USD');
$writer->startElement('fee:fee');
$writer->writeAttribute('refundable', 1);
$writer->writeAttribute('grace-period', 'P5D');
$writer->text($resp['fee_price']);
$writer->endElement(); // End of 'fee:fee'
$writer->writeElement('fee:balance', $resp['fee_balance']);
$writer->writeElement('fee:creditLimit', $resp['fee_creditLimit']);
$writer->endElement(); // End of 'fee:creData'
$writer->endElement(); // End of 'extension'
}
} }
$this->_postamble($writer, $resp); $this->_postamble($writer, $resp);

View file

@ -341,15 +341,29 @@ function processDomainCheck($conn, $db, $xml, $trans) {
$returnValue = getDomainPrice($db, $domainName, $tld_id, $date_add, $commandName); $returnValue = getDomainPrice($db, $domainName, $tld_id, $date_add, $commandName);
$price = $returnValue['price']; $price = $returnValue['price'];
// Add to fee response array $sth = $db->prepare("SELECT price FROM domain_restore_price WHERE tldid = ? LIMIT 1");
$feeResponses[] = [ $sth->execute([$tld_id]);
'command' => $commandName, $restore_price = $sth->fetchColumn();
'period' => $period,
'period_unit' => $period_unit, if ($commandName == 'restore') {
'avail' => $domainEntry[1], $feeResponses[] = [
'fee' => $price, 'command' => $commandName,
'name' => $domainName, 'period' => $period,
]; 'period_unit' => $period_unit,
'avail' => $domainEntry[1],
'fee' => $restore_price,
'name' => $domainName,
];
} else {
$feeResponses[] = [
'command' => $commandName,
'period' => $period,
'period_unit' => $period_unit,
'avail' => $domainEntry[1],
'fee' => $price,
'name' => $domainName,
];
}
} else { } else {
$feeResponses[] = [ $feeResponses[] = [
'command' => $commandName, 'command' => $commandName,

View file

@ -574,6 +574,11 @@ function processDomainCreate($conn, $db, $xml, $clid, $database_type, $trans) {
$domainName = $xml->command->create->children('urn:ietf:params:xml:ns:domain-1.0')->create->name; $domainName = $xml->command->create->children('urn:ietf:params:xml:ns:domain-1.0')->create->name;
$clTRID = (string) $xml->command->clTRID; $clTRID = (string) $xml->command->clTRID;
$extensionNode = $xml->command->extension;
if (isset($extensionNode)) {
$fee_create = $xml->xpath('//fee:create')[0] ?? null;
}
$parts = extractDomainAndTLD($domainName); $parts = extractDomainAndTLD($domainName);
$label = $parts['domain']; $label = $parts['domain'];
$domain_extension = $parts['tld']; $domain_extension = $parts['tld'];
@ -1038,6 +1043,24 @@ function processDomainCreate($conn, $db, $xml, $clid, $database_type, $trans) {
try { try {
$db->beginTransaction(); $db->beginTransaction();
$response = [];
if (isset($fee_create)) {
$response['fee_fee'] = (string) $fee_create->children('urn:ietf:params:xml:ns:epp:fee-1.0')->fee;
if ($response['fee_fee'] >= $price) {
$response['fee_currency'] = (string) $fee_create->children('urn:ietf:params:xml:ns:epp:fee-1.0')->currency;
$response['fee_price'] = $price;
$response['fee_balance'] = $registrar_balance;
$response['fee_creditLimit'] = $creditLimit;
$response['fee_include'] = true;
} else {
$response['fee_include'] = false;
$db->rollBack();
sendEppError($conn, $db, 2004, "Provided fee is less than the server domain fee", $clTRID, $trans);
return;
}
}
$domainSql = "INSERT INTO domain (name,tldid,registrant,crdate,exdate,lastupdate,clid,crid,upid,trdate,trstatus,reid,redate,acid,acdate,rgpstatus,addPeriod) $domainSql = "INSERT INTO domain (name,tldid,registrant,crdate,exdate,lastupdate,clid,crid,upid,trdate,trstatus,reid,redate,acid,acdate,rgpstatus,addPeriod)
VALUES(:name, :tld_id, :registrant_id, CURRENT_TIMESTAMP(3), DATE_ADD(CURRENT_TIMESTAMP(3), INTERVAL :date_add MONTH), NULL, :registrar_id, :registrar_id, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'addPeriod', :date_add2)"; VALUES(:name, :tld_id, :registrant_id, CURRENT_TIMESTAMP(3), DATE_ADD(CURRENT_TIMESTAMP(3), INTERVAL :date_add MONTH), NULL, :registrar_id, :registrar_id, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'addPeriod', :date_add2)";
@ -1072,10 +1095,12 @@ function processDomainCreate($conn, $db, $xml, $clid, $database_type, $trans) {
// Data sanity checks // Data sanity checks
// Validate keyTag // Validate keyTag
if (!isset($keyTag) || !is_int($keyTag)) { if (!isset($keyTag) || !is_int($keyTag)) {
$db->rollBack();
sendEppError($conn, $db, 2005, 'Incomplete keyTag provided', $clTRID, $trans); sendEppError($conn, $db, 2005, 'Incomplete keyTag provided', $clTRID, $trans);
return; return;
} }
if ($keyTag < 0 || $keyTag > 65535) { if ($keyTag < 0 || $keyTag > 65535) {
$db->rollBack();
sendEppError($conn, $db, 2006, 'Invalid keyTag provided', $clTRID, $trans); sendEppError($conn, $db, 2006, 'Invalid keyTag provided', $clTRID, $trans);
return; return;
} }
@ -1083,12 +1108,14 @@ function processDomainCreate($conn, $db, $xml, $clid, $database_type, $trans) {
// Validate alg // Validate alg
$validAlgorithms = [2, 3, 5, 6, 7, 8, 10, 13, 14, 15, 16]; $validAlgorithms = [2, 3, 5, 6, 7, 8, 10, 13, 14, 15, 16];
if (!isset($alg) || !in_array($alg, $validAlgorithms)) { if (!isset($alg) || !in_array($alg, $validAlgorithms)) {
$db->rollBack();
sendEppError($conn, $db, 2006, 'Invalid algorithm', $clTRID, $trans); sendEppError($conn, $db, 2006, 'Invalid algorithm', $clTRID, $trans);
return; return;
} }
// Validate digestType and digest // Validate digestType and digest
if (!isset($digestType) || !is_int($digestType)) { if (!isset($digestType) || !is_int($digestType)) {
$db->rollBack();
sendEppError($conn, $db, 2005, 'Invalid digestType', $clTRID, $trans); sendEppError($conn, $db, 2005, 'Invalid digestType', $clTRID, $trans);
return; return;
} }
@ -1098,10 +1125,12 @@ function processDomainCreate($conn, $db, $xml, $clid, $database_type, $trans) {
4 => 96 // SHA-384 4 => 96 // SHA-384
]; ];
if (!isset($validDigests[$digestType])) { if (!isset($validDigests[$digestType])) {
$db->rollBack();
sendEppError($conn, $db, 2006, 'Unsupported digestType', $clTRID, $trans); sendEppError($conn, $db, 2006, 'Unsupported digestType', $clTRID, $trans);
return; return;
} }
if (!isset($digest) || strlen($digest) != $validDigests[$digestType] || !ctype_xdigit($digest)) { if (!isset($digest) || strlen($digest) != $validDigests[$digestType] || !ctype_xdigit($digest)) {
$db->rollBack();
sendEppError($conn, $db, 2006, 'Invalid digest length or format', $clTRID, $trans); sendEppError($conn, $db, 2006, 'Invalid digest length or format', $clTRID, $trans);
return; return;
} }
@ -1122,24 +1151,28 @@ function processDomainCreate($conn, $db, $xml, $clid, $database_type, $trans) {
// Validate flags // Validate flags
$validFlags = [256, 257]; $validFlags = [256, 257];
if (isset($flags) && !in_array($flags, $validFlags)) { if (isset($flags) && !in_array($flags, $validFlags)) {
$db->rollBack();
sendEppError($conn, $db, 2005, 'Invalid flags', $clTRID, $trans); sendEppError($conn, $db, 2005, 'Invalid flags', $clTRID, $trans);
return; return;
} }
// Validate protocol // Validate protocol
if (isset($protocol) && $protocol != 3) { if (isset($protocol) && $protocol != 3) {
$db->rollBack();
sendEppError($conn, $db, 2006, 'Invalid protocol', $clTRID, $trans); sendEppError($conn, $db, 2006, 'Invalid protocol', $clTRID, $trans);
return; return;
} }
// Validate algKeyData // Validate algKeyData
if (isset($algKeyData)) { if (isset($algKeyData)) {
$db->rollBack();
sendEppError($conn, $db, 2005, 'Invalid algKeyData encoding', $clTRID, $trans); sendEppError($conn, $db, 2005, 'Invalid algKeyData encoding', $clTRID, $trans);
return; return;
} }
// Validate pubKey // Validate pubKey
if (isset($pubKey) && base64_encode(base64_decode($pubKey, true)) !== $pubKey) { if (isset($pubKey) && base64_encode(base64_decode($pubKey, true)) !== $pubKey) {
$db->rollBack();
sendEppError($conn, $db, 2005, 'Invalid pubKey encoding', $clTRID, $trans); sendEppError($conn, $db, 2005, 'Invalid pubKey encoding', $clTRID, $trans);
return; return;
} }
@ -1329,7 +1362,7 @@ function processDomainCreate($conn, $db, $xml, $clid, $database_type, $trans) {
$stmt->execute(); $stmt->execute();
} }
$db->exec("UPDATE statistics SET created_domains = created_domains + 1 WHERE date = CURDATE()"); $db->exec("UPDATE statistics SET created_domains = created_domains + 1 WHERE date = CURDATE()");
$db->commit(); $db->commit();
} catch (Exception $e) { } catch (Exception $e) {
$db->rollBack(); $db->rollBack();
@ -1337,18 +1370,16 @@ function processDomainCreate($conn, $db, $xml, $clid, $database_type, $trans) {
sendEppError($conn, $db, 2400, "Database failure: " . $e->getMessage(), $clTRID, $trans); sendEppError($conn, $db, 2400, "Database failure: " . $e->getMessage(), $clTRID, $trans);
} }
$svTRID = generateSvTRID(); $svTRID = generateSvTRID();
$response = [ $response['command'] = 'create_domain';
'command' => 'create_domain', $response['resultCode'] = 1000;
'resultCode' => 1000, $response['lang'] = 'en-US';
'lang' => 'en-US', $response['message'] = 'Command completed successfully';
'message' => 'Command completed successfully', $response['name'] = $domainName;
'name' => $domainName, $response['crDate'] = $crdate;
'crDate' => $crdate, $response['exDate'] = $exdate;
'exDate' => $exdate, $response['clTRID'] = $clTRID;
'clTRID' => $clTRID, $response['svTRID'] = $svTRID;
'svTRID' => $svTRID,
];
$epp = new EPP\EppWriter(); $epp = new EPP\EppWriter();
$xml = $epp->epp_writer($response); $xml = $epp->epp_writer($response);
updateTransaction($db, 'create', 'domain', $domainName, 1000, 'Command completed successfully', $svTRID, $xml, $trans); updateTransaction($db, 'create', 'domain', $domainName, 1000, 'Command completed successfully', $svTRID, $xml, $trans);