mirror of
https://github.com/ngoduykhanh/wireguard-ui.git
synced 2025-04-19 19:59:13 +03:00
171 lines
4.6 KiB
Go
171 lines
4.6 KiB
Go
package handler
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/labstack/echo/v4"
|
|
"github.com/labstack/gommon/log"
|
|
"github.com/ngoduykhanh/wireguard-ui/model"
|
|
"github.com/ngoduykhanh/wireguard-ui/store"
|
|
"github.com/sabhiram/go-wol/wol"
|
|
"net"
|
|
"net/http"
|
|
"time"
|
|
)
|
|
|
|
type WakeOnLanHostSavePayload struct {
|
|
Name string `json:"name"`
|
|
MacAddress string `json:"mac_address"`
|
|
OldMacAddress string `json:"old_mac_address"`
|
|
}
|
|
|
|
func createError(c echo.Context, err error, msg string) error {
|
|
log.Error(msg, err)
|
|
return c.JSON(
|
|
http.StatusInternalServerError,
|
|
jsonHTTPResponse{
|
|
false,
|
|
msg})
|
|
}
|
|
|
|
func GetWakeOnLanHosts(db store.IStore) echo.HandlerFunc {
|
|
return func(c echo.Context) error {
|
|
var err error
|
|
|
|
hosts, err := db.GetWakeOnLanHosts()
|
|
if err != nil {
|
|
return createError(c, err, fmt.Sprintf("wake_on_lan_hosts database error: %s", err))
|
|
}
|
|
|
|
err = c.Render(http.StatusOK, "wake_on_lan_hosts.html", map[string]interface{}{
|
|
"baseData": model.BaseData{Active: "wake_on_lan_hosts", CurrentUser: currentUser(c)},
|
|
"hosts": hosts,
|
|
"error": "",
|
|
})
|
|
if err != nil {
|
|
return createError(c, err, fmt.Sprintf("wake_on_lan_hosts.html render error: %s", err))
|
|
}
|
|
|
|
return nil
|
|
}
|
|
}
|
|
|
|
func SaveWakeOnLanHost(db store.IStore) echo.HandlerFunc {
|
|
return func(c echo.Context) error {
|
|
var payload WakeOnLanHostSavePayload
|
|
err := c.Bind(&payload)
|
|
if err != nil {
|
|
log.Error("Wake On Host Save Payload Bind Error: ", err)
|
|
return c.JSON(http.StatusInternalServerError, payload)
|
|
}
|
|
|
|
var host = model.WakeOnLanHost{
|
|
MacAddress: payload.MacAddress,
|
|
Name: payload.Name,
|
|
}
|
|
if len(payload.OldMacAddress) != 0 { // Edit
|
|
if payload.OldMacAddress != payload.MacAddress { // modified mac address
|
|
oldHost, err := db.GetWakeOnLanHost(payload.OldMacAddress)
|
|
if err != nil {
|
|
return createError(c, err, fmt.Sprintf("Wake On Host Update Err: %s", err))
|
|
}
|
|
|
|
if payload.OldMacAddress != payload.MacAddress {
|
|
existHost, _ := db.GetWakeOnLanHost(payload.MacAddress)
|
|
if existHost != nil {
|
|
return createError(c, nil, "Mac Address already exists.")
|
|
}
|
|
}
|
|
|
|
err = db.DeleteWakeOnHostLanHost(payload.OldMacAddress)
|
|
if err != nil {
|
|
return createError(c, err, fmt.Sprintf("Wake On Host Update Err: %s", err))
|
|
}
|
|
host.LatestUsed = oldHost.LatestUsed
|
|
}
|
|
err = db.SaveWakeOnLanHost(host)
|
|
} else { // new
|
|
existHost, _ := db.GetWakeOnLanHost(payload.MacAddress)
|
|
if existHost != nil {
|
|
return createError(c, nil, "Mac Address already exists.")
|
|
}
|
|
|
|
err = db.SaveWakeOnLanHost(host)
|
|
}
|
|
|
|
if err != nil {
|
|
return createError(c, err, fmt.Sprintf("Wake On Host Save Error: %s", err))
|
|
}
|
|
|
|
return c.JSON(http.StatusOK, host)
|
|
}
|
|
}
|
|
|
|
func DeleteWakeOnHost(db store.IStore) echo.HandlerFunc {
|
|
return func(c echo.Context) error {
|
|
var macAddress = c.Param("mac_address")
|
|
var host, err = db.GetWakeOnLanHost(macAddress)
|
|
|
|
if err != nil {
|
|
log.Error("Wake On Host Delete Error: ", err)
|
|
return createError(c, err, fmt.Sprintf("Wake On Host Delete Error: %s", macAddress))
|
|
}
|
|
|
|
err = db.DeleteWakeOnHost(*host)
|
|
if err != nil {
|
|
return createError(c, err, fmt.Sprintf("Wake On Host Delete Error: %s", macAddress))
|
|
}
|
|
|
|
return c.JSON(http.StatusOK, nil)
|
|
}
|
|
}
|
|
|
|
func WakeOnHost(db store.IStore) echo.HandlerFunc {
|
|
return func(c echo.Context) error {
|
|
macAddress := c.Param("mac_address")
|
|
host, err := db.GetWakeOnLanHost(macAddress)
|
|
|
|
now := time.Now().UTC()
|
|
host.LatestUsed = &now
|
|
err = db.SaveWakeOnLanHost(*host)
|
|
if err != nil {
|
|
return createError(c, err, fmt.Sprintf("Latest Used Update Error: %s", macAddress))
|
|
}
|
|
|
|
magicPacket, err := wol.New(macAddress)
|
|
if err != nil {
|
|
return createError(c, err, fmt.Sprintf("Magic Packet Create Error: %s", macAddress))
|
|
}
|
|
|
|
bytes, err := magicPacket.Marshal()
|
|
if err != nil {
|
|
return createError(c, err, fmt.Sprintf("Magic Packet Bytestream Error: %s", macAddress))
|
|
}
|
|
|
|
udpAddr, err := net.ResolveUDPAddr("udp", "255.255.255.255:0")
|
|
if err != nil {
|
|
return createError(c, err, fmt.Sprintf("ResolveUDPAddr Error: %s", macAddress))
|
|
}
|
|
|
|
// Grab a UDP connection to send our packet of bytes.
|
|
conn, err := net.DialUDP("udp", nil, udpAddr)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer func(conn *net.UDPConn) {
|
|
err := conn.Close()
|
|
if err != nil {
|
|
log.Error(err)
|
|
}
|
|
}(conn)
|
|
|
|
n, err := conn.Write(bytes)
|
|
if err == nil && n != 102 {
|
|
return createError(c, nil, fmt.Sprintf("magic packet sent was %d bytes (expected 102 bytes sent)", n))
|
|
}
|
|
if err != nil {
|
|
return createError(c, err, fmt.Sprintf("Network Send Error: %s", macAddress))
|
|
}
|
|
|
|
return c.JSON(http.StatusOK, host.LatestUsed)
|
|
}
|
|
}
|