작업중 커밋
This commit is contained in:
		
							parent
							
								
									4be3a65691
								
							
						
					
					
						commit
						6e87a96d34
					
				
							
								
								
									
										18
									
								
								go.mod
								
								
								
								
							
							
						
						
									
										18
									
								
								go.mod
								
								
								
								
							|  | @ -5,21 +5,27 @@ go 1.14 | |||
| require ( | ||||
| 	github.com/GeertJohan/go.rice v1.0.0 | ||||
| 	github.com/glendc/go-external-ip v0.0.0-20170425150139-139229dcdddd | ||||
| 	github.com/go-playground/universal-translator v0.17.0 // indirect | ||||
| 	github.com/gorilla/sessions v1.2.0 | ||||
| 	github.com/jcelliott/lumber v0.0.0-20160324203708-dd349441af25 // indirect | ||||
| 	github.com/labstack/echo-contrib v0.9.0 | ||||
| 	github.com/labstack/echo/v4 v4.1.16 | ||||
| 	github.com/labstack/gommon v0.3.0 | ||||
| 	github.com/leodido/go-urn v1.2.0 // indirect | ||||
| 	github.com/rs/xid v1.2.1 | ||||
| 	github.com/sdomino/scribble v0.0.0-20191024200645-4116320640ba | ||||
| 	github.com/sendgrid/rest v2.6.4+incompatible // indirect | ||||
| 	github.com/sendgrid/sendgrid-go v3.10.0+incompatible | ||||
| 	github.com/skip2/go-qrcode v0.0.0-20191027152451-9434209cb086 | ||||
| 	github.com/xhit/go-simple-mail/v2 v2.10.0 | ||||
| 	golang.zx2c4.com/wireguard v0.0.20200121 // indirect | ||||
| 	golang.zx2c4.com/wireguard/wgctrl v0.0.0-20210803171230-4253848d036c | ||||
| 	gopkg.in/go-playground/assert.v1 v1.2.1 // indirect | ||||
| 	gopkg.in/go-playground/validator.v9 v9.31.0 | ||||
| ) | ||||
| 
 | ||||
| require ( | ||||
| 	github.com/go-playground/universal-translator v0.17.0 // indirect | ||||
| 	github.com/jcelliott/lumber v0.0.0-20160324203708-dd349441af25 // indirect | ||||
| 	github.com/leodido/go-urn v1.2.0 // indirect | ||||
| 	github.com/sendgrid/rest v2.6.4+incompatible // indirect | ||||
| 	golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 // indirect | ||||
| 	golang.org/x/net v0.0.0-20211215060638-4ddde0e984e9 // indirect | ||||
| 	golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect | ||||
| 	golang.org/x/text v0.3.8-0.20211105212822-18b340fc7af2 // indirect | ||||
| 	gopkg.in/go-playground/assert.v1 v1.2.1 // indirect | ||||
| ) | ||||
|  |  | |||
							
								
								
									
										31
									
								
								go.sum
								
								
								
								
							
							
						
						
									
										31
									
								
								go.sum
								
								
								
								
							|  | @ -149,23 +149,26 @@ github.com/valyala/fasttemplate v1.1.0 h1:RZqt0yGBsps8NGvLSGW804QQqCUYYLsaOjTVHy | |||
| github.com/valyala/fasttemplate v1.1.0/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= | ||||
| github.com/xhit/go-simple-mail/v2 v2.10.0 h1:nib6RaJ4qVh5HD9UE9QJqnUZyWp3upv+Z6CFxaMj0V8= | ||||
| github.com/xhit/go-simple-mail/v2 v2.10.0/go.mod h1:kA1XbQfCI4JxQ9ccSN6VFyIEkkugOm7YiPkA5hKiQn4= | ||||
| github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= | ||||
| go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= | ||||
| golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= | ||||
| golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | ||||
| golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | ||||
| golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | ||||
| golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | ||||
| golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= | ||||
| golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= | ||||
| golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= | ||||
| golang.org/x/crypto v0.0.0-20210503195802-e9a32991a82e h1:8foAy0aoO5GkqCvAEJ4VC4P3zksTg4X4aJCDpZzmgQI= | ||||
| golang.org/x/crypto v0.0.0-20210503195802-e9a32991a82e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= | ||||
| golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 h1:0es+/5331RGQPcXlMfP+WrnIIS6dNnNRe0WB02W0F4M= | ||||
| golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= | ||||
| golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= | ||||
| golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||||
| golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= | ||||
| golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= | ||||
| golang.org/x/net v0.0.0-20190607181551-461777fb6f67/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | ||||
| golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | ||||
| golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | ||||
| golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | ||||
| golang.org/x/net v0.0.0-20191003171128-d98b1b443823/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | ||||
| golang.org/x/net v0.0.0-20191007182048-72f939374954/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | ||||
| golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | ||||
| golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | ||||
|  | @ -175,11 +178,15 @@ golang.org/x/net v0.0.0-20201216054612-986b41b23924/go.mod h1:m0MpNAwzfU5UDzcl9v | |||
| golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= | ||||
| golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= | ||||
| golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= | ||||
| golang.org/x/net v0.0.0-20210504132125-bbd867fde50d h1:nTDGCTeAu2LhcsHTRzjyIUbZHCJ4QePArsm27Hka0UM= | ||||
| golang.org/x/net v0.0.0-20210504132125-bbd867fde50d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= | ||||
| golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= | ||||
| golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= | ||||
| golang.org/x/net v0.0.0-20211215060638-4ddde0e984e9 h1:kmreh1vGI63l2FxOAYS3Yv6ATsi7lSTuwNSVbGfJV9I= | ||||
| golang.org/x/net v0.0.0-20211215060638-4ddde0e984e9/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= | ||||
| golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||
| golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||
| golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||
| golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||
| golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||
| golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||
| golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||
|  | @ -192,7 +199,6 @@ golang.org/x/sys v0.0.0-20190609082536-301114b31cce/go.mod h1:h1NjWce9XRLGQEsW7w | |||
| golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20191003212358-c178f38b412c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
|  | @ -209,23 +215,30 @@ golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7w | |||
| golang.org/x/sys v0.0.0-20210216163648-f7da38b97c65/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210309040221-94ec62e08169/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20210503173754-0981d6026fa6 h1:cdsMqa2nXzqlgs183pHxtvoVwU7CyzaCTAUOg94af4c= | ||||
| golang.org/x/sys v0.0.0-20210503173754-0981d6026fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= | ||||
| golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= | ||||
| golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= | ||||
| golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||||
| golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= | ||||
| golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | ||||
| golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= | ||||
| golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | ||||
| golang.org/x/text v0.3.8-0.20211105212822-18b340fc7af2 h1:GLw7MR8AfAG2GmGcmVgObFOHXYypgGjnGno25RDwn3Y= | ||||
| golang.org/x/text v0.3.8-0.20211105212822-18b340fc7af2/go.mod h1:EFNZuWvGYxIRUEX+K8UmCFwYmZjqcrnq15ZuVldZkZ0= | ||||
| golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||||
| golang.org/x/tools v0.0.0-20190608022120-eacb66d2a7c3/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= | ||||
| golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= | ||||
| golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= | ||||
| golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||||
| golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||||
| golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||||
| golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= | ||||
| golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||||
| golang.zx2c4.com/wireguard v0.0.0-20210427022245-097af6e1351b h1:XDLXhn7ryprJVo+Lpkiib6CIuXE2031GDwtfEm7vLjI= | ||||
| golang.zx2c4.com/wireguard v0.0.0-20210427022245-097af6e1351b/go.mod h1:a057zjmoc00UN7gVkaJt2sXVK523kMJcogDTEvPIasg= | ||||
| golang.zx2c4.com/wireguard v0.0.20200121 h1:vcswa5Q6f+sylDfjqyrVNNrjsFUUbPsgAQTBCAg/Qf8= | ||||
| golang.zx2c4.com/wireguard v0.0.20200121/go.mod h1:P2HsVp8SKwZEufsnezXZA4GRX/T49/HlU7DGuelXsU4= | ||||
| golang.zx2c4.com/wireguard/wgctrl v0.0.0-20210803171230-4253848d036c h1:ADNrRDI5NR23/TUCnEmlLZLt4u9DnZ2nwRkPrAcFvto= | ||||
| golang.zx2c4.com/wireguard/wgctrl v0.0.0-20210803171230-4253848d036c/go.mod h1:+1XihzyZUBJcSc5WO9SwNA7v26puQwOEDwanaxfNXPQ= | ||||
| gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= | ||||
|  |  | |||
|  | @ -4,6 +4,7 @@ import ( | |||
| 	"encoding/base64" | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"github.com/labstack/echo/v4" | ||||
| 	"net/http" | ||||
| 	"sort" | ||||
| 	"strings" | ||||
|  | @ -12,7 +13,6 @@ import ( | |||
| 	rice "github.com/GeertJohan/go.rice" | ||||
| 	"github.com/gorilla/sessions" | ||||
| 	"github.com/labstack/echo-contrib/session" | ||||
| 	"github.com/labstack/echo/v4" | ||||
| 	"github.com/labstack/gommon/log" | ||||
| 	"github.com/rs/xid" | ||||
| 	"golang.zx2c4.com/wireguard/wgctrl" | ||||
|  | @ -685,3 +685,77 @@ func ApplyServerConfig(db store.IStore, tmplBox *rice.Box) echo.HandlerFunc { | |||
| 		return c.JSON(http.StatusOK, jsonHTTPResponse{true, "Applied server config successfully"}) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func GetWakeOnLanHosts(db store.IStore) echo.HandlerFunc { | ||||
| 	return func(c echo.Context) error { | ||||
| 		var err error | ||||
| 
 | ||||
| 		hosts, err := db.GetWakeOnLanHosts() | ||||
| 		if err != nil { | ||||
| 			log.Errorf("WOL ERROR") | ||||
| 			return c.JSON(http.StatusNotFound, jsonHTTPResponse{false, "Host not found"}) | ||||
| 		} | ||||
| 
 | ||||
| 		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 { | ||||
| 
 | ||||
| 			print(err.Error() + "\n") | ||||
| 			return err | ||||
| 		} | ||||
| 
 | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| func SaveWakeOnLanHost(db store.IStore) echo.HandlerFunc { | ||||
| 	return func(c echo.Context) error { | ||||
| 		type WakeOnLanHostPayload struct { | ||||
| 			Name          string `json:"name"` | ||||
| 			MacAddress    string `json:"mac_address"` | ||||
| 			OldMacAddress string `json:"old_mac_address"` | ||||
| 		} | ||||
| 
 | ||||
| 		var payload WakeOnLanHostPayload | ||||
| 		err := c.Bind(&payload) | ||||
| 		if err != nil { | ||||
| 			log.Error("Wake On Host Bind Error: ", err) | ||||
| 			return c.JSON(http.StatusInternalServerError, payload) | ||||
| 		} | ||||
| 
 | ||||
| 		host := model.WakeOnLanHost{ | ||||
| 			MacAddress: payload.MacAddress, | ||||
| 			Name:       payload.Name, | ||||
| 		} | ||||
| 		if len(payload.OldMacAddress) != 0 { | ||||
| 			oldHost, err := db.GetWakeOnLanHost(payload.OldMacAddress) | ||||
| 			if err != nil { | ||||
| 				log.Error("Wake On Host Update Err: ", err) | ||||
| 				return c.JSON(http.StatusInternalServerError, payload) | ||||
| 			} | ||||
| 
 | ||||
| 			err = db.DeleteWakeOnHostLanHost(payload.OldMacAddress) | ||||
| 			if err != nil { | ||||
| 				log.Error("Wake On Host Update Err: ", err) | ||||
| 				return c.JSON(http.StatusInternalServerError, payload) | ||||
| 			} | ||||
| 			host.LatestUsed = oldHost.LatestUsed | ||||
| 			err = db.SaveWakeOnLanHost(host) | ||||
| 		} else { | ||||
| 			now := time.Now() | ||||
| 			host.LatestUsed = &now | ||||
| 			err = db.SaveWakeOnLanHost(host) | ||||
| 		} | ||||
| 
 | ||||
| 		if err != nil { | ||||
| 			log.Error("Wake On Host Save Error: ", err) | ||||
| 			return c.JSON(http.StatusInternalServerError, payload) | ||||
| 		} | ||||
| 
 | ||||
| 		return c.JSON(http.StatusOK, host) | ||||
| 	} | ||||
| } | ||||
|  |  | |||
							
								
								
									
										5
									
								
								main.go
								
								
								
								
							
							
						
						
									
										5
									
								
								main.go
								
								
								
								
							|  | @ -3,12 +3,11 @@ package main | |||
| import ( | ||||
| 	"flag" | ||||
| 	"fmt" | ||||
| 	"github.com/labstack/echo/v4" | ||||
| 	"net/http" | ||||
| 	"time" | ||||
| 
 | ||||
| 	rice "github.com/GeertJohan/go.rice" | ||||
| 	"github.com/labstack/echo/v4" | ||||
| 
 | ||||
| 	"github.com/ngoduykhanh/wireguard-ui/emailer" | ||||
| 	"github.com/ngoduykhanh/wireguard-ui/handler" | ||||
| 	"github.com/ngoduykhanh/wireguard-ui/router" | ||||
|  | @ -147,6 +146,8 @@ func main() { | |||
| 	app.GET("/api/machine-ips", handler.MachineIPAddresses(), handler.ValidSession) | ||||
| 	app.GET("/api/suggest-client-ips", handler.SuggestIPAllocation(db), handler.ValidSession) | ||||
| 	app.GET("/api/apply-wg-config", handler.ApplyServerConfig(db, tmplBox), handler.ValidSession) | ||||
| 	app.GET("/wake_on_lan_hosts", handler.GetWakeOnLanHosts(db), handler.ValidSession) | ||||
| 	app.POST("/wake_on_lan_host", handler.SaveWakeOnLanHost(db), handler.ValidSession) | ||||
| 
 | ||||
| 	// servers other static files
 | ||||
| 	app.GET("/static/*", echo.WrapHandler(http.StripPrefix("/static/", assetHandler))) | ||||
|  |  | |||
|  | @ -0,0 +1,24 @@ | |||
| package model | ||||
| 
 | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"strings" | ||||
| 	"time" | ||||
| ) | ||||
| 
 | ||||
| type WakeOnLanHost struct { | ||||
| 	MacAddress string     `json:"MacAddress"` | ||||
| 	Name       string     `json:"Name"` | ||||
| 	LatestUsed *time.Time `json:"LatestUsed"` | ||||
| } | ||||
| 
 | ||||
| func (host WakeOnLanHost) ResolveResourceName() (string, error) { | ||||
| 	resourceName := strings.Trim(host.MacAddress, " \t\r\n\000") | ||||
| 	if len(resourceName) == 0 { | ||||
| 		return "", errors.New("mac Address is Empty") | ||||
| 	} | ||||
| 	resourceName = strings.ToUpper(resourceName) | ||||
| 	return strings.ReplaceAll(resourceName, ":", "-"), nil | ||||
| } | ||||
| 
 | ||||
| const WakeOnLanHostCollectionName = "wake_on_lan_hosts" | ||||
|  | @ -79,6 +79,11 @@ func New(tmplBox *rice.Box, extraData map[string]string, secret []byte) *echo.Ec | |||
| 		log.Fatal(err) | ||||
| 	} | ||||
| 
 | ||||
| 	tmplWakeOnLanHostsString, err := tmplBox.String("wake_on_lan_hosts.html") | ||||
| 	if err != nil { | ||||
| 		log.Fatal(err) | ||||
| 	} | ||||
| 
 | ||||
| 	// create template list
 | ||||
| 	templates := make(map[string]*template.Template) | ||||
| 	templates["login.html"] = template.Must(template.New("login").Parse(tmplLoginString)) | ||||
|  | @ -86,6 +91,7 @@ func New(tmplBox *rice.Box, extraData map[string]string, secret []byte) *echo.Ec | |||
| 	templates["server.html"] = template.Must(template.New("server").Parse(tmplBaseString + tmplServerString)) | ||||
| 	templates["global_settings.html"] = template.Must(template.New("global_settings").Parse(tmplBaseString + tmplGlobalSettingsString)) | ||||
| 	templates["status.html"] = template.Must(template.New("status").Parse(tmplBaseString + tmplStatusString)) | ||||
| 	templates["wake_on_lan_hosts.html"] = template.Must(template.New("wake_on_lan_hosts").Parse(tmplBaseString + tmplWakeOnLanHostsString)) | ||||
| 
 | ||||
| 	e.Logger.SetLevel(log.DEBUG) | ||||
| 	e.Pre(middleware.RemoveTrailingSlash()) | ||||
|  |  | |||
|  | @ -38,10 +38,12 @@ func New(dbPath string) (*JsonDB, error) { | |||
| func (o *JsonDB) Init() error { | ||||
| 	var clientPath string = path.Join(o.dbPath, "clients") | ||||
| 	var serverPath string = path.Join(o.dbPath, "server") | ||||
| 	var wakeOnLanListPath string = path.Join(o.dbPath, model.WakeOnLanHostCollectionName) | ||||
| 	var serverInterfacePath string = path.Join(serverPath, "interfaces.json") | ||||
| 	var serverKeyPairPath string = path.Join(serverPath, "keypair.json") | ||||
| 	var globalSettingPath string = path.Join(serverPath, "global_settings.json") | ||||
| 	var userPath string = path.Join(serverPath, "users.json") | ||||
| 
 | ||||
| 	// create directories if they do not exist
 | ||||
| 	if _, err := os.Stat(clientPath); os.IsNotExist(err) { | ||||
| 		os.MkdirAll(clientPath, os.ModePerm) | ||||
|  | @ -99,6 +101,10 @@ func (o *JsonDB) Init() error { | |||
| 		o.conn.Write("server", "users", user) | ||||
| 	} | ||||
| 
 | ||||
| 	if _, err := os.Stat(wakeOnLanListPath); os.IsNotExist(err) { | ||||
| 		os.MkdirAll(wakeOnLanListPath, os.ModePerm) | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
|  | @ -221,3 +227,54 @@ func (o *JsonDB) SaveServerKeyPair(serverKeyPair model.ServerKeypair) error { | |||
| func (o *JsonDB) SaveGlobalSettings(globalSettings model.GlobalSetting) error { | ||||
| 	return o.conn.Write("server", "global_settings", globalSettings) | ||||
| } | ||||
| 
 | ||||
| func (o *JsonDB) GetWakeOnLanHosts() ([]model.WakeOnLanHost, error) { | ||||
| 	var hosts []model.WakeOnLanHost | ||||
| 
 | ||||
| 	// read all client json file in "hosts" directory
 | ||||
| 	records, err := o.conn.ReadAll(model.WakeOnLanHostCollectionName) | ||||
| 	if err != nil { | ||||
| 		return hosts, err | ||||
| 	} | ||||
| 
 | ||||
| 	// build the ClientData list
 | ||||
| 	for _, f := range records { | ||||
| 		host := model.WakeOnLanHost{} | ||||
| 
 | ||||
| 		// get client info
 | ||||
| 		if err := json.Unmarshal([]byte(f), &host); err != nil { | ||||
| 			return hosts, fmt.Errorf("cannot decode client json structure: %v", err) | ||||
| 		} | ||||
| 
 | ||||
| 		// create the list of hosts and their qrcode data
 | ||||
| 		hosts = append(hosts, host) | ||||
| 	} | ||||
| 
 | ||||
| 	return hosts, nil | ||||
| } | ||||
| 
 | ||||
| func (o *JsonDB) GetWakeOnLanHost(macAddress string) (*model.WakeOnLanHost, error) { | ||||
| 	host := &model.WakeOnLanHost{ | ||||
| 		MacAddress: macAddress, | ||||
| 	} | ||||
| 	resourceName, err := host.ResolveResourceName() | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	err = o.conn.Read(model.WakeOnLanHostCollectionName, resourceName, host) | ||||
| 	return host, err | ||||
| } | ||||
| 
 | ||||
| func (o *JsonDB) DeleteWakeOnHostLanHost(macAddress string) error { | ||||
| 	return o.conn.Delete(model.WakeOnLanHostCollectionName, macAddress) | ||||
| } | ||||
| 
 | ||||
| func (o *JsonDB) SaveWakeOnLanHost(host model.WakeOnLanHost) error { | ||||
| 	resourceName, err := host.ResolveResourceName() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	return o.conn.Write(model.WakeOnLanHostCollectionName, resourceName, host) | ||||
| } | ||||
|  |  | |||
|  | @ -16,4 +16,8 @@ type IStore interface { | |||
| 	SaveServerInterface(serverInterface model.ServerInterface) error | ||||
| 	SaveServerKeyPair(serverKeyPair model.ServerKeypair) error | ||||
| 	SaveGlobalSettings(globalSettings model.GlobalSetting) error | ||||
| 	GetWakeOnLanHosts() ([]model.WakeOnLanHost, error) | ||||
| 	GetWakeOnLanHost(macAddress string) (*model.WakeOnLanHost, error) | ||||
| 	DeleteWakeOnHostLanHost(macAddress string) error | ||||
| 	SaveWakeOnLanHost(host model.WakeOnLanHost) error | ||||
| } | ||||
|  |  | |||
|  | @ -128,6 +128,15 @@ | |||
|                                 </p> | ||||
|                             </a> | ||||
|                         </li> | ||||
|                         <li class="nav-item"> | ||||
|                             <a href="/wake_on_lan_hosts" class="nav-link {{if eq .baseData.Active "wake_on_lan_hosts" }}active{{end}}"> | ||||
|                                 <i class="nav-icon fas  fa-solid fa-power-off"></i> | ||||
| 
 | ||||
|                                 <p> | ||||
|                                     Wake On Lan Hosts | ||||
|                                 </p> | ||||
|                             </a> | ||||
|                         </li> | ||||
|                     </ul> | ||||
|                 </nav> | ||||
|                 <!-- /.sidebar-menu --> | ||||
|  |  | |||
|  | @ -0,0 +1,171 @@ | |||
| {{define "title"}} | ||||
| Wake On Lan Hosts | ||||
| {{end}} | ||||
| 
 | ||||
| {{define "top_css"}} | ||||
| {{end}} | ||||
| 
 | ||||
| {{define "username"}} | ||||
| {{ .username }} | ||||
| {{end}} | ||||
| 
 | ||||
| {{define "page_title"}} | ||||
| Wake On Lan Hosts | ||||
| {{end}} | ||||
| 
 | ||||
| {{define "page_content"}} | ||||
| 
 | ||||
| <div class="modal fade" id="modal_wake_on_lan_host"> | ||||
| <!--    MacAddress      string `json:"MacAddress"`--> | ||||
| <!--    Name            string `json:"Name"`--> | ||||
| <!--    LatestIPAddress string `json:"LatestIPAddress"`--> | ||||
|     <div class="modal-dialog"> | ||||
|         <div class="modal-content"> | ||||
|             <div class="modal-header"> | ||||
|                 <h4 class="modal-title">New Wake On Lan Host</h4> | ||||
|                 <button type="button" class="close" data-dismiss="modal" aria-label="Close"> | ||||
|                     <span aria-hidden="true">×</span> | ||||
|                 </button> | ||||
|             </div> | ||||
|             <form name="frm_wake_on_lan_host" id="frm_wake_on_lan_host"> | ||||
|                 <div class="modal-body"> | ||||
|                     <input type="hidden" id="frm_wake_on_lan_host_old_mac_address" name="old_mac_address"> | ||||
|                     <div class="form-group"> | ||||
|                         <label for="frm_wake_on_lan_host_name" class="control-label">Name</label> | ||||
|                         <input type="text" class="form-control" id="frm_wake_on_lan_host_name" name="name"> | ||||
|                     </div> | ||||
|                     <div class="form-group"> | ||||
|                         <label for="frm_wake_on_lan_host_mac_address" class="control-label">Mac Address</label> | ||||
|                         <input type="text" class="form-control" id="frm_wake_on_lan_host_mac_address" name="mac_address"> | ||||
|                     </div> | ||||
|                 </div> | ||||
|                 <div class="modal-footer justify-content-between"> | ||||
|                     <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button> | ||||
|                     <button type="submit" class="btn btn-primary">Submit</button> | ||||
|                 </div> | ||||
|             </form> | ||||
|         </div> | ||||
|         <!-- /.modal-content --> | ||||
|     </div> | ||||
| </div> | ||||
| 
 | ||||
| <section class="content"> | ||||
|     <div class="container-fluid"> | ||||
|         {{ if .error }} | ||||
|         <div class="alert alert-warning" role="alert">{{.error}}</div> | ||||
|         {{ end}} | ||||
| 
 | ||||
|         <div class="row"> | ||||
|             {{ range $idx, $host := .hosts }} | ||||
|             {{- /*gotype: github.com/ngoduykhanh/wireguard-ui/model.WakeOnLanHost*/ -}} | ||||
|             <div class="col-sm-4" id="{{.MacAddress}}"> | ||||
|                 <div class="info-box"> | ||||
|                     <div class="info-box-content"> | ||||
|                         <div class="btn-group"> | ||||
|                             <button type="button" class="btn btn-outline-success btn-sm" data-mac-address="{{ .MacAddress }}">Wake On</button> | ||||
|                             <button type="button" class="btn btn-outline-primary btn-sm btn_modify_wake_on_lan_host" data-toggle="modal" data-target="#modal_wake_on_lan_host" data-name="{{ .Name }}" data-mac-address="{{ .MacAddress }}">Edit</button> | ||||
|                             <button type="button" class="btn btn-outline-danger btn-sm" data-toggle="modal" data-target="#modal_remove_wake_on_lan_host" data-mac-address="{{ .MacAddress }}">Remove</button> | ||||
|                         </div> | ||||
|                         <hr> | ||||
|                         <span class="info-box-text"><i class="fas fa-address-card"></i> {{ .Name }}</span> | ||||
|                         <span class="info-box-text"><i class="fas fa-ethernet"></i> {{ .MacAddress }}</span> | ||||
|                         <span class="info-box-text"><i class="fas fa-ethernet"></i> | ||||
|                             {{ if .LatestUsed }} | ||||
|                                 {{ .LatestUsed }} | ||||
|                             {{ else }} | ||||
|                                 Unused | ||||
|                             {{ end }} | ||||
|                         </span> | ||||
|                     </div> | ||||
|                 </div> | ||||
|             </div> | ||||
|             {{ end }} | ||||
|         </div> | ||||
|     </div> | ||||
| </section> | ||||
| 
 | ||||
| {{end}} | ||||
| {{define "bottom_js"}} | ||||
|     <script> | ||||
|         jQuery(function ($) { | ||||
|             let newHostHtml = '<div class="col-sm-2 offset-md-4" style=" text-align: right;"><button style="" id="btn_new_wake_on_lan_host" type="button" class="btn btn-outline-primary btn-sm" data-toggle="modal" data-target="#modal_wake_on_lan_host"><i class="nav-icon fas fa-plus"></i> New Host</button></div>'; | ||||
|             $('h1').parents(".row").append(newHostHtml); | ||||
| 
 | ||||
|             // https://jqueryvalidation.org/ | ||||
|             let $modal = $("#modal_wake_on_lan_host"); | ||||
|             let $name = $('#frm_wake_on_lan_host_name'); | ||||
|             let $macAddress = $('#frm_wake_on_lan_host_mac_address'); | ||||
|             let $oldMacAddress = $('#frm_wake_on_lan_host_old_mac_address'); | ||||
| 
 | ||||
|             $('#btn_new_wake_on_lan_host').click(function() { | ||||
|                 alert(1); | ||||
|                 // FIXME modal 초기화 | ||||
|             }); | ||||
|             $('.btn_modify_wake_on_lan_host').each(function () { | ||||
|                 let $btn = $(this); | ||||
|                 $btn.click(function () { | ||||
|                    console.log($btn.data('mac-address'), $btn.data('name')); | ||||
|                     // FIXME MODAL Data데이터삽입 | ||||
|                 }); | ||||
|             }); | ||||
|             $modal.on('shown.bs.modal', function (e) {}); | ||||
| 
 | ||||
|             $("#frm_wake_on_lan_host").validate({ | ||||
|                 submitHandler: function() { | ||||
|                     let data = { | ||||
|                         name: $name.val(), | ||||
|                         mac_address: $macAddress.val(), | ||||
|                         old_mac_address: $oldMacAddress.val() | ||||
|                     }; | ||||
|                     $.ajax({ | ||||
|                         cache: false, | ||||
|                         method: 'POST', | ||||
|                         url: '/wake_on_lan_host', | ||||
|                         dataType: 'json', | ||||
|                         contentType: "application/json", | ||||
|                         data: JSON.stringify(data), | ||||
|                         success: function(response) { | ||||
|                             // FIXME 화면에 동적으로 추가 하는 코드 추가 | ||||
|                             $modal.modal('hide'); | ||||
|                             toastr.success('Wake on Lan Host Save successfully'); | ||||
|                         }, | ||||
|                         error: function(jqXHR, exception) { | ||||
|                             const responseJson = jQuery.parseJSON(jqXHR.responseText); | ||||
|                             toastr.error(responseJson['message']); | ||||
|                         } | ||||
|                     }); | ||||
| 
 | ||||
|                     return false; | ||||
|                 }, | ||||
|                 rules: { | ||||
|                     name: { | ||||
|                         required: true, | ||||
|                     }, | ||||
|                     mac_address: { | ||||
|                         required: true, | ||||
|                     } | ||||
|                 }, | ||||
|                 messages: { | ||||
|                     name: { | ||||
|                         required: "Please enter a name" | ||||
|                     }, | ||||
|                     mac_address: { | ||||
|                         required: "Please enter a Mac Address" | ||||
|                     } | ||||
|                 }, | ||||
|                 errorElement: 'span', | ||||
|                 errorPlacement: function (error, element) { | ||||
|                     error.addClass('invalid-feedback'); | ||||
|                     element.closest('.form-group').append(error); | ||||
|                 }, | ||||
|                 highlight: function (element, errorClass, validClass) { | ||||
|                     $(element).addClass('is-invalid'); | ||||
|                 }, | ||||
|                 unhighlight: function (element, errorClass, validClass) { | ||||
|                     $(element).removeClass('is-invalid'); | ||||
|                 } | ||||
|             }); | ||||
|         }); | ||||
| 
 | ||||
|     </script> | ||||
| {{end}} | ||||
		Loading…
	
		Reference in New Issue