* update to go 1.27

* go fix changes
This commit is contained in:
h44z
2026-09-12 17:52:01 +02:00
committed by GitHub
parent 34ee98a51e
commit 38c372e239
46 changed files with 418 additions and 505 deletions
+1 -1
View File
@@ -20,7 +20,7 @@ RUN npm run build
######
# Build backend
######
FROM --platform=${BUILDPLATFORM} golang:1.26-alpine AS builder
FROM --platform=${BUILDPLATFORM} golang:1.27-alpine AS builder
# Set the working directory
WORKDIR /build
# Download dependencies
+1 -1
View File
@@ -1,6 +1,6 @@
# Go parameters
GOCMD=go
GOVERSION=1.25
GOVERSION=1.27
MODULENAME=github.com/h44z/wg-portal
GOFILES=$(shell go list ./... | grep -v /vendor/)
BUILDDIR=dist
@@ -4,7 +4,7 @@ To build the application from source files, use the Makefile provided in the rep
- [Git](https://git-scm.com/downloads)
- [Make](https://www.gnu.org/software/make/)
- [Go](https://go.dev/dl/): `>=1.25.0`
- [Go](https://go.dev/dl/): `>=1.27.0`
- [Node.js with npm](https://nodejs.org/en/download): `node>=18, npm>=9`
## Build
+45 -47
View File
@@ -1,31 +1,31 @@
module github.com/h44z/wg-portal
go 1.25.7
go 1.27
require (
github.com/a8m/envsubst v1.4.3
github.com/alexedwards/scs/v2 v2.9.0
github.com/coreos/go-oidc/v3 v3.20.0
github.com/coreos/go-oidc/v3 v3.21.0
github.com/glebarez/sqlite v1.11.0
github.com/go-ldap/ldap/v3 v3.4.14
github.com/go-pkgz/routegroup v1.6.0
github.com/go-playground/validator/v10 v10.30.3
github.com/go-webauthn/webauthn v0.17.4
github.com/go-pkgz/routegroup v1.6.1
github.com/go-playground/validator/v10 v10.30.4
github.com/go-webauthn/webauthn v0.18.1
github.com/google/uuid v1.6.0
github.com/gorilla/websocket v1.5.3
github.com/prometheus-community/pro-bing v0.9.1
github.com/prometheus/client_golang v1.24.1
github.com/stretchr/testify v1.11.1
github.com/stretchr/testify v1.12.1
github.com/swaggo/swag v1.16.6
github.com/vardius/message-bus v1.1.5
github.com/vishvananda/netlink v1.3.1
github.com/xhit/go-simple-mail/v2 v2.16.0
github.com/yeqown/go-qrcode/v2 v2.2.5
github.com/yeqown/go-qrcode/writer/compressed v1.0.1
golang.org/x/crypto v0.54.0
golang.org/x/oauth2 v0.36.0
golang.org/x/sys v0.47.0
golang.org/x/text v0.40.0
github.com/yeqown/go-qrcode/v2 v2.3.0
github.com/yeqown/go-qrcode/writer/compressed v1.0.2
golang.org/x/crypto v0.57.0
golang.org/x/oauth2 v0.37.0
golang.org/x/sys v0.48.0
golang.org/x/text v0.42.0
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20241231184526-a9ab2273dd10
gopkg.in/yaml.v3 v3.0.1
gorm.io/driver/mysql v1.6.0
@@ -41,29 +41,28 @@ require (
github.com/KyleBanks/depth v1.2.1 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/fxamacker/cbor/v2 v2.9.2 // indirect
github.com/gabriel-vasile/mimetype v1.4.13 // indirect
github.com/glebarez/go-sqlite v1.22.0 // indirect
github.com/fxamacker/cbor/v2 v2.9.3 // indirect
github.com/gabriel-vasile/mimetype v1.4.15 // indirect
github.com/glebarez/go-sqlite v1.23.0 // indirect
github.com/go-asn1-ber/asn1-ber v1.5.8 // indirect
github.com/go-jose/go-jose/v4 v4.1.4 // indirect
github.com/go-openapi/jsonpointer v1.0.0 // indirect
github.com/go-openapi/jsonreference v1.0.0 // indirect
github.com/go-openapi/spec v0.22.9 // indirect
github.com/go-openapi/swag/conv v0.27.3 // indirect
github.com/go-openapi/swag/jsonutils v0.27.3 // indirect
github.com/go-openapi/swag/loading v0.27.3 // indirect
github.com/go-openapi/swag/pools v0.27.3 // indirect
github.com/go-openapi/swag/stringutils v0.27.3 // indirect
github.com/go-openapi/swag/typeutils v0.27.3 // indirect
github.com/go-openapi/swag/yamlutils v0.27.3 // indirect
github.com/go-jose/go-jose/v4 v4.1.5 // indirect
github.com/go-openapi/jsonpointer v1.0.1 // indirect
github.com/go-openapi/jsonreference v1.0.2 // indirect
github.com/go-openapi/spec v1.0.1 // indirect
github.com/go-openapi/swag/conv v0.29.2 // indirect
github.com/go-openapi/swag/jsonutils v0.29.2 // indirect
github.com/go-openapi/swag/loading v0.29.2 // indirect
github.com/go-openapi/swag/pools v0.29.2 // indirect
github.com/go-openapi/swag/stringutils v0.29.2 // indirect
github.com/go-openapi/swag/typeutils v0.29.2 // indirect
github.com/go-openapi/swag/yamlutils v0.29.2 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-sql-driver/mysql v1.10.0 // indirect
github.com/go-sql-driver/mysql v1.10.1 // indirect
github.com/go-test/deep v1.1.1 // indirect
github.com/go-viper/mapstructure/v2 v2.5.0 // indirect
github.com/go-webauthn/x v0.2.6 // indirect
github.com/go-webauthn/x v0.3.1 // indirect
github.com/golang-jwt/jwt/v5 v5.3.1 // indirect
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect
github.com/golang-sql/sqlexp v0.1.0 // indirect
@@ -71,24 +70,23 @@ require (
github.com/google/go-tpm v0.9.8 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
github.com/jackc/pgx/v5 v5.10.0 // indirect
github.com/jackc/pgx/v5 v5.11.0 // indirect
github.com/jackc/puddle/v2 v2.2.2 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/mattn/go-isatty v0.0.23 // indirect
github.com/leodido/go-urn v1.5.0 // indirect
github.com/mattn/go-isatty v0.0.24 // indirect
github.com/mdlayher/genetlink v1.4.0 // indirect
github.com/mdlayher/netlink v1.11.2 // indirect
github.com/mdlayher/socket v0.6.1 // indirect
github.com/microsoft/go-mssqldb v1.10.0 // indirect
github.com/mdlayher/socket v0.7.0 // indirect
github.com/microsoft/go-mssqldb v1.11.0 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/ncruces/go-strftime v1.0.0 // indirect
github.com/philhofer/fwd v1.2.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.70.1 // indirect
github.com/prometheus/procfs v0.21.1 // indirect
github.com/prometheus/client_model v0.6.3 // indirect
github.com/prometheus/common v0.71.0 // indirect
github.com/prometheus/procfs v0.22.0 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/rogpeppe/go-internal v1.15.0 // indirect
github.com/shopspring/decimal v1.4.0 // indirect
@@ -98,16 +96,16 @@ require (
github.com/x448/float16 v0.8.4 // indirect
github.com/yeqown/reedsolomon v1.0.0 // indirect
go.yaml.in/yaml/v2 v2.4.4 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/mod v0.38.0 // indirect
golang.org/x/net v0.57.0 // indirect
golang.org/x/sync v0.22.0 // indirect
golang.org/x/tools v0.48.0 // indirect
go.yaml.in/yaml/v3 v3.0.5 // indirect
golang.org/x/mod v0.41.0 // indirect
golang.org/x/net v0.59.0 // indirect
golang.org/x/sync v0.23.0 // indirect
golang.org/x/tools v0.50.0 // indirect
golang.zx2c4.com/wireguard v0.0.0-20260522210424-ecfc5a8d5446 // indirect
google.golang.org/protobuf v1.36.11 // indirect
modernc.org/libc v1.74.3 // indirect
google.golang.org/protobuf v1.36.12 // indirect
modernc.org/libc v1.75.7 // indirect
modernc.org/mathutil v1.7.1 // indirect
modernc.org/memory v1.11.0 // indirect
modernc.org/sqlite v1.54.0 // indirect
modernc.org/memory v1.12.1 // indirect
modernc.org/sqlite v1.58.0 // indirect
sigs.k8s.io/yaml v1.6.0 // indirect
)
+110 -113
View File
@@ -1,19 +1,19 @@
filippo.io/edwards25519 v1.2.0 h1:crnVqOiS4jqYleHd9vaKZ+HKtHfllngJIiOpNpoJsjo=
filippo.io/edwards25519 v1.2.0/go.mod h1:xzAOLCNug/yB62zG1bQ8uziwrIqIuxhctzJT18Q77mc=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.1 h1:jHb/wfvRikGdxMXYV3QG/SzUOPYN9KEUUuC0Yd0/vC0=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.1/go.mod h1:pzBXCYn05zvYIrwLgtK8Ap8QcjRg+0i76tMQdWN6wOk=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1 h1:Hk5QBxZQC1jb2Fwj6mpzme37xbCDdNTxU7O9eb5+LB4=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1/go.mod h1:IYus9qsFobWIc2YVwe/WPjcnyCkPKtnHAqUYeebc8z0=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.23.0 h1:4gRPBpN1f6xt88yi4WR26m7XaD9OlWtVT6bWPdGUIok=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.23.0/go.mod h1:G7QVLxw1j1JVyrO1MA95S8m8HStaaleDZYTcfGgjB2o=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.14.0 h1:CU4+EJeJi3TKYWEcYuSdWsjzw0nVsK/H0MSQOiPcymU=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.14.0/go.mod h1:q0+UTSRvShwUCrR/s5HtyInYphN7Wvxb7snFM3u+SLA=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.12.0 h1:fhqpLE3UEXi9lPaBRpQ6XuRW0nU7hgg4zlmZZa+a9q4=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.12.0/go.mod h1:7dCRMLwisfRH3dBupKeNCioWYUZ4SS09Z14H+7i8ZoY=
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.4.0 h1:E4MgwLBGeVB5f2MdcIVD3ELVAWpr+WD6MUe1i+tM/PA=
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.4.0/go.mod h1:Y2b/1clN4zsAoUd/pgNAQHjLDnTis/6ROkUfyob6psM=
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.5.0 h1:MaKvxE6D0KkjOg6Wd9M00iqP5PR0kUxCfiezes4JweM=
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.5.0/go.mod h1:i2h9fsTFKZorh8RdV2IcSUf/Qj98GlTkrTvUbX/s8as=
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.2.0 h1:nCYfgcSyHZXJI8J0IWE5MsCGlb2xp9fJiXyxWgmOFg4=
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.2.0/go.mod h1:ucUjca2JtSZboY8IoUqyQyuuXvwbMBVwFOm0vdQPNhA=
github.com/Azure/go-ntlmssp v0.1.1 h1:l+FM/EEMb0U9QZE7mKNEDw5Mu3mFiaa2GKOoTSsNDPw=
github.com/Azure/go-ntlmssp v0.1.1/go.mod h1:NYqdhxd/8aAct/s4qSYZEerdPuH1liG2/X9DiVTbhpk=
github.com/AzureAD/microsoft-authentication-library-for-go v1.6.0 h1:XRzhVemXdgvJqCH0sFfrBUTnUJSBrBf7++ypk+twtRs=
github.com/AzureAD/microsoft-authentication-library-for-go v1.6.0/go.mod h1:HKpQxkWaGLJ+D/5H8QRpyQXA1eKjxkFlOMwck5+33Jk=
github.com/AzureAD/microsoft-authentication-library-for-go v1.7.2 h1:RHK7bS+HQMslb1sZpAokUt+zTVmue0hKSs2C791hhzU=
github.com/AzureAD/microsoft-authentication-library-for-go v1.7.2/go.mod h1:HKpQxkWaGLJ+D/5H8QRpyQXA1eKjxkFlOMwck5+33Jk=
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
github.com/a8m/envsubst v1.4.3 h1:kDF7paGK8QACWYaQo6KtyYBozY2jhQrTuNNuUxQkhJY=
@@ -26,75 +26,73 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/coreos/go-oidc/v3 v3.20.0 h1:EtE0WIBHk03N+DqGkY4+UONzzZHk7amKt6IyNd7OsZE=
github.com/coreos/go-oidc/v3 v3.20.0/go.mod h1:DYCf24+ncYi+XkIH97GY1+dqoRlbaSI26KVTCI9SrY4=
github.com/coreos/go-oidc/v3 v3.21.0 h1:wZo4Q9Pum8dYEj0eMUPrqR+kvuGkeUplbLpNCkBqoWM=
github.com/coreos/go-oidc/v3 v3.21.0/go.mod h1:DYCf24+ncYi+XkIH97GY1+dqoRlbaSI26KVTCI9SrY4=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/fxamacker/cbor/v2 v2.9.2 h1:X4Ksno9+x3cz0TZv69ec1hxP/+tymuR8PXQJyDwfh78=
github.com/fxamacker/cbor/v2 v2.9.2/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
github.com/gabriel-vasile/mimetype v1.4.13 h1:46nXokslUBsAJE/wMsp5gtO500a4F3Nkz9Ufpk2AcUM=
github.com/gabriel-vasile/mimetype v1.4.13/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
github.com/glebarez/go-sqlite v1.22.0 h1:uAcMJhaA6r3LHMTFgP0SifzgXg46yJkgxqyuyec+ruQ=
github.com/glebarez/go-sqlite v1.22.0/go.mod h1:PlBIdHe0+aUEFn+r2/uthrWq4FxbzugL0L8Li6yQJbc=
github.com/fxamacker/cbor/v2 v2.9.3 h1:oQBnFATpNdY8gJHTndDDv5Xl4QqNaz51G5LLEPhng3Q=
github.com/fxamacker/cbor/v2 v2.9.3/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
github.com/gabriel-vasile/mimetype v1.4.15 h1:05iP/CYtZ/w455R/KZM6rZ5ieAdh99UPtd+d3YzLmaI=
github.com/gabriel-vasile/mimetype v1.4.15/go.mod h1:azpTcoLcDZRNgFou5j+APrqQx9HqVPWa6ijYQIIVswQ=
github.com/glebarez/go-sqlite v1.23.0 h1:FyhIq4jqmgphQAUlY79zPldYGwISEZikaDfhiGWkkaI=
github.com/glebarez/go-sqlite v1.23.0/go.mod h1:IIYrOH3L0rHY3jb4IXOHoWdklNajSGUN2eJcvK8WrnI=
github.com/glebarez/sqlite v1.11.0 h1:wSG0irqzP6VurnMEpFGer5Li19RpIRi2qvQz++w0GMw=
github.com/glebarez/sqlite v1.11.0/go.mod h1:h8/o8j5wiAsqSPoWELDUdJXhjAhsVliSn7bWZjOhrgQ=
github.com/go-asn1-ber/asn1-ber v1.5.8 h1:H9AZkK22UOmfX8J84ubyaZxKJZ3FMHVwn8swoMML7iQ=
github.com/go-asn1-ber/asn1-ber v1.5.8/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
github.com/go-jose/go-jose/v4 v4.1.4 h1:moDMcTHmvE6Groj34emNPLs/qtYXRVcd6S7NHbHz3kA=
github.com/go-jose/go-jose/v4 v4.1.4/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08=
github.com/go-jose/go-jose/v4 v4.1.5 h1:RjgjO2LOtWOJKUC5wpwY9LR3B3vwVAz6JS2YHfYU6eA=
github.com/go-jose/go-jose/v4 v4.1.5/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08=
github.com/go-ldap/ldap/v3 v3.4.14 h1:D6PYdEgsaVzsXyr6w/yDC06Ria4uUhWm+Rb+er8lfAs=
github.com/go-ldap/ldap/v3 v3.4.14/go.mod h1:S4eJUMUNjDkE0ZJtIZdybwyb03sGGLW6gxXT1Hs8VKA=
github.com/go-openapi/jsonpointer v1.0.0 h1:kR9tHqY0CtZaOPVFm622dPVNhrvYpwr4uCxgL3h1H8s=
github.com/go-openapi/jsonpointer v1.0.0/go.mod h1:Z3rw7dWu1p9IgitXCFamSlA5lmDiklEB6vkaxcNZW5Y=
github.com/go-openapi/jsonreference v1.0.0 h1:jlmTr6torcd1YgDQvSfNmRtKzYDO4FGBkrAdlAVWnpY=
github.com/go-openapi/jsonreference v1.0.0/go.mod h1:jtwdyGbJk0Xhe5Y+rwtglQP6Sb1WZST4rT32LWB+sv0=
github.com/go-openapi/spec v0.22.9 h1:/vKIFDcGKp0ktZWGbym/tJEWbk6/XOEmAVU0kqKMH+w=
github.com/go-openapi/spec v0.22.9/go.mod h1:b/mNUYIOQOyIiUzUzXEE8xzyZqf93KvM9hQGP91yfl0=
github.com/go-openapi/jsonpointer v1.0.1 h1:2KxywRmNwJkT/FMBa3iRNHEaAxSJvjqoufQZy3au1Mg=
github.com/go-openapi/jsonpointer v1.0.1/go.mod h1:wI7ZYsFmbIi9nBXOZqgDaS/bqOchRGZjqxFli7FBYxY=
github.com/go-openapi/jsonreference v1.0.2 h1:oS4et8FOf3p3UQxEo4Xt0esijmBUM+F259Xl72OSZsc=
github.com/go-openapi/jsonreference v1.0.2/go.mod h1:TbUNSOo+fcorZjFaNoiSDSoaNnnZtqJtLGR1PuvE/Cs=
github.com/go-openapi/spec v1.0.1 h1:lj2vdGpNDcVgwRc6qXdw6qt/KQpCtSa9tnUH6vpDPDk=
github.com/go-openapi/spec v1.0.1/go.mod h1:M//GWQGtDUAjnP37gE6fInLgaczB+FatoipV3H1fYw8=
github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM=
github.com/go-openapi/swag/conv v0.27.3 h1:iqJFmGEjmX3AY0lSszABFqRVqOSt99XS0LzNIMJYuhU=
github.com/go-openapi/swag/conv v0.27.3/go.mod h1:nPRmN6jgNme99hpf+nM0auDZGALWIqlwhisKPK/bQhQ=
github.com/go-openapi/swag/jsonutils v0.27.3 h1:1DEz+O82frtSMBcos/7XIn1GnpNTbsD4Bru4Dc/uhRc=
github.com/go-openapi/swag/jsonutils v0.27.3/go.mod h1:qiDCoQvzkMxrV3G8FLEdIU5L+EFYc0zcDOHWT3Yofvo=
github.com/go-openapi/swag/jsonutils/fixtures_test v0.27.3 h1:h/eT9kmGCDdFLJF29lOhzLtF0FmP1AX2MhLJWVebsb8=
github.com/go-openapi/swag/jsonutils/fixtures_test v0.27.3/go.mod h1:mofwUWx70wvskwESqRJ//k/9kURmCgyJl5m5Ppoh5kY=
github.com/go-openapi/swag/loading v0.27.3 h1:L9nQkEgzU7QgFQL+pLEMfGUKxeM4pWwGwbET9Z3weW0=
github.com/go-openapi/swag/loading v0.27.3/go.mod h1:rJ0NeaKsF4CVPnMGjPQl7JlSHzvD0bc2DKXLss1hiuE=
github.com/go-openapi/swag/pools v0.27.3 h1:gXjImP3F6/56wRRcFgEPld084Y6u2gs21ikPBt8NKBk=
github.com/go-openapi/swag/pools v0.27.3/go.mod h1:kVQefhSK5RWuRe7BXsL8htgBPAMpN7HDGpGEknqugeE=
github.com/go-openapi/swag/stringutils v0.27.3 h1:Ru28hnbAvN5wycALQYy8IobHvASq+FUFMlp1QzLM0JI=
github.com/go-openapi/swag/stringutils v0.27.3/go.mod h1:lzRN95CxXmA03XcDWHLOb6nOMcxCqR5rGY0lOgsfRoM=
github.com/go-openapi/swag/typeutils v0.27.3 h1:l6SSrx5eR5/WVwrGNzN6bQ9WqL04mrxNBl9YgQ3rcJ4=
github.com/go-openapi/swag/typeutils v0.27.3/go.mod h1:Srm0xFNRZ1Y+vCxJclo5qzx8aj+1pAKda/YfFPrG0dQ=
github.com/go-openapi/swag/yamlutils v0.27.3 h1:cRFCAoYtslYn9L9T0xWryHy1t7c1MACC+DMj3CLvwvs=
github.com/go-openapi/swag/yamlutils v0.27.3/go.mod h1:6JYBGj8sw/NawMllyZY+cTA8Mzk2etS3ZBASdcyPsiU=
github.com/go-openapi/testify/enable/yaml/v2 v2.6.0 h1:gGHwAJ0R/5jU8BEGDbfRNR3hL68dAVi84WuOApp29B0=
github.com/go-openapi/testify/enable/yaml/v2 v2.6.0/go.mod h1:tY+St1SGq4NFl0QIqdTY4aEdbChAHxhyB77XQi9iJCo=
github.com/go-openapi/testify/v2 v2.6.0 h1:5PKH2HE7YJ/LuRPQGvSxBRlFXNQhSetBLlGAgUEu3ug=
github.com/go-openapi/testify/v2 v2.6.0/go.mod h1:SgsVHtfooshd0tublTtJ50FPKhujf47YRqauXXOUxfw=
github.com/go-pkgz/routegroup v1.6.0 h1:44XHZgF6JIIldRlv+zjg6SygULASmjifnfIQjwCT0e4=
github.com/go-pkgz/routegroup v1.6.0/go.mod h1:Pmu04fhgWhRtBMIJ8HXppnnzOPjnL/IEPBIdO2zmeqg=
github.com/go-openapi/swag/conv v0.29.2 h1:8c9shoB8l0QRSR6ymq1llHdBWDqpIgJfjTGHx3Vuhm0=
github.com/go-openapi/swag/conv v0.29.2/go.mod h1:AZS0YigTNf8qNtD6WqJz/N4RUNmpr76SyjFGkq4+p6Q=
github.com/go-openapi/swag/jsonutils v0.29.2 h1:uZNSD2/rJDYAfvsLYkykTzXuyxM3QpDKV9jhRHrMu6k=
github.com/go-openapi/swag/jsonutils v0.29.2/go.mod h1:ONTdNvj3Y+IXRzfa17E+Rgt2ns/qiSOYjIo2K7v2yDs=
github.com/go-openapi/swag/jsonutils/fixtures_test v0.29.2 h1:w+Fd6EBOMGlC74GYGHqCLGyb3Bpams8TtNrgM/SG4jo=
github.com/go-openapi/swag/jsonutils/fixtures_test v0.29.2/go.mod h1:HC2egPORFzbj/gf05Zrfgz8Mgplx3oW7hgGi7pjZVhM=
github.com/go-openapi/swag/loading v0.29.2 h1:QU1ry24e6r6Shoxe380Nx0X5iKkpRO+hJffsyJ2dVlY=
github.com/go-openapi/swag/loading v0.29.2/go.mod h1:DqilDjuiJKETecsS4TRopWG1acUDsfqN39ZmQhPu6uI=
github.com/go-openapi/swag/pools v0.29.2 h1:PlGoDRF8WtSyXkedZZkpW3f9wDhFf3u8KtaBcmgmh8c=
github.com/go-openapi/swag/pools v0.29.2/go.mod h1:V3lhxVT4qDYRqc2MRSSbLsTYIYV/2HlHafhyEkmzLIc=
github.com/go-openapi/swag/stringutils v0.29.2 h1:lcnBxwAaysT3bMUVBfn9V/PkfVqkurpqufKU6rTUMGk=
github.com/go-openapi/swag/stringutils v0.29.2/go.mod h1:i9cdh7sGaa0nm3CqIvH5IM5h2QClk1wns2ktKeILvRI=
github.com/go-openapi/swag/typeutils v0.29.2 h1:O7aVvkTs3pXwikgtrPLenigEMdQFgONKRooQA9pgf2I=
github.com/go-openapi/swag/typeutils v0.29.2/go.mod h1:7+GDG+uz9Ke+eVt4rClZg7wklSDp8hT/mKNh/pC26TE=
github.com/go-openapi/swag/yamlutils v0.29.2 h1:IFKFFeDnuIwzfsuWRQU+rI8iL3g4XyAYjV/RlnlxPLM=
github.com/go-openapi/swag/yamlutils v0.29.2/go.mod h1:7MGqtcrK73sxQ4ceiyIf8qiXS/s09JLMdR5esK5euYQ=
github.com/go-openapi/testify/enable/yaml/v2 v2.7.0 h1:wPW6YRgx3+SID1yUy/Xwa17L8kFEaEKod2VRbJDZNUs=
github.com/go-openapi/testify/enable/yaml/v2 v2.7.0/go.mod h1:mI1M88etYbc3PhgHsWQK2kwvNwW5aGFqMPbmib+SGIs=
github.com/go-openapi/testify/v2 v2.7.0 h1:bycOreEj6wfBvijg3YFogZ/sFjTCDmQnwSodSzHa3X8=
github.com/go-openapi/testify/v2 v2.7.0/go.mod h1:SgsVHtfooshd0tublTtJ50FPKhujf47YRqauXXOUxfw=
github.com/go-pkgz/routegroup v1.6.1 h1:6I/0LabazpZsHAI+jYPeyH/KU2cvZF0bFylUScMNi+Q=
github.com/go-pkgz/routegroup v1.6.1/go.mod h1:Pmu04fhgWhRtBMIJ8HXppnnzOPjnL/IEPBIdO2zmeqg=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.30.3 h1:4MU6YkEwx7GbcPJOZxrtbu+QfF3pJLJuaYTeAH0DYy8=
github.com/go-playground/validator/v10 v10.30.3/go.mod h1:4Axh7oCNGcoGkqLoE4YWt6n20mcEIsPRlB7vPk3lpyc=
github.com/go-sql-driver/mysql v1.10.0 h1:Q+1LV8DkHJvSYAdR83XzuhDaTykuDx0l6fkXxoWCWfw=
github.com/go-sql-driver/mysql v1.10.0/go.mod h1:M+cqaI7+xxXGG9swrdeUIoPG3Y3KCkF0pZej+SK+nWk=
github.com/go-playground/validator/v10 v10.30.4 h1:9Rcod2ZPO6mOEG6b4GqyoHE/H6//Ze0RuhOo1hT1x0w=
github.com/go-playground/validator/v10 v10.30.4/go.mod h1:numpT+RPLE91R9oYWMY/R9zRgJBewr3IXHko4OISPpk=
github.com/go-sql-driver/mysql v1.10.1 h1:arlSnNLq6a5yxGxV7qg9lF4j0C+KwD6NbQyKr9QL6ME=
github.com/go-sql-driver/mysql v1.10.1/go.mod h1:M+cqaI7+xxXGG9swrdeUIoPG3Y3KCkF0pZej+SK+nWk=
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-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro=
github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
github.com/go-webauthn/webauthn v0.17.4 h1:KFTSz3R2RYDiUn/0cDi3XTJgFenSG74eKTTHlqWhlxk=
github.com/go-webauthn/webauthn v0.17.4/go.mod h1:pZk63EE/BdztlmyS4Yc+9H5g4a8blNlbtGmdHQHbZX8=
github.com/go-webauthn/x v0.2.6 h1:TEyDuQAIiEgYpx60nKiBJIX/5nSUC8LxNbH+uf5U9uk=
github.com/go-webauthn/x v0.2.6/go.mod h1:45bA7YEqyQhRcQJ/TiBb46Ww8yqHBGvgEhQ3WWF0aDo=
github.com/go-webauthn/webauthn v0.18.1 h1:KaQw6M+ODLvxHwddyeo6zFhhmicfLup/BClhigB6A+0=
github.com/go-webauthn/webauthn v0.18.1/go.mod h1:s4rZTQnKHWxIh6G3yEGqlxvtiLceA1jigll8FpqSgQ8=
github.com/go-webauthn/x v0.3.1 h1:1ff37z3XfmTTomkhlURgGizLIDyOvPgTt2t9nlzKLRo=
github.com/go-webauthn/x v0.3.1/go.mod h1:ZInxAynYXfBPvvm5gzKZ7geBlL23K71xASMgohHl/Rg=
github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY=
github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA=
@@ -107,8 +105,8 @@ github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo=
github.com/google/go-tpm v0.9.8/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY=
github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba h1:qJEJcuLzH5KDR0gKc0zcktin6KSAwL7+jWKBYceddTc=
github.com/google/go-tpm-tools v0.3.13-0.20230620182252-4639ecce2aba/go.mod h1:EFYHy8/1y2KfgTAsx7Luu7NGhoxtuVHnNo8jE7FikKc=
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs=
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
github.com/google/pprof v0.0.0-20260802141513-ef3492d7dac3 h1:LMLX+LgTNWpfvCBdFebv6EsYotImrt/Ppc5cXIriCSo=
github.com/google/pprof v0.0.0-20260802141513-ef3492d7dac3/go.mod h1:jl5iWTm0/hd5PjEYEOuwAJ57L/CibdZfrqZ5XA5GrCk=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
@@ -121,8 +119,8 @@ github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsI
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgx/v5 v5.10.0 h1:VhSvgU2jSli8o3AqIEOTJr7rZwAEUVo4E4XhR94Zfr0=
github.com/jackc/pgx/v5 v5.10.0/go.mod h1:mal1tBGAFfLHvZzaYh77YS/eC6IX9OWbRV1QIIM0Jn4=
github.com/jackc/pgx/v5 v5.11.0 h1:IzBBtyK9AHqf98cctWFifYSci2hgQR/cd56wB4p+ogg=
github.com/jackc/pgx/v5 v5.11.0/go.mod h1:mal1tBGAFfLHvZzaYh77YS/eC6IX9OWbRV1QIIM0Jn4=
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8=
@@ -149,20 +147,20 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/mattn/go-isatty v0.0.23 h1:cYwCQTQf3HB6xUC+BtyCLZNr7IzbOmoZbmssVNzSyiQ=
github.com/mattn/go-isatty v0.0.23/go.mod h1:nMCL3Zebbrt45jsMDgnfIwz6ydEQApk5oEI3HqDio6A=
github.com/leodido/go-urn v1.5.0 h1:pLqT2kq1zpHW/1D18QMjMpdtX7cekxqtJJjg5ANyWw0=
github.com/leodido/go-urn v1.5.0/go.mod h1:9BORnCDhdPBJNDEX+w1bJisa8yOKYi116VeO96s4ifE=
github.com/mattn/go-isatty v0.0.24 h1:tGZZoVgT/KiqK1c8ocVLeDS8BSWMRd47J3Lbz7vsReI=
github.com/mattn/go-isatty v0.0.24/go.mod h1:nMCL3Zebbrt45jsMDgnfIwz6ydEQApk5oEI3HqDio6A=
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/mdlayher/genetlink v1.4.0 h1:f/Xs7Y2T+GyX9b3dbiUhnLE9InGs5F9RxJ2JwBMl71o=
github.com/mdlayher/genetlink v1.4.0/go.mod h1:d1hrKr8fwZU2JkcAtQUAzeTrI7nbgQSl+5k1cC0biSA=
github.com/mdlayher/netlink v1.11.2 h1:HKh2jqe+omdSWcQ88nrT7INE61B0NXfiSPFdgL4YbNI=
github.com/mdlayher/netlink v1.11.2/go.mod h1:uT2Yc/QLaZubzDpZIBi9d4GoeLwtp3x1AMeqSRrK2sA=
github.com/mdlayher/socket v0.6.1 h1:M7uj2NtuujUY4mYr1C57NmfNiRHbkKpnBxO856lsc3A=
github.com/mdlayher/socket v0.6.1/go.mod h1:+/SGtqc9V+5dAuRgQsU0fGBI+oRDiW7O2Obx10OIWfg=
github.com/microsoft/go-mssqldb v1.10.0 h1:pHEt+Qz6YFPWqREq10mqSE524QQo+/QremwTCQht7TY=
github.com/microsoft/go-mssqldb v1.10.0/go.mod h1:mnG7lGa9iYJbzJqGCXyuQCegStKMr3kogDLD6+bmggg=
github.com/mdlayher/socket v0.7.0 h1:qVREPVwtUMg17pwvveQxpurq0PVisMxi3FGgpsorMYQ=
github.com/mdlayher/socket v0.7.0/go.mod h1:f7iKql2EK/rfsWYDKofKjk2Ig7I+6HQWdMIdn1tO4A4=
github.com/microsoft/go-mssqldb v1.11.0 h1:YbDqolEjGH9hBfvKzONTf5/dbl9RKXmizMJE93lVxNs=
github.com/microsoft/go-mssqldb v1.11.0/go.mod h1:goQLDOPlMN/l1REhnNPElMoY/yX+fUWn1+7UoFJPH9Y=
github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721 h1:RlZweED6sbSArvlE924+mUcZuXKLBHA35U7LN621Bws=
github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721/go.mod h1:Ickgr2WtCLZ2MDGd4Gr0geeCH5HybhRJbonOgQpvSxc=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
@@ -173,18 +171,17 @@ github.com/philhofer/fwd v1.2.0 h1:e6DnBTl7vGY+Gz322/ASL4Gyp1FspeMvx1RNDoToZuM=
github.com/philhofer/fwd v1.2.0/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM=
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus-community/pro-bing v0.9.1 h1:kpuAr6AU2oRtzGihJSUcetHtjc7ku7h6PxeuW9RVrQw=
github.com/prometheus-community/pro-bing v0.9.1/go.mod h1:z79wYTxAOf6FpTng0QdIhZ3j/Nd5l3+gnFSCIT+SiSQ=
github.com/prometheus/client_golang v1.24.1 h1:JnJkREXzWxUdCuPFpIWZiPispT9xVV59uiuyR2bPlnU=
github.com/prometheus/client_golang v1.24.1/go.mod h1:F+oSRECHg4sse5ucfYpYDeIv/hu68Zo0uoHKetWnzcE=
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
github.com/prometheus/common v0.70.1 h1:1HvjP4D5oL3t8RsPlwxA9onvvStjtIHYE5XuuwOi/PY=
github.com/prometheus/common v0.70.1/go.mod h1:VdFUQDMZK3VLkurFUVhia6uys/0suUp86TJz5qbJRhc=
github.com/prometheus/procfs v0.21.1 h1:GljZCt+zSTS+NZq88cyQ1LjZ+RCHp3uVuabBWA5+OJI=
github.com/prometheus/procfs v0.21.1/go.mod h1:aB55Cww9pdSJVHk0hUf0inxWyyjPogFIjmHKYgMKmtY=
github.com/prometheus/client_model v0.6.3 h1:O0jaTVAYNxTHYInEPFJt5I3+sN8zqBtVMPTB1qyxiEo=
github.com/prometheus/client_model v0.6.3/go.mod h1:gpN5P9S7Rr6Yr92PiQ+Ixvhf6JZEkF1dnxsYL2aPBEM=
github.com/prometheus/common v0.71.0 h1:9KDAKb7Mj3HEVKyFCK6Dc/HIwlBzZIN2l7/lrHl3KK8=
github.com/prometheus/common v0.71.0/go.mod h1:CLJ5H8TEsGX8bl31BdMkfhIZ+QmZ9tBPPotUxUbfcmk=
github.com/prometheus/procfs v0.22.0 h1:6q9+/JL9IKAPbCmBrv9n5O5Ty3NKnciV5X7YGw0oics=
github.com/prometheus/procfs v0.22.0/go.mod h1:CvmFr/GVhIjIvWJZW3tgkODBQMRIf0EyWMQLHCHab58=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rogpeppe/go-internal v1.15.0 h1:D0RCU5rMAp+SpgkiNdrjfJ+LX4J1M32V2NeCY7EJ6hc=
@@ -194,8 +191,8 @@ github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+D
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/stretchr/testify v1.12.1 h1:EuwCh5fleGS7H32xRwO3wRGT7DxrDhLAT6FF8MpWDWE=
github.com/stretchr/testify v1.12.1/go.mod h1:MDEgiDPPsNp5cuIrHPPCyornHKgEVbtFUmoNlxoYthg=
github.com/swaggo/swag v1.16.6 h1:qBNcx53ZaX+M5dxVyTrgQ0PJ/ACK+NzhwcbieTt+9yI=
github.com/swaggo/swag v1.16.6/go.mod h1:ngP2etMK5a0P3QBizic5MEwpRmluJZPHjXcMoj4Xesg=
github.com/tinylib/msgp v1.6.4 h1:mOwYbyYDLPj35mkA2BjjYejgJk9BuHxDdvRnb6v2ZcQ=
@@ -213,10 +210,10 @@ github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/xhit/go-simple-mail/v2 v2.16.0 h1:ouGy/Ww4kuaqu2E2UrDw7SvLaziWTB60ICLkIkNVccA=
github.com/xhit/go-simple-mail/v2 v2.16.0/go.mod h1:b7P5ygho6SYE+VIqpxA6QkYfv4teeyG4MKqB3utRu98=
github.com/yeqown/go-qrcode/v2 v2.2.5 h1:HCOe2bSjkhZyYoyyNaXNzh4DJZll6inVJQQw+8228Zk=
github.com/yeqown/go-qrcode/v2 v2.2.5/go.mod h1:uHpt9CM0V1HeXLz+Wg5MN50/sI/fQhfkZlOM+cOTHxw=
github.com/yeqown/go-qrcode/writer/compressed v1.0.1 h1:0el6zOppx3oPiYWMUJWRYGvxWYh8MDmUU0j3rSWGWlI=
github.com/yeqown/go-qrcode/writer/compressed v1.0.1/go.mod h1:BJScsGUIKM+eg0CCLCcVaDTaclDM1IEXtq2r8qQnDKk=
github.com/yeqown/go-qrcode/v2 v2.3.0 h1:MMsNJgZrG95g8SOGGGaGcEZkOt1ByHjeCLSaymGm9aY=
github.com/yeqown/go-qrcode/v2 v2.3.0/go.mod h1:WBrb4qHlVtggZtquxDyMq+Uv+R4xtUaz4laG2iqG34s=
github.com/yeqown/go-qrcode/writer/compressed v1.0.2 h1:LgGSU2chM16fyWoXOeXp9eT4v1nxtyxsy0RtxW3/XMc=
github.com/yeqown/go-qrcode/writer/compressed v1.0.2/go.mod h1:slFRpq2jbrZoUXmkg8is6Jvp/1qkSSakQ2Yb7JmxCR0=
github.com/yeqown/reedsolomon v1.0.0 h1:x1h/Ej/uJnNu8jaX7GLHBWmZKCAWjEJTetkqaabr4B0=
github.com/yeqown/reedsolomon v1.0.0/go.mod h1:P76zpcn2TCuL0ul1Fso373qHRc69LKwAw/Iy6g1WiiM=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
@@ -225,32 +222,32 @@ 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.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ=
go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ=
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
golang.org/x/crypto v0.54.0 h1:YLIA59K4fiNzHzjnZt2tUJQjQtUWfWbeHBqKtk3eScw=
golang.org/x/crypto v0.54.0/go.mod h1:KWL8ny2AZdGR2cWmzeHrp2azQPGogOv+HeQaVEXC2dk=
golang.org/x/mod v0.38.0 h1:MECBjubtXD7yj4HrhIUcywNaGeNVUdfVnxmPajOk4yk=
golang.org/x/mod v0.38.0/go.mod h1:V6Xz0pq8TQ3dGqVQ1FVHuelZpAL0uNhSkk9ogYP3c40=
golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE=
golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU=
golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek=
golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
go.yaml.in/yaml/v3 v3.0.5 h1:N6y/pJk8buWs9NY5ERU2HSMfm+IuD/OtfdAnq6kESPw=
go.yaml.in/yaml/v3 v3.0.5/go.mod h1:HVTZu1O7/Vkt2N+BFy8Zza+lnLsABggaTM2ZpNIGuKg=
golang.org/x/crypto v0.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M=
golang.org/x/crypto v0.57.0/go.mod h1:Fdz0i5U6CoizGwLda9DttjSk6qlZo25zYNtR+ycvuZA=
golang.org/x/mod v0.41.0 h1:qJmnOUb4YB+FsEuM3HcWucdZASCPGhsX6uljO6pog0c=
golang.org/x/mod v0.41.0/go.mod h1:Ek9pY8RKWXwsWvd3rQiHYtMqkjSUV+s1Rj7j4H5Ur6o=
golang.org/x/net v0.59.0 h1:5zfYln+w5XCxwrnMMJPufRgNoXEaGxl0wo5GqPXyues=
golang.org/x/net v0.59.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg=
golang.org/x/oauth2 v0.37.0 h1:JUlcxA8oAtauLfiH8FX2/FkAWHAdi0QtGCGc+hofE98=
golang.org/x/oauth2 v0.37.0/go.mod h1:IxwZNxUULJmpBFf9K/9NTMSIfZZuvuTy1gGxhigP/58=
golang.org/x/sync v0.23.0 h1:KameEIfc1IkluZyXWLn39Wd4tURc6GbCiISGiZm2bQk=
golang.org/x/sync v0.23.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/text v0.40.0 h1:Ub2Z6/xjgF1WrYQz2nuITOEegKFtiIy+rieRJ5lHZKs=
golang.org/x/text v0.40.0/go.mod h1:hpnzDAfGV753zIKo+wk3u1bVKCGPbrnF7+7LBF/UHVY=
golang.org/x/tools v0.48.0 h1:3+hClM1aLL5mjMKm5ovokw9epgRXPuu2tILgismM6RE=
golang.org/x/tools v0.48.0/go.mod h1:08xX0orndb/F7jJxGDicx061tyd5pcMto75YMAXr6lk=
golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo=
golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og=
golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI=
golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E=
golang.org/x/tools v0.50.0 h1:c2ifzfcuY7L90lZ2aKd8S4K2NpASF08SZx9ZuJkHmSU=
golang.org/x/tools v0.50.0/go.mod h1:7ulVMw3831Mwi5EZD6RomGyffr4VFjuNYXf2BbCEAV0=
golang.zx2c4.com/wireguard v0.0.0-20260522210424-ecfc5a8d5446 h1:cqHQ3AycTHvM2R7ikgyX57D+XvtcSnGylsLkOVhta/w=
golang.zx2c4.com/wireguard v0.0.0-20260522210424-ecfc5a8d5446/go.mod h1:rpwXGsirqLqN2L0JDJQlwOboGHmptD5ZD6T2VmcqhTw=
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20241231184526-a9ab2273dd10 h1:3GDAcqdIg1ozBNLgPy4SLT84nfcBjr6rhGtXYtrkWLU=
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20241231184526-a9ab2273dd10/go.mod h1:T97yPqesLiNrOYxkwmhMI0ZIlJDm+p0PMR8eRVeR5tQ=
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
google.golang.org/protobuf v1.36.12 h1:pJOKDDOyeXErUroCihFAd5LQuwXBSpVnKGrj5o/fwxc=
google.golang.org/protobuf v1.36.12/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
@@ -267,30 +264,30 @@ gorm.io/driver/sqlserver v1.6.4 h1:kGA9Z0D7dnIz7yVvWp18qLBSPFpUQWGqMA4rnxkScdQ=
gorm.io/driver/sqlserver v1.6.4/go.mod h1:oRtXDKFRYj8MqyMq+JFEdaA+StSQKC4zupU6blIdB0s=
gorm.io/gorm v1.31.2 h1:3o8FXNo9v9S858gil+3LlZA1LkCOzgb4g5BL64FgaCo=
gorm.io/gorm v1.31.2/go.mod h1:XyQVbO2k6YkOis7C2437jSit3SsDK72s7n7rsSHd+Gs=
modernc.org/cc/v4 v4.29.1 h1:MKgdCV3WykTSPqpVrnxdEDS0HEd2FHpKZDzxzU5LyeI=
modernc.org/cc/v4 v4.29.1/go.mod h1:OnovgIhbbMXMu1aISnJ0wvVD1KnW+cAUJkIrAWh+kVI=
modernc.org/ccgo/v4 v4.34.6 h1:sBgfIwyN0TQ9C5hwIeuqyeAKyMWnbvj2fvpF4L11uzU=
modernc.org/ccgo/v4 v4.34.6/go.mod h1:SZ8YcN9NG7XVsQYdm6jYBvi8PQP1qi+kqB6OhjqI3Fk=
modernc.org/cc/v4 v4.29.2 h1:h6+9ciCnPKutf4I03CvheAvDLX7+IHlqR6Iy6J+cgd8=
modernc.org/cc/v4 v4.29.2/go.mod h1:OnovgIhbbMXMu1aISnJ0wvVD1KnW+cAUJkIrAWh+kVI=
modernc.org/ccgo/v4 v4.35.0 h1:F+TUsmw09QxLzmi3aeYYGxjAXarmZaKgj3mKQHNaA8w=
modernc.org/ccgo/v4 v4.35.0/go.mod h1:qrVGs9S3Sr2Ztcg9ve+kTAYMp5a3YvWjo+SoN06kJ5I=
modernc.org/fileutil v1.4.0 h1:j6ZzNTftVS054gi281TyLjHPp6CPHr2KCxEXjEbD6SM=
modernc.org/fileutil v1.4.0/go.mod h1:EqdKFDxiByqxLk8ozOxObDSfcVOv/54xDs/DUHdvCUU=
modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI=
modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito=
modernc.org/gc/v3 v3.1.4 h1:2g65LGVSmFQrXeITAw97x7hCRvZFcyE1uDP+7Vng7JI=
modernc.org/gc/v3 v3.1.4/go.mod h1:HFK/6AGESC7Ex+EZJhJ2Gni6cTaYpSMmU/cT9RmlfYY=
modernc.org/gc/v3 v3.1.5 h1:21ldfPfRYE31Tb7B3mwAK8gy1AxP4+dKjrOQPfqakoc=
modernc.org/gc/v3 v3.1.5/go.mod h1:HFK/6AGESC7Ex+EZJhJ2Gni6cTaYpSMmU/cT9RmlfYY=
modernc.org/goabi0 v0.2.0 h1:HvEowk7LxcPd0eq6mVOAEMai46V+i7Jrj13t4AzuNks=
modernc.org/goabi0 v0.2.0/go.mod h1:CEFRnnJhKvWT1c1JTI3Avm+tgOWbkOu5oPA8eH8LnMI=
modernc.org/libc v1.74.3 h1:a4J+Z8aVaxPyjyxRAdJzw246PqpcFGvVPnfT/AuM5Ws=
modernc.org/libc v1.74.3/go.mod h1:4H7h/MJ8wnjL8RAbp9v3OXgnk22X7MouHIhDbvP3gj4=
modernc.org/libc v1.75.7 h1:o3DTP9/0p9pKmY2WCKQaySW6wIiZhNM7wc2lUoyhfew=
modernc.org/libc v1.75.7/go.mod h1:bO5o2ztHxBb2rjz0PgdHN0sSMw57CgxGFLZ3Qd/QpVQ=
modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU=
modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg=
modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI=
modernc.org/memory v1.11.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw=
modernc.org/memory v1.12.1 h1:nFMiWrpStgZczNl6XI9GnIk/rWhYIyHGUaR04pGbp9g=
modernc.org/memory v1.12.1/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw=
modernc.org/opt v0.2.0 h1:tGyef5ApycA7FSEOMraay9SaTk5zmbx7Tu+cJs4QKZg=
modernc.org/opt v0.2.0/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns=
modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w=
modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE=
modernc.org/sqlite v1.54.0 h1:JCxR4qwkJvOaqAoYcgDoO25Nc+ROg6EJ2LfBVzdrgog=
modernc.org/sqlite v1.54.0/go.mod h1:4ntCLuNmnH8+GNqjka1wNg7KJd5/Hi5FYp8K+XQ7GZw=
modernc.org/sqlite v1.58.0 h1:38u40/bwkfM7f0Myhosl+SEMltSDxnGdQf8o6Kjmys0=
modernc.org/sqlite v1.58.0/go.mod h1:rsD2CckafgObKC4DhBlGBf+RiHxkc3hINGt1Xw32tVY=
modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0=
modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A=
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
+16 -24
View File
@@ -279,12 +279,10 @@ func (r *SqlRepo) migrate() error {
now := time.Now()
for _, user := range users {
auth := domain.UserAuthentication{
BaseModel: domain.BaseModel{
CreatedBy: domain.CtxSystemDBMigrator,
UpdatedBy: domain.CtxSystemDBMigrator,
CreatedAt: now,
UpdatedAt: now,
},
CreatedBy: domain.CtxSystemDBMigrator,
UpdatedBy: domain.CtxSystemDBMigrator,
CreatedAt: now,
UpdatedAt: now,
UserIdentifier: user.Identifier,
Source: user.Source,
ProviderName: user.ProviderName,
@@ -493,12 +491,10 @@ func (r *SqlRepo) getOrCreateInterface(
// interfaceDefaults will be applied to newly created interface records
interfaceDefaults := domain.Interface{
BaseModel: domain.BaseModel{
CreatedBy: ui.UserId(),
UpdatedBy: ui.UserId(),
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
},
CreatedBy: ui.UserId(),
UpdatedBy: ui.UserId(),
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
Identifier: id,
}
@@ -702,12 +698,10 @@ func (r *SqlRepo) getOrCreatePeer(ui *domain.ContextUserInfo, tx *gorm.DB, id do
// interfaceDefaults will be applied to newly created interface records
interfaceDefaults := domain.Peer{
BaseModel: domain.BaseModel{
CreatedBy: ui.UserId(),
UpdatedBy: ui.UserId(),
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
},
CreatedBy: ui.UserId(),
UpdatedBy: ui.UserId(),
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
Identifier: id,
}
@@ -995,12 +989,10 @@ func (r *SqlRepo) getOrCreateUser(ui *domain.ContextUserInfo, tx *gorm.DB, id do
// create a new user record if no user record exists yet
userDefaults := domain.User{
BaseModel: domain.BaseModel{
CreatedBy: ui.UserId(),
UpdatedBy: ui.UserId(),
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
},
CreatedBy: ui.UserId(),
UpdatedBy: ui.UserId(),
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
Identifier: id,
IsAdmin: false,
}
@@ -54,10 +54,8 @@ func TestUpsertUser_PreservesExistingCreatedAt(t *testing.T) {
user := &domain.User{
Identifier: "test-user",
Email: "test@example.com",
BaseModel: domain.BaseModel{
CreatedAt: originalTime,
CreatedBy: "original-creator",
},
CreatedAt: originalTime,
CreatedBy: "original-creator",
}
err := repo.upsertUser(ui, db, user)
+10 -23
View File
@@ -127,11 +127,9 @@ func (c LocalController) convertWireGuardInterface(device *wgtypes.Device) (doma
// read data from wgctrl interface
iface := domain.PhysicalInterface{
Identifier: domain.InterfaceIdentifier(device.Name),
KeyPair: domain.KeyPair{
PrivateKey: device.PrivateKey.String(),
PublicKey: device.PublicKey.String(),
},
Identifier: domain.InterfaceIdentifier(device.Name),
PrivateKey: device.PrivateKey.String(),
PublicKey: device.PublicKey.String(),
ListenPort: device.ListenPort,
Addresses: nil,
Mtu: 0,
@@ -190,12 +188,10 @@ func (c LocalController) GetPeers(_ context.Context, deviceId domain.InterfaceId
func (c LocalController) convertWireGuardPeer(peer *wgtypes.Peer) (domain.PhysicalPeer, error) {
peerModel := domain.PhysicalPeer{
Identifier: domain.PeerIdentifier(peer.PublicKey.String()),
Endpoint: "",
AllowedIPs: nil,
KeyPair: domain.KeyPair{
PublicKey: peer.PublicKey.String(),
},
Identifier: domain.PeerIdentifier(peer.PublicKey.String()),
Endpoint: "",
AllowedIPs: nil,
PublicKey: peer.PublicKey.String(),
PresharedKey: "",
PersistentKeepalive: int(peer.PersistentKeepaliveInterval.Seconds()),
LastHandshake: peer.LastHandshakeTime,
@@ -280,9 +276,7 @@ func (c LocalController) getInterface(id domain.InterfaceIdentifier) (*domain.Ph
func (c LocalController) createLowLevelInterface(id domain.InterfaceIdentifier) error {
link := &netlink.GenericLink{
LinkAttrs: netlink.LinkAttrs{
Name: string(id),
},
Name: string(id),
LinkType: "wireguard",
}
err := c.nl.LinkAdd(link)
@@ -318,13 +312,7 @@ func (c LocalController) updateLowLevelInterface(pi *domain.PhysicalInterface) e
}
for _, rawAddr := range rawAddresses {
netlinkAddr := domain.CidrFromNetlinkAddr(rawAddr)
remove := true
for _, addr := range pi.Addresses {
if addr == netlinkAddr {
remove = false
break
}
}
remove := !slices.Contains(pi.Addresses, netlinkAddr)
if !remove {
continue
@@ -385,8 +373,7 @@ func (c LocalController) DeleteInterface(_ context.Context, id domain.InterfaceI
func (c LocalController) deleteLowLevelInterface(id domain.InterfaceIdentifier) error {
link, err := c.nl.LinkByName(string(id))
if err != nil {
var linkNotFoundError netlink.LinkNotFoundError
if errors.As(err, &linkNotFoundError) {
if _, ok := errors.AsType[netlink.LinkNotFoundError](err); ok {
return nil // ignore not found error
}
return fmt.Errorf("unable to find low level interface: %w", err)
+10 -20
View File
@@ -263,11 +263,9 @@ func (c *MikrotikController) convertWireGuardInterface(
error,
) {
pi := domain.PhysicalInterface{
Identifier: domain.InterfaceIdentifier(wg.GetString("name")),
KeyPair: domain.KeyPair{
PrivateKey: wg.GetString("private-key"),
PublicKey: wg.GetString("public-key"),
},
Identifier: domain.InterfaceIdentifier(wg.GetString("name")),
PrivateKey: wg.GetString("private-key"),
PublicKey: wg.GetString("public-key"),
ListenPort: wg.GetInt("listen-port"),
Addresses: addresses,
Mtu: wg.GetInt("mtu"),
@@ -354,13 +352,11 @@ func (c *MikrotikController) convertWireGuardPeer(peer lowlevel.GenericJsonObjec
}
peerModel := domain.PhysicalPeer{
Identifier: domain.PeerIdentifier(peer.GetString("public-key")),
Endpoint: currentEndpoint,
AllowedIPs: allowedAddresses,
KeyPair: domain.KeyPair{
PublicKey: peer.GetString("public-key"),
PrivateKey: peer.GetString("private-key"),
},
Identifier: domain.PeerIdentifier(peer.GetString("public-key")),
Endpoint: currentEndpoint,
AllowedIPs: allowedAddresses,
PublicKey: peer.GetString("public-key"),
PrivateKey: peer.GetString("private-key"),
PresharedKey: domain.PreSharedKey(peer.GetString("preshared-key")),
PersistentKeepalive: keepAliveSeconds,
LastHandshake: lastHandshakeTime,
@@ -792,7 +788,7 @@ func (c *MikrotikController) ExecuteInterfaceHook(
}
scriptName := fmt.Sprintf("wg-portal-hook-%s-%d", id, time.Now().UnixNano())
// Replace %i with the interface ID to mimic wg-quick behavior
scriptSource := strings.ReplaceAll(hookCmd, "%i", string(id))
// Inject the interface ID as a local variable for convenience in RouterOS scripts
@@ -1076,13 +1072,7 @@ func (c *MikrotikController) setRoutesForFamily(
continue
}
valid := false
for _, cidr := range cidrs {
if existingRoute.EqualPrefix(cidr) {
valid = true
break
}
}
valid := slices.ContainsFunc(cidrs, existingRoute.EqualPrefix)
if valid {
continue // route is still valid, nothing to do
}
+12 -16
View File
@@ -168,7 +168,7 @@ func parseCidrsTolerant(value, what, owner string) []domain.Cidr {
}
parsed := make([]domain.Cidr, 0, 1)
for _, part := range strings.Split(value, ",") {
for part := range strings.SplitSeq(value, ",") {
part = strings.TrimSpace(part)
if part == "" {
continue
@@ -424,11 +424,9 @@ func (c *OpnsenseController) convertServer(
stats := interfaceStats[string(identifier)]
physicalInterface := &domain.PhysicalInterface{
Identifier: identifier,
KeyPair: domain.KeyPair{
PrivateKey: row.GetString("privkey"),
PublicKey: row.GetString("pubkey"),
},
Identifier: identifier,
PrivateKey: row.GetString("privkey"),
PublicKey: row.GetString("pubkey"),
ListenPort: row.GetInt("port"),
Addresses: addresses,
Mtu: row.GetInt("mtu"),
@@ -494,7 +492,7 @@ func clientBelongsToServer(row lowlevel.GenericJsonObject, serverUuid string) bo
if serverUuid == "" {
return false
}
for _, uuid := range strings.Split(row.GetString("servers"), ",") {
for uuid := range strings.SplitSeq(row.GetString("servers"), ",") {
if strings.TrimSpace(uuid) == serverUuid {
return true
}
@@ -522,12 +520,10 @@ func (c *OpnsenseController) convertClient(
Identifier: domain.PeerIdentifier(publicKey),
Endpoint: endpoint,
AllowedIPs: allowedIPs,
KeyPair: domain.KeyPair{
PublicKey: publicKey,
// OPNsense stores only the public key for a peer; the private key
// stays with the client device.
PrivateKey: "",
},
PublicKey: publicKey,
// OPNsense stores only the public key for a peer; the private key
// stays with the client device.
PrivateKey: "",
PresharedKey: domain.PreSharedKey(row.GetString("psk")),
PersistentKeepalive: row.GetInt("keepalive"),
LastHandshake: stats.lastHandshake,
@@ -726,7 +722,7 @@ func (c *OpnsenseController) SavePeer(
} else {
physicalPeer = &domain.PhysicalPeer{
Identifier: id,
KeyPair: domain.KeyPair{PublicKey: string(id)},
PublicKey: string(id),
ImportSource: domain.ControllerTypeOpnsense,
}
physicalPeer.SetExtras(domain.OpnsensePeerExtras{})
@@ -781,7 +777,7 @@ func (c *OpnsenseController) createOrUpdatePeer(
// from them.
servers := map[string]struct{}{serverUuid: {}}
if existingRow != nil {
for _, uuid := range strings.Split(existingRow.GetString("servers"), ",") {
for uuid := range strings.SplitSeq(existingRow.GetString("servers"), ",") {
if uuid = strings.TrimSpace(uuid); uuid != "" {
servers[uuid] = struct{}{}
}
@@ -912,7 +908,7 @@ func (c *OpnsenseController) DeletePeer(
remaining := make([]string, 0)
if serverRow != nil {
serverUuid := serverRow.GetString("uuid")
for _, attached := range strings.Split(row.GetString("servers"), ",") {
for attached := range strings.SplitSeq(row.GetString("servers"), ",") {
if attached = strings.TrimSpace(attached); attached != "" && attached != serverUuid {
remaining = append(remaining, attached)
}
+9 -13
View File
@@ -340,11 +340,9 @@ func (c *PfsenseController) convertWireGuardInterface(
var rxBytes, txBytes uint64
pi := domain.PhysicalInterface{
Identifier: domain.InterfaceIdentifier(wg.GetString("name")),
KeyPair: domain.KeyPair{
PrivateKey: privateKey,
PublicKey: publicKey,
},
Identifier: domain.InterfaceIdentifier(wg.GetString("name")),
PrivateKey: privateKey,
PublicKey: publicKey,
ListenPort: listenPort,
Addresses: addresses,
Mtu: mtu,
@@ -559,13 +557,11 @@ func (c *PfsenseController) convertWireGuardPeer(peer lowlevel.GenericJsonObject
txBytes := uint64(0)
peerModel := domain.PhysicalPeer{
Identifier: domain.PeerIdentifier(publicKey),
Endpoint: endpoint,
AllowedIPs: allowedAddresses,
KeyPair: domain.KeyPair{
PublicKey: publicKey,
PrivateKey: privateKey,
},
Identifier: domain.PeerIdentifier(publicKey),
Endpoint: endpoint,
AllowedIPs: allowedAddresses,
PublicKey: publicKey,
PrivateKey: privateKey,
PresharedKey: domain.PreSharedKey(presharedKey),
PersistentKeepalive: keepAliveSeconds,
LastHandshake: lastHandshakeTime,
@@ -794,7 +790,7 @@ func (c *PfsenseController) SavePeer(
if physicalPeer == nil {
physicalPeer = &domain.PhysicalPeer{
Identifier: id,
KeyPair: domain.KeyPair{PublicKey: string(id)},
PublicKey: string(id),
ImportSource: domain.ControllerTypePfsense,
}
physicalPeer.SetExtras(domain.PfsensePeerExtras{})
+11 -23
View File
@@ -6,6 +6,7 @@ import (
"fmt"
"log/slog"
"os"
"slices"
"github.com/vishvananda/netlink"
"golang.zx2c4.com/wireguard/wgctrl"
@@ -106,11 +107,9 @@ func (r *WgRepo) convertWireGuardInterface(device *wgtypes.Device) (domain.Physi
// read data from wgctrl interface
iface := domain.PhysicalInterface{
Identifier: domain.InterfaceIdentifier(device.Name),
KeyPair: domain.KeyPair{
PrivateKey: device.PrivateKey.String(),
PublicKey: device.PublicKey.String(),
},
Identifier: domain.InterfaceIdentifier(device.Name),
PrivateKey: device.PrivateKey.String(),
PublicKey: device.PublicKey.String(),
ListenPort: device.ListenPort,
Addresses: nil,
Mtu: 0,
@@ -148,12 +147,10 @@ func (r *WgRepo) convertWireGuardInterface(device *wgtypes.Device) (domain.Physi
func (r *WgRepo) convertWireGuardPeer(peer *wgtypes.Peer) (domain.PhysicalPeer, error) {
peerModel := domain.PhysicalPeer{
Identifier: domain.PeerIdentifier(peer.PublicKey.String()),
Endpoint: "",
AllowedIPs: nil,
KeyPair: domain.KeyPair{
PublicKey: peer.PublicKey.String(),
},
Identifier: domain.PeerIdentifier(peer.PublicKey.String()),
Endpoint: "",
AllowedIPs: nil,
PublicKey: peer.PublicKey.String(),
PresharedKey: "",
PersistentKeepalive: int(peer.PersistentKeepaliveInterval.Seconds()),
LastHandshake: peer.LastHandshakeTime,
@@ -241,9 +238,7 @@ func (r *WgRepo) getInterface(id domain.InterfaceIdentifier) (*domain.PhysicalIn
func (r *WgRepo) createLowLevelInterface(id domain.InterfaceIdentifier) error {
link := &netlink.GenericLink{
LinkAttrs: netlink.LinkAttrs{
Name: string(id),
},
Name: string(id),
LinkType: "wireguard",
}
err := r.nl.LinkAdd(link)
@@ -279,13 +274,7 @@ func (r *WgRepo) updateLowLevelInterface(pi *domain.PhysicalInterface) error {
}
for _, rawAddr := range rawAddresses {
netlinkAddr := domain.CidrFromNetlinkAddr(rawAddr)
remove := true
for _, addr := range pi.Addresses {
if addr == netlinkAddr {
remove = false
break
}
}
remove := !slices.Contains(pi.Addresses, netlinkAddr)
if !remove {
continue
@@ -351,8 +340,7 @@ func (r *WgRepo) DeleteInterface(_ context.Context, id domain.InterfaceIdentifie
func (r *WgRepo) deleteLowLevelInterface(id domain.InterfaceIdentifier) error {
link, err := r.nl.LinkByName(string(id))
if err != nil {
var linkNotFoundError netlink.LinkNotFoundError
if errors.As(err, &linkNotFoundError) {
if _, ok := errors.AsType[netlink.LinkNotFoundError](err); ok {
return nil // ignore not found error
}
return fmt.Errorf("unable to find low level interface: %w", err)
@@ -18,10 +18,10 @@ func (w wildcard) match(s string) bool {
}
func newWildcard(s string) wildcard {
if i := strings.IndexByte(s, '*'); i >= 0 {
if before, after, ok := strings.Cut(s, "*"); ok {
return wildcard{
prefix: s[:i],
suffix: s[i+1:],
prefix: before,
suffix: after,
}
}
@@ -52,7 +52,7 @@ func maskToken(token, key []byte) []byte {
// masked contains the key in the first half and the XOR masked token in the second half
tokenLength := len(token)
masked := make([]byte, tokenLength*2)
for i := 0; i < len(token); i++ {
for i := range token {
masked[i] = key[i]
masked[i+tokenLength] = token[i] ^ key[i] // XOR mask
}
@@ -65,7 +65,7 @@ func maskToken(token, key []byte) []byte {
func unmaskToken(masked []byte) []byte {
tokenLength := len(masked) / 2
token := make([]byte, tokenLength)
for i := 0; i < tokenLength; i++ {
for i := range tokenLength {
token[i] = masked[i] ^ masked[i+tokenLength] // XOR unmask
}
@@ -85,7 +85,7 @@ func addPrefix(o options, message string) string {
// enabled, the stack trace is included in the response.
func getDefaultErrCallback(o options) func(err error, stack []byte, w http.ResponseWriter, r *http.Request) {
return func(err error, stack []byte, w http.ResponseWriter, r *http.Request) {
responseBody := map[string]interface{}{
responseBody := map[string]any{
"error": "Internal Server Error",
}
if o.exposeStackTrace && len(stack) > 0 {
@@ -120,8 +120,7 @@ func getDefaultLogCallback(o options) func(error, []byte, bool) {
}
func isBrokenPipeError(err error) bool {
var syscallErr *os.SyscallError
if errors.As(err, &syscallErr) {
if syscallErr, ok := errors.AsType[*os.SyscallError](err); ok {
errMsg := strings.ToLower(syscallErr.Err.Error())
if strings.Contains(errMsg, "broken pipe") ||
strings.Contains(errMsg, "connection reset by peer") {
+1 -1
View File
@@ -114,7 +114,7 @@ type Session interface {
type Validator interface {
// Struct validates the given struct.
Struct(s interface{}) error
Struct(s any) error
}
// endregion handler-interfaces
@@ -5,6 +5,7 @@ import (
"errors"
"net/http"
"net/http/httptest"
"sync"
"testing"
"time"
@@ -18,6 +19,24 @@ import (
// region test-helper
type syncEventBus struct {
bus evbus.MessageBus
onSubscribe func(topic string)
}
func (s *syncEventBus) Subscribe(topic string, fn any) error {
defer func() {
if s.onSubscribe != nil {
s.onSubscribe(topic)
}
}()
return s.bus.Subscribe(topic, fn)
}
func (s *syncEventBus) Unsubscribe(topic string, fn any) error {
return s.bus.Unsubscribe(topic, fn)
}
type websocketTestPeerService struct {
peers map[domain.PeerIdentifier]*domain.Peer
}
@@ -39,8 +58,17 @@ func newTestWebsocketConnection(
) (*websocket.Conn, func()) {
t.Helper()
var wg sync.WaitGroup
wg.Add(2) // TopicPeerStatsUpdated and TopicInterfaceStatsUpdated
wrappedBus := &syncEventBus{
bus: bus,
onSubscribe: func(topic string) {
wg.Done()
},
}
cfg := &config.Config{}
endpoint := NewWebsocketEndpoint(cfg, nil, bus, websocketTestPeerService{peers: peers})
endpoint := NewWebsocketEndpoint(cfg, nil, wrappedBus, websocketTestPeerService{peers: peers})
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
r = r.WithContext(domain.SetUserInfo(r.Context(), userInfo))
@@ -55,6 +83,8 @@ func newTestWebsocketConnection(
t.Fatalf("failed to dial websocket: %v", err)
}
wg.Wait() // wait for eventbus to be ready
cleanup := func() {
conn.Close()
server.Close()
@@ -3,6 +3,7 @@ package handlers
import (
"context"
"net/http"
"slices"
"github.com/h44z/wg-portal/internal/app/api/core/request"
"github.com/h44z/wg-portal/internal/app/api/core/respond"
@@ -137,10 +138,8 @@ func UserHasScopes(session SessionData, scopes ...Scope) bool {
}
// Check if admin scope is required
for _, scope := range scopes {
if scope == ScopeAdmin {
return false
}
if slices.Contains(scopes, ScopeAdmin) {
return false
}
// For all other scopes, a logged-in user is sufficient (for now)
@@ -137,12 +137,10 @@ func NewDomainInterface(src *Interface) *domain.Interface {
cidrs, _ := domain.CidrsFromArray(src.Addresses)
res := &domain.Interface{
BaseModel: domain.BaseModel{},
Identifier: domain.InterfaceIdentifier(src.Identifier),
KeyPair: domain.KeyPair{
PrivateKey: src.PrivateKey,
PublicKey: src.PublicKey,
},
BaseModel: domain.BaseModel{},
Identifier: domain.InterfaceIdentifier(src.Identifier),
PrivateKey: src.PrivateKey,
PublicKey: src.PublicKey,
ListenPort: src.ListenPort,
Addresses: cidrs,
DnsStr: internal.SliceToString(src.Dns),
+1 -1
View File
@@ -47,7 +47,7 @@ type Peer struct {
InterfaceIdentifier string `json:"InterfaceIdentifier"` // the interface id
Disabled bool `json:"Disabled"` // flag that specifies if the peer is enabled (up) or not (down)
DisabledReason string `json:"DisabledReason"` // the reason why the peer has been disabled
ExpiresAt ExpiryDate `json:"ExpiresAt,omitempty"` // expiry dates for peers
ExpiresAt ExpiryDate `json:"ExpiresAt"` // expiry dates for peers
Notes string `json:"Notes"` // a note field for peers
IsDynamic bool `json:"IsDynamic"` // specifies if the peer is dynamically created by mikrotik
+1 -1
View File
@@ -88,7 +88,7 @@ type Authenticator interface {
type Validator interface {
// Struct validates the given struct.
Struct(s interface{}) error
Struct(s any) error
}
// endregion handler-interfaces
@@ -3,6 +3,7 @@ package handlers
import (
"context"
"net/http"
"slices"
"github.com/h44z/wg-portal/internal/app/api/core/respond"
"github.com/h44z/wg-portal/internal/app/api/v0/model"
@@ -104,11 +105,5 @@ func UserHasScopes(user *domain.User, scopes ...Scope) bool {
}
// Check if admin scope is required
for _, scope := range scopes {
if scope == ScopeAdmin {
return false
}
}
return true
return !slices.Contains(scopes, ScopeAdmin)
}
@@ -159,12 +159,10 @@ func NewDomainInterface(src *Interface) *domain.Interface {
cidrs, _ := domain.CidrsFromArray(src.Addresses)
res := &domain.Interface{
BaseModel: domain.BaseModel{},
Identifier: domain.InterfaceIdentifier(src.Identifier),
KeyPair: domain.KeyPair{
PrivateKey: src.PrivateKey,
PublicKey: src.PublicKey,
},
BaseModel: domain.BaseModel{},
Identifier: domain.InterfaceIdentifier(src.Identifier),
PrivateKey: src.PrivateKey,
PublicKey: src.PublicKey,
ListenPort: src.ListenPort,
Addresses: cidrs,
DnsStr: internal.SliceToString(src.Dns),
+4 -6
View File
@@ -122,12 +122,10 @@ func (a *App) createDefaultUser(ctx context.Context) error {
now := time.Now()
defaultAdmin := &domain.User{
BaseModel: domain.BaseModel{
CreatedBy: domain.CtxSystemAdminId,
UpdatedBy: domain.CtxSystemAdminId,
CreatedAt: now,
UpdatedAt: now,
},
CreatedBy: domain.CtxSystemAdminId,
UpdatedBy: domain.CtxSystemAdminId,
CreatedAt: now,
UpdatedAt: now,
Identifier: adminUserId,
Email: "admin@wgportal.local",
IsAdmin: true,
+1 -1
View File
@@ -20,7 +20,7 @@ type DatabaseRepo interface {
type EventBus interface {
// Subscribe subscribes to a topic
Subscribe(topic string, fn interface{}) error
Subscribe(topic string, fn any) error
}
// endregion dependencies
+8 -12
View File
@@ -673,12 +673,10 @@ func (a *Authenticator) registerNewUser(
Department: userInfo.Department,
Authentications: []domain.UserAuthentication{
{
BaseModel: domain.BaseModel{
CreatedBy: ctxUserInfo.UserId(),
UpdatedBy: ctxUserInfo.UserId(),
CreatedAt: now,
UpdatedAt: now,
},
CreatedBy: ctxUserInfo.UserId(),
UpdatedBy: ctxUserInfo.UserId(),
CreatedAt: now,
UpdatedAt: now,
UserIdentifier: userInfo.Identifier,
Source: source,
ProviderName: provider,
@@ -742,12 +740,10 @@ func (a *Authenticator) updateExternalUser(
ctxUserInfo := domain.GetUserInfo(ctx)
now := time.Now()
existingUser.Authentications = append(existingUser.Authentications, domain.UserAuthentication{
BaseModel: domain.BaseModel{
CreatedBy: ctxUserInfo.UserId(),
UpdatedBy: ctxUserInfo.UserId(),
CreatedAt: now,
UpdatedAt: now,
},
CreatedBy: ctxUserInfo.UserId(),
UpdatedBy: ctxUserInfo.UserId(),
CreatedAt: now,
UpdatedAt: now,
UserIdentifier: existingUser.Identifier,
Source: source,
ProviderName: provider,
+11 -15
View File
@@ -1,6 +1,7 @@
package auth
import (
"slices"
"strings"
"github.com/h44z/wg-portal/internal"
@@ -49,11 +50,8 @@ func parseOauthUserInfo(
if !isAdmin && mapping.UserGroups != "" && adminMapping.AdminGroupRegex != "" {
adminInfoAvailable = true
re := adminMapping.GetAdminGroupRegex()
for _, group := range userInfo.UserGroups {
if re.MatchString(group) {
isAdmin = true
break
}
if slices.ContainsFunc(userInfo.UserGroups, re.MatchString) {
isAdmin = true
}
userInfo.IsAdmin = isAdmin
userInfo.AdminInfoAvailable = adminInfoAvailable
@@ -65,16 +63,14 @@ func parseOauthUserInfo(
// getOauthFieldMapping returns the default field mapping for the oauth provider
func getOauthFieldMapping(f config.OauthFields) config.OauthFields {
defaultMap := config.OauthFields{
BaseFields: config.BaseFields{
UserIdentifier: "sub",
Email: "email",
Firstname: "given_name",
Lastname: "family_name",
Phone: "phone",
Department: "department",
},
IsAdmin: "admin_flag",
UserGroups: "", // by default, do not use user groups
UserIdentifier: "sub",
Email: "email",
Firstname: "given_name",
Lastname: "family_name",
Phone: "phone",
Department: "department",
IsAdmin: "admin_flag",
UserGroups: "", // by default, do not use user groups
}
if f.UserIdentifier != "" {
defaultMap.UserIdentifier = f.UserIdentifier
@@ -16,14 +16,12 @@ import (
// makeOauthFieldMapping returns a minimal OauthFields mapping for testing.
func makeOauthFieldMapping() config.OauthFields {
return config.OauthFields{
BaseFields: config.BaseFields{
UserIdentifier: "sub",
Email: "email",
Firstname: "given_name",
Lastname: "family_name",
Phone: "phone",
Department: "department",
},
UserIdentifier: "sub",
Email: "email",
Firstname: "given_name",
Lastname: "family_name",
Phone: "phone",
Department: "department",
}
}
+21 -29
View File
@@ -32,14 +32,12 @@ func Test_parseOauthUserInfo_no_admin(t *testing.T) {
require.NoError(t, err)
fieldMapping := getOauthFieldMapping(config.OauthFields{
BaseFields: config.BaseFields{
UserIdentifier: "email",
Email: "email",
Firstname: "name",
Lastname: "family_name",
},
IsAdmin: "is_admin",
UserGroups: "groups",
UserIdentifier: "email",
Email: "email",
Firstname: "name",
Lastname: "family_name",
IsAdmin: "is_admin",
UserGroups: "groups",
})
adminMapping := &config.OauthAdminMapping{}
@@ -78,13 +76,11 @@ func Test_parseOauthUserInfo_admin_group(t *testing.T) {
require.NoError(t, err)
fieldMapping := getOauthFieldMapping(config.OauthFields{
BaseFields: config.BaseFields{
UserIdentifier: "email",
Email: "email",
Firstname: "name",
Lastname: "family_name",
},
UserGroups: "groups",
UserIdentifier: "email",
Email: "email",
Firstname: "name",
Lastname: "family_name",
UserGroups: "groups",
})
adminMapping := &config.OauthAdminMapping{
AdminGroupRegex: "^wgportal-admins@mydomain.net$",
@@ -122,13 +118,11 @@ func Test_parseOauthUserInfo_admin_value(t *testing.T) {
require.NoError(t, err)
fieldMapping := getOauthFieldMapping(config.OauthFields{
BaseFields: config.BaseFields{
UserIdentifier: "email",
Email: "email",
Firstname: "name",
Lastname: "family_name",
},
IsAdmin: "is_admin",
UserIdentifier: "email",
Email: "email",
Firstname: "name",
Lastname: "family_name",
IsAdmin: "is_admin",
})
adminMapping := &config.OauthAdminMapping{} // test with default regex
@@ -163,13 +157,11 @@ func Test_parseOauthUserInfo_admin_value_custom(t *testing.T) {
require.NoError(t, err)
fieldMapping := getOauthFieldMapping(config.OauthFields{
BaseFields: config.BaseFields{
UserIdentifier: "email",
Email: "email",
Firstname: "name",
Lastname: "family_name",
},
IsAdmin: "is_admin",
UserIdentifier: "email",
Email: "email",
Firstname: "name",
Lastname: "family_name",
IsAdmin: "is_admin",
})
adminMapping := &config.OauthAdminMapping{
AdminValueRegex: "^1$",
+27 -41
View File
@@ -136,12 +136,10 @@ func migrateV1Users(oldDb, newDb *gorm.DB) error {
deletionReason = "disabled prior to migration"
}
newUser := domain.User{
BaseModel: domain.BaseModel{
CreatedBy: domain.CtxSystemV1Migrator,
UpdatedBy: domain.CtxSystemV1Migrator,
CreatedAt: oldUser.CreatedAt,
UpdatedAt: oldUser.UpdatedAt,
},
CreatedBy: domain.CtxSystemV1Migrator,
UpdatedBy: domain.CtxSystemV1Migrator,
CreatedAt: oldUser.CreatedAt,
UpdatedAt: oldUser.UpdatedAt,
Identifier: domain.UserIdentifier(oldUser.Email),
Email: oldUser.Email,
IsAdmin: oldUser.IsAdmin,
@@ -162,12 +160,10 @@ func migrateV1Users(oldDb, newDb *gorm.DB) error {
}
authentication := domain.UserAuthentication{
BaseModel: domain.BaseModel{
CreatedBy: domain.CtxSystemV1Migrator,
UpdatedBy: domain.CtxSystemV1Migrator,
CreatedAt: oldUser.CreatedAt,
UpdatedAt: oldUser.UpdatedAt,
},
CreatedBy: domain.CtxSystemV1Migrator,
UpdatedBy: domain.CtxSystemV1Migrator,
CreatedAt: oldUser.CreatedAt,
UpdatedAt: oldUser.UpdatedAt,
UserIdentifier: domain.UserIdentifier(oldUser.Email),
Source: domain.UserSource(oldUser.Source),
ProviderName: "", // unknown
@@ -223,17 +219,13 @@ func migrateV1Interfaces(oldDb, newDb *gorm.DB) error {
networks[i] = domain.CidrFromIpNet(*ip.IpNet())
}
newInterface := domain.Interface{
BaseModel: domain.BaseModel{
CreatedBy: domain.CtxSystemV1Migrator,
UpdatedBy: domain.CtxSystemV1Migrator,
CreatedAt: oldDevice.CreatedAt,
UpdatedAt: oldDevice.UpdatedAt,
},
Identifier: domain.InterfaceIdentifier(oldDevice.DeviceName),
KeyPair: domain.KeyPair{
PrivateKey: oldDevice.PrivateKey,
PublicKey: oldDevice.PublicKey,
},
CreatedBy: domain.CtxSystemV1Migrator,
UpdatedBy: domain.CtxSystemV1Migrator,
CreatedAt: oldDevice.CreatedAt,
UpdatedAt: oldDevice.UpdatedAt,
Identifier: domain.InterfaceIdentifier(oldDevice.DeviceName),
PrivateKey: oldDevice.PrivateKey,
PublicKey: oldDevice.PublicKey,
ListenPort: oldDevice.ListenPort,
Addresses: ips,
DnsStr: "",
@@ -350,12 +342,10 @@ func migrateV1Peers(oldDb, newDb *gorm.DB) error {
// create dummy user
now := time.Now()
user = domain.User{
BaseModel: domain.BaseModel{
CreatedBy: domain.CtxSystemV1Migrator,
UpdatedBy: domain.CtxSystemV1Migrator,
CreatedAt: now,
UpdatedAt: now,
},
CreatedBy: domain.CtxSystemV1Migrator,
UpdatedBy: domain.CtxSystemV1Migrator,
CreatedAt: now,
UpdatedAt: now,
Identifier: domain.UserIdentifier(oldPeer.Email),
Email: oldPeer.Email,
IsAdmin: false,
@@ -369,12 +359,10 @@ func migrateV1Peers(oldDb, newDb *gorm.DB) error {
}
authentication := domain.UserAuthentication{
BaseModel: domain.BaseModel{
CreatedBy: domain.CtxSystemV1Migrator,
UpdatedBy: domain.CtxSystemV1Migrator,
CreatedAt: now,
UpdatedAt: now,
},
CreatedBy: domain.CtxSystemV1Migrator,
UpdatedBy: domain.CtxSystemV1Migrator,
CreatedAt: now,
UpdatedAt: now,
UserIdentifier: domain.UserIdentifier(oldPeer.Email),
Source: domain.UserSourceDatabase,
ProviderName: "", // unknown
@@ -386,12 +374,10 @@ func migrateV1Peers(oldDb, newDb *gorm.DB) error {
slog.Debug("dummy user migrated successfully", "identifier", user.Identifier)
}
newPeer := domain.Peer{
BaseModel: domain.BaseModel{
CreatedBy: domain.CtxSystemV1Migrator,
UpdatedBy: domain.CtxSystemV1Migrator,
CreatedAt: oldPeer.CreatedAt,
UpdatedAt: oldPeer.UpdatedAt,
},
CreatedBy: domain.CtxSystemV1Migrator,
UpdatedBy: domain.CtxSystemV1Migrator,
CreatedAt: oldPeer.CreatedAt,
UpdatedAt: oldPeer.UpdatedAt,
Endpoint: domain.NewConfigOption(oldPeer.Endpoint, !oldPeer.IgnoreGlobalSettings),
EndpointPublicKey: domain.NewConfigOption(iface.PublicKey, !oldPeer.IgnoreGlobalSettings),
AllowedIPsStr: domain.NewConfigOption(oldPeer.AllowedIPsStr, !oldPeer.IgnoreGlobalSettings),
+1 -1
View File
@@ -25,7 +25,7 @@ type InterfaceAndPeerDatabaseRepo interface {
type EventBus interface {
// Subscribe subscribes to a topic
Subscribe(topic string, fn interface{}) error
Subscribe(topic string, fn any) error
}
type RoutesController interface {
+4 -6
View File
@@ -29,12 +29,10 @@ func convertRawLdapUser(
uid := domain.UserIdentifier(internal.MapDefaultString(rawUser, fields.UserIdentifier, ""))
user := &domain.User{
BaseModel: domain.BaseModel{
CreatedBy: domain.CtxSystemLdapSyncer,
UpdatedBy: domain.CtxSystemLdapSyncer,
CreatedAt: now,
UpdatedAt: now,
},
CreatedBy: domain.CtxSystemLdapSyncer,
UpdatedBy: domain.CtxSystemLdapSyncer,
CreatedAt: now,
UpdatedAt: now,
Identifier: uid,
Email: strings.ToLower(internal.MapDefaultString(rawUser, fields.Email, "")),
IsAdmin: isAdmin,
@@ -16,14 +16,12 @@ import (
// makeTestLdapFields returns a minimal LdapFields config for testing.
func makeTestLdapFields() *config.LdapFields {
return &config.LdapFields{
BaseFields: config.BaseFields{
UserIdentifier: "uid",
Email: "mail",
Firstname: "givenName",
Lastname: "sn",
Phone: "telephoneNumber",
Department: "department",
},
UserIdentifier: "uid",
Email: "mail",
Firstname: "givenName",
Lastname: "sn",
Phone: "telephoneNumber",
Department: "department",
GroupMembership: "memberOf",
}
}
+5 -7
View File
@@ -156,7 +156,7 @@ func (m Manager) GetAllUsers(ctx context.Context) ([]domain.User, error) {
wg := sync.WaitGroup{}
workers := int(math.Min(float64(len(users)), 10))
wg.Add(workers)
for i := 0; i < workers; i++ {
for range workers {
go func() {
defer wg.Done()
for user := range ch {
@@ -500,12 +500,10 @@ func (m Manager) create(ctx context.Context, user *domain.User) (*domain.User, e
now := time.Now()
user.Authentications = []domain.UserAuthentication{
{
BaseModel: domain.BaseModel{
CreatedBy: ctxUserInfo.UserId(),
UpdatedBy: ctxUserInfo.UserId(),
CreatedAt: now,
UpdatedAt: now,
},
CreatedBy: ctxUserInfo.UserId(),
UpdatedBy: ctxUserInfo.UserId(),
CreatedAt: now,
UpdatedAt: now,
UserIdentifier: user.Identifier,
Source: domain.UserSourceDatabase,
ProviderName: "",
+1 -1
View File
@@ -19,7 +19,7 @@ type EventBus interface {
// Publish sends a message to the message bus.
Publish(topic string, args ...any)
// Subscribe subscribes to a topic
Subscribe(topic string, fn interface{}) error
Subscribe(topic string, fn any) error
}
// endregion dependencies
@@ -23,7 +23,8 @@ func TestRegisterOpnsenseControllers(t *testing.T) {
cfg := &config.Config{}
cfg.Backend.Opnsense = []config.BackendOpnsense{
{
BackendBase: config.BackendBase{Id: "opn1", DisplayName: "Edge firewall"},
Id: "opn1",
DisplayName: "Edge firewall",
ApiUrl: "https://127.0.0.1",
ApiKey: "key",
ApiSecret: "secret",
@@ -51,10 +52,10 @@ func TestRegisterOpnsenseControllersSkipsReservedId(t *testing.T) {
cfg := &config.Config{}
cfg.Backend.Opnsense = []config.BackendOpnsense{
{
BackendBase: config.BackendBase{Id: config.LocalBackendName},
ApiUrl: "https://127.0.0.1",
ApiKey: "key",
ApiSecret: "secret",
Id: config.LocalBackendName,
ApiUrl: "https://127.0.0.1",
ApiKey: "key",
ApiSecret: "secret",
},
}
+1 -1
View File
@@ -36,7 +36,7 @@ type StatisticsMetricsServer interface {
type StatisticsEventBus interface {
// Subscribe subscribes to a topic
Subscribe(topic string, fn interface{}) error
Subscribe(topic string, fn any) error
// Publish sends a message to the message bus.
Publish(topic string, args ...any)
}
+1 -1
View File
@@ -49,7 +49,7 @@ type EventBus interface {
// Publish sends a message to the message bus.
Publish(topic string, args ...any)
// Subscribe subscribes to a topic
Subscribe(topic string, fn interface{}) error
Subscribe(topic string, fn any) error
}
// endregion dependencies
@@ -375,12 +375,10 @@ func (m Manager) PrepareInterface(ctx context.Context) (*domain.Interface, error
}
freshInterface := &domain.Interface{
BaseModel: domain.BaseModel{
CreatedBy: string(currentUser.Id),
UpdatedBy: string(currentUser.Id),
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
},
CreatedBy: string(currentUser.Id),
UpdatedBy: string(currentUser.Id),
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
Identifier: id,
KeyPair: kp,
ListenPort: port,
@@ -114,7 +114,7 @@ func TestImportPeer_AddressMapping(t *testing.T) {
p := &domain.PhysicalPeer{
Identifier: "peer1",
KeyPair: domain.KeyPair{PublicKey: "peer1-public-key-is-long-enough"},
PublicKey: "peer1-public-key-is-long-enough",
AllowedIPs: allowedIPs,
}
+4 -6
View File
@@ -166,12 +166,10 @@ func (m Manager) PreparePeer(ctx context.Context, id domain.InterfaceIdentifier)
peerId := domain.PeerIdentifier(kp.PublicKey)
freshPeer := &domain.Peer{
BaseModel: domain.BaseModel{
CreatedBy: string(currentUser.Id),
UpdatedBy: string(currentUser.Id),
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
},
CreatedBy: string(currentUser.Id),
UpdatedBy: string(currentUser.Id),
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
Endpoint: domain.NewConfigOption(iface.PeerDefEndpoint, true),
EndpointPublicKey: domain.NewConfigOption(iface.PublicKey, true),
AllowedIPsStr: domain.NewConfigOption(iface.PeerDefAllowedIPsStr, true),
@@ -12,8 +12,8 @@ import (
type mockBus struct{}
func (f *mockBus) Publish(topic string, args ...any) {}
func (f *mockBus) Subscribe(topic string, fn interface{}) error { return nil }
func (f *mockBus) Publish(topic string, args ...any) {}
func (f *mockBus) Subscribe(topic string, fn any) error { return nil }
type mockController struct{}
+6 -8
View File
@@ -130,14 +130,12 @@ type LdapFields struct {
// If specific fields are not set, the default values are used.
func (f LdapFields) getMappingWithDefaults() LdapFields {
defaultMap := LdapFields{
BaseFields: BaseFields{
UserIdentifier: "mail",
Email: "mail",
Firstname: "givenName",
Lastname: "sn",
Phone: "telephoneNumber",
Department: "department",
},
UserIdentifier: "mail",
Email: "mail",
Firstname: "givenName",
Lastname: "sn",
Phone: "telephoneNumber",
Department: "department",
GroupMembership: "memberOf",
}
if f.UserIdentifier != "" {
+8 -8
View File
@@ -16,9 +16,9 @@ func TestBackendValidate_DefaultsToLocal(t *testing.T) {
func TestBackendValidate_RejectsReservedId(t *testing.T) {
tests := map[string]Backend{
"mikrotik": {Mikrotik: []BackendMikrotik{{BackendBase: BackendBase{Id: LocalBackendName}}}},
"pfsense": {Pfsense: []BackendPfsense{{BackendBase: BackendBase{Id: LocalBackendName}}}},
"opnsense": {Opnsense: []BackendOpnsense{{BackendBase: BackendBase{Id: LocalBackendName}}}},
"mikrotik": {Mikrotik: []BackendMikrotik{{Id: LocalBackendName}}},
"pfsense": {Pfsense: []BackendPfsense{{Id: LocalBackendName}}},
"opnsense": {Opnsense: []BackendOpnsense{{Id: LocalBackendName}}},
}
for name, backend := range tests {
@@ -35,8 +35,8 @@ func TestBackendValidate_RejectsReservedId(t *testing.T) {
// controller map would silently keep only one of them.
func TestBackendValidate_RejectsDuplicateIdAcrossTypes(t *testing.T) {
backend := Backend{
Pfsense: []BackendPfsense{{BackendBase: BackendBase{Id: "fw1"}}},
Opnsense: []BackendOpnsense{{BackendBase: BackendBase{Id: "fw1"}}},
Pfsense: []BackendPfsense{{Id: "fw1"}},
Opnsense: []BackendOpnsense{{Id: "fw1"}},
}
err := backend.Validate()
@@ -47,7 +47,7 @@ func TestBackendValidate_RejectsDuplicateIdAcrossTypes(t *testing.T) {
func TestBackendValidate_RejectsUnknownDefault(t *testing.T) {
backend := Backend{
Default: "does-not-exist",
Opnsense: []BackendOpnsense{{BackendBase: BackendBase{Id: "fw1"}}},
Opnsense: []BackendOpnsense{{Id: "fw1"}},
}
err := backend.Validate()
@@ -58,7 +58,7 @@ func TestBackendValidate_RejectsUnknownDefault(t *testing.T) {
func TestBackendValidate_AcceptsOpnsenseAsDefault(t *testing.T) {
backend := Backend{
Default: "fw1",
Opnsense: []BackendOpnsense{{BackendBase: BackendBase{Id: "fw1"}}},
Opnsense: []BackendOpnsense{{Id: "fw1"}},
}
assert.NoError(t, backend.Validate())
@@ -77,7 +77,7 @@ func TestBackendOpnsenseDefaults(t *testing.T) {
}
func TestBackendOpnsenseDisplayName(t *testing.T) {
backend := BackendOpnsense{BackendBase: BackendBase{Id: "fw1"}}
backend := BackendOpnsense{Id: "fw1"}
assert.Equal(t, "fw1", backend.GetDisplayName(), "display name falls back to the id")
backend.DisplayName = "Edge firewall"
+5 -6
View File
@@ -6,6 +6,7 @@ import (
"math"
"net"
"regexp"
"slices"
"strconv"
"strings"
"time"
@@ -60,8 +61,8 @@ type Interface struct {
DriverType string // the interface driver type (linux, software, ...)
IsDynamic bool `gorm:"column:is_dynamic;default:false"` // specifies if the interface is a dynamic object
Disabled *time.Time `gorm:"index"` // flag that specifies if the interface is enabled (up) or not (down)
DisabledReason string // the reason why the interface has been disabled
Disabled *time.Time `gorm:"index"` // flag that specifies if the interface is enabled (up) or not (down)
DisabledReason string // the reason why the interface has been disabled
// Default settings for the peer, used for new peers, those settings will be published to ConfigOption options of
// the peer config
@@ -100,10 +101,8 @@ func (i *Interface) IsUserAllowed(userId UserIdentifier, cfg *config.Config) boo
}
for _, allowedUsers := range i.LdapAllowedUsers {
for _, uid := range allowedUsers {
if uid == userId {
return true
}
if slices.Contains(allowedUsers, userId) {
return true
}
}
return false
+3 -5
View File
@@ -4,8 +4,8 @@ import (
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/h44z/wg-portal/internal/config"
"github.com/stretchr/testify/assert"
)
func TestPeer_IsDisabled(t *testing.T) {
@@ -69,10 +69,8 @@ func TestPeer_ApplyInterfaceDefaults(t *testing.T) {
},
}
iface := &Interface{
PeerDefEndpoint: "192.168.1.1",
KeyPair: KeyPair{
PublicKey: "publicKey",
},
PeerDefEndpoint: "192.168.1.1",
PublicKey: "publicKey",
PeerDefAllowedIPsStr: "8.8.8.8/32",
}