From 9dca2b736190326c749cefd58af06f90d7b23738 Mon Sep 17 00:00:00 2001 From: Khanh Ngo Date: Fri, 9 Oct 2020 23:33:29 +0200 Subject: [PATCH] Login disable (#35) Add ability to disable authentication --- handler/routes.go | 41 +++++++++++++++++++++++++++-------------- handler/session.go | 22 ++++++++++++---------- main.go | 45 ++++++++++++++++++++++++++++++++------------- model/client.go | 2 +- model/misc.go | 3 ++- templates/base.html | 6 ++++-- util/config.go | 6 ++++++ 7 files changed, 84 insertions(+), 41 deletions(-) create mode 100644 util/config.go diff --git a/handler/routes.go b/handler/routes.go index 5164fd6..28bc576 100644 --- a/handler/routes.go +++ b/handler/routes.go @@ -3,11 +3,12 @@ package handler import ( "encoding/json" "fmt" - rice "github.com/GeertJohan/go.rice" "net/http" "strings" "time" + rice "github.com/GeertJohan/go.rice" + "github.com/gorilla/sessions" "github.com/labstack/echo-contrib/session" "github.com/labstack/echo/v4" @@ -81,12 +82,13 @@ func WireGuardClients() echo.HandlerFunc { clientDataList, err := util.GetClients(true) if err != nil { - return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, fmt.Sprintf("Cannot get client list: %v", err)}) + return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{ + false, fmt.Sprintf("Cannot get client list: %v", err), + }) } return c.Render(http.StatusOK, "clients.html", map[string]interface{}{ - "baseData": model.BaseData{Active: ""}, - "username": currentUser(c), + "baseData": model.BaseData{Active: "", CurrentUser: currentUser(c)}, "clientDataList": clientDataList, }) } @@ -100,7 +102,9 @@ func GetClients() echo.HandlerFunc { clientDataList, err := util.GetClients(true) if err != nil { - return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, fmt.Sprintf("Cannot get client list: %v", err)}) + return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{ + false, fmt.Sprintf("Cannot get client list: %v", err), + }) } return c.JSON(http.StatusOK, clientDataList) @@ -171,7 +175,9 @@ func NewClient() echo.HandlerFunc { presharedKey, err := wgtypes.GenerateKey() if err != nil { log.Error("Cannot generated preshared key: ", err) - return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot generate Wireguard preshared key"}) + return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{ + false, "Cannot generate Wireguard preshared key", + }) } client.PrivateKey = key.String() @@ -213,7 +219,9 @@ func UpdateClient() echo.HandlerFunc { serverInterface := model.ServerInterface{} if err := db.Read("server", "interfaces", &serverInterface); err != nil { log.Error("Cannot fetch server interface config from database: ", err) - return c.JSON(http.StatusBadRequest, jsonHTTPResponse{false, fmt.Sprintf("Cannot fetch server config: %s", err)}) + return c.JSON(http.StatusBadRequest, jsonHTTPResponse{ + false, fmt.Sprintf("Cannot fetch server config: %s", err), + }) } // validate the input Allocation IPs @@ -346,8 +354,7 @@ func WireGuardServer() echo.HandlerFunc { } return c.Render(http.StatusOK, "server.html", map[string]interface{}{ - "baseData": model.BaseData{Active: "wg-server"}, - "username": currentUser(c), + "baseData": model.BaseData{Active: "wg-server", CurrentUser: currentUser(c)}, "serverInterface": server.Interface, "serverKeyPair": server.KeyPair, }) @@ -429,8 +436,7 @@ func GlobalSettings() echo.HandlerFunc { } return c.Render(http.StatusOK, "global_settings.html", map[string]interface{}{ - "baseData": model.BaseData{Active: "global-settings"}, - "username": currentUser(c), + "baseData": model.BaseData{Active: "global-settings", CurrentUser: currentUser(c)}, "globalSettings": globalSettings, }) } @@ -511,13 +517,18 @@ func SuggestIPAllocation() echo.HandlerFunc { allocatedIPs, err := util.GetAllocatedIPs("") if err != nil { log.Error("Cannot suggest ip allocation. Failed to get list of allocated ip addresses: ", err) - return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot suggest ip allocation: failed to get list of allocated ip addresses"}) + return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{ + false, "Cannot suggest ip allocation: failed to get list of allocated ip addresses", + }) } for _, cidr := range server.Interface.Addresses { ip, err := util.GetAvailableIP(cidr, allocatedIPs) if err != nil { log.Error("Failed to get available ip from a CIDR: ", err) - return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, fmt.Sprintf("Cannot suggest ip allocation: failed to get available ip from network %s", cidr)}) + return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{ + false, + fmt.Sprintf("Cannot suggest ip allocation: failed to get available ip from network %s", cidr), + }) } suggestedIPs = append(suggestedIPs, fmt.Sprintf("%s/32", ip)) } @@ -554,7 +565,9 @@ func ApplyServerConfig(tmplBox *rice.Box) echo.HandlerFunc { err = util.WriteWireGuardServerConfig(tmplBox, server, clients, 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)}) + return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{ + false, fmt.Sprintf("Cannot apply server config: %v", err), + }) } return c.JSON(http.StatusOK, jsonHTTPResponse{true, "Applied server config successfully"}) diff --git a/handler/session.go b/handler/session.go index 13fbea0..5d3606a 100644 --- a/handler/session.go +++ b/handler/session.go @@ -6,19 +6,21 @@ import ( "github.com/labstack/echo-contrib/session" "github.com/labstack/echo/v4" + "github.com/ngoduykhanh/wireguard-ui/util" ) -// validSession to redirect user to the login page if they are not -// authenticated or session expired. +// validSession to redirect user to the login page if they are not authenticated or session expired. func validSession(c echo.Context) { - sess, _ := session.Get("session", c) - cookie, err := c.Cookie("session_token") - if err != nil || sess.Values["session_token"] != cookie.Value { - nextURL := c.Request().URL - if nextURL != nil { - c.Redirect(http.StatusTemporaryRedirect, fmt.Sprintf("/login?next=%s", c.Request().URL)) - } else { - c.Redirect(http.StatusTemporaryRedirect, "/login") + if !util.DisableLogin { + sess, _ := session.Get("session", c) + cookie, err := c.Cookie("session_token") + if err != nil || sess.Values["session_token"] != cookie.Value { + nextURL := c.Request().URL + if nextURL != nil { + c.Redirect(http.StatusTemporaryRedirect, fmt.Sprintf("/login?next=%s", c.Request().URL)) + } else { + c.Redirect(http.StatusTemporaryRedirect, "/login") + } } } } diff --git a/main.go b/main.go index b289c99..15a8fae 100644 --- a/main.go +++ b/main.go @@ -1,22 +1,34 @@ package main import ( + "flag" "fmt" + "net/http" + "time" + rice "github.com/GeertJohan/go.rice" "github.com/labstack/echo/v4" "github.com/ngoduykhanh/wireguard-ui/handler" "github.com/ngoduykhanh/wireguard-ui/router" "github.com/ngoduykhanh/wireguard-ui/util" - "net/http" - "time" ) -var appVersion = "development" -var gitCommit = "N/A" -var gitRef = "N/A" -var buildTime = fmt.Sprintf(time.Now().UTC().Format("01-02-2006 15:04:05")) +// command-line banner information +var ( + appVersion = "development" + gitCommit = "N/A" + gitRef = "N/A" + buildTime = fmt.Sprintf(time.Now().UTC().Format("01-02-2006 15:04:05")) +) + +func init() { + // command-line flags + flagDisableLogin := flag.Bool("disable-login", false, "Disable login page. Turn off authentication.") + flag.Parse() + + // update runtime config + util.DisableLogin = *flagDisableLogin -func main() { // print app information fmt.Println("Wireguard UI") fmt.Println("App Version\t:", appVersion) @@ -24,16 +36,19 @@ func main() { fmt.Println("Git Ref\t\t:", gitRef) fmt.Println("Build Time\t:", buildTime) fmt.Println("Git Repo\t:", "https://github.com/ngoduykhanh/wireguard-ui") - - // set app extra data - extraData := make(map[string]string) - extraData["appVersion"] = appVersion + fmt.Println("Authentication\t:", !util.DisableLogin) // initialize DB err := util.InitDB() if err != nil { fmt.Print("Cannot init database: ", err) } +} + +func main() { + // set app extra data + extraData := make(map[string]string) + extraData["appVersion"] = appVersion // create rice box for embedded template tmplBox := rice.MustFindBox("templates") @@ -45,8 +60,12 @@ func main() { app := router.New(tmplBox, extraData) app.GET("/", handler.WireGuardClients()) - app.GET("/login", handler.LoginPage()) - app.POST("/login", handler.Login()) + + if !util.DisableLogin { + app.GET("/login", handler.LoginPage()) + app.POST("/login", handler.Login()) + } + app.GET("/logout", handler.Logout()) app.POST("/new-client", handler.NewClient()) app.POST("/update-client", handler.UpdateClient()) diff --git a/model/client.go b/model/client.go index 2d610a6..913d5f1 100644 --- a/model/client.go +++ b/model/client.go @@ -9,7 +9,7 @@ type Client struct { ID string `json:"id"` PrivateKey string `json:"private_key"` PublicKey string `json:"public_key"` - PresharedKey string `json:"preshared_key"` + PresharedKey string `json:"preshared_key"` Name string `json:"name"` Email string `json:"email"` AllocatedIPs []string `json:"allocated_ips"` diff --git a/model/misc.go b/model/misc.go index 2f3274d..12d6906 100644 --- a/model/misc.go +++ b/model/misc.go @@ -8,5 +8,6 @@ type Interface struct { // BaseData struct to pass value to the base template type BaseData struct { - Active string + Active string + CurrentUser string } diff --git a/templates/base.html b/templates/base.html index 0e04f31..314c200 100644 --- a/templates/base.html +++ b/templates/base.html @@ -64,8 +64,10 @@ + {{if .baseData.CurrentUser}} + {{end}} @@ -87,7 +89,7 @@
- {{template "username" .}} + {{if .baseData.CurrentUser}} {{.baseData.CurrentUser}} {{else}} Administrator {{end}}
@@ -95,7 +97,7 @@