diff --git a/assets/tpl/admin_create_clients.html b/assets/tpl/admin_create_clients.html
index 9d11549..12dd8a9 100644
--- a/assets/tpl/admin_create_clients.html
+++ b/assets/tpl/admin_create_clients.html
@@ -41,7 +41,7 @@
diff --git a/assets/tpl/admin_index.html b/assets/tpl/admin_index.html
index ec944c8..b76694d 100644
--- a/assets/tpl/admin_index.html
+++ b/assets/tpl/admin_index.html
@@ -111,8 +111,13 @@
{{$p.PublicKey}} |
{{$p.Email}} |
{{$p.IPsStr}} |
+ {{if not $p.Peer}}
+ ? / ? |
+ ? |
+ {{else}}
{{if $p.DeactivatedAt}}-{{else}}{{$p.Peer.ReceiveBytes}} / {{$p.Peer.TransmitBytes}}{{end}} |
{{if $p.DeactivatedAt}}-{{else}}{{$p.Peer.LastHandshakeTime}}{{end}} |
+ {{end}}
{{if eq $.Session.IsAdmin true}}
diff --git a/internal/common/iputil.go b/internal/common/iputil.go
index 0241b02..240c620 100644
--- a/internal/common/iputil.go
+++ b/internal/common/iputil.go
@@ -39,19 +39,19 @@ func IsIPv6(address string) bool {
return ip.To4() == nil
}
-func ParseIPList(lst string) []string {
- ips := strings.Split(lst, ",")
- validatedIPs := make([]string, 0, len(ips))
- for i := range ips {
- ips[i] = strings.TrimSpace(ips[i])
- if ips[i] != "" {
- validatedIPs = append(validatedIPs, ips[i])
+func ParseStringList(lst string) []string {
+ tokens := strings.Split(lst, ",")
+ validatedTokens := make([]string, 0, len(tokens))
+ for i := range tokens {
+ tokens[i] = strings.TrimSpace(tokens[i])
+ if tokens[i] != "" {
+ validatedTokens = append(validatedTokens, tokens[i])
}
}
- return validatedIPs
+ return validatedTokens
}
-func IPListToString(lst []string) string {
+func ListToString(lst []string) string {
return strings.Join(lst, ", ")
}
diff --git a/internal/server/handlers.go b/internal/server/handlers.go
index 8def6a9..1a9ad14 100644
--- a/internal/server/handlers.go
+++ b/internal/server/handlers.go
@@ -6,8 +6,11 @@ import (
"net/http"
"net/url"
"strconv"
+ "strings"
"time"
+ log "github.com/sirupsen/logrus"
+
"github.com/h44z/wg-portal/internal/ldap"
"github.com/h44z/wg-portal/internal/common"
@@ -89,12 +92,12 @@ func (s *Server) PostAdminEditInterface(c *gin.Context) {
return
}
// Clean list input
- formDevice.IPs = common.ParseIPList(formDevice.IPsStr)
- formDevice.AllowedIPs = common.ParseIPList(formDevice.AllowedIPsStr)
- formDevice.DNS = common.ParseIPList(formDevice.DNSStr)
- formDevice.IPsStr = common.IPListToString(formDevice.IPs)
- formDevice.AllowedIPsStr = common.IPListToString(formDevice.AllowedIPs)
- formDevice.DNSStr = common.IPListToString(formDevice.DNS)
+ formDevice.IPs = common.ParseStringList(formDevice.IPsStr)
+ formDevice.AllowedIPs = common.ParseStringList(formDevice.AllowedIPsStr)
+ formDevice.DNS = common.ParseStringList(formDevice.DNSStr)
+ formDevice.IPsStr = common.ListToString(formDevice.IPs)
+ formDevice.AllowedIPsStr = common.ListToString(formDevice.AllowedIPs)
+ formDevice.DNSStr = common.ListToString(formDevice.DNS)
// Update WireGuard device
err := s.wg.UpdateDevice(formDevice.DeviceName, formDevice.GetDeviceConfig())
@@ -149,10 +152,10 @@ func (s *Server) PostAdminEditPeer(c *gin.Context) {
}
// Clean list input
- formUser.IPs = common.ParseIPList(formUser.IPsStr)
- formUser.AllowedIPs = common.ParseIPList(formUser.AllowedIPsStr)
- formUser.IPsStr = common.IPListToString(formUser.IPs)
- formUser.AllowedIPsStr = common.IPListToString(formUser.AllowedIPs)
+ formUser.IPs = common.ParseStringList(formUser.IPsStr)
+ formUser.AllowedIPs = common.ParseStringList(formUser.AllowedIPsStr)
+ formUser.IPsStr = common.ListToString(formUser.IPs)
+ formUser.AllowedIPsStr = common.ListToString(formUser.AllowedIPs)
disabled := c.PostForm("isdisabled") != ""
now := time.Now()
@@ -244,10 +247,10 @@ func (s *Server) PostAdminCreatePeer(c *gin.Context) {
}
// Clean list input
- formUser.IPs = common.ParseIPList(formUser.IPsStr)
- formUser.AllowedIPs = common.ParseIPList(formUser.AllowedIPsStr)
- formUser.IPsStr = common.IPListToString(formUser.IPs)
- formUser.AllowedIPsStr = common.IPListToString(formUser.AllowedIPs)
+ formUser.IPs = common.ParseStringList(formUser.IPsStr)
+ formUser.AllowedIPs = common.ParseStringList(formUser.AllowedIPsStr)
+ formUser.IPsStr = common.ListToString(formUser.IPs)
+ formUser.AllowedIPsStr = common.ListToString(formUser.AllowedIPs)
disabled := c.PostForm("isdisabled") != ""
now := time.Now()
@@ -265,7 +268,7 @@ func (s *Server) PostAdminCreatePeer(c *gin.Context) {
}
}
- // Update in database
+ // Create in database
err := s.users.CreateUser(formUser)
if err != nil {
s.setAlert(c, "failed to add user in database: "+err.Error(), "danger")
@@ -297,6 +300,73 @@ func (s *Server) GetAdminCreateLdapPeers(c *gin.Context) {
})
}
+func (s *Server) PostAdminCreateLdapPeers(c *gin.Context) {
+ email := c.PostForm("email")
+ identifier := c.PostForm("identifier")
+ if identifier == "" {
+ identifier = "Default"
+ }
+ if email == "" {
+ s.setAlert(c, "missing email address", "danger")
+ c.Redirect(http.StatusSeeOther, "/admin/peer/createldap")
+ return
+ }
+ emails := common.ParseStringList(email)
+ for i := range emails {
+ // TODO: also check email addr for validity?
+ if !strings.ContainsRune(emails[i], '@') || s.ldapUsers.GetUserDNByMail(emails[i]) == "" {
+ s.setAlert(c, "invalid email address: "+emails[i], "danger")
+ c.Redirect(http.StatusSeeOther, "/admin/peer/createldap")
+ return
+ }
+ }
+
+ log.Infof("creating %d ldap peers", len(emails))
+ device := s.users.GetDevice()
+
+ for i := range emails {
+ ldapUser := s.ldapUsers.GetUserData(s.ldapUsers.GetUserDNByMail(emails[i]))
+ user := User{}
+ user.AllowedIPsStr = device.AllowedIPsStr
+ user.IPsStr = "" // TODO: add a valid ip here
+ psk, err := wgtypes.GenerateKey()
+ if err != nil {
+ s.HandleError(c, http.StatusInternalServerError, "Preshared key generation error", err.Error())
+ return
+ }
+ key, err := wgtypes.GeneratePrivateKey()
+ if err != nil {
+ s.HandleError(c, http.StatusInternalServerError, "Private key generation error", err.Error())
+ return
+ }
+ user.PresharedKey = psk.String()
+ user.PrivateKey = key.String()
+ user.PublicKey = key.PublicKey().String()
+ user.UID = fmt.Sprintf("u%x", md5.Sum([]byte(user.PublicKey)))
+ user.Email = emails[i]
+ user.Identifier = fmt.Sprintf("%s %s (%s)", ldapUser.Firstname, ldapUser.Lastname, identifier)
+
+ // Create wireguard interface
+ err = s.wg.AddPeer(user.GetPeerConfig())
+ if err != nil {
+ s.setAlert(c, "failed to add peer in WireGuard: "+err.Error(), "danger")
+ c.Redirect(http.StatusSeeOther, "/admin/peer/createldap")
+ return
+ }
+
+ // Create in database
+ err = s.users.CreateUser(user)
+ if err != nil {
+ s.setAlert(c, "failed to add user in database: "+err.Error(), "danger")
+ c.Redirect(http.StatusSeeOther, "/admin/peer/createldap")
+ return
+ }
+ }
+
+ s.setAlert(c, "client(s) created successfully", "success")
+ c.Redirect(http.StatusSeeOther, "/admin/peer/createldap")
+}
+
func (s *Server) GetUserQRCode(c *gin.Context) {
user := s.users.GetUserByKey(c.Query("pkey"))
png, err := user.GetQRCode()
diff --git a/internal/server/routes.go b/internal/server/routes.go
index 9d2d99e..8c66fdf 100644
--- a/internal/server/routes.go
+++ b/internal/server/routes.go
@@ -27,6 +27,7 @@ func SetupRoutes(s *Server) {
admin.GET("/peer/create", s.GetAdminCreatePeer)
admin.POST("/peer/create", s.PostAdminCreatePeer)
admin.GET("/peer/createldap", s.GetAdminCreateLdapPeers)
+ admin.POST("/peer/createldap", s.PostAdminCreateLdapPeers)
// User routes
user := s.server.Group("/user")
diff --git a/internal/server/usermanager.go b/internal/server/usermanager.go
index cef6878..a9316e9 100644
--- a/internal/server/usermanager.go
+++ b/internal/server/usermanager.go
@@ -32,7 +32,7 @@ import (
var cidrList validator.Func = func(fl validator.FieldLevel) bool {
cidrListStr := fl.Field().String()
- cidrList := common.ParseIPList(cidrListStr)
+ cidrList := common.ParseStringList(cidrListStr)
for i := range cidrList {
_, _, err := net.ParseCIDR(cidrList[i])
if err != nil {
@@ -45,7 +45,7 @@ var cidrList validator.Func = func(fl validator.FieldLevel) bool {
var ipList validator.Func = func(fl validator.FieldLevel) bool {
ipListStr := fl.Field().String()
- ipList := common.ParseIPList(ipListStr)
+ ipList := common.ParseStringList(ipListStr)
for i := range ipList {
ip := net.ParseIP(ipList[i])
if ip == nil {
|