mirror of
https://github.com/h44z/wg-portal.git
synced 2025-10-07 08:56:18 +00:00
Compare commits
2 Commits
v2.1.0-bet
...
mikrotik_i
Author | SHA1 | Date | |
---|---|---|---|
|
facdeb785f | ||
|
0c291a4eff |
6
go.mod
6
go.mod
@@ -10,7 +10,7 @@ require (
|
|||||||
github.com/go-ldap/ldap/v3 v3.4.11
|
github.com/go-ldap/ldap/v3 v3.4.11
|
||||||
github.com/go-pkgz/routegroup v1.5.3
|
github.com/go-pkgz/routegroup v1.5.3
|
||||||
github.com/go-playground/validator/v10 v10.27.0
|
github.com/go-playground/validator/v10 v10.27.0
|
||||||
github.com/go-webauthn/webauthn v0.14.0
|
github.com/go-webauthn/webauthn v0.13.4
|
||||||
github.com/google/uuid v1.6.0
|
github.com/google/uuid v1.6.0
|
||||||
github.com/prometheus-community/pro-bing v0.7.0
|
github.com/prometheus-community/pro-bing v0.7.0
|
||||||
github.com/prometheus/client_golang v1.23.2
|
github.com/prometheus/client_golang v1.23.2
|
||||||
@@ -29,7 +29,7 @@ require (
|
|||||||
gorm.io/driver/mysql v1.6.0
|
gorm.io/driver/mysql v1.6.0
|
||||||
gorm.io/driver/postgres v1.6.0
|
gorm.io/driver/postgres v1.6.0
|
||||||
gorm.io/driver/sqlserver v1.6.1
|
gorm.io/driver/sqlserver v1.6.1
|
||||||
gorm.io/gorm v1.31.0
|
gorm.io/gorm v1.30.5
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
@@ -64,7 +64,7 @@ require (
|
|||||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||||
github.com/go-sql-driver/mysql v1.9.3 // indirect
|
github.com/go-sql-driver/mysql v1.9.3 // indirect
|
||||||
github.com/go-test/deep v1.1.1 // indirect
|
github.com/go-test/deep v1.1.1 // indirect
|
||||||
github.com/go-webauthn/x v0.1.25 // indirect
|
github.com/go-webauthn/x v0.1.24 // indirect
|
||||||
github.com/golang-jwt/jwt/v5 v5.3.0 // indirect
|
github.com/golang-jwt/jwt/v5 v5.3.0 // indirect
|
||||||
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect
|
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect
|
||||||
github.com/golang-sql/sqlexp v0.1.0 // indirect
|
github.com/golang-sql/sqlexp v0.1.0 // indirect
|
||||||
|
14
go.sum
14
go.sum
@@ -106,10 +106,10 @@ github.com/go-sql-driver/mysql v1.9.3 h1:U/N249h2WzJ3Ukj8SowVFjdtZKfu9vlLZxjPXV1
|
|||||||
github.com/go-sql-driver/mysql v1.9.3/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU=
|
github.com/go-sql-driver/mysql v1.9.3/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU=
|
||||||
github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U=
|
github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U=
|
||||||
github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
|
github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
|
||||||
github.com/go-webauthn/webauthn v0.14.0 h1:ZLNPUgPcDlAeoxe+5umWG/tEeCoQIDr7gE2Zx2QnhL0=
|
github.com/go-webauthn/webauthn v0.13.4 h1:q68qusWPcqHbg9STSxBLBHnsKaLxNO0RnVKaAqMuAuQ=
|
||||||
github.com/go-webauthn/webauthn v0.14.0/go.mod h1:QZzPFH3LJ48u5uEPAu+8/nWJImoLBWM7iAH/kSVSo6k=
|
github.com/go-webauthn/webauthn v0.13.4/go.mod h1:MglN6OH9ECxvhDqoq1wMoF6P6JRYDiQpC9nc5OomQmI=
|
||||||
github.com/go-webauthn/x v0.1.25 h1:g/0noooIGcz/yCVqebcFgNnGIgBlJIccS+LYAa+0Z88=
|
github.com/go-webauthn/x v0.1.24 h1:6LaWf2zzWqbyKT8IyQkhje1/1KCGhlEkMz4V1tDnt/A=
|
||||||
github.com/go-webauthn/x v0.1.25/go.mod h1:ieblaPY1/BVCV0oQTsA/VAo08/TWayQuJuo5Q+XxmTY=
|
github.com/go-webauthn/x v0.1.24/go.mod h1:2o5XKJ+X1AKqYKGgHdKflGnoQFQZ6flJ2IFCBKSbSOw=
|
||||||
github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||||
@@ -255,8 +255,6 @@ github.com/yeqown/reedsolomon v1.0.0/go.mod h1:P76zpcn2TCuL0ul1Fso373qHRc69LKwAw
|
|||||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||||
go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
|
|
||||||
go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=
|
|
||||||
go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=
|
go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=
|
||||||
go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=
|
go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=
|
||||||
go.yaml.in/yaml/v3 v3.0.3 h1:bXOww4E/J3f66rav3pX3m8w6jDE4knZjGOw8b5Y6iNE=
|
go.yaml.in/yaml/v3 v3.0.3 h1:bXOww4E/J3f66rav3pX3m8w6jDE4knZjGOw8b5Y6iNE=
|
||||||
@@ -399,8 +397,8 @@ gorm.io/driver/postgres v1.6.0/go.mod h1:vUw0mrGgrTK+uPHEhAdV4sfFELrByKVGnaVRkXD
|
|||||||
gorm.io/driver/sqlserver v1.6.1 h1:XWISFsu2I2pqd1KJhhTZNJMx1jNQ+zVL/Q8ovDcUjtY=
|
gorm.io/driver/sqlserver v1.6.1 h1:XWISFsu2I2pqd1KJhhTZNJMx1jNQ+zVL/Q8ovDcUjtY=
|
||||||
gorm.io/driver/sqlserver v1.6.1/go.mod h1:VZeNn7hqX1aXoN5TPAFGWvxWG90xtA8erGn2gQmpc6U=
|
gorm.io/driver/sqlserver v1.6.1/go.mod h1:VZeNn7hqX1aXoN5TPAFGWvxWG90xtA8erGn2gQmpc6U=
|
||||||
gorm.io/gorm v1.30.0/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE=
|
gorm.io/gorm v1.30.0/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE=
|
||||||
gorm.io/gorm v1.31.0 h1:0VlycGreVhK7RF/Bwt51Fk8v0xLiiiFdbGDPIZQ7mJY=
|
gorm.io/gorm v1.30.5 h1:dvEfYwxL+i+xgCNSGGBT1lDjCzfELK8fHZxL3Ee9X0s=
|
||||||
gorm.io/gorm v1.31.0/go.mod h1:XyQVbO2k6YkOis7C2437jSit3SsDK72s7n7rsSHd+Gs=
|
gorm.io/gorm v1.30.5/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE=
|
||||||
modernc.org/cc/v4 v4.26.4 h1:jPhG8oNjtTYuP2FA4YefTJ/wioNUGALmGuEWt7SUR6s=
|
modernc.org/cc/v4 v4.26.4 h1:jPhG8oNjtTYuP2FA4YefTJ/wioNUGALmGuEWt7SUR6s=
|
||||||
modernc.org/cc/v4 v4.26.4/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0=
|
modernc.org/cc/v4 v4.26.4/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0=
|
||||||
modernc.org/ccgo/v4 v4.28.1 h1:wPKYn5EC/mYTqBO373jKjvX2n+3+aK7+sICCv4Fjy1A=
|
modernc.org/ccgo/v4 v4.28.1 h1:wPKYn5EC/mYTqBO373jKjvX2n+3+aK7+sICCv4Fjy1A=
|
||||||
|
@@ -188,8 +188,6 @@ func (m Manager) CreatePeer(ctx context.Context, peer *domain.Peer) (*domain.Pee
|
|||||||
|
|
||||||
sessionUser := domain.GetUserInfo(ctx)
|
sessionUser := domain.GetUserInfo(ctx)
|
||||||
|
|
||||||
peer.Identifier = domain.PeerIdentifier(peer.Interface.PublicKey) // ensure that identifier corresponds to the public key
|
|
||||||
|
|
||||||
// Enforce peer limit for non-admin users if LimitAdditionalUserPeers is set
|
// Enforce peer limit for non-admin users if LimitAdditionalUserPeers is set
|
||||||
if m.cfg.Core.SelfProvisioningAllowed && !sessionUser.IsAdmin && m.cfg.Advanced.LimitAdditionalUserPeers > 0 {
|
if m.cfg.Core.SelfProvisioningAllowed && !sessionUser.IsAdmin && m.cfg.Advanced.LimitAdditionalUserPeers > 0 {
|
||||||
peers, err := m.db.GetUserPeers(ctx, peer.UserIdentifier)
|
peers, err := m.db.GetUserPeers(ctx, peer.UserIdentifier)
|
||||||
|
@@ -1,194 +0,0 @@
|
|||||||
package wireguard
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/h44z/wg-portal/internal/config"
|
|
||||||
"github.com/h44z/wg-portal/internal/domain"
|
|
||||||
)
|
|
||||||
|
|
||||||
// --- Test mocks ---
|
|
||||||
|
|
||||||
type mockBus struct{}
|
|
||||||
|
|
||||||
func (f *mockBus) Publish(topic string, args ...any) {}
|
|
||||||
func (f *mockBus) Subscribe(topic string, fn interface{}) error { return nil }
|
|
||||||
|
|
||||||
type mockController struct{}
|
|
||||||
|
|
||||||
func (f *mockController) GetId() domain.InterfaceBackend { return "local" }
|
|
||||||
func (f *mockController) GetInterfaces(_ context.Context) ([]domain.PhysicalInterface, error) {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
func (f *mockController) GetInterface(_ context.Context, id domain.InterfaceIdentifier) (
|
|
||||||
*domain.PhysicalInterface,
|
|
||||||
error,
|
|
||||||
) {
|
|
||||||
return &domain.PhysicalInterface{Identifier: id}, nil
|
|
||||||
}
|
|
||||||
func (f *mockController) GetPeers(_ context.Context, _ domain.InterfaceIdentifier) ([]domain.PhysicalPeer, error) {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
func (f *mockController) SaveInterface(
|
|
||||||
_ context.Context,
|
|
||||||
_ domain.InterfaceIdentifier,
|
|
||||||
updateFunc func(pi *domain.PhysicalInterface) (*domain.PhysicalInterface, error),
|
|
||||||
) error {
|
|
||||||
_, _ = updateFunc(&domain.PhysicalInterface{})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
func (f *mockController) DeleteInterface(_ context.Context, _ domain.InterfaceIdentifier) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
func (f *mockController) SavePeer(
|
|
||||||
_ context.Context,
|
|
||||||
_ domain.InterfaceIdentifier,
|
|
||||||
_ domain.PeerIdentifier,
|
|
||||||
updateFunc func(pp *domain.PhysicalPeer) (*domain.PhysicalPeer, error),
|
|
||||||
) error {
|
|
||||||
_, _ = updateFunc(&domain.PhysicalPeer{})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
func (f *mockController) DeletePeer(_ context.Context, _ domain.InterfaceIdentifier, _ domain.PeerIdentifier) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
func (f *mockController) PingAddresses(_ context.Context, _ string) (*domain.PingerResult, error) {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type mockDB struct {
|
|
||||||
savedPeers map[domain.PeerIdentifier]*domain.Peer
|
|
||||||
iface *domain.Interface
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *mockDB) GetInterface(ctx context.Context, id domain.InterfaceIdentifier) (*domain.Interface, error) {
|
|
||||||
if f.iface != nil && f.iface.Identifier == id {
|
|
||||||
return f.iface, nil
|
|
||||||
}
|
|
||||||
return &domain.Interface{Identifier: id}, nil
|
|
||||||
}
|
|
||||||
func (f *mockDB) GetInterfaceAndPeers(ctx context.Context, id domain.InterfaceIdentifier) (
|
|
||||||
*domain.Interface,
|
|
||||||
[]domain.Peer,
|
|
||||||
error,
|
|
||||||
) {
|
|
||||||
return f.iface, nil, nil
|
|
||||||
}
|
|
||||||
func (f *mockDB) GetPeersStats(ctx context.Context, ids ...domain.PeerIdentifier) ([]domain.PeerStatus, error) {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
func (f *mockDB) GetAllInterfaces(ctx context.Context) ([]domain.Interface, error) { return nil, nil }
|
|
||||||
func (f *mockDB) GetInterfaceIps(ctx context.Context) (map[domain.InterfaceIdentifier][]domain.Cidr, error) {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
func (f *mockDB) SaveInterface(
|
|
||||||
ctx context.Context,
|
|
||||||
id domain.InterfaceIdentifier,
|
|
||||||
updateFunc func(in *domain.Interface) (*domain.Interface, error),
|
|
||||||
) error {
|
|
||||||
if f.iface == nil {
|
|
||||||
f.iface = &domain.Interface{Identifier: id}
|
|
||||||
}
|
|
||||||
var err error
|
|
||||||
f.iface, err = updateFunc(f.iface)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
func (f *mockDB) DeleteInterface(ctx context.Context, id domain.InterfaceIdentifier) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
func (f *mockDB) GetInterfacePeers(ctx context.Context, id domain.InterfaceIdentifier) ([]domain.Peer, error) {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
func (f *mockDB) GetUserPeers(ctx context.Context, id domain.UserIdentifier) ([]domain.Peer, error) {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
func (f *mockDB) SavePeer(
|
|
||||||
ctx context.Context,
|
|
||||||
id domain.PeerIdentifier,
|
|
||||||
updateFunc func(in *domain.Peer) (*domain.Peer, error),
|
|
||||||
) error {
|
|
||||||
if f.savedPeers == nil {
|
|
||||||
f.savedPeers = make(map[domain.PeerIdentifier]*domain.Peer)
|
|
||||||
}
|
|
||||||
existing := f.savedPeers[id]
|
|
||||||
if existing == nil {
|
|
||||||
existing = &domain.Peer{Identifier: id}
|
|
||||||
}
|
|
||||||
updated, err := updateFunc(existing)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
f.savedPeers[updated.Identifier] = updated
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
func (f *mockDB) DeletePeer(ctx context.Context, id domain.PeerIdentifier) error { return nil }
|
|
||||||
func (f *mockDB) GetPeer(ctx context.Context, id domain.PeerIdentifier) (*domain.Peer, error) {
|
|
||||||
return nil, domain.ErrNotFound
|
|
||||||
}
|
|
||||||
func (f *mockDB) GetUsedIpsPerSubnet(ctx context.Context, subnets []domain.Cidr) (
|
|
||||||
map[domain.Cidr][]domain.Cidr,
|
|
||||||
error,
|
|
||||||
) {
|
|
||||||
return map[domain.Cidr][]domain.Cidr{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- Test ---
|
|
||||||
|
|
||||||
func TestCreatePeer_SetsIdentifier_FromPublicKey(t *testing.T) {
|
|
||||||
// Arrange
|
|
||||||
cfg := &config.Config{}
|
|
||||||
cfg.Core.SelfProvisioningAllowed = true
|
|
||||||
cfg.Core.EditableKeys = true
|
|
||||||
cfg.Advanced.LimitAdditionalUserPeers = 0
|
|
||||||
|
|
||||||
bus := &mockBus{}
|
|
||||||
|
|
||||||
// Prepare a controller manager with our mock controller
|
|
||||||
ctrlMgr := &ControllerManager{
|
|
||||||
controllers: map[domain.InterfaceBackend]backendInstance{
|
|
||||||
config.LocalBackendName: {Implementation: &mockController{}},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
db := &mockDB{iface: &domain.Interface{Identifier: "wg0", Type: domain.InterfaceTypeServer}}
|
|
||||||
|
|
||||||
m := Manager{
|
|
||||||
cfg: cfg,
|
|
||||||
bus: bus,
|
|
||||||
db: db,
|
|
||||||
wg: ctrlMgr,
|
|
||||||
}
|
|
||||||
|
|
||||||
userId := domain.UserIdentifier("user@example.com")
|
|
||||||
ctx := domain.SetUserInfo(context.Background(), &domain.ContextUserInfo{Id: userId, IsAdmin: false})
|
|
||||||
|
|
||||||
pubKey := "TEST_PUBLIC_KEY_ABC123"
|
|
||||||
|
|
||||||
input := &domain.Peer{
|
|
||||||
Identifier: "should_be_overwritten",
|
|
||||||
UserIdentifier: userId,
|
|
||||||
InterfaceIdentifier: domain.InterfaceIdentifier("wg0"),
|
|
||||||
Interface: domain.PeerInterfaceConfig{
|
|
||||||
KeyPair: domain.KeyPair{PublicKey: pubKey},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// Act
|
|
||||||
out, err := m.CreatePeer(ctx, input)
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("CreatePeer returned error: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
expectedId := domain.PeerIdentifier(pubKey)
|
|
||||||
if out.Identifier != expectedId {
|
|
||||||
t.Fatalf("expected Identifier to be set from public key %q, got %q", expectedId, out.Identifier)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure the saved peer in DB also has the expected identifier
|
|
||||||
if db.savedPeers[expectedId] == nil {
|
|
||||||
t.Fatalf("expected peer with identifier %q to be saved in DB", expectedId)
|
|
||||||
}
|
|
||||||
}
|
|
Reference in New Issue
Block a user