From 7ae4dd12ddb4b2be86dc8c799f70c9a8be1e05e5 Mon Sep 17 00:00:00 2001 From: Khanh Ngo Date: Sun, 19 Apr 2020 10:46:43 +0700 Subject: [PATCH] Validate AllowedIPs from user input --- handler/response.go | 6 ++++++ handler/routes.go | 35 +++++++++++++++++++++-------------- templates/base.html | 4 ++++ templates/home.html | 4 ++++ util/util.go | 20 ++++++++++++++++++++ 5 files changed, 55 insertions(+), 14 deletions(-) create mode 100644 handler/response.go diff --git a/handler/response.go b/handler/response.go new file mode 100644 index 0000000..711115f --- /dev/null +++ b/handler/response.go @@ -0,0 +1,6 @@ +package handler + +type jsonHTTPResponse struct { + Status bool `json:"status"` + Message string `json:"message"` +} diff --git a/handler/routes.go b/handler/routes.go index 19e9ae8..959a131 100644 --- a/handler/routes.go +++ b/handler/routes.go @@ -1,19 +1,19 @@ package handler import ( - "encoding/json" "encoding/base64" + "encoding/json" "net/http" "time" "github.com/labstack/echo/v4" + "github.com/labstack/gommon/log" "github.com/ngoduykhanh/wireguard-ui/model" "github.com/ngoduykhanh/wireguard-ui/util" - "github.com/sdomino/scribble" - "github.com/labstack/gommon/log" "github.com/rs/xid" - "golang.zx2c4.com/wireguard/wgctrl/wgtypes" + "github.com/sdomino/scribble" "github.com/skip2/go-qrcode" + "golang.zx2c4.com/wireguard/wgctrl/wgtypes" ) // Home handler @@ -54,7 +54,7 @@ func Home() echo.HandlerFunc { } return c.Render(http.StatusOK, "home.html", map[string]interface{}{ - "name": "Khanh", + "name": "Khanh", "clientDataList": clientDataList, }) } @@ -62,10 +62,16 @@ func Home() echo.HandlerFunc { // NewClient handler func NewClient() echo.HandlerFunc { - return func (c echo.Context) error { + return func(c echo.Context) error { client := new(model.Client) c.Bind(client) + // validate the input AllowedIPs + if util.ValidateAllowedIPs(client.AllowedIPs) == false { + log.Warn("Invalid Allowed IPs input from user: %v", client.AllowedIPs) + return c.JSON(http.StatusBadRequest, jsonHTTPResponse{false, "Allowed IPs must be in CIDR format"}) + } + // gen ID guid := xid.New() client.ID = guid.String() @@ -80,38 +86,39 @@ func NewClient() echo.HandlerFunc { client.CreatedAt = time.Now().UTC() client.UpdatedAt = client.CreatedAt - // write to the database + // write client to the database dir := "./db" db, err := scribble.New(dir, nil) if err != nil { log.Error("Cannot initialize the database: ", err) + return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot access database"}) } db.Write("clients", client.ID, client) log.Infof("Created wireguard client: %v", client) - return c.JSON(http.StatusOK, client) + return c.JSON(http.StatusOK, client) } } // RemoveClient handler func RemoveClient() echo.HandlerFunc { - return func (c echo.Context) error { + return func(c echo.Context) error { client := new(model.Client) c.Bind(client) - // delete from database + // delete client from database dir := "./db" db, err := scribble.New(dir, nil) if err != nil { log.Error("Cannot initialize the database: ", err) + return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot access database"}) } - if err := db.Delete("clients", client.ID); err != nil { log.Error("Cannot delete wireguard client: ", err) + return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot delete client from database"}) } log.Infof("Removed wireguard client: %v", client) - - return c.JSON(http.StatusOK, "Client removed!") + return c.JSON(http.StatusOK, jsonHTTPResponse{true, "Client removed"}) } -} \ No newline at end of file +} diff --git a/templates/base.html b/templates/base.html index a1e6393..6136aac 100644 --- a/templates/base.html +++ b/templates/base.html @@ -246,6 +246,10 @@ $('#modal_new_client').modal('hide'); toastr.success('Created new client successfully'); // TODO: trigger reloading the dashboard + }, + error: function(jqXHR, exception) { + var responseJson = jQuery.parseJSON(jqXHR.responseText); + toastr.error(responseJson['message']); } }); } diff --git a/templates/home.html b/templates/home.html index 8c34402..9a65140 100644 --- a/templates/home.html +++ b/templates/home.html @@ -105,6 +105,10 @@ Dashboard $('#modal_remove_client').modal('hide'); toastr.success('Removed client successfully'); // TODO: trigger reloading the dashboard + }, + error: function(jqXHR, exception) { + var responseJson = jQuery.parseJSON(jqXHR.responseText); + toastr.error(responseJson['message']); } }); }); diff --git a/util/util.go b/util/util.go index d4182cf..d825eb0 100644 --- a/util/util.go +++ b/util/util.go @@ -2,6 +2,7 @@ package util import ( "fmt" + "net" "strings" "github.com/ngoduykhanh/wireguard-ui/model" @@ -38,3 +39,22 @@ func BuildClientConfig(client model.Client) string { return strConfig } + +// ValidateCIDR to validate an network CIDR +func ValidateCIDR(cidr string) bool { + _, _, err := net.ParseCIDR(cidr) + if err != nil { + return false + } + return true +} + +// ValidateAllowedIPs to validate allowed ip addresses in CIDR format. +func ValidateAllowedIPs(cidrs []string) bool { + for _, cidr := range cidrs { + if ValidateCIDR(cidr) == false { + return false + } + } + return true +}