mirror of
https://github.com/ZeroDream-CN/SakuraPanel.git
synced 2025-01-12 09:52:52 +08:00
Feature: New frps api server
合并了原来的独立 API,直接调用 configuration.php 里面的配置,不再需要单独配置一次 增加配置文件获取接口 getconf,请求地址:`/api/?action=getconf&user=用户名&token=访问密钥&node=节点ID`
This commit is contained in:
parent
e1f3a683b3
commit
5a26258cde
354
api/index.php
354
api/index.php
@ -1,223 +1,205 @@
|
||||
<?php
|
||||
error_reporting(0);
|
||||
Header("Content-type: text/plain");
|
||||
$conn = mysqli_connect(
|
||||
/* 数据库地址 */ "localhost",
|
||||
/* 数据库账号 */ "root",
|
||||
/* 数据库密码 */ "123456",
|
||||
/* 数据库名称 */ "spanel",
|
||||
/* 数据库端口 */ 3306
|
||||
) or die("Database error");
|
||||
namespace SakuraPanel;
|
||||
|
||||
use SakuraPanel;
|
||||
|
||||
// API 密码,需要和 Frps.ini 里面设置的一样
|
||||
define("API_TOKEN", "SakuraFrpToken");
|
||||
define("ROOT", realpath(__DIR__ . "/../"));
|
||||
|
||||
// 输出禁止错误 Header
|
||||
function ServerForbidden($msg) {
|
||||
Header("HTTP/1.1 403 {$msg}");
|
||||
echo json_encode(Array(
|
||||
'status' => 403,
|
||||
'message' => $msg
|
||||
), JSON_UNESCAPED_UNICODE);
|
||||
exit;
|
||||
if(ROOT === false) {
|
||||
exit("Please place this file on /api/ folder");
|
||||
}
|
||||
|
||||
// 输出未找到错误 Header
|
||||
function ServerNotFound($msg) {
|
||||
Header("HTTP/1.1 404 {$msg}");
|
||||
echo json_encode(Array(
|
||||
'status' => 404,
|
||||
'message' => $msg
|
||||
), JSON_UNESCAPED_UNICODE);
|
||||
exit;
|
||||
}
|
||||
include(ROOT . "/configuration.php");
|
||||
include(ROOT . "/core/Database.php");
|
||||
include(ROOT . "/core/Regex.php");
|
||||
include(ROOT . "/core/Utils.php");
|
||||
|
||||
// 输出未找到错误 Header
|
||||
function ServerBadRequest($msg) {
|
||||
Header("HTTP/1.1 400 {$msg}");
|
||||
echo json_encode(Array(
|
||||
'status' => 400,
|
||||
'message' => $msg
|
||||
), JSON_UNESCAPED_UNICODE);
|
||||
exit;
|
||||
}
|
||||
$conn = null;
|
||||
$db = new SakuraPanel\Database();
|
||||
|
||||
// 输出正常消息
|
||||
function LoginSuccessful($msg) {
|
||||
Header("Content-type: text/plain", true, 200);
|
||||
echo json_encode(Array(
|
||||
'status' => 200,
|
||||
'success' => true,
|
||||
'message' => $msg
|
||||
), JSON_UNESCAPED_UNICODE);
|
||||
exit;
|
||||
}
|
||||
include(ROOT . "/core/UserManager.php");
|
||||
include(ROOT . "/core/NodeManager.php");
|
||||
include(ROOT . "/core/ProxyManager.php");
|
||||
|
||||
// 输出正常消息
|
||||
function CheckSuccessful($msg) {
|
||||
Header("Content-type: text/plain", true, 200);
|
||||
echo json_encode(Array(
|
||||
'status' => 200,
|
||||
'success' => true,
|
||||
'message' => $msg
|
||||
), JSON_UNESCAPED_UNICODE);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Json 格式消息输出
|
||||
function Println($data) {
|
||||
Header("Content-type: text/plain", true, 200);
|
||||
echo json_encode($data, JSON_UNESCAPED_UNICODE);
|
||||
exit;
|
||||
}
|
||||
|
||||
function getBoolean($str) {
|
||||
return $str == "true";
|
||||
}
|
||||
$pm = new ProxyManager();
|
||||
$nm = new NodeManager();
|
||||
|
||||
// 服务端 API 部分
|
||||
// 先进行 Frps 鉴权
|
||||
if(isset($_GET['apitoken']) && $_GET['apitoken'] == API_TOKEN) {
|
||||
if(isset($_GET['action'])) {
|
||||
switch($_GET['action']) {
|
||||
|
||||
// 检查客户端是否合法
|
||||
case "checktoken":
|
||||
if(isset($_GET['user'])) {
|
||||
if(preg_match("/^[A-Za-z0-9]{1,32}$/", $_GET['user'])) {
|
||||
$userToken = mysqli_real_escape_string($conn, $_GET['user']);
|
||||
$rs = mysqli_fetch_array(mysqli_query($conn, "SELECT * FROM `tokens` WHERE `token`='{$userToken}'"));
|
||||
if($rs) {
|
||||
LoginSuccessful("Login successful, welcome!");
|
||||
if((isset($_GET['apitoken']) && $_GET['apitoken'] == API_TOKEN) || (isset($_GET['action']) && $_GET['action'] == "getconf")) {
|
||||
switch($_GET['action']) {
|
||||
case "getconf":
|
||||
if(isset($_GET['user'], $_GET['token'], $_GET['node'])) {
|
||||
if(Regex::isUserName($_GET['user']) && Regex::isLetter($_GET['token']) && Regex::isNumber($_GET['node'])) {
|
||||
$rs = Database::querySingleLine("tokens", [
|
||||
"username" => $_GET['user'],
|
||||
"token" => $_GET['token']
|
||||
]);
|
||||
if($rs && $nm->isNodeExist($_GET['node'])) {
|
||||
$rs = $pm->getUserProxiesConfig($_GET['user'], $_GET['node']);
|
||||
if(is_string($rs)) {
|
||||
Header("Content-Type: text/plain");
|
||||
exit($rs);
|
||||
} else {
|
||||
ServerForbidden("Login failed");
|
||||
Utils::sendServerNotFound("User or node not found");
|
||||
}
|
||||
} else {
|
||||
ServerForbidden("Invalid username");
|
||||
Utils::sendServerNotFound("User or node not found");
|
||||
}
|
||||
} else {
|
||||
ServerForbidden("Username cannot be empty");
|
||||
Utils::sendServerNotFound("Invalid username or token");
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
Utils::sendServerNotFound("Invalid request");
|
||||
}
|
||||
break;
|
||||
|
||||
// 检查隧道是否合法
|
||||
case "checkproxy":
|
||||
if(isset($_GET['user'])) {
|
||||
if(preg_match("/^[A-Za-z0-9]{1,32}$/", $_GET['user'])) {
|
||||
$proxyName = str_replace("{$_GET['user']}.", "", $_GET['proxy_name']);
|
||||
$proxyType = $_GET['proxy_type'] ?? "tcp";
|
||||
$remotePort = Intval($_GET['remote_port']) ?? "";
|
||||
$userToken = mysqli_real_escape_string($conn, $_GET['user']);
|
||||
$rs = mysqli_fetch_array(mysqli_query($conn, "SELECT * FROM `tokens` WHERE `token`='{$userToken}'"));
|
||||
if($rs) {
|
||||
if($proxyType == "tcp" || $proxyType == "udp" || $proxyType == "stcp" || $proxyType == "xtcp") {
|
||||
if(isset($remotePort) && preg_match("/^[0-9]{1,5}$/", $remotePort)) {
|
||||
$username = mysqli_real_escape_string($conn, $rs['username']);
|
||||
// 这里只对远程端口做限制,可根据自己的需要修改
|
||||
$rs = mysqli_fetch_array(mysqli_query($conn, "SELECT * FROM `proxies` WHERE `username`='{$username}' AND `remote_port`='{$remotePort}' AND `proxy_type`='{$proxyType}'"));
|
||||
if($rs) {
|
||||
if($rs['status'] !== "0") {
|
||||
ServerForbidden("Proxy disabled");
|
||||
}
|
||||
CheckSuccessful("Proxy exist");
|
||||
} else {
|
||||
ServerNotFound("Proxy not found");
|
||||
// 检查客户端是否合法
|
||||
case "checktoken":
|
||||
if(isset($_GET['user'])) {
|
||||
if(Regex::isLetter($_GET['user']) && strlen($_GET['user']) == 16) {
|
||||
$userToken = Database::escape($_GET['user']);
|
||||
$rs = Database::querySingleLine("tokens", ["token" => $userToken]);
|
||||
if($rs) {
|
||||
Utils::sendLoginSuccessful("Login successful, welcome!");
|
||||
} else {
|
||||
Utils::sendServerForbidden("Login failed");
|
||||
}
|
||||
} else {
|
||||
Utils::sendServerForbidden("Invalid username");
|
||||
}
|
||||
} else {
|
||||
Utils::sendServerForbidden("Username cannot be empty");
|
||||
}
|
||||
break;
|
||||
|
||||
// 检查隧道是否合法
|
||||
case "checkproxy":
|
||||
if(isset($_GET['user'])) {
|
||||
if(Regex::isLetter($_GET['user']) && strlen($_GET['user']) == 16) {
|
||||
$proxyName = str_replace("{$_GET['user']}.", "", $_GET['proxy_name']);
|
||||
$proxyType = $_GET['proxy_type'] ?? "tcp";
|
||||
$remotePort = Intval($_GET['remote_port']) ?? "";
|
||||
$userToken = Database::escape($_GET['user']);
|
||||
$rs = Database::querySingleLine("tokens", ["token" => $userToken]);
|
||||
if($rs) {
|
||||
if($proxyType == "tcp" || $proxyType == "udp" || $proxyType == "stcp" || $proxyType == "xtcp") {
|
||||
if(isset($remotePort) && Regex::isNumber($remotePort)) {
|
||||
$username = Database::escape($rs['username']);
|
||||
// 这里只对远程端口做限制,可根据自己的需要修改
|
||||
$rs = Database::querySingleLine("proxies", [
|
||||
"username" => $username,
|
||||
"remote_port" => $remotePort,
|
||||
"proxy_type" => $proxyType
|
||||
]);
|
||||
if($rs) {
|
||||
if($rs['status'] !== "0") {
|
||||
Utils::sendServerForbidden("Proxy disabled");
|
||||
}
|
||||
Utils::sendCheckSuccessful("Proxy exist");
|
||||
} else {
|
||||
ServerBadRequest("Invalid request");
|
||||
}
|
||||
} elseif($proxyType == "http" || $proxyType == "https") {
|
||||
if(isset($_GET['domain']) || isset($_GET['subdomain'])) {
|
||||
// 目前只验证域名和子域名
|
||||
$domain = $_GET['domain'] ?? "null";
|
||||
$subdomain = $_GET['subdomain'] ?? "null";
|
||||
$username = mysqli_real_escape_string($conn, $rs['username']);
|
||||
$domain = mysqli_real_escape_string($conn, $domain);
|
||||
$subdomain = mysqli_real_escape_string($conn, $subdomain);
|
||||
$domainsql = (isset($_GET['domain']) && !empty($_GET['domain'])) ? "`domain`='{$domain}'" : "`subdomain`='{$subdomain}'";
|
||||
$rs = mysqli_fetch_array(mysqli_query($conn, "SELECT * FROM `proxies` WHERE `username`='{$username}' AND {$domainsql} AND `proxy_type`='{$proxyType}'"));
|
||||
if($rs) {
|
||||
if($rs['status'] !== "0") {
|
||||
ServerForbidden("Proxy disabled");
|
||||
}
|
||||
CheckSuccessful("Proxy exist");
|
||||
} else {
|
||||
ServerNotFound("Proxy not found");
|
||||
}
|
||||
} else {
|
||||
ServerBadRequest("Invalid request");
|
||||
Utils::sendServerNotFound("Proxy not found");
|
||||
}
|
||||
} else {
|
||||
ServerBadRequest("Invalid request");
|
||||
Utils::sendServerBadRequest("Invalid request");
|
||||
}
|
||||
} else {
|
||||
ServerNotFound("User not found");
|
||||
}
|
||||
} else {
|
||||
ServerBadRequest("Invalid request");
|
||||
}
|
||||
} else {
|
||||
ServerForbidden("Invalid username");
|
||||
}
|
||||
break;
|
||||
case "getlimit":
|
||||
Header("Content-type: text/plain", true, 200);
|
||||
if(isset($_GET['user'])) {
|
||||
if(preg_match("/^[A-Za-z0-9]{1,32}$/", $_GET['user'])) {
|
||||
$userToken = mysqli_real_escape_string($conn, $_GET['user']);
|
||||
$rs = mysqli_fetch_array(mysqli_query($conn, "SELECT * FROM `tokens` WHERE `token`='{$userToken}'"));
|
||||
if($rs) {
|
||||
$username = mysqli_real_escape_string($conn, $rs['username']);
|
||||
$ls = mysqli_fetch_array(mysqli_query($conn, "SELECT * FROM `limits` WHERE `username`='{$username}'"));
|
||||
if($ls) {
|
||||
exit(json_encode(Array(
|
||||
'status' => 200,
|
||||
'max-in' => Floatval($ls['inbound']),
|
||||
'max-out' => Floatval($ls['outbound'])
|
||||
)));
|
||||
} else {
|
||||
$uinfo = mysqli_fetch_array(mysqli_query($conn, "SELECT * FROM `users` WHERE `username`='{$username}'"));
|
||||
if($uinfo) {
|
||||
if($rs['group'] == "admin") {
|
||||
exit(json_encode(Array(
|
||||
'status' => 200,
|
||||
'max-in' => 1000000,
|
||||
'max-out' => 1000000
|
||||
)));
|
||||
}
|
||||
$group = mysqli_real_escape_string($conn, $rs['group']);
|
||||
$gs = mysqli_fetch_array(mysqli_query($conn, "SELECT * FROM `groups` WHERE `name`='{$group}'"));
|
||||
if($gs) {
|
||||
exit(json_encode(Array(
|
||||
'status' => 200,
|
||||
'max-in' => Floatval($gs['inbound']),
|
||||
'max-out' => Floatval($gs['outbound'])
|
||||
)));
|
||||
} else {
|
||||
exit(json_encode(Array(
|
||||
'status' => 200,
|
||||
'max-in' => 1024,
|
||||
'max-out' => 1024
|
||||
)));
|
||||
} elseif($proxyType == "http" || $proxyType == "https") {
|
||||
if(isset($_GET['domain']) || isset($_GET['subdomain'])) {
|
||||
// 目前只验证域名和子域名
|
||||
$domain = $_GET['domain'] ?? "null";
|
||||
$subdomain = $_GET['subdomain'] ?? "null";
|
||||
$username = Database::escape($rs['username']);
|
||||
$domain = Database::escape($domain);
|
||||
$subdomain = Database::escape($subdomain);
|
||||
$domainSQL = (isset($_GET['domain']) && !empty($_GET['domain'])) ? ["domain" => $domain] : ["subdomain" => $subdomain];
|
||||
$querySQL = [
|
||||
"username" => $username,
|
||||
"proxy_type" => $proxyType
|
||||
];
|
||||
$querySQL = Array_merge($querySQL, $domainSQL);
|
||||
$rs = Database::querySingleLine("proxies", $querySQL);
|
||||
if($rs) {
|
||||
if($rs['status'] !== "0") {
|
||||
Utils::sendServerForbidden("Proxy disabled");
|
||||
}
|
||||
Utils::sendCheckSuccessful("Proxy exist");
|
||||
} else {
|
||||
Utils::sendServerNotFound("Proxy not found");
|
||||
}
|
||||
} else {
|
||||
Utils::sendServerBadRequest("Invalid request");
|
||||
}
|
||||
} else {
|
||||
ServerForbidden("Login failed");
|
||||
Utils::sendServerBadRequest("Invalid request");
|
||||
}
|
||||
} else {
|
||||
ServerForbidden("Invalid username");
|
||||
Utils::sendServerNotFound("User not found");
|
||||
}
|
||||
} else {
|
||||
ServerForbidden("Username cannot be empty");
|
||||
Utils::sendServerBadRequest("Invalid request");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ServerNotFound("Undefined action");
|
||||
}
|
||||
} else {
|
||||
ServerNotFound("Invalid request");
|
||||
} else {
|
||||
Utils::sendServerForbidden("Invalid username");
|
||||
}
|
||||
break;
|
||||
case "getlimit":
|
||||
if(isset($_GET['user'])) {
|
||||
if(Regex::isLetter($_GET['user']) && strlen($_GET['user']) == 16) {
|
||||
$userToken = Database::escape($_GET['user']);
|
||||
$rs = Database::querySingleLine("tokens", ["token" => $userToken]);
|
||||
if($rs) {
|
||||
$username = Database::escape($rs['username']);
|
||||
$ls = Database::querySingleLine("limits", ["username" => $username]);
|
||||
if($ls) {
|
||||
Utils::sendJson(Array(
|
||||
'status' => 200,
|
||||
'max-in' => Floatval($ls['inbound']),
|
||||
'max-out' => Floatval($ls['outbound'])
|
||||
));
|
||||
} else {
|
||||
$uinfo = Database::querySingleLine("users", ["username" => $username]);
|
||||
if($uinfo) {
|
||||
if($uinfo['group'] == "admin") {
|
||||
Utils::sendJson(Array(
|
||||
'status' => 200,
|
||||
'max-in' => 1000000,
|
||||
'max-out' => 1000000
|
||||
));
|
||||
}
|
||||
$group = Database::escape($uinfo['group']);
|
||||
$gs = Database::querySingleLine("groups", ["name" => $group]);
|
||||
if($gs) {
|
||||
Utils::sendJson(Array(
|
||||
'status' => 200,
|
||||
'max-in' => Floatval($gs['inbound']),
|
||||
'max-out' => Floatval($gs['outbound'])
|
||||
));
|
||||
} else {
|
||||
Utils::sendJson(Array(
|
||||
'status' => 200,
|
||||
'max-in' => 1024,
|
||||
'max-out' => 1024
|
||||
));
|
||||
}
|
||||
} else {
|
||||
Utils::sendServerForbidden("User not exist");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Utils::sendServerForbidden("Login failed");
|
||||
}
|
||||
} else {
|
||||
Utils::sendServerForbidden("Invalid username");
|
||||
}
|
||||
} else {
|
||||
Utils::sendServerForbidden("Username cannot be empty");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Utils::sendServerNotFound("Undefined action");
|
||||
}
|
||||
} else {
|
||||
ServerNotFound("Invalid request");
|
||||
Utils::sendServerNotFound("Invalid request");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user