diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 976c271..1eeebf1 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -35,9 +35,9 @@ jobs:
uses: managedkaos/print-env@v1.0
# setup node
- - uses: actions/setup-node@v1
+ - uses: actions/setup-node@v2
with:
- node-version: '10.x'
+ node-version: '14'
registry-url: 'https://registry.npmjs.org'
# prepare assets for go rice
@@ -61,7 +61,7 @@ jobs:
github_token: ${{ secrets.GITHUB_TOKEN }}
goos: ${{ matrix.goos }}
goarch: ${{ matrix.goarch }}
- goversion: "https://dl.google.com/go/go1.14.2.linux-amd64.tar.gz"
+ goversion: "https://dl.google.com/go/go1.16.1.linux-amd64.tar.gz"
binary_name: "wireguard-ui"
build_flags: -v
ldflags: -X "main.appVersion=${{ env.APP_VERSION }}" -X "main.buildTime=${{ env.BUILD_TIME }}" -X main.gitCommit=${{ github.sha }} -X main.gitRef=${{ github.ref }}
diff --git a/Dockerfile b/Dockerfile
index 88fa7e6..1b24728 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,5 +1,5 @@
# Build stage
-FROM golang:1.14.2-alpine3.11 as builder
+FROM golang:1.16.7-alpine3.14 as builder
LABEL maintainer="Khanh Ngo %v", client)
return c.JSON(http.StatusOK, jsonHTTPResponse{true, "Updated client successfully"})
@@ -291,7 +287,7 @@ func UpdateClient() echo.HandlerFunc {
}
// SetClientStatus handler to enable / disable a client
-func SetClientStatus() echo.HandlerFunc {
+func SetClientStatus(db store.IStore) echo.HandlerFunc {
return func(c echo.Context) error {
data := make(map[string]interface{})
@@ -304,19 +300,17 @@ func SetClientStatus() echo.HandlerFunc {
clientID := data["id"].(string)
status := data["status"].(bool)
- db, err := util.DBConn()
+ clientdata, err := db.GetClientByID(clientID, false)
if err != nil {
- log.Error("Cannot initialize database: ", err)
- return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot access database"})
+ return c.JSON(http.StatusNotFound, jsonHTTPResponse{false, err.Error()})
}
- client := model.Client{}
- if err := db.Read("clients", clientID, &client); err != nil {
- log.Error("Cannot get client from database: ", err)
- }
+ client := *clientdata.Client
client.Enabled = status
- db.Write("clients", clientID, &client)
+ if err := db.SaveClient(client); err != nil {
+ return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, err.Error()})
+ }
log.Infof("Changed client %s enabled status to %v", client.ID, status)
return c.JSON(http.StatusOK, jsonHTTPResponse{true, "Changed client status successfully"})
@@ -324,22 +318,28 @@ func SetClientStatus() echo.HandlerFunc {
}
// DownloadClient handler
-func DownloadClient() echo.HandlerFunc {
+func DownloadClient(db store.IStore) echo.HandlerFunc {
return func(c echo.Context) error {
clientID := c.QueryParam("clientid")
if clientID == "" {
return c.JSON(http.StatusNotFound, jsonHTTPResponse{false, "Missing clientid parameter"})
}
- clientData, err := util.GetClientByID(clientID, false)
+ clientData, err := db.GetClientByID(clientID, false)
if err != nil {
log.Errorf("Cannot generate client id %s config file for downloading: %v", clientID, err)
return c.JSON(http.StatusNotFound, jsonHTTPResponse{false, "Client not found"})
}
// build config
- server, _ := util.GetServer()
- globalSettings, _ := util.GetGlobalSettings()
+ server, err := db.GetServer()
+ if err != nil {
+ return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, err.Error()})
+ }
+ globalSettings, err := db.GetGlobalSettings()
+ if err != nil {
+ return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, err.Error()})
+ }
config := util.BuildClientConfig(*clientData.Client, server, globalSettings)
// create io reader from string
@@ -352,20 +352,15 @@ func DownloadClient() echo.HandlerFunc {
}
// RemoveClient handler
-func RemoveClient() echo.HandlerFunc {
+func RemoveClient(db store.IStore) echo.HandlerFunc {
return func(c echo.Context) error {
client := new(model.Client)
c.Bind(client)
// delete client from database
- db, err := util.DBConn()
- if err != nil {
- log.Error("Cannot initialize database: ", err)
- return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot access database"})
- }
- if err := db.Delete("clients", client.ID); err != nil {
+ if err := db.DeleteClient(client.ID); err != nil {
log.Error("Cannot delete wireguard client: ", err)
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot delete client from database"})
}
@@ -376,10 +371,10 @@ func RemoveClient() echo.HandlerFunc {
}
// WireGuardServer handler
-func WireGuardServer() echo.HandlerFunc {
+func WireGuardServer(db store.IStore) echo.HandlerFunc {
return func(c echo.Context) error {
- server, err := util.GetServer()
+ server, err := db.GetServer()
if err != nil {
log.Error("Cannot get server config: ", err)
}
@@ -393,11 +388,11 @@ func WireGuardServer() echo.HandlerFunc {
}
// WireGuardServerInterfaces handler
-func WireGuardServerInterfaces() echo.HandlerFunc {
+func WireGuardServerInterfaces(db store.IStore) echo.HandlerFunc {
return func(c echo.Context) error {
- serverInterface := new(model.ServerInterface)
- c.Bind(serverInterface)
+ var serverInterface model.ServerInterface
+ c.Bind(&serverInterface)
// validate the input addresses
if util.ValidateServerAddresses(serverInterface.Addresses) == false {
@@ -408,13 +403,10 @@ func WireGuardServerInterfaces() echo.HandlerFunc {
serverInterface.UpdatedAt = time.Now().UTC()
// write config to the database
- db, err := util.DBConn()
- if err != nil {
- log.Error("Cannot initialize database: ", err)
- return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot access database"})
- }
- db.Write("server", "interfaces", serverInterface)
+ if err := db.SaveServerInterface(serverInterface); err != nil {
+ return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Interface IP address must be in CIDR format"})
+ }
log.Infof("Updated wireguard server interfaces settings: %v", serverInterface)
return c.JSON(http.StatusOK, jsonHTTPResponse{true, "Updated interface addresses successfully"})
@@ -422,7 +414,7 @@ func WireGuardServerInterfaces() echo.HandlerFunc {
}
// WireGuardServerKeyPair handler to generate private and public keys
-func WireGuardServerKeyPair() echo.HandlerFunc {
+func WireGuardServerKeyPair(db store.IStore) echo.HandlerFunc {
return func(c echo.Context) error {
// gen Wireguard key pair
@@ -432,19 +424,14 @@ func WireGuardServerKeyPair() echo.HandlerFunc {
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot generate Wireguard key pair"})
}
- serverKeyPair := new(model.ServerKeypair)
+ var serverKeyPair model.ServerKeypair
serverKeyPair.PrivateKey = key.String()
serverKeyPair.PublicKey = key.PublicKey().String()
serverKeyPair.UpdatedAt = time.Now().UTC()
- // write config to the database
- db, err := util.DBConn()
- if err != nil {
- log.Error("Cannot initialize database: ", err)
- return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot access database"})
+ if err := db.SaveServerKeyPair(serverKeyPair); err != nil {
+ return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot generate Wireguard key pair"})
}
-
- db.Write("server", "keypair", serverKeyPair)
log.Infof("Updated wireguard server interfaces settings: %v", serverKeyPair)
return c.JSON(http.StatusOK, serverKeyPair)
@@ -452,10 +439,10 @@ func WireGuardServerKeyPair() echo.HandlerFunc {
}
// GlobalSettings handler
-func GlobalSettings() echo.HandlerFunc {
+func GlobalSettings(db store.IStore) echo.HandlerFunc {
return func(c echo.Context) error {
- globalSettings, err := util.GetGlobalSettings()
+ globalSettings, err := db.GetGlobalSettings()
if err != nil {
log.Error("Cannot get global settings: ", err)
}
@@ -467,12 +454,99 @@ func GlobalSettings() echo.HandlerFunc {
}
}
-// GlobalSettingSubmit handler to update the global settings
-func GlobalSettingSubmit() echo.HandlerFunc {
+// Status handler
+func Status(db store.IStore) echo.HandlerFunc {
+ type PeerVM struct {
+ Name string
+ Email string
+ PublicKey string
+ ReceivedBytes int64
+ TransmitBytes int64
+ LastHandshakeTime time.Time
+ LastHandshakeRel time.Duration
+ Connected bool
+ }
+
+ type DeviceVM struct {
+ Name string
+ Peers []PeerVM
+ }
return func(c echo.Context) error {
- globalSettings := new(model.GlobalSetting)
- c.Bind(globalSettings)
+ wgclient, err := wgctrl.New()
+ if err != nil {
+ return c.Render(http.StatusInternalServerError, "status.html", map[string]interface{}{
+ "baseData": model.BaseData{Active: "status", CurrentUser: currentUser(c)},
+ "error": err.Error(),
+ "devices": nil,
+ })
+ }
+
+ devices, err := wgclient.Devices()
+ if err != nil {
+ return c.Render(http.StatusInternalServerError, "status.html", map[string]interface{}{
+ "baseData": model.BaseData{Active: "status", CurrentUser: currentUser(c)},
+ "error": err.Error(),
+ "devices": nil,
+ })
+ }
+
+ devicesVm := make([]DeviceVM, 0, len(devices))
+ if len(devices) > 0 {
+ m := make(map[string]*model.Client)
+ clients, err := db.GetClients(false)
+ if err != nil {
+ return c.Render(http.StatusInternalServerError, "status.html", map[string]interface{}{
+ "baseData": model.BaseData{Active: "status", CurrentUser: currentUser(c)},
+ "error": err.Error(),
+ "devices": nil,
+ })
+ }
+ for i := range clients {
+ if clients[i].Client != nil {
+ m[clients[i].Client.PublicKey] = clients[i].Client
+ }
+ }
+
+ conv := map[bool]int{true: 1, false: 0}
+ for i := range devices {
+ devVm := DeviceVM{Name: devices[i].Name}
+ for j := range devices[i].Peers {
+ pVm := PeerVM{
+ PublicKey: devices[i].Peers[j].PublicKey.String(),
+ ReceivedBytes: devices[i].Peers[j].ReceiveBytes,
+ TransmitBytes: devices[i].Peers[j].TransmitBytes,
+ LastHandshakeTime: devices[i].Peers[j].LastHandshakeTime,
+ LastHandshakeRel: time.Since(devices[i].Peers[j].LastHandshakeTime),
+ }
+ pVm.Connected = pVm.LastHandshakeRel.Minutes() < 3.
+
+ if _client, ok := m[pVm.PublicKey]; ok {
+ pVm.Name = _client.Name
+ pVm.Email = _client.Email
+ }
+ devVm.Peers = append(devVm.Peers, pVm)
+ }
+ sort.SliceStable(devVm.Peers, func(i, j int) bool { return devVm.Peers[i].Name < devVm.Peers[j].Name })
+ sort.SliceStable(devVm.Peers, func(i, j int) bool { return conv[devVm.Peers[i].Connected] > conv[devVm.Peers[j].Connected] })
+ devicesVm = append(devicesVm, devVm)
+ }
+ }
+
+ return c.Render(http.StatusOK, "status.html", map[string]interface{}{
+ "baseData": model.BaseData{Active: "status", CurrentUser: currentUser(c)},
+ "devices": devicesVm,
+ "error": "",
+ })
+ }
+}
+
+// GlobalSettingSubmit handler to update the global settings
+func GlobalSettingSubmit(db store.IStore) echo.HandlerFunc {
+ return func(c echo.Context) error {
+
+ var globalSettings model.GlobalSetting
+ c.Bind(&globalSettings)
// validate the input dns server list
if util.ValidateIPAddressList(globalSettings.DNSServers) == false {
@@ -483,13 +557,10 @@ func GlobalSettingSubmit() echo.HandlerFunc {
globalSettings.UpdatedAt = time.Now().UTC()
// write config to the database
- db, err := util.DBConn()
- if err != nil {
- log.Error("Cannot initialize database: ", err)
- return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot access database"})
+ if err := db.SaveGlobalSettings(globalSettings); err != nil {
+ return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot generate Wireguard key pair"})
}
- db.Write("server", "global_settings", globalSettings)
log.Infof("Updated global settings: %v", globalSettings)
return c.JSON(http.StatusOK, jsonHTTPResponse{true, "Updated global settings successfully"})
@@ -521,12 +592,13 @@ func MachineIPAddresses() echo.HandlerFunc {
}
// SuggestIPAllocation handler to get the list of ip address for client
-func SuggestIPAllocation() echo.HandlerFunc {
+func SuggestIPAllocation(db store.IStore) echo.HandlerFunc {
return func(c echo.Context) error {
- server, err := util.GetServer()
+ server, err := db.GetServer()
if err != nil {
log.Error("Cannot fetch server config from database: ", err)
+ return c.JSON(http.StatusBadRequest, jsonHTTPResponse{false, err.Error()})
}
// return the list of suggestedIPs
@@ -557,22 +629,22 @@ func SuggestIPAllocation() echo.HandlerFunc {
}
// ApplyServerConfig handler to write config file and restart Wireguard server
-func ApplyServerConfig(tmplBox *rice.Box) echo.HandlerFunc {
+func ApplyServerConfig(db store.IStore, tmplBox *rice.Box) echo.HandlerFunc {
return func(c echo.Context) error {
- server, err := util.GetServer()
+ server, err := db.GetServer()
if err != nil {
log.Error("Cannot get server config: ", err)
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot get server config"})
}
- clients, err := util.GetClients(false)
+ clients, err := db.GetClients(false)
if err != nil {
log.Error("Cannot get client config: ", err)
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot get client config"})
}
- settings, err := util.GetGlobalSettings()
+ settings, err := db.GetGlobalSettings()
if err != nil {
log.Error("Cannot get global settings: ", err)
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot get global settings"})
diff --git a/main.go b/main.go
index c2d42a3..c2e117e 100644
--- a/main.go
+++ b/main.go
@@ -12,6 +12,7 @@ import (
"github.com/ngoduykhanh/wireguard-ui/emailer"
"github.com/ngoduykhanh/wireguard-ui/handler"
"github.com/ngoduykhanh/wireguard-ui/router"
+ "github.com/ngoduykhanh/wireguard-ui/store/jsondb"
"github.com/ngoduykhanh/wireguard-ui/util"
)
@@ -72,14 +73,16 @@ func init() {
fmt.Println("Email from name\t:", util.EmailFromName)
//fmt.Println("Session secret\t:", util.SessionSecret)
- // initialize DB
- err := util.InitDB()
- if err != nil {
- fmt.Print("Cannot init database: ", err)
- }
}
func main() {
+ db, err := jsondb.New("./db")
+ if err != nil {
+ panic(err)
+ }
+ if err := db.Init(); err != nil {
+ panic(err)
+ }
// set app extra data
extraData := make(map[string]string)
extraData["appVersion"] = appVersion
@@ -93,32 +96,33 @@ func main() {
// register routes
app := router.New(tmplBox, extraData, util.SessionSecret)
- app.GET("/", handler.WireGuardClients(), handler.ValidSession)
+ app.GET("/", handler.WireGuardClients(db), handler.ValidSession)
if !util.DisableLogin {
app.GET("/login", handler.LoginPage())
- app.POST("/login", handler.Login())
+ app.POST("/login", handler.Login(db))
}
sendmail := emailer.NewSendgridApiMail(util.SendgridApiKey, util.EmailFromName, util.EmailFrom)
app.GET("/logout", handler.Logout(), handler.ValidSession)
- app.POST("/new-client", handler.NewClient(), handler.ValidSession)
- app.POST("/update-client", handler.UpdateClient(), handler.ValidSession)
- app.POST("/email-client", handler.EmailClient(sendmail, defaultEmailSubject, defaultEmailContent), handler.ValidSession)
- app.POST("/client/set-status", handler.SetClientStatus(), handler.ValidSession)
- app.POST("/remove-client", handler.RemoveClient(), handler.ValidSession)
- app.GET("/download", handler.DownloadClient(), handler.ValidSession)
- app.GET("/wg-server", handler.WireGuardServer(), handler.ValidSession)
- app.POST("wg-server/interfaces", handler.WireGuardServerInterfaces(), handler.ValidSession)
- app.POST("wg-server/keypair", handler.WireGuardServerKeyPair(), handler.ValidSession)
- app.GET("/global-settings", handler.GlobalSettings(), handler.ValidSession)
- app.POST("/global-settings", handler.GlobalSettingSubmit(), handler.ValidSession)
- app.GET("/api/clients", handler.GetClients(), handler.ValidSession)
- app.GET("/api/client/:id", handler.GetClient(), handler.ValidSession)
+ app.POST("/new-client", handler.NewClient(db), handler.ValidSession)
+ app.POST("/update-client", handler.UpdateClient(db), handler.ValidSession)
+ app.POST("/email-client", handler.EmailClient(db, sendmail, defaultEmailSubject, defaultEmailContent), handler.ValidSession)
+ app.POST("/client/set-status", handler.SetClientStatus(db), handler.ValidSession)
+ app.POST("/remove-client", handler.RemoveClient(db), handler.ValidSession)
+ app.GET("/download", handler.DownloadClient(db), handler.ValidSession)
+ app.GET("/wg-server", handler.WireGuardServer(db), handler.ValidSession)
+ app.POST("wg-server/interfaces", handler.WireGuardServerInterfaces(db), handler.ValidSession)
+ app.POST("wg-server/keypair", handler.WireGuardServerKeyPair(db), handler.ValidSession)
+ app.GET("/global-settings", handler.GlobalSettings(db), handler.ValidSession)
+ app.POST("/global-settings", handler.GlobalSettingSubmit(db), handler.ValidSession)
+ app.GET("/status", handler.Status(db), handler.ValidSession)
+ app.GET("/api/clients", handler.GetClients(db), handler.ValidSession)
+ app.GET("/api/client/:id", handler.GetClient(db), handler.ValidSession)
app.GET("/api/machine-ips", handler.MachineIPAddresses(), handler.ValidSession)
- app.GET("/api/suggest-client-ips", handler.SuggestIPAllocation(), handler.ValidSession)
- app.GET("/api/apply-wg-config", handler.ApplyServerConfig(tmplBox), 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)
// servers other static files
app.GET("/static/*", echo.WrapHandler(http.StripPrefix("/static/", assetHandler)))
diff --git a/router/router.go b/router/router.go
index bb14431..2c91d49 100644
--- a/router/router.go
+++ b/router/router.go
@@ -74,12 +74,18 @@ func New(tmplBox *rice.Box, extraData map[string]string, secret []byte) *echo.Ec
log.Fatal(err)
}
+ tmplStatusString, err := tmplBox.String("status.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))
templates["clients.html"] = template.Must(template.New("clients").Parse(tmplBaseString + tmplClientsString))
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))
e.Logger.SetLevel(log.DEBUG)
e.Pre(middleware.RemoveTrailingSlash())
diff --git a/util/db.go b/store/jsondb/jsondb.go
similarity index 54%
rename from util/db.go
rename to store/jsondb/jsondb.go
index ded1306..763756e 100644
--- a/util/db.go
+++ b/store/jsondb/jsondb.go
@@ -1,4 +1,4 @@
-package util
+package jsondb
import (
"encoding/base64"
@@ -8,40 +8,40 @@ import (
"path"
"time"
- "github.com/ngoduykhanh/wireguard-ui/model"
"github.com/sdomino/scribble"
"github.com/skip2/go-qrcode"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
+
+ "github.com/ngoduykhanh/wireguard-ui/model"
+ "github.com/ngoduykhanh/wireguard-ui/util"
)
-const dbPath = "./db"
-const defaultUsername = "admin"
-const defaultPassword = "admin"
-const defaultServerAddress = "10.252.1.0/24"
-const defaultServerPort = 51820
-const defaultDNS = "1.1.1.1"
-const defaultMTU = 1450
-const defaultPersistentKeepalive = 15
-const defaultConfigFilePath = "/etc/wireguard/wg0.conf"
+type JsonDB struct {
+ conn *scribble.Driver
+ dbPath string
+}
-// DBConn to initialize the database connection
-func DBConn() (*scribble.Driver, error) {
- db, err := scribble.New(dbPath, nil)
+// New returns a new pointer JsonDB
+func New(dbPath string) (*JsonDB, error) {
+ conn, err := scribble.New(dbPath, nil)
if err != nil {
return nil, err
}
- return db, nil
+ ans := JsonDB{
+ conn: conn,
+ dbPath: dbPath,
+ }
+ return &ans, nil
+
}
-// InitDB to create the default database
-func InitDB() error {
- var clientPath string = path.Join(dbPath, "clients")
- var serverPath string = path.Join(dbPath, "server")
+func (o *JsonDB) Init() error {
+ var clientPath string = path.Join(o.dbPath, "clients")
+ var serverPath string = path.Join(o.dbPath, "server")
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)
@@ -52,24 +52,15 @@ func InitDB() error {
// server's interface
if _, err := os.Stat(serverInterfacePath); os.IsNotExist(err) {
- db, err := DBConn()
- if err != nil {
- return err
- }
-
serverInterface := new(model.ServerInterface)
- serverInterface.Addresses = []string{defaultServerAddress}
- serverInterface.ListenPort = defaultServerPort
+ serverInterface.Addresses = []string{util.DefaultServerAddress}
+ serverInterface.ListenPort = util.DefaultServerPort
serverInterface.UpdatedAt = time.Now().UTC()
- db.Write("server", "interfaces", serverInterface)
+ o.conn.Write("server", "interfaces", serverInterface)
}
// server's key pair
if _, err := os.Stat(serverKeyPairPath); os.IsNotExist(err) {
- db, err := DBConn()
- if err != nil {
- return err
- }
key, err := wgtypes.GeneratePrivateKey()
if err != nil {
@@ -79,97 +70,62 @@ func InitDB() error {
serverKeyPair.PrivateKey = key.String()
serverKeyPair.PublicKey = key.PublicKey().String()
serverKeyPair.UpdatedAt = time.Now().UTC()
- db.Write("server", "keypair", serverKeyPair)
+ o.conn.Write("server", "keypair", serverKeyPair)
}
// global settings
if _, err := os.Stat(globalSettingPath); os.IsNotExist(err) {
- db, err := DBConn()
- if err != nil {
- return err
- }
- publicInterface, err := GetPublicIP()
+ publicInterface, err := util.GetPublicIP()
if err != nil {
return err
}
globalSetting := new(model.GlobalSetting)
globalSetting.EndpointAddress = publicInterface.IPAddress
- globalSetting.DNSServers = []string{defaultDNS}
- globalSetting.MTU = defaultMTU
- globalSetting.PersistentKeepalive = defaultPersistentKeepalive
- globalSetting.ConfigFilePath = defaultConfigFilePath
+ globalSetting.DNSServers = []string{util.DefaultDNS}
+ globalSetting.MTU = util.DefaultMTU
+ globalSetting.PersistentKeepalive = util.DefaultPersistentKeepalive
+ globalSetting.ConfigFilePath = util.DefaultConfigFilePath
globalSetting.UpdatedAt = time.Now().UTC()
- db.Write("server", "global_settings", globalSetting)
+ o.conn.Write("server", "global_settings", globalSetting)
}
// user info
if _, err := os.Stat(userPath); os.IsNotExist(err) {
- db, err := DBConn()
- if err != nil {
- return err
- }
-
user := new(model.User)
- user.Username = defaultUsername
- user.Password = defaultPassword
- db.Write("server", "users", user)
+ user.Username = util.GetCredVar(util.UsernameEnvVar, util.DefaultUsername)
+ user.Password = util.GetCredVar(util.PasswordEnvVar, util.DefaultPassword)
+ o.conn.Write("server", "users", user)
}
return nil
}
// GetUser func to query user info from the database
-func GetUser() (model.User, error) {
+func (o *JsonDB) GetUser() (model.User, error) {
user := model.User{}
-
- db, err := DBConn()
- if err != nil {
- return user, err
- }
-
- if err := db.Read("server", "users", &user); err != nil {
- return user, err
- }
-
- return user, nil
+ return user, o.conn.Read("server", "users", &user)
}
// GetGlobalSettings func to query global settings from the database
-func GetGlobalSettings() (model.GlobalSetting, error) {
+func (o *JsonDB) GetGlobalSettings() (model.GlobalSetting, error) {
settings := model.GlobalSetting{}
-
- db, err := DBConn()
- if err != nil {
- return settings, err
- }
-
- if err := db.Read("server", "global_settings", &settings); err != nil {
- return settings, err
- }
-
- return settings, nil
+ return settings, o.conn.Read("server", "global_settings", &settings)
}
// GetServer func to query Server setting from the database
-func GetServer() (model.Server, error) {
+func (o *JsonDB) GetServer() (model.Server, error) {
server := model.Server{}
-
- db, err := DBConn()
- if err != nil {
- return server, err
- }
-
// read server interface information
serverInterface := model.ServerInterface{}
- if err := db.Read("server", "interfaces", &serverInterface); err != nil {
+ if err := o.conn.Read("server", "interfaces", &serverInterface); err != nil {
return server, err
}
// read server key pair information
serverKeyPair := model.ServerKeypair{}
- if err := db.Read("server", "keypair", &serverKeyPair); err != nil {
+ if err := o.conn.Read("server", "keypair", &serverKeyPair); err != nil {
return server, err
}
@@ -179,17 +135,11 @@ func GetServer() (model.Server, error) {
return server, nil
}
-// GetClients to get all clients from the database
-func GetClients(hasQRCode bool) ([]model.ClientData, error) {
+func (o *JsonDB) GetClients(hasQRCode bool) ([]model.ClientData, error) {
var clients []model.ClientData
- db, err := DBConn()
- if err != nil {
- return clients, err
- }
-
// read all client json file in "clients" directory
- records, err := db.ReadAll("clients")
+ records, err := o.conn.ReadAll("clients")
if err != nil {
return clients, err
}
@@ -206,10 +156,10 @@ func GetClients(hasQRCode bool) ([]model.ClientData, error) {
// generate client qrcode image in base64
if hasQRCode {
- server, _ := GetServer()
- globalSettings, _ := GetGlobalSettings()
+ server, _ := o.GetServer()
+ globalSettings, _ := o.GetGlobalSettings()
- png, err := qrcode.Encode(BuildClientConfig(client, server, globalSettings), qrcode.Medium, 256)
+ png, err := qrcode.Encode(util.BuildClientConfig(client, server, globalSettings), qrcode.Medium, 256)
if err == nil {
clientData.QRCode = "data:image/png;base64," + base64.StdEncoding.EncodeToString([]byte(png))
} else {
@@ -225,27 +175,21 @@ func GetClients(hasQRCode bool) ([]model.ClientData, error) {
return clients, nil
}
-// GetClientByID func to query a client from the database
-func GetClientByID(clientID string, hasQRCode bool) (model.ClientData, error) {
+func (o *JsonDB) GetClientByID(clientID string, hasQRCode bool) (model.ClientData, error) {
client := model.Client{}
clientData := model.ClientData{}
- db, err := DBConn()
- if err != nil {
- return clientData, err
- }
-
// read client information
- if err := db.Read("clients", clientID, &client); err != nil {
+ if err := o.conn.Read("clients", clientID, &client); err != nil {
return clientData, err
}
// generate client qrcode image in base64
if hasQRCode {
- server, _ := GetServer()
- globalSettings, _ := GetGlobalSettings()
+ server, _ := o.GetServer()
+ globalSettings, _ := o.GetGlobalSettings()
- png, err := qrcode.Encode(BuildClientConfig(client, server, globalSettings), qrcode.Medium, 256)
+ png, err := qrcode.Encode(util.BuildClientConfig(client, server, globalSettings), qrcode.Medium, 256)
if err == nil {
clientData.QRCode = "data:image/png;base64," + base64.StdEncoding.EncodeToString([]byte(png))
} else {
@@ -257,3 +201,23 @@ func GetClientByID(clientID string, hasQRCode bool) (model.ClientData, error) {
return clientData, nil
}
+
+func (o *JsonDB) SaveClient(client model.Client) error {
+ return o.conn.Write("clients", client.ID, client)
+}
+
+func (o *JsonDB) DeleteClient(clientID string) error {
+ return o.conn.Delete("clients", clientID)
+}
+
+func (o *JsonDB) SaveServerInterface(serverInterface model.ServerInterface) error {
+ return o.conn.Write("server", "interfaces", serverInterface)
+}
+
+func (o *JsonDB) SaveServerKeyPair(serverKeyPair model.ServerKeypair) error {
+ return o.conn.Write("server", "keypair", serverKeyPair)
+}
+
+func (o *JsonDB) SaveGlobalSettings(globalSettings model.GlobalSetting) error {
+ return o.conn.Write("server", "global_settings", globalSettings)
+}
diff --git a/store/store.go b/store/store.go
new file mode 100644
index 0000000..8750cf2
--- /dev/null
+++ b/store/store.go
@@ -0,0 +1,19 @@
+package store
+
+import (
+ "github.com/ngoduykhanh/wireguard-ui/model"
+)
+
+type IStore interface {
+ Init() error
+ GetUser() (model.User, error)
+ GetGlobalSettings() (model.GlobalSetting, error)
+ GetServer() (model.Server, error)
+ GetClients(hasQRCode bool) ([]model.ClientData, error)
+ GetClientByID(clientID string, hasQRCode bool) (model.ClientData, error)
+ SaveClient(client model.Client) error
+ DeleteClient(clientID string) error
+ SaveServerInterface(serverInterface model.ServerInterface) error
+ SaveServerKeyPair(serverKeyPair model.ServerKeypair) error
+ SaveGlobalSettings(globalSettings model.GlobalSetting) error
+}
diff --git a/templates/base.html b/templates/base.html
index 3ba800c..6b09a32 100644
--- a/templates/base.html
+++ b/templates/base.html
@@ -120,6 +120,14 @@
+
+
+
+
+ Status
+
+
+
@@ -446,4 +454,4 @@