mirror of
https://github.com/h44z/wg-portal.git
synced 2025-09-13 14:31:15 +00:00
switch to bootstrap 4
This commit is contained in:
@@ -43,15 +43,35 @@ func (s *Server) GetAdminIndex(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
device := s.users.GetDevice()
|
||||
device.Interface = dev
|
||||
|
||||
users := make([]User, len(peers))
|
||||
for i, peer := range peers {
|
||||
users[i] = s.users.GetOrCreateUserForPeer(peer)
|
||||
}
|
||||
c.HTML(http.StatusOK, "admin_index.html", gin.H{
|
||||
"route": c.Request.URL.Path,
|
||||
"session": s.getSessionData(c),
|
||||
"static": s.getStaticData(),
|
||||
"peers": users,
|
||||
"interface": dev,
|
||||
c.HTML(http.StatusOK, "admin_index.html", struct {
|
||||
Route string
|
||||
Session SessionData
|
||||
Static StaticData
|
||||
Peers []User
|
||||
Device Device
|
||||
}{
|
||||
Route: c.Request.URL.Path,
|
||||
Session: s.getSessionData(c),
|
||||
Static: s.getStaticData(),
|
||||
Peers: users,
|
||||
Device: device,
|
||||
})
|
||||
}
|
||||
|
||||
func (s *Server) GetUserQRCode(c *gin.Context) {
|
||||
user := s.users.GetUser(c.Param("pkey"))
|
||||
png, err := user.GetQRCode()
|
||||
if err != nil {
|
||||
s.HandleError(c, http.StatusInternalServerError, "QRCode error", err.Error())
|
||||
return
|
||||
}
|
||||
c.Data(http.StatusOK, "image/png", png)
|
||||
return
|
||||
}
|
||||
|
@@ -24,6 +24,7 @@ func SetupRoutes(s *Server) {
|
||||
// User routes
|
||||
user := s.server.Group("/user")
|
||||
user.Use(s.RequireAuthentication("")) // empty scope = all logged in users
|
||||
user.GET("/qrcode", s.GetUserQRCode)
|
||||
}
|
||||
|
||||
func (s *Server) RequireAuthentication(scope string) gin.HandlerFunc {
|
||||
|
@@ -1,25 +1,31 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/md5"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
"text/template"
|
||||
"time"
|
||||
|
||||
"github.com/h44z/wg-portal/internal/wireguard"
|
||||
|
||||
"github.com/h44z/wg-portal/internal/common"
|
||||
|
||||
"github.com/h44z/wg-portal/internal/ldap"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/skip2/go-qrcode"
|
||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
Peer wgtypes.Peer `gorm:"-"`
|
||||
User *ldap.UserCacheHolderEntry `gorm:"-"` // optional, it is still possible to have users without ldap
|
||||
Peer wgtypes.Peer `gorm:"-"`
|
||||
User *ldap.UserCacheHolderEntry `gorm:"-"` // optional, it is still possible to have users without ldap
|
||||
Config string `gorm:"-"`
|
||||
|
||||
UID string // uid for html identification
|
||||
IsOnline bool `gorm:"-"`
|
||||
@@ -42,7 +48,7 @@ type User struct {
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
|
||||
func (u *User) GetPeerConfig() wgtypes.PeerConfig {
|
||||
func (u User) GetPeerConfig() wgtypes.PeerConfig {
|
||||
publicKey, _ := wgtypes.ParseKey(u.PublicKey)
|
||||
var presharedKey *wgtypes.Key
|
||||
if u.PresharedKey != "" {
|
||||
@@ -70,7 +76,20 @@ func (u *User) GetPeerConfig() wgtypes.PeerConfig {
|
||||
return cfg
|
||||
}
|
||||
|
||||
func (u User) GetQRCode() ([]byte, error) {
|
||||
png, err := qrcode.Encode(u.Config, qrcode.Medium, 250)
|
||||
if err != nil {
|
||||
log.WithFields(log.Fields{
|
||||
"err": err,
|
||||
}).Error("failed to create qrcode")
|
||||
return nil, err
|
||||
}
|
||||
return png, nil
|
||||
}
|
||||
|
||||
type Device struct {
|
||||
Interface *wgtypes.Device `gorm:"-"`
|
||||
|
||||
DeviceName string `gorm:"primaryKey"`
|
||||
PrivateKey string
|
||||
PublicKey string
|
||||
@@ -92,7 +111,7 @@ type Device struct {
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
|
||||
func (d *Device) IsValid() bool {
|
||||
func (d Device) IsValid() bool {
|
||||
if len(d.IPs) == 0 {
|
||||
return false
|
||||
}
|
||||
@@ -150,13 +169,15 @@ func (u *UserManager) GetAllUsers() []User {
|
||||
for i := range users {
|
||||
users[i].AllowedIPs = strings.Split(users[i].AllowedIPsStr, ", ")
|
||||
users[i].IPs = strings.Split(users[i].IPsStr, ", ")
|
||||
tmpCfg, _ := u.GetPeerConfigFile(users[i])
|
||||
users[i].Config = string(tmpCfg)
|
||||
}
|
||||
|
||||
return users
|
||||
}
|
||||
|
||||
func (u *UserManager) GetAllDevices() []Device {
|
||||
devices := make([]Device, 0)
|
||||
func (u *UserManager) GetDevice() Device {
|
||||
devices := make([]Device, 0, 1)
|
||||
u.db.Find(&devices)
|
||||
|
||||
for i := range devices {
|
||||
@@ -165,7 +186,7 @@ func (u *UserManager) GetAllDevices() []Device {
|
||||
devices[i].DNS = strings.Split(devices[i].DNSStr, ", ")
|
||||
}
|
||||
|
||||
return devices
|
||||
return devices[0]
|
||||
}
|
||||
|
||||
func (u *UserManager) GetOrCreateUserForPeer(peer wgtypes.Peer) User {
|
||||
@@ -199,6 +220,20 @@ func (u *UserManager) GetOrCreateUserForPeer(peer wgtypes.Peer) User {
|
||||
|
||||
user.IPs = strings.Split(user.IPsStr, ", ")
|
||||
user.AllowedIPs = strings.Split(user.AllowedIPsStr, ", ")
|
||||
tmpCfg, _ := u.GetPeerConfigFile(user)
|
||||
user.Config = string(tmpCfg)
|
||||
|
||||
return user
|
||||
}
|
||||
|
||||
func (u *UserManager) GetUser(publicKey string) User {
|
||||
user := User{}
|
||||
u.db.Where("public_key = ?", publicKey).FirstOrInit(&user)
|
||||
|
||||
user.IPs = strings.Split(user.IPsStr, ", ")
|
||||
user.AllowedIPs = strings.Split(user.AllowedIPsStr, ", ")
|
||||
tmpCfg, _ := u.GetPeerConfigFile(user)
|
||||
user.Config = string(tmpCfg)
|
||||
|
||||
return user
|
||||
}
|
||||
@@ -250,18 +285,16 @@ func (u *UserManager) GetAllReservedIps() ([]string, error) {
|
||||
}
|
||||
}
|
||||
|
||||
devices := u.GetAllDevices()
|
||||
for _, device := range devices {
|
||||
for _, cidr := range device.IPs {
|
||||
ip, _, err := net.ParseCIDR(cidr)
|
||||
if err != nil {
|
||||
log.WithFields(log.Fields{
|
||||
"err": err,
|
||||
"cidr": cidr,
|
||||
}).Error("failed to ip from cidr")
|
||||
} else {
|
||||
reservedIps = append(reservedIps, ip.String())
|
||||
}
|
||||
device := u.GetDevice()
|
||||
for _, cidr := range device.IPs {
|
||||
ip, _, err := net.ParseCIDR(cidr)
|
||||
if err != nil {
|
||||
log.WithFields(log.Fields{
|
||||
"err": err,
|
||||
"cidr": cidr,
|
||||
}).Error("failed to ip from cidr")
|
||||
} else {
|
||||
reservedIps = append(reservedIps, ip.String())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -320,3 +353,25 @@ func (u *UserManager) GetOrCreateDevice(dev wgtypes.Device) Device {
|
||||
|
||||
return device
|
||||
}
|
||||
|
||||
func (u *UserManager) GetPeerConfigFile(user User) ([]byte, error) {
|
||||
tpl, err := template.New("client").Funcs(template.FuncMap{"StringsJoin": strings.Join}).Parse(wireguard.ClientCfgTpl)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tplBuff bytes.Buffer
|
||||
|
||||
err = tpl.Execute(&tplBuff, struct {
|
||||
Client User
|
||||
Server Device
|
||||
}{
|
||||
Client: user,
|
||||
Server: u.GetDevice(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return tplBuff.Bytes(), nil
|
||||
}
|
||||
|
22
internal/wireguard/template.go
Normal file
22
internal/wireguard/template.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package wireguard
|
||||
|
||||
var (
|
||||
ClientCfgTpl = `[Interface]
|
||||
Address = {{ .Client.IPsStr }}
|
||||
PrivateKey = {{ .Client.PrivateKey }}
|
||||
{{ if ne (len .Server.DNS) 0 -}}
|
||||
DNS = {{ .Server.DNSStr }}
|
||||
{{- end }}
|
||||
{{ if ne .Server.Mtu 0 -}}
|
||||
MTU = {{.Server.Mtu}}
|
||||
{{- end}}
|
||||
[Peer]
|
||||
PublicKey = {{ .Server.PublicKey }}
|
||||
PresharedKey = {{ .Client.PresharedKey }}
|
||||
AllowedIPs = {{ .Client.AllowedIPsStr }}
|
||||
Endpoint = {{ .Server.Endpoint }}
|
||||
{{ if and (ne .Server.PersistentKeepalive 0) (not .Client.IgnorePersistentKeepalive) -}}
|
||||
PersistentKeepalive = {{.Server.PersistentKeepalive}}
|
||||
{{- end}}
|
||||
`
|
||||
)
|
Reference in New Issue
Block a user