沢山追加

This commit is contained in:
2026-04-27 13:18:55 +09:00
parent f0f75124ee
commit 1bc9e594e2
21 changed files with 971 additions and 175 deletions

2
.gitignore vendored
View File

@@ -1,5 +1,7 @@
data/*.pem
data/*.txt
data/*.json
data/cache/*.json
data/user/*.json
log/*.txt
public/static/user

View File

@@ -25,7 +25,7 @@ define('OPENPROVIDER', [
'username' => '',
'password' => '',
'ip' => '0.0.0.0',
'owner_handle' => 'HK912631-JP',
'owner_handle' => '',
]);
define('MAILER_ENABLED', false);
@@ -34,6 +34,7 @@ define('ATOM_ENABLED', true);
define('ACTIVITYPUB_ENABLED', false);
define('CURL_ENABLED', true);
define('AUTH_ENABLED', false);
define('OPENPROVIDER_ENABLED', false);
define('AUTH_REGISTER_ENABLED', false);
define('COPYRIGHT_YEAR', '2018-'.date('Y'));
define('DEBUG_MODE', false);

View File

@@ -0,0 +1,25 @@
textarea {
background: #232023;
color: #fcfcfc;
width: 100%;
max-width: 1260px;
height: 300px;
}
button {
border: 1px solid #ea79d8;
color: #fcfcfc;
border-radius: 4px;
background: #ea79d8;
font-size: 16px;
transition: background-color 0.2s ease-in-out;
}
button:hover {
background-color: #b421f8;
}
tr.status-free { background-color: #34860e; color: #fff; }
tr.status-reserved { background-color: #c59e1d; color: #fff; }
tr.status-use { background-color: #850000; color: #fff; }
tr.status-fumei { background-color: #888; color: #000; }

View File

@@ -8,6 +8,7 @@ use Site\Controller\Atom;
use Site\Controller\Fediverse;
use Site\Controller\Home;
use Site\Controller\Notfound;
use Site\Controller\Op;
use Site\Controller\Page;
use Site\Controller\User;
@@ -57,6 +58,17 @@ if (ATOM_ENABLED) {
$routes[] = Route::add('GET', 'blog.atom', Atom::class.'@feed');
}
if (OPENPROVIDER_ENABLED) {
$routes[] = Route::add('GET', 'openprovider', Op::class.'@index');
$routes[] = Route::add('GET', 'openprovider/searchcustomer', Op::class.'@opSearchCustomers');
$routes[] = Route::add('GET', 'openprovider/listtlds', Op::class.'@opListTlds');
$routes[] = Route::add('GET', 'openprovider/gettld/{tld}', Op::class.'@opGetTld');
$routes[] = Route::add('GET', 'openprovider/checkdomain', Op::class.'@opCheckDomainAvailable');
$routes[] = Route::add('GET', 'openprovider/getdomainprices', Op::class.'@opGetDomainPrices');
$routes[] = Route::add('GET', 'openprovider/listdnszones', Op::class.'@opListDns');
$routes[] = Route::add('GET', 'openprovider/getdns/{domain}', Op::class.'@opGetDns');
}
$routes[] = Route::add('GET', '', Home::class.'@show');
Route::init($routes);

View File

@@ -46,6 +46,13 @@ trait Mods {
'text' => 'スタッフ限定',
'show' => true,
],
[
'class' => 'menu-item',
'href' => '/openprovider',
'page' => 'openprovider',
'text' => 'OpenProvider管理',
'show' => true,
],
];
}
}

341
src/Site/Controller/Op.php Normal file
View File

@@ -0,0 +1,341 @@
<?php
namespace Site\Controller;
use Site\Controller\Mods;
use Std\Lib\Auth;
use Std\Lib\Template;
use Std\Lib\Openprovider;
class Op {
use Mods;
public function index(array $params): void {
try {
$tmpl = new Template('/openprovider/');
$pagetit = 'OpenProvider管理 - ホーム';
$description = '';
// ユーザー
$auth = new Auth();
$user = $auth->getLoggedInUser();
$tmpl->assign('user', $user);
$tmpl->assign('pagetit', $pagetit);
$tmpl->assign('curPage', 'openprovider');
$tmpl->assign('custCss', false);
$tmpl->assign('menu', $this->getMenu());
$tmpl->assign('description', $description);
if (!$user || $user->role !== \Roles::ADMIN) goto noaccess;
$tmpl->addCss('table');
$tmpl->render('index');
exit();
noaccess:
$tmpl->render('nopermission');
} catch (\Exception $e) {
throw new \Exception($e->getMessage());
}
}
public function opSearchCustomers(array $params): void {
try {
$tmpl = new Template('/openprovider/');
$pagetit = 'OpenProvider管理 - 顧客様検索';
$description = '';
// ユーザー
$auth = new Auth();
$user = $auth->getLoggedInUser();
$tmpl->assign('user', $user);
$tmpl->assign('pagetit', $pagetit);
$tmpl->assign('curPage', 'openprovider');
$tmpl->assign('custCss', true);
$tmpl->assign('menu', $this->getMenu());
$tmpl->assign('description', $description);
if (!$user || $user->role !== \Roles::ADMIN) goto noaccess;
$op = new Openprovider();
$op->login();
$data = $op->searchCustomers();
$tmpl->assign('data', $data);
$tmpl->addCss('table');
$tmpl->render('searchcustomer');
exit();
noaccess:
$tmpl->render('nopermission');
} catch (\Exception $e) {
throw new \Exception($e->getMessage());
}
}
public function opListTlds(array $params): void {
try {
$tmpl = new Template('/openprovider/');
$pagetit = 'OpenProvider管理 - TLD一覧';
$description = '';
// ユーザー
$auth = new Auth();
$user = $auth->getLoggedInUser();
$tmpl->assign('user', $user);
$tmpl->assign('pagetit', $pagetit);
$tmpl->assign('curPage', 'openprovider');
$tmpl->assign('custCss', false);
$tmpl->assign('menu', $this->getMenu());
$tmpl->assign('description', $description);
if (!$user || $user->role !== \Roles::ADMIN) goto noaccess;
$op = new Openprovider();
$op->login();
$data = $op->listTlds();
$tmpl->assign('data', $data);
$tmpl->addCss('table');
$tmpl->render('listtlds');
exit();
noaccess:
$tmpl->render('nopermission');
} catch (\Exception $e) {
throw new \Exception($e->getMessage());
}
}
public function opGetTld(array $params): void {
try {
$tld = '';
if (isset($params['tld'])) $tld = $params['tld'];
if ($tld === '') {
header('Location: /');
exit();
}
$tmpl = new Template('/openprovider/');
$pagetit = "OpenProvider管理 - .{$tld}の表示";
$description = '';
// ユーザー
$auth = new Auth();
$user = $auth->getLoggedInUser();
$tmpl->assign('user', $user);
$tmpl->assign('pagetit', $pagetit);
$tmpl->assign('curPage', 'openprovider');
$tmpl->assign('custCss', false);
$tmpl->assign('menu', $this->getMenu());
$tmpl->assign('description', $description);
if (!$user || $user->role !== \Roles::ADMIN) goto noaccess;
$op = new Openprovider();
$op->login();
$data = $op->getTld($tld);
$tmpl->assign('data', $data);
$tmpl->addCss('table');
$tmpl->render('gettld');
exit();
noaccess:
$tmpl->render('nopermission');
} catch (\Exception $e) {
throw new \Exception($e->getMessage());
}
}
public function opListDomains(array $params): void {
try {
$tmpl = new Template('/openprovider/');
$pagetit = 'OpenProvider管理 - ドメイン確認';
$description = '';
// ユーザー
$auth = new Auth();
$user = $auth->getLoggedInUser();
$tmpl->assign('user', $user);
$tmpl->assign('pagetit', $pagetit);
$tmpl->assign('curPage', 'openprovider');
$tmpl->assign('custCss', false);
$tmpl->assign('menu', $this->getMenu());
$tmpl->assign('description', $description);
if (!$user || $user->role !== \Roles::ADMIN) goto noaccess;
$op = new Openprovider();
$op->login();
$data = $op->listDomains($domains, true);
$tmpl->assign('data', $data);
$tmpl->assign('saved', $saved);
$tmpl->addCss('table');
$tmpl->addCss('openprovider');
$tmpl->render('checkdomain');
exit();
noaccess:
$tmpl->render('nopermission');
} catch (\Exception $e) {
throw new \Exception($e->getMessage());
}
}
public function opCheckDomainAvailable(array $params): void {
try {
$domains = isset($_GET['domains']) ? explode("\n", $_GET['domains']) : [];
$saved = '';
$tmpl = new Template('/openprovider/');
$pagetit = 'OpenProvider管理 - ドメイン確認';
$description = '';
// ユーザー
$auth = new Auth();
$user = $auth->getLoggedInUser();
$tmpl->assign('user', $user);
$tmpl->assign('pagetit', $pagetit);
$tmpl->assign('curPage', 'openprovider');
$tmpl->assign('custCss', false);
$tmpl->assign('menu', $this->getMenu());
$tmpl->assign('description', $description);
if (!$user || $user->role !== \Roles::ADMIN) goto noaccess;
$op = new Openprovider();
$op->login();
if (!empty($domains)) {
$data = $op->checkDomainAvailable($domains, true);
$tmpl->assign('data', $data);
$saved = $_GET['domains'];
}
$tmpl->assign('saved', $saved);
$tmpl->addCss('table');
$tmpl->addCss('openprovider');
$tmpl->render('checkdomain');
exit();
noaccess:
$tmpl->render('nopermission');
} catch (\Exception $e) {
throw new \Exception($e->getMessage());
}
}
public function opGetDomainPrices(array $params): void {
try {
$domainname = $_GET['domain_name'] ?? '';
$domainext = $_GET['domain_extension'] ?? '';
$tmpl = new Template('/openprovider/');
$pagetit = 'OpenProvider管理 - ドメイン値段一覧';
$description = '';
// ユーザー
$auth = new Auth();
$user = $auth->getLoggedInUser();
$tmpl->assign('user', $user);
$tmpl->assign('pagetit', $pagetit);
$tmpl->assign('curPage', 'openprovider');
$tmpl->assign('custCss', false);
$tmpl->assign('menu', $this->getMenu());
$tmpl->assign('description', $description);
if (!$user || $user->role !== \Roles::ADMIN) goto noaccess;
$op = new Openprovider();
$op->login();
$data = $op->getDomainPrices(['domain.name' => $domainname, 'domain.extension' => $domainext]);
$tmpl->assign('data', $data);
$tmpl->addCss('table');
$tmpl->render('getdomainprices');
exit();
noaccess:
$tmpl->render('nopermission');
} catch (\Exception $e) {
throw new \Exception($e->getMessage());
}
}
public function opListDns(array $params): void {
try {
$tmpl = new Template('/openprovider/');
$pagetit = "OpenProvider管理 - DNS一覧";
$description = '';
// ユーザー
$auth = new Auth();
$user = $auth->getLoggedInUser();
$tmpl->assign('user', $user);
$tmpl->assign('pagetit', $pagetit);
$tmpl->assign('curPage', 'openprovider');
$tmpl->assign('custCss', true);
$tmpl->assign('menu', $this->getMenu());
$tmpl->assign('description', $description);
if (!$user || $user->role !== \Roles::ADMIN) goto noaccess;
$op = new Openprovider();
$op->login();
$data = $op->listDnsZones();
$tmpl->assign('data', $data);
$tmpl->addCss('table');
if ($user && $user->role & (\Roles::ADMIN)) $tmpl->render('listdnszones');
else goto noaccess;
exit();
noaccess:
$tmpl->render('nopermission');
} catch (\Exception $e) {
throw new \Exception($e->getMessage());
}
}
public function opGetDns(array $params): void {
try {
$domain = '';
if (isset($params['domain'])) $domain = $params['domain'];
if ($domain === '') {
header('Location: /');
exit();
}
$tmpl = new Template('/openprovider/');
$pagetit = "OpenProvider管理 - {$domain}のDNS管理";
$description = '';
// ユーザー
$auth = new Auth();
$user = $auth->getLoggedInUser();
$tmpl->assign('user', $user);
$tmpl->assign('pagetit', $pagetit);
$tmpl->assign('curPage', 'openprovider');
$tmpl->assign('custCss', false);
$tmpl->assign('menu', $this->getMenu());
$tmpl->assign('description', $description);
if (!$user || $user->role !== \Roles::ADMIN) goto noaccess;
$op = new Openprovider();
$op->login();
$data = ['rec' => $op->listZoneRecords($domain), 'zone' => $op->getDnsZone($domain)];
$tmpl->assign('data', $data);
$tmpl->addCss('table');
$tmpl->render('getdns');
exit();
noaccess:
$tmpl->render('nopermission');
} catch (\Exception $e) {
throw new \Exception($e->getMessage());
}
}
}

View File

@@ -5,20 +5,11 @@ use Site\Controller\Mods;
use Std\Lib\Auth;
use Std\Lib\Template;
use Std\Lib\Openprovider;
class Page {
use Mods;
public function about(array $params): void {
try {
$op = new OpenProvider();
$op->login();
// kys($op->getToken());
// kys($op->checkDomainAvailable(['076.moe', '076.xxx', '076.nigger']));
// kys($op->listTlds());
kys($op->searchCustomers());
$tmpl = new Template('/');
$pagetit = '新ページ';
$description = 'PHPフレームワークについて';
@@ -121,7 +112,6 @@ class Page {
// ユーザー
$auth = new Auth();
$user = $auth->getLoggedInUser();
$tmpl->assign('user', $user);
$tmpl->assign('pagetit', $pagetit);
@@ -136,4 +126,4 @@ class Page {
throw new \Exception($e->getMessage());
}
}
}
}

View File

@@ -456,80 +456,43 @@ class Curl {
$headersComplete = false;
// ヘッダーとボディを分けて読み込む
while (!feof($socket)) {
$line = fgets($socket);
if ($line === false) {
break;
}
$rawResponse .= $line;
if (!$headersComplete) {
if (trim($line) === '') {
$headersComplete = true;
} else {
$headers .= $line;
}
} else {
$body .= $line;
}
}
while (!feof($socket)) $rawResponse .= fread($socket, 8192);
fclose($socket);
// レスポンスヘッダーを解析
$headerLines = explode("\r\n", $headers);
if ($rawResponse === '') {
$this->responseError = 'リスポンスエラー';
return \Result::Error($this->responseError);
}
// ステータスコードを取得
$statusLine = isset($headerLines[0]) ? $headerLines[0] : '';
$statusParts = explode(' ', $statusLine, 3);
$this->responseCode = isset($statusParts[1]) ? (int)$statusParts[1] : 0;
$this->info['http_code'] = $this->responseCode;
list($headerLines, $body) = $this->parseResponse($rawResponse);
// ヘッダーを解析
$this->responseHeaders = [];
$redirectUrl = '';
$this->responseCode = 0;
foreach ($headerLines as $index => $header) {
if ($index === 0) continue;
if ($index === 0) {
if (preg_match('#HTTP/\d\.\d (\d+)#', $header, $m))
$this->responseCode = (int)$m[1];
continue;
}
if (strpos($header, ':') !== false) {
list($name, $value) = explode(':', $header, 2);
[$name, $value] = explode(':', $header, 2);
$name = trim($name);
$value = trim($value);
$this->responseHeaders[$name] = $value;
if (strtolower($name) === 'content-type') {
$this->info['content_type'] = $value;
}
// リダイレクトをチェック
if ($this->followRedirects &&
strtolower($name) === 'location' &&
$this->responseCode >= 300 &&
$this->responseCode < 400) {
$redirectUrl = $value;
// 相対URLを絶対URLに変換
if (strpos($redirectUrl, 'http') !== 0) {
if ($redirectUrl[0] === '/') {
$redirectUrl = "{$scheme}://{$host}"
.($port != 80 && $port != 443 ? ":{$port}" : '').$redirectUrl;
} else {
$redirectUrl = "{$scheme}://{$host}"
.($port != 80 && $port != 443 ? ":{$port}" : '')
.dirname($path).'/'.$redirectUrl;
}
}
$this->info['redirect_url'] = $redirectUrl;
}
}
}
$this->info['http_code'] = $this->responseCode;
if (isset($this->responseHeaders['Transfer-Encoding'])
&& stripos($this->responseHeaders['Transfer-Encoding'], 'chunked') !== false) {
$body = $this->decodeChunkedBody($body);
}
$this->info['header_size'] += strlen($headers);
$this->responseBody .= $body;
$this->responseBody = $body;
if ($this->verbose && $this->stderr) {
fwrite($this->stderr, "* レスポンスコード: {$this->responseCode}\n");
@@ -688,20 +651,11 @@ class Curl {
*/
private function parseResponse(string $response): array {
$parts = explode("\r\n\r\n", $response, 2);
if (count($parts) < 2) {
return [[], ''];
}
if (count($parts) < 2) return [explode("\r\n", $response), ''];
$headers = explode("\r\n", $parts[0]);
$body = $parts[1];
// チャンク転送エンコーディングを処理
if (isset($this->responseHeaders['Transfer-Encoding']) &&
strtolower($this->responseHeaders['Transfer-Encoding']) === 'chunked') {
$body = $this->decodeChunkedBody($body);
}
return [$headers, $body];
}
@@ -717,15 +671,9 @@ class Curl {
while ($position < strlen($body)) {
$lineEnd = strpos($body, "\r\n", $position);
if ($lineEnd === false) {
break;
}
if ($lineEnd === false) break;
$chunkSize = hexdec(substr($body, $position, $lineEnd - $position));
if ($chunkSize === 0) {
break;
}
if ($chunkSize === 0) break;
$position = $lineEnd + 2;
$decodedBody .= substr($body, $position, $chunkSize);

View File

@@ -4,13 +4,17 @@ namespace Std\Lib;
use Std\Lib\Curl;
class Openprovider {
private string $user;
private string $pass;
private string $token;
private string $ip;
private int $reseller_id;
private string $BASEURL = 'https://api.openprovider.eu/v1beta';
// private Curl $curl;
protected string $dataFile = ROOT."/data/session.json";
protected int $tokenDuration = 172800; // 48時間
private string $user = '';
private string $pass = '';
private string $token = '';
private string $ip = '';
private int $reseller_id = 0;
private int $last_auth = 0;
private string $BASEURL = DEBUG_MODE ? 'http://api.sandbox.openprovider.nl:8480/v1beta'
: 'https://api.openprovider.eu/v1beta';
public function __construct() {
if (!OPENPROVIDER_ENABLED) return;
@@ -22,10 +26,13 @@ class Openprovider {
/***
* トークンの受け取り。
* このライブリリーを使ったら、一回「login()」を実行する事が必須となります。
*
* @return Result 結果
*
* @return Result|false 結果
*/
public function login(): \Result {
public function login(): \Result|false {
if (!OPENPROVIDER_ENABLED) return \Result::error('エラーOpenProviderは無効です。');
$this->getCache();
if (time() < ($this->last_auth + $this->tokenDuration)) return false;
$curl = new Curl("{$this->BASEURL}/auth/login");
$payload = [
@@ -58,7 +65,10 @@ class Openprovider {
$data = json_decode($body, true);
if (isset($data['data']['token'])) {
$this->token = $data['data']['token'];
$this->last_auth = time();
$this->reseller_id = $data['data']['reseller_id'];
$this->mkCache();
return \Result::Success();
}
@@ -71,14 +81,82 @@ class Openprovider {
//// ドメイン
/***
* ドメイン一覧。
*
* @return Result|array 結果。
*/
public function listDomains(array $query = []): \Result|array {
if (!OPENPROVIDER_ENABLED) return \Result::error('エラーOpenProviderは無効です。');
$curl = $this->setupCurl('/domains');
$data = $this->curlResult($curl);
if (isset($data['data']['results'])) return $data['data']['results'];
return \Result::Error("ドメインの確認に失敗。");
}
/**
* ドメイン名の登録。
*
* @param string $name 登録したいドメイン名(例:"076studio.jp"
* @param array $info カスタマー情報等
* @param int $period 年間(デフォルト=1年)
* @return Result|array 結果。配列の場合:'activation_date'(リアルタイムで成功したのみ), 'auth_code'TLDが対応している場合のみ, 'expiration_date', 'id', 'renewal_date', 'status'ACT又はREQ
*/
public function createDomain(string $name, array $info, int $period = 1): \Result|array {
if (!OPENPROVIDER_ENABLED) return \Result::error('エラーOpenProviderは無効です。');
if (!isset($info['owner_handle']) || $info['owner_handle'] === '') $info['owner_handle'] = OPENPROVIDER['owner_handle'];
if (!isset($info['admin_handle']) || $info['admin_handle'] === '') $info['admin_handle'] = OPENPROVIDER['owner_handle'];
if (!isset($info['tech_handle']) || $info['tech_handle'] === '') $info['tech_handle'] = OPENPROVIDER['owner_handle'];
if (!isset($info['billing_handle']) || $info['billing_handle'] === '') $info['billing_handle'] = OPENPROVIDER['owner_handle'];
if (!isset($info['reseller_handle']) || $info['reseller_handle'] === '') $info['reseller_handle'] = OPENPROVIDER['owner_handle'];
if (!isset($info['name_servers']) || empty($info['name_servers'])) $info['name_servers'] = ['ns1.openprovider.nl', 'ns2.openprovider.be', 'ns3.openprovider.eu'];
if (!isset($info['autorenew']) || $info['autorenew'] === '') $info['autorenew'] = 'default';
// 新しい顧客の場合
$parts = explode('.', $name, 2);
assert_exists($parts[0]);
assert_exists($parts[1]);
$domain = [
'name' => $parts[0],
'extension' => $parts[1],
];
$ns = [];
foreach ($info['name_servers'] as $n) {
$ns[] = ['name' => $n];
}
$payload = [
'name' => $domain,
'period' => $period,
'owner_handle' => $owner_handle,
'admin_handle' => $admin_handle,
'tech_handle' => $tech_handle,
'billing_handle' => $billing_handle,
'reseller_handle' => $reseller_handle,
'name_servers' => $ns,
'autorenew' => $autorenew,
];
$curl = $this->setupCurl('/domains/', 'POST', $payload);
kys('TODO');
$data = $this->curlResult($curl);
if (isset($data['data'])) return $data['data'];
return \Result::Error("ドメインの確認に失敗。");
}
/***
* ドメインを登録可能かどうかの確認。
*
*
* @param array $domains ドメイン名リスト。例:['076.moe', '076.co.jp', '076.com']
* @param bool $with_price 値段を表示するかどうか。デフォルトは「false」
* @return Result|array 結果。配列の場合:'domain'と'status'はいつでもあり、'reason', 'premium', 'is_premium'が多分あり、そして'price'が「with_price」が「true」の場合のみ。
*/
public function checkDomainAvailable(array $domains, bool $with_price = false): \Result|array {
if (!OPENPROVIDER_ENABLED) return \Result::error('エラーOpenProviderは無効です。');
$domainList = [];
foreach ($domains as $d) {
$domain = explode('.', $d);
@@ -106,80 +184,23 @@ class Openprovider {
return \Result::Error("ドメインの確認に失敗。");
}
/**
* ドメイン名の登録。
*
* @param string $name 登録したいドメイン名(例:"076studio.jp"
* @param int $period 年間(デフォルト=1年)
* @param string $owner_handle
* @param string $admin_handle
* @param string $tech_handle
* @param string $billing_handle
* @param string $reseller_handle
* @param array $name_servers ネームサーバーつまで、デフォルトはOpenProviderさんのネームサーバー
* @param string $autorenew 自動的に更新するかどうか可能な値on|off|default、デフォルトdefault
* @return Result|array 結果。配列の場合:'activation_date'(リアルタイムで成功したのみ), 'auth_code'TLDが対応している場合のみ, 'expiration_date', 'id', 'renewal_date', 'status'ACT又はREQ
*/
public function registerDomain(string $name, int $period = 1, string $owner_handle = '',
string $admin_handle = '', string $tech_handle = '',
string $billing_handle = '', string $reseller_handle = '',
array $name_servers = [], string $autorenew = 'default'): \Result|array {
if ($owner_handle === '') $owner_handle = OPENPROVIDER['owner_handle'];
if ($admin_handle === '') $admin_handle = $owner_handle;
if ($tech_handle === '') $tech_handle = $owner_handle;
if ($billing_handle === '') $billing_handle = $owner_handle;
if ($reseller_handle === '') $reseller_handle = $owner_handle;
$parts = explode('.', $name, 2);
assert_exists($parts[0]);
assert_exists($parts[1]);
$domain = [
'name' => $parts[0],
'extension' => $parts[1],
];
$ns = [];
if (empty($name_servers)) $name_servers = ['ns1.openprovider.nl', 'ns2.openprovider.be', 'ns3.openprovider.eu'];
foreach ($name_servers as $n) {
$ns[] = ['name' => $n];
}
$payload = [
'name' => $domain,
'period' => $period,
'owner_handle' => $owner_handle,
'admin_handle' => $admin_handle,
'tech_handle' => $tech_handle,
'billing_handle' => $billing_handle,
'reseller_handle' => $reseller_handle,
'name_servers' => $ns,
'autorenew' => $autorenew,
];
$curl = $this->setupCurl('/domains/', 'POST', $payload);
kys('TODO');
$data = $this->curlResult($curl);
if (isset($data['data'])) return $data['data'];
return \Result::Error("ドメインの確認に失敗。");
}
//// 追加データ
//// 顧客様の追加データ
/**
* 顧客様の検索
* @param array $query 検索クエリー可能handle_pattern (string), email_pattern (string), first_name_pattern (string), last_name_pattern (string), company_name_pattern (string), comment_pattern (string), with_additional_data (bool), limit (int = 100、最大1000), offset (int = 0
*
* @param array $query 検索クエリー
* @return Result|array
*/
public function searchCustomers(array $query = []): \Result|array {
if (!OPENPROVIDER_ENABLED) return \Result::error('エラーOpenProviderは無効です。');
foreach ($query as $k => $v) { if (is_bool($v)) $query[$k] = $v ? '1' : '0'; }
$uri = '/customers?'.http_build_query($query, '', '&', PHP_QUERY_RFC3986);
$curl = $this->setupCurl($uri);
kys("TODO: 問題");
$data = $this->curlResult($curl);
kys($data);
if (isset($data['data'])) return $data['data'];
return \Result::Error("TLD一覧の受け取りに失敗。");
@@ -187,16 +208,34 @@ class Openprovider {
//// ドメイン値段
/**
* ドメイン値段一覧
*
* @param array $query 検索クエリー
* @return Result|array
*/
public function getDomainPrices(array $query): \Result|array {
if (!OPENPROVIDER_ENABLED) return \Result::error('エラーOpenProviderは無効です。');
$uri = "/domains/prices?".http_build_query($query, '', '&', PHP_QUERY_RFC3986);
$curl = $this->setupCurl($uri);
$data = $this->curlResult($curl);
if (isset($data['data'])) return $data['data'];
return \Result::Error("TLD一覧の受け取りに失敗。");
}
//// 認証コード
//// TLD
/**
* TLD一覧
*
* @param array $query 検索クエリー可能limit (int),offset (int),order (string),order_by (string),extensions(array), name_pattern (string), only_names (bool), with_description (bool),with_restrictions (bool)with_usage_count (bool)with_application_mode (bool),with_price (bool),with_level_prices (bool)is_active (bool)is_new_gtld (bool),status (string),application_mode (string)
*
* @param array $query 検索クエリー
* @return Result|array
*/
public function listTlds(array $query = []): \Result|array {
if (!OPENPROVIDER_ENABLED) return \Result::error('エラーOpenProviderは無効です。');
if (empty($query)) $query = [ 'limit' => 10, 'offset' => 0, 'order' => 'ASC' ];
foreach ($query as $k => $v) {
@@ -204,11 +243,31 @@ class Openprovider {
}
$uri = '/tlds?'.http_build_query($query, '', '&', PHP_QUERY_RFC3986);
// kys($uri);
$curl = $this->setupCurl($uri);
kys("TODO: JSONの問題");
$data = $this->curlResult($curl);
kys($data);
if (isset($data['data'])) return $data['data'];
return \Result::Error("TLD一覧の受け取りに失敗。");
}
/**
* TLDの表示
*
* @param string $tld TLD
* @param array $query 検索クエリー
* @return Result|array
*/
public function getTld(string $tld, array $query = []): \Result|array {
if (!OPENPROVIDER_ENABLED) return \Result::error('エラーOpenProviderは無効です。');
if (empty($query)) $query = [ 'limit' => 10, 'offset' => 0 ];
foreach ($query as $k => $v) {
if (is_bool($v)) $query[$k] = $v ? '1' : '0';
}
$uri = "/tlds/{$tld}?".http_build_query($query, '', '&', PHP_QUERY_RFC3986);
$curl = $this->setupCurl($uri);
$data = $this->curlResult($curl);
if (isset($data['data'])) return $data['data'];
return \Result::Error("TLD一覧の受け取りに失敗。");
@@ -229,8 +288,66 @@ class Openprovider {
//// NSグループ
//// テンプレート
//// ゾーン
/**
* DNSゾーン一覧
*
* @param array $query
* @return Result|array
*/
public function listDnsZones(array $query = []): \Result|array {
if (!OPENPROVIDER_ENABLED) return \Result::error('エラーOpenProviderは無効です。');
if (empty($query)) $query = [ 'limit' => 25, 'offset' => 0, 'order_by.name' => 'asc' ];
foreach ($query as $k => $v) {
if (is_bool($v)) $query[$k] = $v ? '1' : '0';
}
$uri = "/dns/zones?".http_build_query($query, '', '&', PHP_QUERY_RFC3986);
$curl = $this->setupCurl($uri);
$data = $this->curlResult($curl);
if (isset($data['data'])) return $data['data'];
return \Result::Error("TLD一覧の受け取りに失敗。");
}
/**
* DNSゾーン一覧
*
* @param string $domain ドメイン名
* @param array $query 検索クエリー
* @return Result|array
*/
public function getDnsZone(string $domain, array $query = []): \Result|array {
if (!OPENPROVIDER_ENABLED) return \Result::error('エラーOpenProviderは無効です。');
if (empty($query)) $query = [ 'limit' => 100, 'offset' => 0, 'order_by.name' => 'asc' ];
foreach ($query as $k => $v) if (is_bool($v)) $query[$k] = $v ? '1' : '0';
$uri = "/dns/zones/{$domain}?".http_build_query($query, '', '&', PHP_QUERY_RFC3986);
$curl = $this->setupCurl($uri);
$data = $this->curlResult($curl);
if (isset($data['data'])) return $data['data'];
return \Result::Error("TLD一覧の受け取りに失敗。");
}
//// ゾーンレコード
/**
* DNSレコード一覧
*
* @param string $domain
* @return Result|array
*/
public function listZoneRecords(string $domain): \Result|array {
if (!OPENPROVIDER_ENABLED) return \Result::error('エラーOpenProviderは無効です。');
$curl = $this->setupCurl("/dns/zones/{$domain}/records");
$data = $this->curlResult($curl);
if (isset($data['data'])) return $data['data'];
return \Result::Error("TLD一覧の受け取りに失敗。");
}
// Easydmarc
// ライセンス
@@ -245,19 +362,21 @@ class Openprovider {
/**
* トークンの受け取り。
*
*
* @return string トークン
*/
public function getToken(): string {
if (!OPENPROVIDER_ENABLED) return '';
return $this->token;
}
/**
* リセラーIDの受け取り。
*
*
* @return int リセラーID
*/
public function getResellerId(): int {
if (!OPENPROVIDER_ENABLED) return 0;
return $this->reseller_id;
}
@@ -277,7 +396,6 @@ class Openprovider {
private function curlResult(Curl &$curl): \Result|array {
$res = $curl->execute();
// kys($curl->getRequestHeader());
if (!$res->isSuccess) {
$err = "CURL実行に失敗 {$curl->message}";
assert_unless_success($res, $err);
@@ -285,18 +403,40 @@ class Openprovider {
}
$body = $curl->getResponseBody();
// kys($body);
// kys($curl->getResponseHeaders());
if ($curl->getResponseCode() != 200) {
$err = json_decode($body, true);
assert_not_null($err, "エラーの受け取りに失敗。");
assert($curl->getResponseCode() == 200, $err['desc']);
return \Result::Error();
return \Result::Error($err['desc']);
}
assert_not_null($body, "返事ボディーは空です。");
// $body = str_
kys($body);
return json_decode($body, true);
}
private function mkCache(): \Result {
$session = new \stdClass;
$session->lastAuth = $this->last_auth;
$session->token = $this->token;
$session->resellerId = $this->reseller_id;
$json = json_encode($session, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
if (file_put_contents($this->dataFile, $json) === false) return \Result::Error('エラー:ユーザーデータの保存に失敗。');
return \Result::Success();
}
private function getCache(): void {
if (!file_exists($this->dataFile)) return;
$content = file_get_contents($this->dataFile);
if ($content === false) return;
$data = json_decode($content, true);
if (json_last_error() !== JSON_ERROR_NONE || !is_array($data)) return;
$this->token = $data['token'] ?? null;
$this->reseller_id = $data['resellerId'] ?? null;
$this->last_auth = $data['lastAuth'] ?? null;
}
}

View File

@@ -1,3 +1,3 @@
{@ include(common/header) @}
<p>見つけられません。ごめんなしゃーい!!</p>
{@ include(common/footer) @}
{@ include(common/footer) @}

View File

@@ -0,0 +1,53 @@
{@ include(common/header) @}
<h2>ドメイン確認</h2>
<form method="GET" action="/openprovider/checkdomain">
各行列で1つのドメイン名をご入力下さい。<br />
<textarea name="domains">{{ $saved }}</textarea><br />
<button>送信</button>
</form>
{@ if (isset($data) && !empty($data)) @}
<hr />
<h2>結果</h2>
<table>
<thead>
<tr>
<th>ドメイン名</th>
<th>状況</th>
<th>理由</th>
<th>値段</th>
</tr>
</thead>
<tbody>
{@ foreach ($data as $d) @}
{$ $status = '不明' $}
{$ $statusClass = 'status-fumei' $}
{@ if ($d['status'] === 'free') @}
{$ $status = '登録可能' $}
{$ $statusClass = 'status-free' $}
{@ elif ($d['status'] === 'reserved') @}
{$ $status = '予約済み' $}
{$ $statusClass = 'status-reserved' $}
{@ elif ($d['status'] === 'active') @}
{$ $status = '登録済み' $}
{$ $statusClass = 'status-use' $}
{@ endif @}
<tr class="{{ $statusClass }}">
<td><a href="/openprovider/registerdomain/{{ $d['domain'] }}">{{ $d['domain'] }}</a>{{ isset($d['is_premium']) && $d['is_premium'] ? '(プレミアム)' : '' }}</td>
<td>{{ $status }}</td>
<td>{{ $d['reason'] ?? '' }}</td>
<td>
{@ if (isset($d['price'])) @}
{@ if (isset($d['price']['product'])) @}
商品: {{ $d['price']['product']['price'] }} {{ $d['price']['product']['currency'] }}
{@ endif @}
{@ if (isset($d['price']['reseller'])) @}
<br />リセラー: {{ $d['price']['reseller']['price'] }} {{ $d['price']['reseller']['currency'] }}
{@ endif @}
{@ endif @}
</td>
</tr>
{@ endforeach @}
</tbody>
</table>
{@ endif @}
{@ include(common/footer) @}

View File

@@ -0,0 +1,34 @@
{@ include(common/header) @}
<a href="#" class="">DNSゾーンの追加ボタン</a><br />
{@ if (isset($data['results'])) @}
検索バー<br />
<h2>編集</h2>
<table>
<thead>
<tr>
<th>名前</th>
<th>種類</th>
<th>内容</th>
<th>プライオリティ</th>
<th>TTL</th>
</tr>
</thead>
<tbody>
{@ foreach ($data['results'] as $d) @}
<tr>
<td><a href="/openprovider/editdnszone/{{ $d['name'] }}">{{ $d['name'] }}</a></td>
<td>{{ $d['type'] }}</td>
<td>{{ substr($d['value'], 0, 40) }}</td>
<td>{{ $d['prio'] ?? '' }}</td>
<td>{{ $d['ttl'] }}</td>
</tr>
{@ endforeach @}
</tbody>
</table>
</div>
{@ else @}
<p>何も見つけられませんでした。</p>
{@ endif @}
{@ kys($data) @}
{@ include(common/footer) @}

View File

@@ -0,0 +1,150 @@
{@ include(common/header) @}
<style>
.tabs {
border-radius: 2px;
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
}
.tab-nav {
display: flex;
border-bottom: 1px solid #ea79d8;
}
.tab-nav label {
flex: 1;
color: #ea79d8;
padding: 16px 20px;
text-align: center;
cursor: pointer;
background: #550f75;
transition: all 0.3s;
font-weight: 600;
}
.tab-nav label:hover {
background: #8952a3;
}
.tab-input {
display: none;
}
#tab1:checked ~ .tab-nav label[for="tab1"],
#tab2:checked ~ .tab-nav label[for="tab2"],
#tab3:checked ~ .tab-nav label[for="tab3"],
#tab4:checked ~ .tab-nav label[for="tab4"] {
background: #2c023f;
border-bottom: 3px solid #ea79d8;
color: #ea79d8;
}
.tab-content {
display: none;
min-height: 200px;
}
#tab1:checked ~ .tab-content[data-tab="1"],
#tab2:checked ~ .tab-nav ~ .tab-content[data-tab="2"],
#tab3:checked ~ .tab-nav ~ .tab-content[data-tab="3"],
#tab4:checked ~ .tab-nav ~ .tab-content[data-tab="4"] {
display: block;
}
</style>
<a href="#" class="">DNSレコードの追加ボタン</a><br />
<a href="#" class="">DNSゾーンの削除ボタン</a><br />
{@ if (isset($data['rec']['results']) || isset($data['zone'])) @}
検索バー<br />
<div class="tabs">
<input type="radio" id="tab1" name="tabs" class="tab-input" checked />
<input type="radio" id="tab2" name="tabs" class="tab-input" />
<input type="radio" id="tab3" name="tabs" class="tab-input" />
<input type="radio" id="tab4" name="tabs" class="tab-input" />
<div class="tab-nav">
<label for="tab1">レコード</label>
<label for="tab2">詳細</label>
<label for="tab3">DNSSEC鍵</label>
<label for="tab4">履歴</label>
</div>
<div class="tab-content" data-tab="1">
<h2>レコード</h2>
<table>
<thead>
<tr>
<th>名前</th>
<th>種類</th>
<th>内容</th>
<th>プライオリティ</th>
<th>TTL</th>
</tr>
</thead>
<tbody>
{@ foreach ($data['rec']['results'] as $d) @}
<tr>
<td><a href="/openprovider/editdnszone/{{ $d['name'] }}">{{ $d['name'] }}</a></td>
<td>{{ $d['type'] }}</td>
<td>{{ substr($d['value'], 0, 40) }}</td>
<td>{{ $d['prio'] ?? '' }}</td>
<td>{{ $d['ttl'] }}</td>
</tr>
{@ endforeach @}
</tbody>
</table>
</div>
<div class="tab-content" data-tab="2">
<h2>詳細</h2>
<table>
<tbody>
<tr>
<td>ドメイン名</td>
<td>{{ $data['zone']['name'] }}</td>
</tr>
<tr>
<td>種類</td>
<td>{{ $data['zone']['type'] }}</td>
</tr>
<tr>
<td>DNSゾーンプロバイダー</td>
<td>Openprovider</td>
</tr>
<tr>
<td>追加日</td>
<td>{{ $data['zone']['creation_date'] }}</td>
</tr>
<tr>
<td>最終更新日</td>
<td>{{ $data['zone']['modification_date'] }}</td>
</tr>
<tr>
<td>レコード数</td>
<td>{{ $data['rec']['total'] }}</td>
</tr>
<tr>
<td>DNSSEC有効</td>
<td></td>
</tr>
<tr>
<td>SpamExperts</td>
<td>{{ $data['zone']['is_spamexperts_enabled'] ? '有' : '無' }}</td>
</tr>
</tbody>
</table>
</div>
<div class="tab-content" data-tab="3">
<h2>DNSSEC鍵</h2>
<p>ささ</p>
</div>
<div class="tab-content" data-tab="4">
<h2>履歴</h2>
<p>ささ</p>
</div>
</div>
{@ else @}
<p>何も見つけられませんでした。</p>
{@ endif @}
{@ include(common/footer) @}

View File

@@ -0,0 +1,3 @@
{@ include(common/header) @}
{@ kys($data) @}
{@ include(common/footer) @}

View File

@@ -0,0 +1,3 @@
{@ include(common/header) @}
{@ kys($data) @}
{@ include(common/footer) @}

View File

@@ -0,0 +1,20 @@
{@ include(common/header) @}
<h1>{{ $description }}</h1>
<ul>
<li>顧客様</li>
<ul>
<li><a href="/openprovider/searchcustomer">顧客様検索</a></li>
</ul>
<li>ドメイン</li>
<ul>
<li><a href="/openprovider/checkdomain">ドメイン確認</a></li>
<li><a href="/openprovider/getdomainprices?domain.name=076&domain.extension=sex">ドメイン値段一覧</a></li>
<li><a href="/openprovider/listtlds">TLD一覧</a></li>
<li><a href="/openprovider/gettld/moe">TLDの表示.moe</a></li>
</ul>
<li>DNS</li>
<ul>
<li><a href="/openprovider/listdnszones">DNSゾーン一覧</a></li>
</ul>
</ul>
{@ include(common/footer) @}

View File

@@ -0,0 +1,32 @@
{@ include(common/header) @}
検索バー<br />
<a href="#" class="">DNSゾーンの追加ボタン</a>
{@ if (isset($data['results'])) @}
<table>
<thead>
<tr>
<th>Domain name</th>
<th>Type</th>
<th>DNS provider</th>
<th>Renewal date</th>
<th>Date added</th>
<th>Last change</th>
</tr>
</thead>
<tbody>
{@ foreach ($data['results'] as $d) @}
<tr>
<td><a href="/openprovider/getdns/{{ $d['name'] }}">{{ $d['name'] }}</a></td>
<td>{{ $d['type'] }}</td>
<td>{{ $d['provider'] }}</td>
<td></td>
<td>{{ $d['creation_date'] }}</td>
<td>{{ $d['modification_date'] }}</td>
</tr>
{@ endforeach @}
</tbody>
</table>
{@ else @}
<p>何も見つけられませんでした。</p>
{@ endif @}
{@ include(common/footer) @}

View File

@@ -0,0 +1,3 @@
{@ include(common/header) @}
{@ kys($data) @}
{@ include(common/footer) @}

View File

@@ -0,0 +1,3 @@
{@ include(common/header) @}
<p>表示許可却下。失礼。</p>
{@ include(common/footer) @}

View File

View File

@@ -0,0 +1,29 @@
{@ include(common/header) @}
検索<br />
{@ if (isset($data['results'])) @}
<table>
<thead>
<tr>
<th>Name</th>
<th>Company</th>
<th>E-mail address</th>
<th>Handle</th>
<th>Notes</th>
</tr>
</thead>
<tbody>
{@ foreach ($data['results'] as $d) @}
<tr>
<td><a href="/openprovider/getcustomer/{{ $d['handle'] }}">{{ $d['name']['full_name'] }}</a></td>
<td>{{ $d['company_name'] }}</td>
<td>{{ $d['email'] }}</td>
<td>{{ $d['handle'] }}</td>
<td></td>
</tr>
{@ endforeach @}
</tbody>
</table>
{@ else @}
<p>何も見つけられませんでした。</p>
{@ endif @}
{@ include(common/footer) @}