From 227e51b9cfcd754b1dcd3bbfd1db2bb35d189be0 Mon Sep 17 00:00:00 2001 From: Alexander Sulfrian Date: Thu, 16 Feb 2023 17:06:45 +0100 Subject: [PATCH 01/23] SMTP: Support disabling encryption (#297) --- README.md | 2 +- emailer/smtp.go | 2 ++ main.go | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 598a994..a946f80 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,7 @@ Note: | `SMTP_USERNAME` | The SMTP username | N/A | | `SMTP_PASSWORD` | The SMTP user password | N/A | | `SMTP_AUTH_TYPE` | The SMTP authentication type. Possible values: `PLAIN`, `LOGIN`, `NONE` | `NONE` | -| `SMTP_ENCRYPTION` | the encryption method. Possible values: `SSL`, `SSLTLS`, `TLS`, `STARTTLS` | `STARTTLS` | +| `SMTP_ENCRYPTION` | the encryption method. Possible values: `NONE`, `SSL`, `SSLTLS`, `TLS`, `STARTTLS` | `STARTTLS` | ### Defaults for server configuration diff --git a/emailer/smtp.go b/emailer/smtp.go index d1fdbae..f77db7c 100644 --- a/emailer/smtp.go +++ b/emailer/smtp.go @@ -33,6 +33,8 @@ func authType(authType string) mail.AuthType { func encryptionType(encryptionType string) mail.Encryption { switch strings.ToUpper(encryptionType) { + case "NONE": + return mail.EncryptionNone case "SSL": return mail.EncryptionSSL case "SSLTLS": diff --git a/main.go b/main.go index 3f0cd13..98a0e7c 100644 --- a/main.go +++ b/main.go @@ -61,7 +61,7 @@ func init() { flag.StringVar(&flagSmtpUsername, "smtp-username", util.LookupEnvOrString("SMTP_USERNAME", flagSmtpUsername), "SMTP Username") flag.StringVar(&flagSmtpPassword, "smtp-password", util.LookupEnvOrString("SMTP_PASSWORD", flagSmtpPassword), "SMTP Password") flag.BoolVar(&flagSmtpNoTLSCheck, "smtp-no-tls-check", util.LookupEnvOrBool("SMTP_NO_TLS_CHECK", flagSmtpNoTLSCheck), "Disable TLS verification for SMTP. This is potentially dangerous.") - flag.StringVar(&flagSmtpEncryption, "smtp-encryption", util.LookupEnvOrString("SMTP_ENCRYPTION", flagSmtpEncryption), "SMTP Encryption : SSL, SSLTLS, TLS or STARTTLS (by default)") + flag.StringVar(&flagSmtpEncryption, "smtp-encryption", util.LookupEnvOrString("SMTP_ENCRYPTION", flagSmtpEncryption), "SMTP Encryption : NONE, SSL, SSLTLS, TLS or STARTTLS (by default)") flag.StringVar(&flagSmtpAuthType, "smtp-auth-type", util.LookupEnvOrString("SMTP_AUTH_TYPE", flagSmtpAuthType), "SMTP Auth Type : PLAIN, LOGIN or NONE.") flag.StringVar(&flagSendgridApiKey, "sendgrid-api-key", util.LookupEnvOrString("SENDGRID_API_KEY", flagSendgridApiKey), "Your sendgrid api key.") flag.StringVar(&flagEmailFrom, "email-from", util.LookupEnvOrString("EMAIL_FROM_ADDRESS", flagEmailFrom), "'From' email address.") From ccffe4028aa84f2c2ce9d4e97f2711f2060fe638 Mon Sep 17 00:00:00 2001 From: Arminas Date: Thu, 16 Feb 2023 18:08:26 +0200 Subject: [PATCH 02/23] Qr code filename fix (#290) --- templates/clients.html | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/templates/clients.html b/templates/clients.html index 689c261..04fb790 100644 --- a/templates/clients.html +++ b/templates/clients.html @@ -70,7 +70,9 @@ Wireguard Clients @@ -490,9 +481,7 @@ Wireguard Clients cache: false, method: 'GET', url: '{{.basePath}}/api/client/' + client_id, - data: { - qrCodeIncludeFwMark: include_fwmark - }, + data: JSON.stringify(data), dataType: 'json', contentType: "application/json", success: function (resp) { diff --git a/templates/global_settings.html b/templates/global_settings.html index 8a41d1f..15d7b4b 100644 --- a/templates/global_settings.html +++ b/templates/global_settings.html @@ -56,10 +56,10 @@ Global Settings value="{{if .globalSettings.PersistentKeepalive }}{{ .globalSettings.PersistentKeepalive }}{{end}}">
- - + +
@@ -100,8 +100,8 @@ Global Settings until they reach out to other peers themselves. Adding PersistentKeepalive can ensure that the connection remains open.
Leave blank to omit this setting in the Client config.
-
5. Forward Mark
-
Set an fwmark on all packets going out of WireGuard's UDP socket. Default value: 0xca6c
+
5. Firewall Mark
+
Add a matching fwmark on all packets going out of a WireGuard non-default-route tunnel. Default value: 0xca6c
6. Wireguard Config File Path
The path of your Wireguard server config file. Please make sure the parent directory exists and is writable.
@@ -149,9 +149,9 @@ Global Settings const dns_servers = $("#dns_servers").val().split(","); const mtu = $("#mtu").val(); const persistent_keepalive = $("#persistent_keepalive").val(); - const forward_mark = $("#forward_mark").val(); + const firewall_mark = $("#firewall_mark").val(); const config_file_path = $("#config_file_path").val(); - const data = {"endpoint_address": endpoint_address, "dns_servers": dns_servers, "mtu": mtu, "persistent_keepalive": persistent_keepalive, "forward_mark": forward_mark, "config_file_path": config_file_path}; + const data = {"endpoint_address": endpoint_address, "dns_servers": dns_servers, "mtu": mtu, "persistent_keepalive": persistent_keepalive, "firewall_mark": firewall_mark, "config_file_path": config_file_path}; $.ajax({ cache: false, @@ -222,7 +222,7 @@ Global Settings config_file_path: { required: true }, - forward_mark: { + firewall_mark: { required: false } }, diff --git a/util/config.go b/util/config.go index 018690f..7a95f97 100644 --- a/util/config.go +++ b/util/config.go @@ -30,7 +30,7 @@ const ( DefaultDNS = "1.1.1.1" DefaultMTU = 1450 DefaultPersistentKeepalive = 15 - DefaultForwardMark = "0xca6c" + DefaultFirewallMark = "0xca6c" // i.e. 51820 DefaultConfigFilePath = "/etc/wireguard/wg0.conf" UsernameEnvVar = "WGUI_USERNAME" PasswordEnvVar = "WGUI_PASSWORD" @@ -40,7 +40,7 @@ const ( DNSEnvVar = "WGUI_DNS" MTUEnvVar = "WGUI_MTU" PersistentKeepaliveEnvVar = "WGUI_PERSISTENT_KEEPALIVE" - ForwardMarkEnvVar = "WGUI_FORWARD_MARK" + FirewallMarkEnvVar = "WGUI_FIREWALL_MARK" ConfigFilePathEnvVar = "WGUI_CONFIG_FILE_PATH" LogLevel = "WGUI_LOG_LEVEL" ServerAddressesEnvVar = "WGUI_SERVER_INTERFACE_ADDRESSES" diff --git a/util/util.go b/util/util.go index 44f357b..04950f9 100644 --- a/util/util.go +++ b/util/util.go @@ -65,18 +65,12 @@ func BuildClientConfig(client model.Client, server model.Server, setting model.G peerPersistentKeepalive = fmt.Sprintf("PersistentKeepalive = %d\n", setting.PersistentKeepalive) } - forwardMark := "" - if setting.ForwardMark != "" { - forwardMark = fmt.Sprintf("FwMark = %s\n", setting.ForwardMark) - } - // build the config as string strConfig := "[Interface]\n" + clientAddress + clientPrivateKey + clientDNS + clientMTU + - forwardMark + "\n[Peer]\n" + peerPublicKey + peerPresharedKey + From 814093cdd32863dc3b5becfc0ae8de6cd0eec982 Mon Sep 17 00:00:00 2001 From: Paul Dee Date: Wed, 15 Mar 2023 21:39:20 +0100 Subject: [PATCH 15/23] Stamp git commit into docker builds. (#325) --- Dockerfile | 3 ++- README.md | 8 +++++++- main.go | 1 + templates/about.html | 6 ++++++ 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index a30cefe..e4d5525 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,6 +4,7 @@ LABEL maintainer="Khanh Ngo Current version
+{{ if .gitCommit }} +
+ + +
+{{ end }}
From abef29bf172482305f940dba7e1519037e05172f Mon Sep 17 00:00:00 2001 From: Matze <37954743+Matze1224@users.noreply.github.com> Date: Wed, 15 Mar 2023 21:41:46 +0100 Subject: [PATCH 16/23] better error-handling if no public IP could be detected (#323) --- README.md | 5 +++-- util/util.go | 6 ++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index eaa18c3..7eca337 100644 --- a/README.md +++ b/README.md @@ -43,14 +43,15 @@ docker-compose up | `WGUI_USERNAME` | The username for the login page. Used for db initialization only | `admin` | | `WGUI_PASSWORD` | The password for the user on the login page. Will be hashed automatically. Used for db initialization only | `admin` | | `WGUI_PASSWORD_HASH` | The password hash for the user on the login page. (alternative to `WGUI_PASSWORD`). Used for db initialization only | N/A | +| `WGUI_ENDPOINT_ADDRESS` | The default endpoint address used in global settings where clients should connect to | Resolved to your public ip address | | `WGUI_FAVICON_FILE_PATH` | The file path used as website favicon | Embedded WireGuard logo | | `WGUI_ENDPOINT_ADDRESS` | The default endpoint address used in global settings | Resolved to your public ip address | | `WGUI_DNS` | The default DNS servers (comma-separated-list) used in the global settings | `1.1.1.1` | | `WGUI_MTU` | The default MTU used in global settings | `1450` | | `WGUI_PERSISTENT_KEEPALIVE` | The default persistent keepalive for WireGuard in global settings | `15` | -| `WGUI_FIREWALL_MARK` | The default WireGuard firewall mark | `0xca6c` (51820) | +| `WGUI_FIREWALL_MARK` | The default WireGuard firewall mark | `0xca6c` (51820) | | `WGUI_CONFIG_FILE_PATH` | The default WireGuard config file path used in global settings | `/etc/wireguard/wg0.conf` | -| `WGUI_LOG_LEVEL` | The default log level. Possible values: `DEBUG`, `INFO`, `WARN`, `ERROR`, `OFF` | `INFO` | | +| `WGUI_LOG_LEVEL` | The default log level. Possible values: `DEBUG`, `INFO`, `WARN`, `ERROR`, `OFF` | `INFO` | | `WG_CONF_TEMPLATE` | The custom `wg.conf` config file template. Please refer to our [default template](https://github.com/ngoduykhanh/wireguard-ui/blob/master/templates/wg.conf) | N/A | | `EMAIL_FROM_ADDRESS` | The sender email address | N/A | | `EMAIL_FROM_NAME` | The sender name | `WireGuard UI` | diff --git a/util/util.go b/util/util.go index 04950f9..35568da 100644 --- a/util/util.go +++ b/util/util.go @@ -220,10 +220,12 @@ func GetPublicIP() (model.Interface, error) { ip, err := consensus.ExternalIP() if err != nil { publicInterface.IPAddress = "N/A" + } else { + publicInterface.IPAddress = ip.String() } - publicInterface.IPAddress = ip.String() - return publicInterface, err + // error handling happend above, no need to pass it through + return publicInterface, nil } // GetIPFromCIDR get ip from CIDR From c8240fe15791d375f5f3441c47cc67cf1d9c856b Mon Sep 17 00:00:00 2001 From: Arminas Date: Wed, 15 Mar 2023 22:45:46 +0200 Subject: [PATCH 17/23] fixed about page not showing menu items (#343) --- handler/routes.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/handler/routes.go b/handler/routes.go index 4f76d22..96be22d 100644 --- a/handler/routes.go +++ b/handler/routes.go @@ -1012,7 +1012,7 @@ func GetHashesChanges(db store.IStore) echo.HandlerFunc { func AboutPage() echo.HandlerFunc { return func(c echo.Context) error { return c.Render(http.StatusOK, "about.html", map[string]interface{}{ - "baseData": model.BaseData{Active: "about", CurrentUser: currentUser(c)}, + "baseData": model.BaseData{Active: "about", CurrentUser: currentUser(c), Admin: isAdmin(c)}, }) } } From e3e363944344ac667f384d8e8bd50df2942eea9b Mon Sep 17 00:00:00 2001 From: Khanh Ngo Date: Wed, 15 Mar 2023 21:50:46 +0100 Subject: [PATCH 18/23] Bracket fixes --- util/util.go | 1 + 1 file changed, 1 insertion(+) diff --git a/util/util.go b/util/util.go index 35568da..b62752d 100644 --- a/util/util.go +++ b/util/util.go @@ -480,6 +480,7 @@ func ParseLogLevel(lvl string) (log.Lvl, error) { default: return log.DEBUG, fmt.Errorf("not a valid log level: %s", lvl) } +} // GetCurrentHash returns current hashes func GetCurrentHash(db store.IStore) (string, string) { From 4fc52b62d21614325d61cc1787dd95bacec9841c Mon Sep 17 00:00:00 2001 From: ByteDream <63594396+ByteDream@users.noreply.github.com> Date: Thu, 16 Mar 2023 08:40:04 +0100 Subject: [PATCH 19/23] Replace go.rice with native go embedding (#331) --- .github/workflows/release.yml | 10 +-------- .gitignore | 1 - Dockerfile | 7 +------ README.md | 11 +--------- go.mod | 3 +-- go.sum | 9 --------- handler/routes.go | 9 ++++----- main.go | 38 +++++++++++++++++++++++------------ router/router.go | 24 +++++++++++----------- util/util.go | 18 ++++++++++++++--- 10 files changed, 60 insertions(+), 70 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8907d06..feb4c93 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -40,20 +40,12 @@ jobs: node-version: '14' registry-url: 'https://registry.npmjs.org' - # prepare assets for go rice + # prepare assets - name: Prepare assets run: | chmod +x ./prepare_assets.sh ./prepare_assets.sh - # get go rice tool - - name: Get go rice tool - run: go get github.com/GeertJohan/go.rice/rice - - # run go rice embed - - name: Run go rice embed - run: ${HOME}/go/bin/rice embed-go - # build and make the releases - name: Build and make the releases uses: wangyoucao577/go-release-action@master diff --git a/.gitignore b/.gitignore index b8e3cf3..f1e3f44 100644 --- a/.gitignore +++ b/.gitignore @@ -16,7 +16,6 @@ wireguard-ui vendor/ assets/ node_modules/ -rice-box.go # IDEs .vscode diff --git a/Dockerfile b/Dockerfile index e4d5525..e42603b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -43,10 +43,6 @@ RUN mkdir -p assets/plugins && \ /build/node_modules/jquery-tags-input/ \ assets/plugins/ -# Get go modules and build tool -RUN go mod download && \ - go get github.com/GeertJohan/go.rice/rice - # Add sources COPY . /build @@ -54,8 +50,7 @@ COPY . /build RUN cp -r /build/custom/ assets/ # Build -RUN rice embed-go && \ - CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -ldflags="-X main.gitCommit=${COMMIT}" -a -o wg-ui . +RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -ldflags="-X main.gitCommit=${COMMIT}" -a -o wg-ui . # Release stage FROM alpine:3.16 diff --git a/README.md b/README.md index 7eca337..7fc3207 100644 --- a/README.md +++ b/README.md @@ -211,18 +211,9 @@ Prepare the assets directory ./prepare_assets.sh ``` -Then you can embed resources by generating Go source code - -```sh -rice embed-go -go build -o wireguard-ui -``` - -Or, append resources to executable as zip file - +Then build your executable ```sh go build -o wireguard-ui -rice append --exec wireguard-ui ``` ## License diff --git a/go.mod b/go.mod index d7c4a16..5842acb 100644 --- a/go.mod +++ b/go.mod @@ -1,9 +1,8 @@ module github.com/ngoduykhanh/wireguard-ui -go 1.14 +go 1.16 require ( - github.com/GeertJohan/go.rice v1.0.2 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 diff --git a/go.sum b/go.sum index 814f123..ee957cb 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,4 @@ -github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0= -github.com/GeertJohan/go.rice v1.0.2 h1:PtRw+Tg3oa3HYwiDBZyvOJ8LdIyf6lAovJJtr7YOAYk= -github.com/GeertJohan/go.rice v1.0.2/go.mod h1:af5vUNlDNkCjOZeSGFgIJxDje9qdjsO6hshx0gTmZt4= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/appleboy/gofight/v2 v2.1.2/go.mod h1:frW+U1QZEdDgixycTj4CygQ48yLTUhplt43+Wczp3rw= @@ -12,8 +8,6 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r github.com/casbin/casbin/v2 v2.0.0/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/coreos/bbolt v1.3.1-coreos.6.0.20180223184059-4f5275f4ebbf/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= -github.com/daaku/go.zipexe v1.0.0 h1:VSOgZtH418pH9L16hC/JrgSNJbbAL26pj7lmD1+CGdY= -github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -52,7 +46,6 @@ github.com/gorilla/sessions v1.2.0/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/z github.com/jcelliott/lumber v0.0.0-20160324203708-dd349441af25 h1:EFT6MH3igZK/dIVqgGbTqWVvkZ7wJ5iGN03SVtvvdd8= github.com/jcelliott/lumber v0.0.0-20160324203708-dd349441af25/go.mod h1:sWkGw/wsaHtRsT9zGQ/WyJCotGWG/Anow/9hsAcBWRw= github.com/jessevdk/go-flags v0.0.0-20150816100521-1acbbaff2f34/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/josharian/native v0.0.0-20200817173448-b6b71def0850 h1:uhL5Gw7BINiiPAo24A2sxkcDI0Jt/sqp1v5xQCniEFA= github.com/josharian/native v0.0.0-20200817173448-b6b71def0850/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w= github.com/jsimonetti/rtnetlink v0.0.0-20190606172950-9527aa82566a/go.mod h1:Oz+70psSo5OFh8DBl0Zv2ACw7Esh6pPUphlvZG9x7uw= @@ -109,7 +102,6 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nkovacs/streamquote v1.0.0/go.mod h1:BN+NaZ2CmdKqUuTUXUEm9j95B2TRbpOWpxbJYzzgUsc= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -252,7 +244,6 @@ golang.zx2c4.com/wireguard v0.0.0-20210427022245-097af6e1351b/go.mod h1:a057zjmo 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= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= diff --git a/handler/routes.go b/handler/routes.go index 96be22d..d43d75f 100644 --- a/handler/routes.go +++ b/handler/routes.go @@ -5,13 +5,13 @@ import ( "encoding/base64" "encoding/json" "fmt" + "io/fs" "net/http" "os" "sort" "strings" "time" - rice "github.com/GeertJohan/go.rice" "github.com/gorilla/sessions" "github.com/labstack/echo-contrib/session" "github.com/labstack/echo/v4" @@ -948,7 +948,7 @@ func SuggestIPAllocation(db store.IStore) echo.HandlerFunc { } // ApplyServerConfig handler to write config file and restart Wireguard server -func ApplyServerConfig(db store.IStore, tmplBox *rice.Box) echo.HandlerFunc { +func ApplyServerConfig(db store.IStore, tmplDir fs.FS) echo.HandlerFunc { return func(c echo.Context) error { server, err := db.GetServer() @@ -976,14 +976,14 @@ func ApplyServerConfig(db store.IStore, tmplBox *rice.Box) echo.HandlerFunc { } // Write config file - err = util.WriteWireGuardServerConfig(tmplBox, server, clients, users, settings) + err = util.WriteWireGuardServerConfig(tmplDir, server, clients, users, settings) if err != nil { log.Error("Cannot apply server config: ", err) return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{ false, fmt.Sprintf("Cannot apply server config: %v", err), }) } - + err = util.UpdateHashes(db) if err != nil { log.Error("Cannot update hashes: ", err) @@ -1016,4 +1016,3 @@ func AboutPage() echo.HandlerFunc { }) } } - diff --git a/main.go b/main.go index ccd163a..2fb2d03 100644 --- a/main.go +++ b/main.go @@ -1,16 +1,17 @@ package main import ( + "embed" "flag" "fmt" "github.com/labstack/echo/v4" "github.com/labstack/gommon/log" "github.com/ngoduykhanh/wireguard-ui/store" + "io/fs" "net/http" "os" "time" - rice "github.com/GeertJohan/go.rice" "github.com/ngoduykhanh/wireguard-ui/emailer" "github.com/ngoduykhanh/wireguard-ui/handler" "github.com/ngoduykhanh/wireguard-ui/router" @@ -51,6 +52,16 @@ const ( ` ) +// embed the "templates" directory +// +//go:embed templates/* +var embeddedTemplates embed.FS + +// embed the "assets" directory +// +//go:embed assets/* +var embeddedAssets embed.FS + func init() { // command-line flags and env variables @@ -122,17 +133,15 @@ func main() { extraData["gitCommit"] = gitCommit extraData["basePath"] = util.BasePath - // create rice box for embedded template - tmplBox := rice.MustFindBox("templates") - - // rice file server for assets. "assets" is the folder where the files come from. - assetHandler := http.FileServer(rice.MustFindBox("assets").HTTPBox()) + // strip the "templates/" prefix from the embedded directory so files can be read by their direct name (e.g. + // "base.html" instead of "templates/base.html") + tmplDir, _ := fs.Sub(fs.FS(embeddedTemplates), "templates") // create the wireguard config on start, if it doesn't exist - initServerConfig(db, tmplBox) + initServerConfig(db, tmplDir) // register routes - app := router.New(tmplBox, extraData, util.SessionSecret) + app := router.New(tmplDir, extraData, util.SessionSecret) app.GET(util.BasePath, handler.WireGuardClients(db), handler.ValidSession) @@ -170,26 +179,29 @@ func main() { app.POST(util.BasePath+"/wg-server/interfaces", handler.WireGuardServerInterfaces(db), handler.ValidSession, handler.ContentTypeJson, handler.NeedsAdmin) app.POST(util.BasePath+"/wg-server/keypair", handler.WireGuardServerKeyPair(db), handler.ValidSession, handler.ContentTypeJson, handler.NeedsAdmin) app.GET(util.BasePath+"/global-settings", handler.GlobalSettings(db), handler.ValidSession, handler.NeedsAdmin) - app.POST(util.BasePath+"/global-settings", handler.GlobalSettingSubmit(db), handler.ValidSession, handler.ContentTypeJson, handler.NeedsAdmin) app.GET(util.BasePath+"/status", handler.Status(db), handler.ValidSession) app.GET(util.BasePath+"/api/clients", handler.GetClients(db), handler.ValidSession) app.GET(util.BasePath+"/api/client/:id", handler.GetClient(db), handler.ValidSession) app.GET(util.BasePath+"/api/machine-ips", handler.MachineIPAddresses(), handler.ValidSession) app.GET(util.BasePath+"/api/suggest-client-ips", handler.SuggestIPAllocation(db), handler.ValidSession) - app.POST(util.BasePath+"/api/apply-wg-config", handler.ApplyServerConfig(db, tmplBox), handler.ValidSession, handler.ContentTypeJson) + app.POST(util.BasePath+"/api/apply-wg-config", handler.ApplyServerConfig(db, tmplDir), handler.ValidSession, handler.ContentTypeJson) app.GET(util.BasePath+"/wake_on_lan_hosts", handler.GetWakeOnLanHosts(db), handler.ValidSession) app.POST(util.BasePath+"/wake_on_lan_host", handler.SaveWakeOnLanHost(db), handler.ValidSession, handler.ContentTypeJson) app.DELETE(util.BasePath+"/wake_on_lan_host/:mac_address", handler.DeleteWakeOnHost(db), handler.ValidSession, handler.ContentTypeJson) app.PUT(util.BasePath+"/wake_on_lan_host/:mac_address", handler.WakeOnHost(db), handler.ValidSession, handler.ContentTypeJson) - // servers other static files + // strip the "assets/" prefix from the embedded directory so files can be called directly without the "assets/" + // prefix + assetsDir, _ := fs.Sub(fs.FS(embeddedAssets), "assets") + assetHandler := http.FileServer(http.FS(assetsDir)) + // serves other static files app.GET(util.BasePath+"/static/*", echo.WrapHandler(http.StripPrefix(util.BasePath+"/static/", assetHandler))) app.Logger.Fatal(app.Start(util.BindAddress)) } -func initServerConfig(db store.IStore, tmplBox *rice.Box) { +func initServerConfig(db store.IStore, tmplDir fs.FS) { settings, err := db.GetGlobalSettings() if err != nil { log.Fatalf("Cannot get global settings: ", err) @@ -216,7 +228,7 @@ func initServerConfig(db store.IStore, tmplBox *rice.Box) { } // write config file - err = util.WriteWireGuardServerConfig(tmplBox, server, clients, users, settings) + err = util.WriteWireGuardServerConfig(tmplDir, server, clients, users, settings) if err != nil { log.Fatalf("Cannot create server config: ", err) } diff --git a/router/router.go b/router/router.go index cdc6424..c2d1943 100644 --- a/router/router.go +++ b/router/router.go @@ -3,11 +3,11 @@ package router import ( "errors" "io" + "io/fs" "reflect" "strings" "text/template" - rice "github.com/GeertJohan/go.rice" "github.com/gorilla/sessions" "github.com/labstack/echo-contrib/session" "github.com/labstack/echo/v4" @@ -48,57 +48,57 @@ func (t *TemplateRegistry) Render(w io.Writer, name string, data interface{}, c } // New function -func New(tmplBox *rice.Box, extraData map[string]string, secret []byte) *echo.Echo { +func New(tmplDir fs.FS, extraData map[string]string, secret []byte) *echo.Echo { e := echo.New() e.Use(session.Middleware(sessions.NewCookieStore(secret))) // read html template file to string - tmplBaseString, err := tmplBox.String("base.html") + tmplBaseString, err := util.StringFromEmbedFile(tmplDir, "base.html") if err != nil { log.Fatal(err) } - tmplLoginString, err := tmplBox.String("login.html") + tmplLoginString, err := util.StringFromEmbedFile(tmplDir, "login.html") if err != nil { log.Fatal(err) } - tmplProfileString, err := tmplBox.String("profile.html") + tmplProfileString, err := util.StringFromEmbedFile(tmplDir, "profile.html") if err != nil { log.Fatal(err) } - tmplClientsString, err := tmplBox.String("clients.html") + tmplClientsString, err := util.StringFromEmbedFile(tmplDir, "clients.html") if err != nil { log.Fatal(err) } - tmplServerString, err := tmplBox.String("server.html") + tmplServerString, err := util.StringFromEmbedFile(tmplDir, "server.html") if err != nil { log.Fatal(err) } - tmplGlobalSettingsString, err := tmplBox.String("global_settings.html") + tmplGlobalSettingsString, err := util.StringFromEmbedFile(tmplDir, "global_settings.html") if err != nil { log.Fatal(err) } - tmplUsersSettingsString, err := tmplBox.String("users_settings.html") + tmplUsersSettingsString, err := util.StringFromEmbedFile(tmplDir, "users_settings.html") if err != nil { log.Fatal(err) } - tmplStatusString, err := tmplBox.String("status.html") + tmplStatusString, err := util.StringFromEmbedFile(tmplDir, "status.html") if err != nil { log.Fatal(err) } - tmplWakeOnLanHostsString, err := tmplBox.String("wake_on_lan_hosts.html") + tmplWakeOnLanHostsString, err := util.StringFromEmbedFile(tmplDir, "wake_on_lan_hosts.html") if err != nil { log.Fatal(err) } - aboutPageString, err := tmplBox.String("about.html") + aboutPageString, err := util.StringFromEmbedFile(tmplDir, "about.html") if err != nil { log.Fatal(err) } diff --git a/util/util.go b/util/util.go index b62752d..7b93a57 100644 --- a/util/util.go +++ b/util/util.go @@ -7,6 +7,7 @@ import ( "github.com/ngoduykhanh/wireguard-ui/store" "golang.org/x/mod/sumdb/dirhash" "io" + "io/fs" "io/ioutil" "net" "os" @@ -17,7 +18,6 @@ import ( "text/template" "time" - rice "github.com/GeertJohan/go.rice" externalip "github.com/glendc/go-external-ip" "github.com/labstack/gommon/log" "github.com/ngoduykhanh/wireguard-ui/model" @@ -382,7 +382,7 @@ func ValidateIPAllocation(serverAddresses []string, ipAllocatedList []string, ip } // WriteWireGuardServerConfig to write Wireguard server config. e.g. wg0.conf -func WriteWireGuardServerConfig(tmplBox *rice.Box, serverConfig model.Server, clientDataList []model.ClientData, usersList []model.User, globalSettings model.GlobalSetting) error { +func WriteWireGuardServerConfig(tmplDir fs.FS, serverConfig model.Server, clientDataList []model.ClientData, usersList []model.User, globalSettings model.GlobalSetting) error { var tmplWireguardConf string // if set, read wg.conf template from WgConfTemplate @@ -394,7 +394,7 @@ func WriteWireGuardServerConfig(tmplBox *rice.Box, serverConfig model.Server, cl tmplWireguardConf = string(fileContentBytes) } else { // read default wg.conf template file to string - fileContent, err := tmplBox.String("wg.conf") + fileContent, err := StringFromEmbedFile(tmplDir, "wg.conf") if err != nil { return err } @@ -465,6 +465,18 @@ func LookupEnvOrStrings(key string, defaultVal []string) []string { return defaultVal } +func StringFromEmbedFile(embed fs.FS, filename string) (string, error) { + file, err := embed.Open(filename) + if err != nil { + return "", err + } + content, err := io.ReadAll(file) + if err != nil { + return "", err + } + return string(content), nil +} + func ParseLogLevel(lvl string) (log.Lvl, error) { switch strings.ToLower(lvl) { case "debug": From 00f7f3d280b90fdaa15faf48379d509b1b37e135 Mon Sep 17 00:00:00 2001 From: Khanh Ngo Date: Thu, 16 Mar 2023 08:58:28 +0100 Subject: [PATCH 20/23] Style fixes --- templates/base.html | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/templates/base.html b/templates/base.html index 6c2e3f3..181049d 100644 --- a/templates/base.html +++ b/templates/base.html @@ -56,13 +56,15 @@
- +
+ +
From d3c47c53c8460b108ac1a0833f77cc0a3dcce33a Mon Sep 17 00:00:00 2001 From: Khanh Ngo Date: Thu, 16 Mar 2023 09:09:48 +0100 Subject: [PATCH 21/23] QR code fixes --- templates/clients.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/templates/clients.html b/templates/clients.html index 513797c..0fa98f7 100644 --- a/templates/clients.html +++ b/templates/clients.html @@ -481,7 +481,9 @@ Wireguard Clients cache: false, method: 'GET', url: '{{.basePath}}/api/client/' + client_id, - data: JSON.stringify(data), + data: { + qrCodeIncludeFwMark: include_fwmark + }, dataType: 'json', contentType: "application/json", success: function (resp) { From 5e0217db049ae0adc8947fa796f9614301603fd6 Mon Sep 17 00:00:00 2001 From: Khanh Ngo Date: Thu, 16 Mar 2023 16:25:38 +0100 Subject: [PATCH 22/23] Set password type field --- templates/users_settings.html | 2 +- util/util.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/templates/users_settings.html b/templates/users_settings.html index 05d8878..6fb8d69 100644 --- a/templates/users_settings.html +++ b/templates/users_settings.html @@ -42,7 +42,7 @@ Users Settings
-
diff --git a/util/util.go b/util/util.go index 7b93a57..4d4b9b3 100644 --- a/util/util.go +++ b/util/util.go @@ -514,11 +514,11 @@ func HashesChanged(db store.IStore) bool { newClient, newServer := GetCurrentHash(db) if oldClient != newClient { - fmt.Println("Hash for client differs") + //fmt.Println("Hash for client differs") return true } if oldServer != newServer { - fmt.Println("Hash for server differs") + //fmt.Println("Hash for server differs") return true } return false From ac99317ba3ff35eb169b6acc561ecf6f674f4062 Mon Sep 17 00:00:00 2001 From: Khanh Ngo Date: Fri, 17 Mar 2023 09:53:57 +0100 Subject: [PATCH 23/23] Update README.md --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 7fc3207..62eef0d 100644 --- a/README.md +++ b/README.md @@ -203,6 +203,11 @@ or docker compose build --build-arg=COMMIT=$(git rev-parse --short HEAD) ``` +:information_source: A container image is avaialble on [Docker Hub](https://hub.docker.com/r/ngoduykhanh/wireguard-ui) which you can pull and use +``` +docker pull ngoduykhanh/wireguard-ui +```` + ### Build binary file Prepare the assets directory