Skip to content

Commit

Permalink
Merge pull request #3 from UnAfraid/feature/transaction_scoper
Browse files Browse the repository at this point in the history
Added proper transactions and multi-backend wireguard interface support
  • Loading branch information
UnAfraid authored Oct 22, 2023
2 parents 3692966 + 7dca370 commit af015e4
Show file tree
Hide file tree
Showing 55 changed files with 1,910 additions and 1,599 deletions.
14 changes: 14 additions & 0 deletions .env.dist
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Wireguard interface backend
# Default: linux
WG_UI_BACKEND=linux

# The main database file path
# Stores all users and wireguard servers configuration
WG_UI_BOLT_DB_PATH=/var/lib/wg-ui/data.db
Expand Down Expand Up @@ -110,6 +114,16 @@ [email protected]
# Default: random
WG_UI_INITIAL_PASSWORD=random

# Automatically updates server's stats from wireguard device
# This also will publish subscription events to anyone listening
# Can be disabled with value of 0s
# Default: 30s
WG_UI_AUTOMATIC_STATS_UPDATE_INTERVAL=30s

# Automatically updates server's stats from wireguard device but only when there is at least 1 subscriber
# Default: false
WG_UI_AUTOMATIC_STATS_UPDATE_ONLY_WITH_SUBSCRIBERS=false

# CORS allowed origins
# Multiple origins are supported separated by comma
# Example: http://localhost:3000,https://wg-ui-abcdf--*.web.app,https://wg-ui.your-domain.com
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ require (
golang.org/x/sys v0.13.0 // indirect
golang.org/x/text v0.13.0 // indirect
golang.org/x/tools v0.14.0 // indirect
golang.zx2c4.com/wireguard v0.0.0-20231018191413-24ea13351eb7 // indirect
golang.zx2c4.com/wireguard v0.0.0-20231022001213-2e0774f246fb // indirect
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,8 @@ golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc=
golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg=
golang.zx2c4.com/wireguard v0.0.0-20231018191413-24ea13351eb7 h1:1+bHXA5s3p7saWQTFJKtQF7WzoU0HEvIe5iUovtpzhU=
golang.zx2c4.com/wireguard v0.0.0-20231018191413-24ea13351eb7/go.mod h1:tkCQ4FQXmpAgYVh++1cq16/dH4QJtmvpRv19DWGAHSA=
golang.zx2c4.com/wireguard v0.0.0-20231022001213-2e0774f246fb h1:c5tyN8sSp8jSDxdCCDXVOpJwYXXhmTkNMt+g0zTSOic=
golang.zx2c4.com/wireguard v0.0.0-20231022001213-2e0774f246fb/go.mod h1:tkCQ4FQXmpAgYVh++1cq16/dH4QJtmvpRv19DWGAHSA=
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6 h1:CawjfCvYQH2OU3/TnxLx97WDSUDRABfT18pCOYwc2GE=
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6/go.mod h1:3rxYc4HtVcSG9gVaTs2GEBdehh+sYPOwKtyUWEOTb80=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
50 changes: 40 additions & 10 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"net/http"
"os"
"os/signal"
"strings"
"syscall"
"time"

Expand All @@ -19,12 +20,15 @@ import (
"github.com/UnAfraid/wg-ui/pkg/config"
"github.com/UnAfraid/wg-ui/pkg/datastore"
"github.com/UnAfraid/wg-ui/pkg/datastore/bbolt"
"github.com/UnAfraid/wg-ui/pkg/dbx"
"github.com/UnAfraid/wg-ui/pkg/manage"
"github.com/UnAfraid/wg-ui/pkg/peer"
"github.com/UnAfraid/wg-ui/pkg/server"
"github.com/UnAfraid/wg-ui/pkg/subscription"
"github.com/UnAfraid/wg-ui/pkg/user"
"github.com/UnAfraid/wg-ui/pkg/wg"
"github.com/UnAfraid/wg-ui/pkg/wireguard"
"github.com/UnAfraid/wg-ui/pkg/wireguard/backend"
"github.com/UnAfraid/wg-ui/pkg/wireguard/linux"
)

const (
Expand Down Expand Up @@ -92,43 +96,69 @@ func main() {
return
}

transactionScoper := dbx.NewBBoltTransactionScoper(db)
subscriptionImpl := subscription.NewInMemorySubscription()

serverRepository := bbolt.NewServerRepository(db)
serverService := server.NewService(serverRepository, subscriptionImpl)
serverService := server.NewService(serverRepository, transactionScoper, subscriptionImpl)

peerRepository := bbolt.NewPeerRepository(db)
peerService := peer.NewService(peerRepository, serverService, subscriptionImpl)
peerService := peer.NewService(peerRepository, transactionScoper, serverService, subscriptionImpl)

userRepository := bbolt.NewUserRepository(db)
userService, err := user.NewService(userRepository, subscriptionImpl, conf.Initial.Email, conf.Initial.Password)
userService, err := user.NewService(userRepository, transactionScoper, subscriptionImpl, conf.Initial.Email, conf.Initial.Password)
if err != nil {
logrus.
WithError(err).
Fatal("failed to initialize user service")
return
}

wgService, err := wg.NewService(serverService, peerService)
if err != nil {
var wireguardBackend backend.Backend
switch strings.ToLower(conf.Backend) {
case "linux":
wireguardBackend, err = linux.NewLinuxBackend()
if err != nil {
logrus.
WithError(err).
Fatal("failed to initialize linux backend for wireguard")
return
}
default:
logrus.
WithError(err).
Fatal("failed to initialize WireGuard service")
Fatal("unsupported wireguard backend")
return
}
defer wgService.Close()

wireguardService := wireguard.NewService(wireguardBackend)
defer func() {
if err := wireguardService.Close(context.Background()); err != nil {
logrus.
WithError(err).
Error("failed to close wireguard service")
}
}()

authService := auth.NewService(jwt.SigningMethodHS256, jwtSecretBytes, jwtSecretBytes, conf.JwtDuration)

manageService := manage.NewService(userService, serverService, peerService, wgService)
manageService := manage.NewService(
transactionScoper,
userService,
serverService,
peerService,
wireguardService,
conf.AutomaticStatsUpdateInterval,
conf.AutomaticStatsUpdateOnlyWithSubscribers,
)
defer manageService.Close()

router := api.NewRouter(
conf,
authService,
userService,
serverService,
peerService,
wgService,
manageService,
)

Expand Down
9 changes: 2 additions & 7 deletions pkg/api/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
"github.com/UnAfraid/wg-ui/pkg/peer"
"github.com/UnAfraid/wg-ui/pkg/server"
"github.com/UnAfraid/wg-ui/pkg/user"
"github.com/UnAfraid/wg-ui/pkg/wg"
)

//go:generate go run github.com/99designs/gqlgen --config ../../gqlgen.yml generate
Expand All @@ -23,16 +22,15 @@ func newConfig(
userService user.Service,
serverService server.Service,
peerService peer.Service,
wgService wg.Service,
manageService manage.Service,
) resolver.Config {
return resolver.Config{
Resolvers: &resolverRoot{
queryResolver: query.NewQueryResolver(
wgService,
peerService,
serverService,
userService,
manageService,
),
mutationResolver: mutation.NewMutationResolver(
authService,
Expand All @@ -48,13 +46,10 @@ func newConfig(
peerService,
),
serverResolver: serverResolver.NewServerResolver(
serverService,
peerService,
wgService,
),
peerResolver: peerResolver.NewPeerResolver(
peerService,
wgService,
manageService,
),
},
Directives: directive.NewDirectiveRoot(),
Expand Down
30 changes: 17 additions & 13 deletions pkg/api/internal/model/adapter_foreign.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package model

import (
"net"

"github.com/UnAfraid/wg-ui/pkg/internal/adapt"
"github.com/UnAfraid/wg-ui/pkg/wg"
"github.com/UnAfraid/wg-ui/pkg/wireguard/backend"
)

func ToForeignInterface(foreignInterface *wg.ForeignInterface) *ForeignInterface {
func ToForeignInterface(foreignInterface *backend.ForeignInterface) *ForeignInterface {
if foreignInterface == nil {
return nil
}
Expand All @@ -17,13 +19,13 @@ func ToForeignInterface(foreignInterface *wg.ForeignInterface) *ForeignInterface
}
}

func ToForeignServer(foreignServer *wg.ForeignServer) *ForeignServer {
func ToForeignServer(foreignServer *backend.ForeignServer) *ForeignServer {
if foreignServer == nil {
return nil
}

return &ForeignServer{
ForeignInterface: ToForeignInterface(foreignServer.ForeignInterface),
ForeignInterface: ToForeignInterface(foreignServer.Interface),
Name: foreignServer.Name,
Type: foreignServer.Type,
PublicKey: foreignServer.PublicKey,
Expand All @@ -33,19 +35,21 @@ func ToForeignServer(foreignServer *wg.ForeignServer) *ForeignServer {
}
}

func ToForeignPeer(foreignPeer *wg.ForeignPeer) *ForeignPeer {
func ToForeignPeer(foreignPeer *backend.Peer) *ForeignPeer {
if foreignPeer == nil {
return nil
}

return &ForeignPeer{
PublicKey: foreignPeer.PublicKey,
Endpoint: foreignPeer.Endpoint,
AllowedIps: foreignPeer.AllowedIPs,
PersistentKeepAliveInterval: int(foreignPeer.PersistentKeepaliveInterval),
LastHandshakeTime: adapt.ToPointer(foreignPeer.LastHandshakeTime),
ReceiveBytes: float64(foreignPeer.ReceiveBytes),
TransmitBytes: float64(foreignPeer.TransmitBytes),
ProtocolVersion: foreignPeer.ProtocolVersion,
PublicKey: foreignPeer.PublicKey,
Endpoint: adapt.ToPointerNilZero(foreignPeer.Endpoint),
AllowedIps: adapt.Array(foreignPeer.AllowedIPs, func(allowedIp net.IPNet) string {
return allowedIp.String()
}),
PersistentKeepAliveInterval: int(foreignPeer.PersistentKeepalive.Seconds()),
LastHandshakeTime: adapt.ToPointer(foreignPeer.Stats.LastHandshakeTime),
ReceiveBytes: float64(foreignPeer.Stats.ReceiveBytes),
TransmitBytes: float64(foreignPeer.Stats.TransmitBytes),
ProtocolVersion: foreignPeer.Stats.ProtocolVersion,
}
}
4 changes: 2 additions & 2 deletions pkg/api/internal/model/adapter_peer.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package model
import (
"github.com/UnAfraid/wg-ui/pkg/internal/adapt"
"github.com/UnAfraid/wg-ui/pkg/peer"
"github.com/UnAfraid/wg-ui/pkg/wg"
"github.com/UnAfraid/wg-ui/pkg/wireguard/backend"
)

func CreatePeerInputToCreateOptions(input CreatePeerInput) *peer.CreateOptions {
Expand Down Expand Up @@ -140,7 +140,7 @@ func PeerHookInputToPeerHook(hook *PeerHookInput) *peer.Hook {
}
}

func ToPeerStats(stats *wg.PeerStats) *PeerStats {
func ToPeerStats(stats *backend.PeerStats) *PeerStats {
if stats == nil {
return nil
}
Expand Down
8 changes: 0 additions & 8 deletions pkg/api/internal/model/adapter_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ func CreateServerInputToCreateServerOptions(input CreateServerInput) (_ *server.
Name: input.Name,
Description: adapt.Dereference(input.Description.Value()),
Enabled: adapt.Dereference(input.Enabled.Value()),
PublicKey: adapt.Dereference(input.PublicKey.Value()),
PrivateKey: adapt.Dereference(input.PrivateKey.Value()),
ListenPort: input.ListenPort.Value(),
FirewallMark: input.FirewallMark.Value(),
Expand Down Expand Up @@ -81,7 +80,6 @@ func UpdateServerInputToUpdateOptionsAndUpdateFieldMask(input UpdateServerInput)
fieldMask = &server.UpdateFieldMask{
Description: input.Description.IsSet(),
Enabled: input.Enabled.IsSet(),
PublicKey: input.PublicKey.IsSet(),
PrivateKey: input.PrivateKey.IsSet(),
ListenPort: input.ListenPort.IsSet(),
FirewallMark: input.FirewallMark.IsSet(),
Expand All @@ -94,7 +92,6 @@ func UpdateServerInputToUpdateOptionsAndUpdateFieldMask(input UpdateServerInput)
var (
description string
enabled bool
publicKey string
privateKey string
listenPort *int
firewallMark *int
Expand All @@ -112,10 +109,6 @@ func UpdateServerInputToUpdateOptionsAndUpdateFieldMask(input UpdateServerInput)
enabled = adapt.Dereference(input.Enabled.Value())
}

if fieldMask.PublicKey {
publicKey = adapt.Dereference(input.PublicKey.Value())
}

if fieldMask.PrivateKey {
privateKey = adapt.Dereference(input.PrivateKey.Value())
}
Expand Down Expand Up @@ -147,7 +140,6 @@ func UpdateServerInputToUpdateOptionsAndUpdateFieldMask(input UpdateServerInput)
options = &server.UpdateOptions{
Description: description,
Enabled: enabled,
PublicKey: publicKey,
PrivateKey: privateKey,
ListenPort: listenPort,
FirewallMark: firewallMark,
Expand Down
24 changes: 22 additions & 2 deletions pkg/api/internal/mutation/mutation_resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,12 +197,22 @@ func (r *mutationResolver) DeleteServer(ctx context.Context, input model.DeleteS
}

func (r *mutationResolver) StartServer(ctx context.Context, input model.StartServerInput) (*model.StartServerPayload, error) {
user, err := model.ContextToUser(ctx)
if err != nil {
return nil, err
}

userId, err := user.ID.String(model.IdKindUser)
if err != nil {
return nil, err
}

serverId, err := input.ID.String(model.IdKindServer)
if err != nil {
return nil, err
}

srv, err := r.manageService.StartServer(ctx, serverId)
srv, err := r.manageService.StartServer(ctx, serverId, userId)
if err != nil {
return nil, err
}
Expand All @@ -214,12 +224,22 @@ func (r *mutationResolver) StartServer(ctx context.Context, input model.StartSer
}

func (r *mutationResolver) StopServer(ctx context.Context, input model.StopServerInput) (*model.StopServerPayload, error) {
user, err := model.ContextToUser(ctx)
if err != nil {
return nil, err
}

userId, err := user.ID.String(model.IdKindUser)
if err != nil {
return nil, err
}

serverId, err := input.ID.String(model.IdKindServer)
if err != nil {
return nil, err
}

srv, err := r.manageService.StopServer(ctx, serverId)
srv, err := r.manageService.StopServer(ctx, serverId, userId)
if err != nil {
return nil, err
}
Expand Down
14 changes: 5 additions & 9 deletions pkg/api/internal/peer/peer_resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,18 @@ import (
"github.com/UnAfraid/wg-ui/pkg/api/internal/handler"
"github.com/UnAfraid/wg-ui/pkg/api/internal/model"
"github.com/UnAfraid/wg-ui/pkg/api/internal/resolver"
"github.com/UnAfraid/wg-ui/pkg/peer"
"github.com/UnAfraid/wg-ui/pkg/wg"
"github.com/UnAfraid/wg-ui/pkg/manage"
)

type peerResolver struct {
peerService peer.Service
wgService wg.Service
manageService manage.Service
}

func NewPeerResolver(
peerService peer.Service,
wgService wg.Service,
manageService manage.Service,
) resolver.PeerResolver {
return &peerResolver{
wgService: wgService,
peerService: peerService,
manageService: manageService,
}
}

Expand Down Expand Up @@ -66,7 +62,7 @@ func (r *peerResolver) Stats(ctx context.Context, p *model.Peer) (*model.PeerSta
return nil, nil
}

stats, err := r.wgService.PeerStats(server.Name, p.PublicKey)
stats, err := r.manageService.PeerStats(ctx, server.Name, p.PublicKey)
if err != nil {
return nil, err
}
Expand Down
Loading

0 comments on commit af015e4

Please sign in to comment.