From 01b9046021ab235f53e3fb7ae1ade8222fc18e45 Mon Sep 17 00:00:00 2001 From: KasuganoSoras Date: Sat, 15 Sep 2018 13:25:18 +0800 Subject: [PATCH] =?UTF-8?q?v7.3.2105=20=E5=AE=89=E5=85=A8=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E5=8F=91=E5=B8=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 增加登录页面 Csrf 验证 修复 Daemon 管理页面显示问题 修复一些操作时的判断问题 修复 AJAX 请求参数构造错误问题 修复控制台字体全绿问题 --- content/PHPMC7/assets/js/console.js | 18 ++--- content/PHPMC7/daemon-list.html | 9 +-- content/PHPMC7/login.html | 9 ++- include/core/PHPMC/Csrf.php | 24 ++++++ include/core/PHPMC/Daemon.php | 2 +- include/core/PHPMC/Event.php | 60 +++++++++++++-- include/core/PHPMC/Main.php | 7 +- include/core/PHPMC/Profile.php | 17 +++++ include/core/PHPMC/Server.php | 109 +++++++++++++++++++++++++++- include/loader.php | 7 ++ 10 files changed, 236 insertions(+), 26 deletions(-) create mode 100644 include/core/PHPMC/Csrf.php diff --git a/content/PHPMC7/assets/js/console.js b/content/PHPMC7/assets/js/console.js index 57dad88..97ea67f 100644 --- a/content/PHPMC7/assets/js/console.js +++ b/content/PHPMC7/assets/js/console.js @@ -23,17 +23,17 @@ function ajaxload() { $("#ping").html(end + " 毫秒"); if(oldlog != htmlobj.responseText) { $("#debug").html("" - + htmlobj.responseText.replace("<", "<").replace(">", ">").replace("\n","
") - .replace("INFO]", "信息]").replace("WARN]", "警告]") - .replace("ERROR]", "错误]").replace("[Server", "[服务器").replace("thread/", "主线程/") + + htmlobj.responseText.replace(//g, ">").replace(/\n/g,"
") + .replace(/INFO\]/g, "信息]").replace(/WARN\]/g, "警告]") + .replace(/ERROR\]/g, "错误]").replace(/\[Server/g, "[服务器").replace(/thread\//g, "主线程/") .replace("Done (", "启动完成,耗时 (").replace("s)! For help, type \"help\" or \"?\"", " 秒)!需要帮助,请输入 “help” 或 “?”") - .replace("Unknown command. Type \"/help\" for help.", "未知命令,请输入 “help” 查看帮助。") - .replace("Usage:", "使用方法:").replace("Stopping the server", "正在关闭服务器") - .replace("You need to agree to the EULA in order to run the server. Go to eula.txt for more info.", + .replace(/Unknown command\. Type \"\/help\" for help\./g, "未知命令,请输入 “help” 查看帮助。") + .replace(/Usage\:/g, "使用方法:").replace(/Stopping the server/g, "正在关闭服务器") + .replace(/You need to agree to the EULA in order to run the server. Go to eula.txt for more info./, "你需要接受 EULA 协议才能开启服务器,编辑服务端的 eula.txt ,将 eula=false 改为 eula=true 并保存即可。") - .replace("Stopping server", "正在终止服务器进程").replace("Loading properties", "正在加载配置文件") - .replace("Failed to load", "无法加载").replace("Starting minecraft server version", "正在启动 Minecraft 服务器,版本:") - .replace("Default game type:", "默认游戏模式:").replace("Container not found", "提示:服务器未在运行状态") + .replace(/Stopping server/, "正在终止服务器进程").replace(/Loading properties/, "正在加载配置文件") + .replace(/Failed to load/, "无法加载").replace(/Starting minecraft server version/, "正在启动 Minecraft 服务器,版本:") + .replace(/Default game type:/, "默认游戏模式:").replace("Container not found", "提示:服务器未在运行状态") .replace("Token Error", "错误:授权验证失败,请检查 Daemon 设置。") + "
"); if(autoflush.checked == true) { debug.scrollTop = debug.scrollHeight; diff --git a/content/PHPMC7/daemon-list.html b/content/PHPMC7/daemon-list.html index 3d7a992..ed8869f 100644 --- a/content/PHPMC7/daemon-list.html +++ b/content/PHPMC7/daemon-list.html @@ -127,11 +127,10 @@ }; function createDaemon() { var htmlobj = $.ajax({ - url: "?", + url: "?action=createdaemon", async:true, timeout:5000, data: { - action: "createdaemon", name: $("#name").val(), host: $("#host").val(), pass: $("#pass").val(), @@ -151,11 +150,10 @@ } function updateDaemon() { var htmlobj = $.ajax({ - url: "?", + url: "?action=updatedaemon", async:true, timeout:5000, data: { - action: "updatedaemon", id: selected, name: $("#modify_name").val(), host: $("#modify_host").val(), @@ -177,11 +175,10 @@ function deleteDaemon() { if(confirm("您确定要删除此 Daemon 吗?此操作不可恢复!")) { var htmlobj = $.ajax({ - url: "?", + url: "?action=deletedaemon", async:true, timeout:5000, data: { - action: "deletedaemon", id: selected }, error: function() { diff --git a/content/PHPMC7/login.html b/content/PHPMC7/login.html index b5bb722..5ab7cd9 100644 --- a/content/PHPMC7/login.html +++ b/content/PHPMC7/login.html @@ -62,10 +62,17 @@ }, data: { username: urname, - password: passwd + password: passwd, + csrf_token: "{CSRF_TOKEN}" } }); }; + window.onkeydown = function(event){ + if(event.keyCode == 13) { + login(); + return false; + } + };
"; } mysqli_close($conn); diff --git a/include/core/PHPMC/Event.php b/include/core/PHPMC/Event.php index 8d77d57..224d468 100644 --- a/include/core/PHPMC/Event.php +++ b/include/core/PHPMC/Event.php @@ -7,6 +7,7 @@ class Event { SESSION_START(); $_SESSION['user'] = $Data['username']; echo "Successful"; + PHPMC::Csrf()->createCsrfToken(); exit; } else { $Option = new Option(); @@ -247,6 +248,16 @@ class Event { if(!preg_match("/^[0-9]+$/", $data['owner'])) { PHPMC::Error()->Println("请填写字段:服务器所有者"); } + $Server = new Server(); + $Server->setServer($data['name']); + if($Server->uuid !== null) { + PHPMC::Error()->Println("相同名字的服务器已经存在。"); + } + $Server->unselectServer(); + $Server->setServer($data['port'], $data['daemon']); + if($Server->uuid !== null) { + PHPMC::Error()->Println("相同端口、相同 Daemon 的服务器已经存在。"); + } $Daemon = new Daemon(); if($Daemon->setDaemon($data['daemon']) == null) { PHPMC::Error()->Println("Daemon 不存在,请检查参数是否正确。"); @@ -285,9 +296,24 @@ class Event { if(!preg_match("/^[0-9]+$/", $data['owner'])) { PHPMC::Error()->Println("请填写字段:服务器所有者"); } + $Server = new Server(); + $Server2 = new Server(); + $Server->setServer($data['id']); + if($Server->uuid == null) { + PHPMC::Error()->Println("Server Not Found"); + } + $Server2->setServer($data['name']); + if($Server2->uuid !== null) { + PHPMC::Error()->Println("相同名字的服务器已经存在。"); + } + $Server2->unselectServer(); + $Server2->setServer($data['port'], $Server->daemon); + if($Server->uuid !== null) { + PHPMC::Error()->Println("相同端口、相同 Daemon 的服务器已经存在。"); + } PHPMC::Server()->updateServer($data['id'], $data['name'], $data['maxram'], $data['jar'], $data['startcommand'], $data['stopcommand'], $data['owner'], "normal", $data['port'], $data['ftppass']); - echo "服务器设置更改成功!"; + echo "服务器设置更改成功,您需要刷新网页后设置才会生效。"; exit; } @@ -340,8 +366,12 @@ class Event { if(!preg_match("/^[a-z]+$/", $data['type'])) { PHPMC::Error()->Println("请填写字段:服务器操作系统类型"); } + $Daemon = new Daemon(); + if($Daemon->setDaemon($data['id']) == null) { + PHPMC::Error()->Println("Daemon Not Found"); + } PHPMC::Daemon()->updateDaemon($data['id'], $data['name'], $data['host'], $data['pass'], $data['fqdn'], $data['type']); - echo "Daemon 设置更改成功!"; + echo "Daemon 设置更改成功,您需要刷新网页后设置才会生效。"; exit; } @@ -374,6 +404,14 @@ class Event { if(!preg_match("/^[A-Za-z0-9\_\-\;\:]+$/", $data['permission'])) { PHPMC::Error()->Println("请填写字段:用户权限"); } + $Profile = new Profile($data['username']); + if($Profile->username == $data['username'] && $Profile->id !== $data['id']) { + PHPMC::Error()->Println("此用户名已经存在。"); + } + $Profile = new Profile($data['email']); + if($Profile->email == $data['email'] && $Profile->id !== $data['id']) { + PHPMC::Error()->Println("此邮箱已经存在。"); + } $password = password_hash(md5($data['password']), PASSWORD_BCRYPT); PHPMC::User()->createUser($data['username'], $password, $data['email'], $data['permission']); echo "用户创建成功!"; @@ -393,13 +431,25 @@ class Event { if(!preg_match("/^[A-Za-z0-9\_\-\;\:]+$/", $data['permission'])) { PHPMC::Error()->Println("请填写字段:用户权限"); } + $Profile = new Profile($data['id']); + if($Profile->username == null) { + PHPMC::Error()->Println("User Not Found"); + } + $Profile = new Profile($data['username']); + if($Profile->username == $data['username'] && $Profile->id !== $data['id']) { + PHPMC::Error()->Println("此用户名已经存在。"); + } + $Profile = new Profile($data['email']); + if($Profile->email == $data['email'] && $Profile->id !== $data['id']) { + PHPMC::Error()->Println("此邮箱已经存在。"); + } if(empty($data['password'])) { PHPMC::User()->updateUser($data['id'], $data['username'], false, $data['email'], $data['permission']); } else { $password = password_hash(md5($data['password']), PASSWORD_BCRYPT); PHPMC::User()->updateUser($data['id'], $data['username'], $password, $data['email'], $data['permission']); } - echo "用户设置更改成功!"; + echo "用户设置更改成功,您需要刷新网页后设置才会生效。"; exit; } @@ -408,7 +458,7 @@ class Event { PHPMC::Error()->Println("请填写字段:用户 ID"); } $Profile = new Profile($data['id']); - if($Daemon->setDaemon($data['id']) == null) { + if($Profile->username == null) { PHPMC::Error()->Println("User Not Found"); } if(PHPMC::Server()->getCountsByOwner($data['id']) > 0) { @@ -433,7 +483,7 @@ class Event { PHPMC::Error()->Println("请填写字段:系统主题"); } PHPMC::Option()->saveConfig($data['SiteName'], $data['Description'], $data['Theme']); - echo "系统设置更改成功!"; + echo "系统设置更改成功,您需要刷新网页后设置才会生效。"; exit; } diff --git a/include/core/PHPMC/Main.php b/include/core/PHPMC/Main.php index 348f058..f14b615 100644 --- a/include/core/PHPMC/Main.php +++ b/include/core/PHPMC/Main.php @@ -1,5 +1,5 @@ id = $rs['id']; @@ -17,12 +18,28 @@ class Profile { $this->email = $rs['email']; $this->permission = $rs['permission']; } else { + // Method 2 通过用户 ID 查找用户 $rs = mysqli_fetch_array(mysqli_query($conn, "SELECT * FROM `{$db['name']}`.`users` WHERE `id`='{$username}'")); if($rs) { $this->id = $rs['id']; $this->username = $rs['username']; $this->email = $rs['email']; $this->permission = $rs['permission']; + } else { + // Method 3 通过用户邮箱查找用户 + $rs = mysqli_fetch_array(mysqli_query($conn, "SELECT * FROM `{$db['name']}`.`users` WHERE `email`='{$username}'")); + if($rs) { + $this->id = $rs['id']; + $this->username = $rs['username']; + $this->email = $rs['email']; + $this->permission = $rs['permission']; + } else { + // 未找到任何数据,返回 null + $this->id = null; + $this->username = null; + $this->email = null; + $this->permission = null; + } } } } diff --git a/include/core/PHPMC/Server.php b/include/core/PHPMC/Server.php index 3888e97..dd6e4ea 100644 --- a/include/core/PHPMC/Server.php +++ b/include/core/PHPMC/Server.php @@ -16,14 +16,16 @@ class Server { public $uuid; /** - * 选择要操作的服务器 + * 选择要操作的服务器,这里写的很杂 * * @param $server 服务器 ID + * @param $daemon 服务器所在 Daemon */ - public function setServer($server) { + public function setServer($server, $daemon = false) { $this->server = $server; $db = Config::MySQL(); $conn = mysqli_connect($db['host'], $db['user'], $db['pass'], $db['name'], $db['port']); + // Method 1 通过服务器 ID 查找服务器 $rs = mysqli_fetch_array(mysqli_query($conn, "SELECT * FROM `{$db['name']}`.`servers` WHERE `id`='" . $this->server . "'")); if($rs) { $this->id = $rs['id']; @@ -38,9 +40,108 @@ class Server { $this->port = $rs['port']; $this->ftppass = $rs['ftppass']; $this->uuid = $rs['uuid']; + } else { + // Method 2 通过服务器 UUID 查找服务器 + $rs = mysqli_fetch_array(mysqli_query($conn, "SELECT * FROM `{$db['name']}`.`servers` WHERE `uuid`='" . $this->server . "'")); + if($rs) { + $this->id = $rs['id']; + $this->name = $rs['name']; + $this->daemon = $rs['daemon']; + $this->maxram = $rs['maxram']; + $this->jar = $rs['jar']; + $this->startcommand = $rs['startcommand']; + $this->stopcommand = $rs['stopcommand']; + $this->owner = $rs['owner']; + $this->status = $rs['status']; + $this->port = $rs['port']; + $this->ftppass = $rs['ftppass']; + $this->uuid = $rs['uuid']; + } else { + // Method 3 通过服务器名字查找服务器 + $rs = mysqli_fetch_array(mysqli_query($conn, "SELECT * FROM `{$db['name']}`.`servers` WHERE `name`='" . $this->server . "'")); + if($rs) { + $this->id = $rs['id']; + $this->name = $rs['name']; + $this->daemon = $rs['daemon']; + $this->maxram = $rs['maxram']; + $this->jar = $rs['jar']; + $this->startcommand = $rs['startcommand']; + $this->stopcommand = $rs['stopcommand']; + $this->owner = $rs['owner']; + $this->status = $rs['status']; + $this->port = $rs['port']; + $this->ftppass = $rs['ftppass']; + $this->uuid = $rs['uuid']; + } else { + // Method 4 通过服务器端口查找服务器 + if($daemon) { + $rs = mysqli_fetch_array(mysqli_query($conn, "SELECT * FROM `{$db['name']}`.`servers` WHERE `port`='" . $this->server . "' AND `daemon`='{$daemon}'")); + if($rs) { + $this->id = $rs['id']; + $this->name = $rs['name']; + $this->daemon = $rs['daemon']; + $this->maxram = $rs['maxram']; + $this->jar = $rs['jar']; + $this->startcommand = $rs['startcommand']; + $this->stopcommand = $rs['stopcommand']; + $this->owner = $rs['owner']; + $this->status = $rs['status']; + $this->port = $rs['port']; + $this->ftppass = $rs['ftppass']; + $this->uuid = $rs['uuid']; + } else { + // 未找到任何数据,返回 null + $this->id = null; + $this->name = null; + $this->daemon = null; + $this->maxram = null; + $this->jar = null; + $this->startcommand = null; + $this->stopcommand = null; + $this->owner = null; + $this->status = null; + $this->port = null; + $this->ftppass = null; + $this->uuid = null; + } + } else { + // 未找到任何数据,返回 null + $this->id = null; + $this->name = null; + $this->daemon = null; + $this->maxram = null; + $this->jar = null; + $this->startcommand = null; + $this->stopcommand = null; + $this->owner = null; + $this->status = null; + $this->port = null; + $this->ftppass = null; + $this->uuid = null; + } + } + } } } + /** + * 取消选择服务器 + */ + public function unselectServer() { + $this->id = null; + $this->name = null; + $this->daemon = null; + $this->maxram = null; + $this->jar = null; + $this->startcommand = null; + $this->stopcommand = null; + $this->owner = null; + $this->status = null; + $this->port = null; + $this->ftppass = null; + $this->uuid = null; + } + /** * 在数据库中创建新的服务器 * @@ -57,11 +158,13 @@ class Server { * @return Boolean 创建状态 */ public function createServer($name, $daemon, $maxram, $jar, $startcommand, $stopcommand, $owner, $status, $port, $ftppass) { - $uuid = md5(md5(time() . rand(0, 999999))); + $uuid = md5(uniqid(rand(0, 10000000), TRUE)); $db = Config::MySQL(); $conn = mysqli_connect($db['host'], $db['user'], $db['pass'], $db['name'], $db['port']); mysqli_query($conn, "INSERT INTO `{$db['name']}`.`servers` (`id`, `name`, `daemon`, `maxram`, `jar`, `startcommand`, `stopcommand`, `owner`, `status`, `port`, `uuid`, `ftppass`) " . "VALUES (NULL, '{$name}', '{$daemon}', '{$maxram}', '{$jar}', '{$startcommand}', '{$stopcommand}', '{$owner}', '{$status}', '{$port}', '{$uuid}', '{$ftppass}')"); + $this->setServer($uuid); + $this->Init(); return true; } diff --git a/include/loader.php b/include/loader.php index 5f52b7b..b8ca093 100644 --- a/include/loader.php +++ b/include/loader.php @@ -37,6 +37,7 @@ class Loader { $str = str_replace("{USERNAME}", $Profile->username, $str); $str = str_replace("{USERMAIL}", $Profile->email, $str); $str = str_replace("{AVATAR_HASH}", md5($Profile->email), $str); + $str = str_replace("{CSRF_TOKEN}", $_SESSION['token'], $str); preg_match_all("/\{User\:(.*)\}/U", $str, $arr); for($i = 0;$i < count($arr[0]);$i++) { $User = new User(); @@ -75,6 +76,9 @@ class Loader { * **/ public function router() { + if(PHPMC::Csrf()->isemptyCsrfToken()) { + PHPMC::Csrf()->createCsrfToken(); + } $Option = new Option(); if(preg_match("/^[A-Za-z0-9\-\_]+$/", $_GET["page"])) { PHPMC::Permission()->checkSession("page:" . $_GET['page']); @@ -83,6 +87,9 @@ class Loader { } elseif($_GET['action']) { switch($_GET['action']) { case 'login': + if(!PHPMC::Csrf()->verifyCsrfToken($_POST)) { + PHPMC::Error()->Println("Csrf 验证失败,请刷新页面重试。"); + } PHPMC::Event()->LoginEvent($_POST); break; case 'logout':