Просмотр исходного кода

Added wip power and auth shutdown api

tobychui 4 лет назад
Родитель
Сommit
9a13d07973

+ 23 - 10
hardware.power.go

@@ -1,15 +1,15 @@
 package main
 
 import (
-	"net/http"
 	"log"
+	"net/http"
 
 	"os/exec"
 	"runtime"
 )
 
-func HardwarePowerInit(){
-	if (*allow_hardware_management){
+func HardwarePowerInit() {
+	if *allow_hardware_management {
 		//Only register these paths when hardware management is enabled
 		http.HandleFunc("/system/power/shutdown", hardware_power_poweroff)
 		http.HandleFunc("/system/power/restart", hardware_power_restart)
@@ -18,17 +18,17 @@ func HardwarePowerInit(){
 	http.HandleFunc("/system/power/accessCheck", hardware_power_checkIfHardware)
 }
 
-func hardware_power_checkIfHardware(w http.ResponseWriter, r *http.Request){
-	if (*allow_hardware_management){
+func hardware_power_checkIfHardware(w http.ResponseWriter, r *http.Request) {
+	if *allow_hardware_management {
 		sendJSONResponse(w, "true")
-	}else{
+	} else {
 		sendJSONResponse(w, "false")
 	}
 }
 
 func hardware_power_poweroff(w http.ResponseWriter, r *http.Request) {
-	userinfo, err := userHandler.GetUserInfoFromRequest(w,r)
-	if err != nil{
+	userinfo, err := userHandler.GetUserInfoFromRequest(w, r)
+	if err != nil {
 		w.WriteHeader(http.StatusUnauthorized)
 		w.Write([]byte("401 Unauthorized"))
 		return
@@ -44,6 +44,19 @@ func hardware_power_poweroff(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
+	//Double check password for this user
+	password, err := mv(r, "pw", true)
+	if err != nil {
+		sendErrorResponse(w, "Password Incorrect")
+		return
+	}
+
+	passwordCorrect := authAgent.ValidateUsernameAndPassword(userinfo.Username, password)
+	if !passwordCorrect {
+		sendErrorResponse(w, "Password Incorrect")
+		return
+	}
+
 	if runtime.GOOS == "windows" {
 		//Only allow Linux to do power operation
 		cmd := exec.Command("shutdown", "-s", "-t", "20")
@@ -81,8 +94,8 @@ func hardware_power_poweroff(w http.ResponseWriter, r *http.Request) {
 }
 
 func hardware_power_restart(w http.ResponseWriter, r *http.Request) {
-	userinfo, err := userHandler.GetUserInfoFromRequest(w,r)
-	if err != nil{
+	userinfo, err := userHandler.GetUserInfoFromRequest(w, r)
+	if err != nil {
 		w.WriteHeader(http.StatusUnauthorized)
 		w.Write([]byte("401 Unauthorized"))
 		return

+ 10 - 0
startup.flags.go

@@ -36,6 +36,16 @@ func StartupFlagsInit() {
 		},
 	})
 
+	//Register a power handler in system setting menu
+	registerSetting(settingModule{
+		Name:         "Power",
+		Desc:         "Set the power state of the host device",
+		IconPath:     "SystemAO/boot/img/boot.png",
+		Group:        "Info",
+		StartDir:     "SystemAO/boot/poweroff.html",
+		RequireAdmin: true,
+	})
+
 	adminRouter.HandleFunc("/system/bootflags", handleBootFlagsFunction)
 }
 

+ 3 - 3
web/SystemAO/boot/bootflags.html

@@ -1,6 +1,6 @@
 <html>
     <head>
-        <title>Start Flags Settings</title>
+        <title>Runtime Adjustment</title>
         <meta charset="UTF-8">
         <meta name="viewport" content="width=device-width, initial-scale=1.0 user-scalable=no">
         <link rel="stylesheet" href="../../script/semantic/semantic.min.css">
@@ -15,9 +15,9 @@
         <div class="ui container">
             <div class="ui basic segment">
                 <h3 class="ui header">
-                    <i class="flag icon"></i>
+                    <i class="play icon"></i>
                     <div class="content">
-                        System Startup Flags
+                        Runtime Adjustment
                       <div class="sub header">Update system startup parameters in runtime</div>
                     </div>
                 </h3>

+ 76 - 0
web/SystemAO/boot/poweroff.html

@@ -0,0 +1,76 @@
+<html>
+    <head>
+        <title>Host Power Options</title>
+        <style>
+
+        </style>
+    </head>
+    <body>
+        <div class="ui container">
+            <div class="ui basic segment">
+                <h3 class="ui header">
+                    <i class="power icon"></i>
+                    <div class="content">
+                        Host Power
+                        <div class="sub header">Change power state of your device</div>
+                    </div>
+                </h3>
+            </div>
+            <div class="ui divider"></div>
+            <div class="ui segment">
+                <h3 class="ui header">
+                    <i class="green check circle icon"></i>
+                    <div class="content">
+                        System Online
+                        <div class="sub header">Last update: <span id="lastupdateTime"></span></div>
+                    </div>
+                </h3>
+            </div>
+           
+            <div class="ui divider"></div>
+            <p>Power Options</p>
+            <button class="ui red button" onclick="shutdown();"><i class="power off icon"></i> Power Off</button>
+            <button class="ui yellow button" onclick="restart();"><i class="refresh icon"></i> Restart</button>
+            <div class="ui icon yellow message">
+                <i class="yellow exclamation circle icon"></i>
+                <div class="content">
+                    <div class="header">
+                        Restart / Shutdown is risky
+                    </div>
+                    <p>Normally, Linux based server don't require reboot. If you decided to shutdown your host server, ArozOS will pass the shutdown sequence to the host operating system and there is no way to know from the web interface if the shutdown / restart process has completed. <br>
+                        <b>Please make sure you are shutting it down in a place where you can physcically power on the host again.</b></p>
+                </div>
+            </div>
+        </div>
+        <script>
+            $("#lastupdateTime").text(ao_module_utils.timeConverter(Date.now()/1000));
+
+            
+
+            function shutdown(){
+
+            }
+
+            function restart(){
+                var apiObject = {
+                    api: "system/power/restart",
+                    data: {},
+                    title: "Restart Host",
+                    desc: "Authentication is required in order to proceed the restart process",
+                    thisuser: true, //This username as default, set to false for entering other user
+                    method: "GET"
+                }
+
+                apiObject = encodeURIComponent(JSON.stringify(apiObject));
+
+                ao_module_newfw({
+                    url: "SystemAO/security/authreq.html#" + apiObject,
+                    width: 380,
+                    height: 200,
+                    appicon: "SystemAO/security/img/lock.svg",
+                    title: "Restart - Authentication Required"
+                });
+            }
+        </script>
+    </body>
+</html>

+ 24 - 0
web/SystemAO/security/authreq.html

@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>Authentication Required</title>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0 user-scalable=no">
+    <link rel="stylesheet" href="../../script/semantic/semantic.min.css">
+    <script type="text/javascript" src="../../script/jquery.min.js"></script>
+    <script type="text/javascript" src="../../script/semantic/semantic.min.js"></script>
+    <script type="text/javascript" src="../../script/ao_module.js"></script>
+    <style>
+    
+    </style>
+</head>
+<body>
+    <div class="ui container">
+       
+    </div>
+    
+    <script>
+       
+    </script>
+</body>
+</html>

Разница между файлами не показана из-за своего большого размера
+ 27 - 0
web/SystemAO/security/img/lock.ai


+ 18 - 0
web/SystemAO/security/img/lock.svg

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="128px"
+	 height="128px" viewBox="0 0 128 128" enable-background="new 0 0 128 128" xml:space="preserve">
+<g id="圖層_1">
+	<path fill="none" stroke="#C9CACA" stroke-width="10" stroke-miterlimit="10" d="M88.414,65.344c0,4.886-4.294,8.846-9.591,8.846
+		H49.177c-5.298,0-9.592-3.96-9.592-8.846V18.301c0-4.886,4.294-8.846,9.592-8.846h29.646c5.297,0,9.591,3.96,9.591,8.846V65.344z"
+		/>
+	<path fill="#00A0E9" d="M101.343,108.52c0,6.132-5.24,11.102-11.703,11.102H38.391c-6.464,0-11.704-4.97-11.704-11.102V59.901
+		c0-6.131,5.24-11.102,11.704-11.102H89.64c6.463,0,11.703,4.971,11.703,11.102V108.52z"/>
+</g>
+<g id="圖層_2">
+	<circle fill="#FFFFFF" cx="64.015" cy="73.466" r="9.735"/>
+	<path fill="#FFFFFF" d="M67.546,100.756c0,1.951-1.581,3.531-3.531,3.531l0,0c-1.95,0-3.53-1.58-3.53-3.531V80.78
+		c0-1.95,1.58-3.53,3.53-3.53l0,0c1.95,0,3.531,1.58,3.531,3.53V100.756z"/>
+</g>
+</svg>

Некоторые файлы не были показаны из-за большого количества измененных файлов