diff --git a/aliapi/lib/AliyunDnsClient.php b/aliapi/lib/AliyunDnsClient.php new file mode 100644 index 0000000..345e9fa --- /dev/null +++ b/aliapi/lib/AliyunDnsClient.php @@ -0,0 +1,189 @@ +accessKeyId = $accessKeyId; + $this->accessKeySecret = $accessKeySecret; + $this->endpoint = $endpoint; + $this->regionId = $regionId; + } + + private function percentEncode($str) { + $res = urlencode($str); + $res = str_replace('+', '%20', $res); + $res = str_replace('*', '%2A', $res); + $res = str_replace('%7E', '~', $res); + return $res; + } + + private function generateSignature($parameters) { + ksort($parameters); + + $canonicalizedQueryString = ''; + foreach ($parameters as $key => $value) { + $canonicalizedQueryString .= '&' . $this->percentEncode($key) . '=' . $this->percentEncode($value); + } + + $canonicalizedQueryString = substr($canonicalizedQueryString, 1); + + $stringToSign = 'GET&%2F&' . $this->percentEncode($canonicalizedQueryString); + + $signature = base64_encode(hash_hmac('sha1', $stringToSign, $this->accessKeySecret . '&', true)); + + return $signature; + } + + private function sendRequest($action, $params) { + $parameters = [ + 'Action' => $action, + 'AccessKeyId' => $this->accessKeyId, + 'Format' => 'JSON', + 'RegionId' => $this->regionId, + 'SignatureMethod' => 'HMAC-SHA1', + 'SignatureNonce' => uniqid() . mt_rand(1000, 9999), + 'SignatureVersion' => '1.0', + 'Timestamp' => gmdate('Y-m-d\TH:i:s\Z'), + 'Version' => '2015-01-09' + ]; + + foreach ($params as $key => $value) { + $parameters[$key] = $value; + } + + ksort($parameters); + + $signature = $this->generateSignature($parameters); + + $queryParts = []; + foreach ($parameters as $key => $value) { + $queryParts[] = $this->percentEncode($key) . '=' . $this->percentEncode($value); + } + $queryParts[] = 'Signature=' . $this->percentEncode($signature); + $queryString = implode('&', $queryParts); + $url = $this->endpoint . '?' . $queryString; + + if (function_exists('curl_init')) { + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); + curl_setopt($ch, CURLOPT_TIMEOUT, 30); + curl_setopt($ch, CURLOPT_USERAGENT, 'AliyunDnsClient/1.0'); + + $response = curl_exec($ch); + $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); + $error = curl_error($ch); + curl_close($ch); + + if ($response === false) { + throw new Exception('cURL error: ' . $error); + } + } else { + $context = stream_context_create([ + 'http' => [ + 'method' => 'GET', + 'timeout' => 30, + 'header' => [ + 'User-Agent: AliyunDnsClient/1.0' + ], + 'protocol_version' => 1.1 + ], + 'ssl' => [ + 'verify_peer' => false, + 'verify_peer_name' => false + ] + ]); + + $response = @file_get_contents($url, false, $context); + + if ($response === false) { + $error = error_get_last(); + throw new Exception('HTTP request failed: ' . ($error ? $error['message'] : 'Unknown error')); + } + } + + $result = json_decode($response, true); + + if (json_last_error() !== JSON_ERROR_NONE) { + throw new Exception('Invalid JSON response: ' . $response); + } + + if (isset($result['Code']) && $result['Code'] !== 'Success') { + throw new Exception($result['Message'] ?? 'API error'); + } + + return $result; + } + + public function addDomainRecord($domainName, $rr, $type, $value, $ttl = 600, $priority = null) { + $params = [ + 'DomainName' => $domainName, + 'RR' => $rr, + 'Type' => $type, + 'Value' => $value, + 'TTL' => $ttl + ]; + + if ($priority !== null && in_array($type, ['MX', 'SRV'])) { + $params['Priority'] = $priority; + } + + return $this->sendRequest('AddDomainRecord', $params); + } + + public function deleteDomainRecord($recordId) { + $params = [ + 'RecordId' => $recordId + ]; + + return $this->sendRequest('DeleteDomainRecord', $params); + } + + public function updateDomainRecord($recordId, $rr, $type, $value, $ttl = 600, $priority = null) { + $params = [ + 'RecordId' => $recordId, + 'RR' => $rr, + 'Type' => $type, + 'Value' => $value, + 'TTL' => $ttl + ]; + + if ($priority !== null && in_array($type, ['MX', 'SRV'])) { + $params['Priority'] = $priority; + } + + return $this->sendRequest('UpdateDomainRecord', $params); + } + + public function describeDomainRecords($domainName, $rrKeyWord = null, $type = null, $pageNumber = 1, $pageSize = 20) { + $params = [ + 'DomainName' => $domainName, + 'PageNumber' => $pageNumber, + 'PageSize' => $pageSize + ]; + + if ($rrKeyWord !== null) { + $params['RRKeyWord'] = $rrKeyWord; + } + + if ($type !== null) { + $params['Type'] = $type; + } + + return $this->sendRequest('DescribeDomainRecords', $params); + } + + public function describeRecordInfo($recordId) { + $params = [ + 'RecordId' => $recordId + ]; + + return $this->sendRequest('DescribeRecordInfo', $params); + } +} +?> \ No newline at end of file diff --git a/aliapi/lib/TokenHelper.php b/aliapi/lib/TokenHelper.php new file mode 100644 index 0000000..c092cf5 --- /dev/null +++ b/aliapi/lib/TokenHelper.php @@ -0,0 +1,59 @@ +