chore: code adjustment (#512)

This commit is contained in:
Khanh Ngo 2023-12-29 10:56:37 +01:00 committed by GitHub
parent 8cfe9a3d5b
commit 45849a2aee
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 79 additions and 69 deletions

View file

@ -75,7 +75,8 @@ func Login(db store.IStore) echo.HandlerFunc {
dbuser, err := db.GetUserByName(username)
if err != nil {
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot query user from DB"})
log.Infof("Cannot query user %s from DB", username)
return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Invalid credentials"})
}
userCorrect := subtle.ConstantTimeCompare([]byte(username), []byte(dbuser.Username)) == 1
@ -173,7 +174,7 @@ func Logout() echo.HandlerFunc {
}
// LoadProfile to load user information
func LoadProfile(db store.IStore) echo.HandlerFunc {
func LoadProfile() echo.HandlerFunc {
return func(c echo.Context) error {
return c.Render(http.StatusOK, "profile.html", map[string]interface{}{
"baseData": model.BaseData{Active: "profile", CurrentUser: currentUser(c), Admin: isAdmin(c)},
@ -182,7 +183,7 @@ func LoadProfile(db store.IStore) echo.HandlerFunc {
}
// UsersSettings handler
func UsersSettings(db store.IStore) echo.HandlerFunc {
func UsersSettings() echo.HandlerFunc {
return func(c echo.Context) error {
return c.Render(http.StatusOK, "users_settings.html", map[string]interface{}{
"baseData": model.BaseData{Active: "users-settings", CurrentUser: currentUser(c), Admin: isAdmin(c)},

59
main.go
View file

@ -31,23 +31,23 @@ var (
gitRef = "N/A"
buildTime = fmt.Sprintf(time.Now().UTC().Format("01-02-2006 15:04:05"))
// configuration variables
flagDisableLogin bool = false
flagBindAddress string = "0.0.0.0:5000"
flagSmtpHostname string = "127.0.0.1"
flagSmtpPort int = 25
flagDisableLogin = false
flagBindAddress = "0.0.0.0:5000"
flagSmtpHostname = "127.0.0.1"
flagSmtpPort = 25
flagSmtpUsername string
flagSmtpPassword string
flagSmtpAuthType string = "NONE"
flagSmtpNoTLSCheck bool = false
flagSmtpEncryption string = "STARTTLS"
flagSmtpHelo string = "localhost"
flagSmtpAuthType = "NONE"
flagSmtpNoTLSCheck = false
flagSmtpEncryption = "STARTTLS"
flagSmtpHelo = "localhost"
flagSendgridApiKey string
flagEmailFrom string
flagEmailFromName string = "WireGuard UI"
flagEmailFromName = "WireGuard UI"
flagTelegramToken string
flagTelegramAllowConfRequest bool = false
flagTelegramFloodWait int = 60
flagSessionSecret string = util.RandomString(32)
flagTelegramAllowConfRequest = false
flagTelegramFloodWait = 60
flagSessionSecret = util.RandomString(32)
flagWgConfTemplate string
flagBasePath string
flagSubnetRanges string
@ -94,9 +94,9 @@ func init() {
flag.StringVar(&flagSubnetRanges, "subnet-ranges", util.LookupEnvOrString("SUBNET_RANGES", flagSubnetRanges), "IP ranges to choose from when assigning an IP for a client.")
var (
smtpPasswordLookup = util.LookupEnvOrString("SMTP_PASSWORD", flagSmtpPassword)
sengridApiKeyLookup = util.LookupEnvOrString("SENDGRID_API_KEY", flagSendgridApiKey)
sessionSecretLookup = util.LookupEnvOrString("SESSION_SECRET", flagSessionSecret)
smtpPasswordLookup = util.LookupEnvOrString("SMTP_PASSWORD", flagSmtpPassword)
sendgridApiKeyLookup = util.LookupEnvOrString("SENDGRID_API_KEY", flagSendgridApiKey)
sessionSecretLookup = util.LookupEnvOrString("SESSION_SECRET", flagSessionSecret)
)
// check empty smtpPassword env var
@ -106,9 +106,9 @@ func init() {
flag.StringVar(&flagSmtpPassword, "smtp-password", util.LookupEnvOrFile("SMTP_PASSWORD_FILE", flagSmtpPassword), "SMTP Password File")
}
// check empty sengridApiKey env var
if sengridApiKeyLookup != "" {
flag.StringVar(&flagSendgridApiKey, "sendgrid-api-key", sengridApiKeyLookup, "Your sendgrid api key.")
// check empty sendgridApiKey env var
if sendgridApiKeyLookup != "" {
flag.StringVar(&flagSendgridApiKey, "sendgrid-api-key", sendgridApiKeyLookup, "Your sendgrid api key.")
} else {
flag.StringVar(&flagSendgridApiKey, "sendgrid-api-key", util.LookupEnvOrFile("SENDGRID_API_KEY_FILE", flagSendgridApiKey), "File containing your sendgrid api key.")
}
@ -215,12 +215,12 @@ func main() {
app.GET(util.BasePath+"/login", handler.LoginPage())
app.POST(util.BasePath+"/login", handler.Login(db), handler.ContentTypeJson)
app.GET(util.BasePath+"/logout", handler.Logout(), handler.ValidSession)
app.GET(util.BasePath+"/profile", handler.LoadProfile(db), handler.ValidSession)
app.GET(util.BasePath+"/users-settings", handler.UsersSettings(db), handler.ValidSession, handler.NeedsAdmin)
app.GET(util.BasePath+"/profile", handler.LoadProfile(), handler.ValidSession)
app.GET(util.BasePath+"/users-settings", handler.UsersSettings(), handler.ValidSession, handler.NeedsAdmin)
app.POST(util.BasePath+"/update-user", handler.UpdateUser(db), handler.ValidSession, handler.ContentTypeJson)
app.POST(util.BasePath+"/create-user", handler.CreateUser(db), handler.ValidSession, handler.ContentTypeJson, handler.NeedsAdmin)
app.POST(util.BasePath+"/remove-user", handler.RemoveUser(db), handler.ValidSession, handler.ContentTypeJson, handler.NeedsAdmin)
app.GET(util.BasePath+"/getusers", handler.GetUsers(db), handler.ValidSession, handler.NeedsAdmin)
app.GET(util.BasePath+"/get-users", handler.GetUsers(db), handler.ValidSession, handler.NeedsAdmin)
app.GET(util.BasePath+"/api/user/:username", handler.GetUser(db), handler.ValidSession)
}
@ -276,10 +276,13 @@ func main() {
if strings.HasPrefix(util.BindAddress, "unix://") {
// Listen on unix domain socket.
// https://github.com/labstack/echo/issues/830
syscall.Unlink(util.BindAddress[6:])
err := syscall.Unlink(util.BindAddress[6:])
if err != nil {
app.Logger.Fatalf("Cannot unlink unix socket: Error: %v", err)
}
l, err := net.Listen("unix", util.BindAddress[6:])
if err != nil {
app.Logger.Fatal(err)
app.Logger.Fatalf("Cannot create unix socket. Error: %v", err)
}
app.Listener = l
app.Logger.Fatal(app.Start(""))
@ -292,7 +295,7 @@ func main() {
func initServerConfig(db store.IStore, tmplDir fs.FS) {
settings, err := db.GetGlobalSettings()
if err != nil {
log.Fatalf("Cannot get global settings: ", err)
log.Fatalf("Cannot get global settings: %v", err)
}
if _, err := os.Stat(settings.ConfigFilePath); err == nil {
@ -302,23 +305,23 @@ func initServerConfig(db store.IStore, tmplDir fs.FS) {
server, err := db.GetServer()
if err != nil {
log.Fatalf("Cannot get server config: ", err)
log.Fatalf("Cannot get server config: %v", err)
}
clients, err := db.GetClients(false)
if err != nil {
log.Fatalf("Cannot get client config: ", err)
log.Fatalf("Cannot get client config: %v", err)
}
users, err := db.GetUsers()
if err != nil {
log.Fatalf("Cannot get user config: ", err)
log.Fatalf("Cannot get user config: %v", err)
}
// write config file
err = util.WriteWireGuardServerConfig(tmplDir, server, clients, users, settings)
if err != nil {
log.Fatalf("Cannot create server config: ", err)
log.Fatalf("Cannot create server config: %v", err)
}
}

View file

@ -37,14 +37,14 @@ 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 userPath string = path.Join(o.dbPath, "users")
var wakeOnLanHostsPath string = path.Join(o.dbPath, "wake_on_lan_hosts")
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 hashesPath string = path.Join(serverPath, "hashes.json")
var clientPath = path.Join(o.dbPath, "clients")
var serverPath = path.Join(o.dbPath, "server")
var userPath = path.Join(o.dbPath, "users")
var wakeOnLanHostsPath = path.Join(o.dbPath, "wake_on_lan_hosts")
var serverInterfacePath = path.Join(serverPath, "interfaces.json")
var serverKeyPairPath = path.Join(serverPath, "keypair.json")
var globalSettingPath = path.Join(serverPath, "global_settings.json")
var hashesPath = path.Join(serverPath, "hashes.json")
// create directories if they do not exist
if _, err := os.Stat(clientPath); os.IsNotExist(err) {
@ -189,7 +189,7 @@ func (o *JsonDB) GetUsers() ([]model.User, error) {
for _, i := range results {
user := model.User{}
if err := json.Unmarshal([]byte(i), &user); err != nil {
if err := json.Unmarshal(i, &user); err != nil {
return users, fmt.Errorf("cannot decode user json structure: %v", err)
}
users = append(users, user)
@ -267,7 +267,7 @@ func (o *JsonDB) GetClients(hasQRCode bool) ([]model.ClientData, error) {
clientData := model.ClientData{}
// get client info
if err := json.Unmarshal([]byte(f), &client); err != nil {
if err := json.Unmarshal(f, &client); err != nil {
return clients, fmt.Errorf("cannot decode client json structure: %v", err)
}
@ -278,7 +278,7 @@ func (o *JsonDB) GetClients(hasQRCode bool) ([]model.ClientData, error) {
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))
clientData.QRCode = "data:image/png;base64," + base64.StdEncoding.EncodeToString(png)
} else {
fmt.Print("Cannot generate QR code: ", err)
}
@ -315,7 +315,7 @@ func (o *JsonDB) GetClientByID(clientID string, qrCodeSettings model.QRCodeSetti
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))
clientData.QRCode = "data:image/png;base64," + base64.StdEncoding.EncodeToString(png)
} else {
fmt.Print("Cannot generate QR code: ", err)
}

View file

@ -23,7 +23,7 @@ func (o *JsonDB) GetWakeOnLanHosts() ([]model.WakeOnLanHost, error) {
host := model.WakeOnLanHost{}
// get client info
if err := json.Unmarshal([]byte(f), &host); err != nil {
if err := json.Unmarshal(f, &host); err != nil {
return hosts, fmt.Errorf("cannot decode client json structure: %v", err)
}

View file

@ -26,8 +26,8 @@ var (
Bot *echotron.API
BotMutex sync.RWMutex
floodWait = make(map[int64]int64, 0)
floodMessageSent = make(map[int64]struct{}, 0)
floodWait = make(map[int64]int64)
floodMessageSent = make(map[int64]struct{})
)
func Start(initDeps TgBotInitDependencies) (err error) {
@ -84,12 +84,15 @@ func Start(initDeps TgBotInitDependencies) (err error) {
continue
}
floodMessageSent[userid] = struct{}{}
bot.SendMessage(
_, err := bot.SendMessage(
fmt.Sprintf("You can only request your configs once per %d minutes", FloodWait),
userid,
&echotron.MessageOptions{
ReplyToMessageID: update.Message.ID,
})
if err != nil {
log.Errorf("Failed to send telegram message. Error %v", err)
}
continue
}
floodWait[userid] = time.Now().Unix()
@ -100,12 +103,15 @@ func Start(initDeps TgBotInitDependencies) (err error) {
for _, f := range failed {
messageText += f + "\n"
}
bot.SendMessage(
_, err := bot.SendMessage(
messageText,
userid,
&echotron.MessageOptions{
ReplyToMessageID: update.Message.ID,
})
if err != nil {
log.Errorf("Failed to send telegram message. Error %v", err)
}
}
}
}

View file

@ -96,7 +96,7 @@ Users Settings
$.ajax({
cache: false,
method: 'GET',
url: '{{.basePath}}/getusers',
url: '{{.basePath}}/get-users',
dataType: 'json',
contentType: "application/json",
success: function (data) {

View file

@ -3,5 +3,5 @@ package util
import "sync"
var IPToSubnetRange = map[string]uint16{}
var TgUseridToClientID = map[int64]([]string){}
var TgUseridToClientID = map[int64][]string{}
var TgUseridToClientIDMutex sync.RWMutex

View file

@ -2,6 +2,7 @@ package util
import (
"encoding/base64"
"errors"
"fmt"
"golang.org/x/crypto/bcrypt"
)
@ -20,7 +21,7 @@ func VerifyHash(base64Hash string, plaintext string) (bool, error) {
return false, fmt.Errorf("cannot decode base64 hash: %w", err)
}
err = bcrypt.CompareHashAndPassword(hash, []byte(plaintext))
if err == bcrypt.ErrMismatchedHashAndPassword {
if errors.Is(err, bcrypt.ErrMismatchedHashAndPassword) {
return false, nil
}
if err != nil {

View file

@ -7,7 +7,6 @@ import (
"fmt"
"io"
"io/fs"
"io/ioutil"
"math/rand"
"net"
"os"
@ -189,7 +188,7 @@ func GetInterfaceIPs() ([]model.Interface, error) {
return nil, err
}
var interfaceList = []model.Interface{}
var interfaceList []model.Interface
// get interface's ip addresses
for _, i := range ifaces {
@ -230,9 +229,9 @@ func GetPublicIP() (model.Interface, error) {
consensus := externalip.NewConsensus(&cfg, nil)
// add trusted voters
consensus.AddVoter(externalip.NewHTTPSource("http://checkip.amazonaws.com/"), 1)
consensus.AddVoter(externalip.NewHTTPSource("https://checkip.amazonaws.com/"), 1)
consensus.AddVoter(externalip.NewHTTPSource("http://whatismyip.akamai.com"), 1)
consensus.AddVoter(externalip.NewHTTPSource("http://ifconfig.top"), 1)
consensus.AddVoter(externalip.NewHTTPSource("https://ifconfig.top"), 1)
publicInterface := model.Interface{}
publicInterface.Name = "Public Address"
@ -244,7 +243,7 @@ func GetPublicIP() (model.Interface, error) {
publicInterface.IPAddress = ip.String()
}
// error handling happend above, no need to pass it through
// error handling happened above, no need to pass it through
return publicInterface, nil
}
@ -292,7 +291,7 @@ func GetAllocatedIPs(ignoreClientID string) ([]string, error) {
// append client's addresses to the result
for _, f := range records {
client := model.Client{}
if err := json.Unmarshal([]byte(f), &client); err != nil {
if err := json.Unmarshal(f, &client); err != nil {
return nil, err
}
@ -336,15 +335,15 @@ func GetBroadcastIP(n *net.IPNet) net.IP {
// GetBroadcastAndNetworkAddrsLookup get the ip address that can't be used with current server interfaces
func GetBroadcastAndNetworkAddrsLookup(interfaceAddresses []string) map[string]bool {
list := make(map[string]bool, 0)
list := make(map[string]bool)
for _, ifa := range interfaceAddresses {
_, net, err := net.ParseCIDR(ifa)
_, netAddr, err := net.ParseCIDR(ifa)
if err != nil {
continue
}
broadcastAddr := GetBroadcastIP(net).String()
networkAddr := net.IP.String()
broadcastAddr := GetBroadcastIP(netAddr).String()
networkAddr := netAddr.IP.String()
list[broadcastAddr] = true
list[networkAddr] = true
}
@ -354,14 +353,14 @@ func GetBroadcastAndNetworkAddrsLookup(interfaceAddresses []string) map[string]b
// GetAvailableIP get the ip address that can be allocated from an CIDR
// We need interfaceAddresses to find real broadcast and network addresses
func GetAvailableIP(cidr string, allocatedList, interfaceAddresses []string) (string, error) {
ip, net, err := net.ParseCIDR(cidr)
ip, netAddr, err := net.ParseCIDR(cidr)
if err != nil {
return "", err
}
unavailableIPs := GetBroadcastAndNetworkAddrsLookup(interfaceAddresses)
for ip := ip.Mask(net.Mask); net.Contains(ip); inc(ip) {
for ip := ip.Mask(netAddr.Mask); netAddr.Contains(ip); inc(ip) {
available := true
suggestedAddr := ip.String()
for _, allocatedAddr := range allocatedList {
@ -386,7 +385,7 @@ func ValidateIPAllocation(serverAddresses []string, ipAllocatedList []string, ip
// clientCIDR must be in CIDR format
if ip == nil {
return false, fmt.Errorf("Invalid ip allocation input %s. Must be in CIDR format", clientCIDR)
return false, fmt.Errorf("invalid ip allocation input %s. Must be in CIDR format", clientCIDR)
}
// return false immediately if the ip is already in use (in ipAllocatedList)
@ -398,7 +397,7 @@ func ValidateIPAllocation(serverAddresses []string, ipAllocatedList []string, ip
// even if it is not in use, we still need to check if it
// belongs to a network of the server.
var isValid bool = false
var isValid = false
for _, serverCIDR := range serverAddresses {
_, serverNet, _ := net.ParseCIDR(serverCIDR)
if serverNet.Contains(ip) {
@ -437,7 +436,7 @@ func findSubnetRangeForIP(cidr string) (uint16, error) {
}
}
}
return 0, fmt.Errorf("Subnet range not found for this IP")
return 0, fmt.Errorf("subnet range not found for this IP")
}
// FillClientSubnetRange to fill subnet ranges client belongs to, does nothing if SRs are not found
@ -470,11 +469,11 @@ func ValidateAndFixSubnetRanges(db store.IStore) error {
var serverSubnets []*net.IPNet
for _, addr := range server.Interface.Addresses {
addr = strings.TrimSpace(addr)
_, net, err := net.ParseCIDR(addr)
_, netAddr, err := net.ParseCIDR(addr)
if err != nil {
return err
}
serverSubnets = append(serverSubnets, net)
serverSubnets = append(serverSubnets, netAddr)
}
for _, rng := range SubnetRangesOrder {
@ -544,7 +543,7 @@ func WriteWireGuardServerConfig(tmplDir fs.FS, serverConfig model.Server, client
// if set, read wg.conf template from WgConfTemplate
if len(WgConfTemplate) > 0 {
fileContentBytes, err := ioutil.ReadFile(WgConfTemplate)
fileContentBytes, err := os.ReadFile(WgConfTemplate)
if err != nil {
return err
}