Compare commits

...

2 commits

Author SHA1 Message Date
59dd8d82cf
More attempt at getting this shit to work
All checks were successful
/ docker (push) Successful in 4m9s
2025-04-14 17:00:11 +02:00
06e6d457da
Add testing 2025-04-14 16:59:59 +02:00
24 changed files with 431 additions and 123 deletions

View file

@ -18,6 +18,8 @@
_or_ return an error defined (as public variable) in that package.
Example: `other.Error("auth", "failed to do something important", originalError)`
- Returned http errors must use `git.mstar.dev/mstar/goutils/webutils.ProblemDetails(StatusOnly)`.
- Every function must either have a test or a doc comment explaining
why it doesn't have a test
## JS/TS

View file

@ -77,10 +77,11 @@ func ImportRemoteAccount(targetName string) (string, error) {
// Sign and send
err = webshared.SignRequest(req, linstromActor.ID+"#main-key", keyBytes, nil)
// err = webshared.SignWithHttpsig(req, linstromActor.ID+"#main-key", keyBytes, nil)
// err = webshared.SignRequestWithHttpsig(req, linstromActor.ID+"#main-key", keyBytes, nil)
if err != nil {
return "", err
}
log.Debug().Str("Signature", req.Header.Get("Signature")).Msg("Post sign signature")
response, err := webshared.RequestClient.Do(req)
if err != nil {
return "", err

25
go.mod
View file

@ -5,6 +5,7 @@ go 1.23.0
toolchain go1.23.7
require (
git.mstar.dev/mstar/canvas v0.13.1
git.mstar.dev/mstar/goutils v1.12.3
github.com/BurntSushi/toml v1.4.0
github.com/dgraph-io/ristretto v0.2.0
@ -13,10 +14,12 @@ require (
github.com/eko/gocache/store/ristretto/v4 v4.2.2
github.com/gabriel-vasile/mimetype v1.4.5
github.com/gen2brain/avif v0.3.2
github.com/go-ap/httpsig v0.0.0-20221203064646-3647b4d88fdf
github.com/go-webauthn/webauthn v0.11.2
github.com/google/jsonapi v1.0.0
github.com/google/uuid v1.6.0
github.com/gorilla/websocket v1.5.3
github.com/jackc/pgx/v5 v5.7.4
github.com/minio/minio-go/v7 v7.0.80
github.com/mstarongithub/passkey v0.0.0-20240817142622-de6912c8303e
github.com/pquerna/otp v1.4.0
@ -25,6 +28,7 @@ require (
golang.org/x/crypto v0.36.0
golang.org/x/image v0.20.0
golang.org/x/sys v0.32.0
gopkg.in/natefinch/lumberjack.v2 v2.2.1
gorm.io/driver/postgres v1.5.7
gorm.io/gen v0.3.26
gorm.io/gorm v1.25.12
@ -33,18 +37,16 @@ require (
require (
filippo.io/edwards25519 v1.1.0 // indirect
git.mstar.dev/mstar/canvas v0.13.1 // indirect
git.mstar.dev/mstar/goap v1.2.5 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/datainq/xml-date-time v0.0.0-20170820214645-2292f08baa38 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/dunglas/httpsfv v1.0.2 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/ebitengine/purego v0.7.1 // indirect
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
github.com/go-fed/httpsig v1.1.0 // indirect
github.com/go-ini/ini v1.67.0 // indirect
github.com/go-sql-driver/mysql v1.8.1 // indirect
github.com/go-webauthn/x v0.1.14 // indirect
@ -56,33 +58,37 @@ require (
github.com/google/go-tpm v0.9.1 // 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.7.4 // 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/klauspost/compress v1.17.11 // indirect
github.com/klauspost/cpuid/v2 v2.2.8 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/lestrrat-go/blackmagic v1.0.2 // indirect
github.com/lestrrat-go/httpcc v1.0.1 // indirect
github.com/lestrrat-go/httprc v1.0.6 // indirect
github.com/lestrrat-go/iter v1.0.2 // indirect
github.com/lestrrat-go/jwx/v2 v2.1.2 // indirect
github.com/lestrrat-go/option v1.0.1 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/minio/md5-simd v1.1.2 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/piprate/json-gold v0.5.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect
github.com/prometheus/client_golang v1.14.0 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.37.0 // indirect
github.com/prometheus/procfs v0.8.0 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/rs/xid v1.6.0 // indirect
github.com/segmentio/asm v1.2.0 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/stretchr/testify v1.9.0 // indirect
github.com/stretchr/testify v1.10.0 // indirect
github.com/tetratelabs/wazero v1.7.3 // indirect
github.com/x448/float16 v0.8.4 // indirect
gitlab.com/mstarongitlab/goutils v1.3.0 // indirect
github.com/yaronf/httpsign v0.3.2 // indirect
golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f // indirect
golang.org/x/mod v0.17.0 // indirect
golang.org/x/net v0.30.0 // indirect
@ -90,7 +96,6 @@ require (
golang.org/x/text v0.23.0 // indirect
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
google.golang.org/protobuf v1.33.0 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
gorm.io/datatypes v1.2.5 // indirect
gorm.io/driver/mysql v1.5.7 // indirect

75
go.sum
View file

@ -35,34 +35,6 @@ filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
git.mstar.dev/mstar/canvas v0.13.1 h1:+oJRv3O+1vDOqMQFXfV6r+o2JiZGBARadlWXOrK6WUo=
git.mstar.dev/mstar/canvas v0.13.1/go.mod h1:CzLWCvOvHXsLbwU9l8WBL/RU5VAorgJ9+Ald5yhWoMs=
git.mstar.dev/mstar/goap v0.0.0-20250407153813-45fa095a1597 h1:KUdA5J1ArvD7X4z8ttE41xaCo+Hv/vWB8scoT+HIpOE=
git.mstar.dev/mstar/goap v0.0.0-20250407153813-45fa095a1597/go.mod h1:cVCXcMGdYk8pySulIYSqMuvGG6lYEkibM5pPy97gylQ=
git.mstar.dev/mstar/goap v1.2.0 h1:jiWgU7zria+uMEq40lyvrNqofmw4Voe+sRboxxcnbZE=
git.mstar.dev/mstar/goap v1.2.0/go.mod h1:cVCXcMGdYk8pySulIYSqMuvGG6lYEkibM5pPy97gylQ=
git.mstar.dev/mstar/goap v1.2.1 h1:nnun+52fpOPhcRerIppFd506EFvPRHZk6tpZXpplwb8=
git.mstar.dev/mstar/goap v1.2.1/go.mod h1:cVCXcMGdYk8pySulIYSqMuvGG6lYEkibM5pPy97gylQ=
git.mstar.dev/mstar/goap v1.2.2 h1:JKXGH2zUnvibjSLDBSCYMAE9MrxkGajhjFKHHPNC7OU=
git.mstar.dev/mstar/goap v1.2.2/go.mod h1:cVCXcMGdYk8pySulIYSqMuvGG6lYEkibM5pPy97gylQ=
git.mstar.dev/mstar/goap v1.2.3 h1:PL4GQ6bvMy8JIzn7oj+PdbSztJLNhO54i49lyVKcuog=
git.mstar.dev/mstar/goap v1.2.3/go.mod h1:cVCXcMGdYk8pySulIYSqMuvGG6lYEkibM5pPy97gylQ=
git.mstar.dev/mstar/goap v1.2.4 h1:3CpL6nPuCwUbnEuwIyErY9sahbPaQGjs2a5fx9FYrOE=
git.mstar.dev/mstar/goap v1.2.4/go.mod h1:cVCXcMGdYk8pySulIYSqMuvGG6lYEkibM5pPy97gylQ=
git.mstar.dev/mstar/goap v1.2.5 h1:K17XzUC+ozJQQy/W6MgSmgMAsczvSLpL0Lvmq6KsB44=
git.mstar.dev/mstar/goap v1.2.5/go.mod h1:cVCXcMGdYk8pySulIYSqMuvGG6lYEkibM5pPy97gylQ=
git.mstar.dev/mstar/goutils v1.9.1 h1:B4km2Xj0Yq8GHIlAYo45NGMRQRdkr+hV9qdvhTJKuuA=
git.mstar.dev/mstar/goutils v1.9.1/go.mod h1:juxY0eZEMnA95fedRp2LVXvUBgEjz66nE8SEdGKcxMA=
git.mstar.dev/mstar/goutils v1.10.0 h1:TXTz+RA4c5tNZRtdb4eVGjeL15xSjQOOSxfQ5ZwmKeE=
git.mstar.dev/mstar/goutils v1.10.0/go.mod h1:juxY0eZEMnA95fedRp2LVXvUBgEjz66nE8SEdGKcxMA=
git.mstar.dev/mstar/goutils v1.11.0 h1:iHpMkGIypKNg4egYdwyx25Bk1pe4aPMFEK76y1JATmo=
git.mstar.dev/mstar/goutils v1.11.0/go.mod h1:juxY0eZEMnA95fedRp2LVXvUBgEjz66nE8SEdGKcxMA=
git.mstar.dev/mstar/goutils v1.11.1 h1:G21MjZzQDnpC7h+ZkfITbqX+jBQtqZ4FB7rj4K6idE0=
git.mstar.dev/mstar/goutils v1.11.1/go.mod h1:juxY0eZEMnA95fedRp2LVXvUBgEjz66nE8SEdGKcxMA=
git.mstar.dev/mstar/goutils v1.12.0 h1:d88hLS8KnLUCI+8aWBR6228M43hxHdJpj8WuSqm4LAM=
git.mstar.dev/mstar/goutils v1.12.0/go.mod h1:juxY0eZEMnA95fedRp2LVXvUBgEjz66nE8SEdGKcxMA=
git.mstar.dev/mstar/goutils v1.12.1 h1:HZKKzMNfx7JKSUi5s8SwwUFEqEX6xvkM6NMf+Pht+lo=
git.mstar.dev/mstar/goutils v1.12.1/go.mod h1:juxY0eZEMnA95fedRp2LVXvUBgEjz66nE8SEdGKcxMA=
git.mstar.dev/mstar/goutils v1.12.2 h1:twCnsl+WRgP52mV5D5FRVJK6Yst1/3VtulHd77U++BY=
git.mstar.dev/mstar/goutils v1.12.2/go.mod h1:juxY0eZEMnA95fedRp2LVXvUBgEjz66nE8SEdGKcxMA=
git.mstar.dev/mstar/goutils v1.12.3 h1:Wx7i8/a99Cp+Y/XcXgqQr0r9cSsJu7QkWBlKyprTH44=
git.mstar.dev/mstar/goutils v1.12.3/go.mod h1:juxY0eZEMnA95fedRp2LVXvUBgEjz66nE8SEdGKcxMA=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
@ -96,17 +68,19 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/datainq/xml-date-time v0.0.0-20170820214645-2292f08baa38 h1:cUoduvNB9/JFJYEVeKy2hX/R5qyg2uwnHVhXCIjhBeI=
github.com/datainq/xml-date-time v0.0.0-20170820214645-2292f08baa38/go.mod h1:a0PnbhSGmzFMGx9KdEqfEdDHoEwTF9KLNbKLcWD8kAo=
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/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
github.com/dgraph-io/ristretto v0.2.0 h1:XAfl+7cmoUDWW/2Lx8TGZQjjxIQ2Ley9DSf52dru4WE=
github.com/dgraph-io/ristretto v0.2.0/go.mod h1:8uBHCU/PBV4Ag0CJrP47b9Ofby5dqWNh4FicAdoqFNU=
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y=
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/dunglas/httpsfv v1.0.2 h1:iERDp/YAfnojSDJ7PW3dj1AReJz4MrwbECSSE59JWL0=
github.com/dunglas/httpsfv v1.0.2/go.mod h1:zID2mqw9mFsnt7YC3vYQ9/cjq30q41W+1AnDwH8TiMg=
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/ebitengine/purego v0.7.1 h1:6/55d26lG3o9VCZX8lping+bZcmShseiqlh2bnUDiPA=
@ -127,8 +101,8 @@ github.com/gabriel-vasile/mimetype v1.4.5 h1:J7wGKdGu33ocBOhGy0z653k/lFKLFDPJMG8
github.com/gabriel-vasile/mimetype v1.4.5/go.mod h1:ibHel+/kbxn9x2407k1izTA1S81ku1z/DlgOW2QE0M4=
github.com/gen2brain/avif v0.3.2 h1:XUR0CBl5n4ISFJE8/pc1RMEKt5KUVoW8InctN+M7+DQ=
github.com/gen2brain/avif v0.3.2/go.mod h1:tdL2sV6oOJXBZZvT5iP55VEM1X2c3/yJmYKMJTl8fXg=
github.com/go-fed/httpsig v1.1.0 h1:9M+hb0jkEICD8/cAiNqEB66R87tTINszBRTjwjQzWcI=
github.com/go-fed/httpsig v1.1.0/go.mod h1:RCMrTZvN1bJYtofsG4rd5NaO5obxQ5xBkdiS7xsT7bM=
github.com/go-ap/httpsig v0.0.0-20221203064646-3647b4d88fdf h1:Ab5yBsD/dXhFmgf2hX7T/YYr+VK0Df7SrIxyNztT9YE=
github.com/go-ap/httpsig v0.0.0-20221203064646-3647b4d88fdf/go.mod h1:+4SUDMvPlRMUPW5PlMTbxj3U5a4fWasBIbakUw7Kp6c=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
@ -232,16 +206,10 @@ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 h1:L0QtFUgDarD7Fpv9jeVMgy/+Ec0mtnmYuImjTz6dtDA=
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
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.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw=
github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A=
github.com/jackc/pgx/v5 v5.7.4 h1:9wKznZrhWa2QiHL+NjTSPP6yjl3451BX3imWDnokYlg=
github.com/jackc/pgx/v5 v5.7.4/go.mod h1:ncY89UGWxg82EykZUwSpUKEfccBGGYq1xjrOpsbsfGQ=
github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
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/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
@ -274,6 +242,18 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/lestrrat-go/blackmagic v1.0.2 h1:Cg2gVSc9h7sz9NOByczrbUvLopQmXrfFx//N+AkAr5k=
github.com/lestrrat-go/blackmagic v1.0.2/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU=
github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE=
github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E=
github.com/lestrrat-go/httprc v1.0.6 h1:qgmgIRhpvBqexMJjA/PmwSvhNk679oqD1RbovdCGW8k=
github.com/lestrrat-go/httprc v1.0.6/go.mod h1:mwwz3JMTPBjHUkkDv/IGJ39aALInZLrhBp0X7KGUZlo=
github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI=
github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4=
github.com/lestrrat-go/jwx/v2 v2.1.2 h1:6poete4MPsO8+LAEVhpdrNI4Xp2xdiafgl2RD89moBc=
github.com/lestrrat-go/jwx/v2 v2.1.2/go.mod h1:pO+Gz9whn7MPdbsqSJzG8TlEpMZCwQDXnFJ+zsUVh8Y=
github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU=
github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
@ -302,16 +282,12 @@ github.com/mstarongithub/passkey v0.0.0-20240817142622-de6912c8303e h1:BjuYFWZZd
github.com/mstarongithub/passkey v0.0.0-20240817142622-de6912c8303e/go.mod h1:vsjtQX07PZmKGSwixqXoKg6bvo3GTCA0GIwjCQ6qpHI=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/piprate/json-gold v0.5.0 h1:RmGh1PYboCFcchVFuh2pbSWAZy4XJaqTMU4KQYsApbM=
github.com/piprate/json-gold v0.5.0/go.mod h1:WZ501QQMbZZ+3pXFPhQKzNwS1+jls0oqov3uQ2WasLs=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
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/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 h1:J9b7z+QKAmPf4YLrFg6oQUotqHQeUNWwkvo7jZp1GLU=
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
github.com/pquerna/otp v1.4.0 h1:wZvl1TIVxKRThZIBiwOOHOGP/1+nZyWBil9Y2XNEDzg=
github.com/pquerna/otp v1.4.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
@ -350,6 +326,8 @@ github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU=
github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8=
github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys=
github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
@ -360,22 +338,25 @@ github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tetratelabs/wazero v1.7.3 h1:PBH5KVahrt3S2AHgEjKu4u+LlDbbk+nsGE3KLucy6Rw=
github.com/tetratelabs/wazero v1.7.3/go.mod h1:ytl6Zuh20R/eROuyDaGPkp82O9C/DJfXAwJfQ3X6/7Y=
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/yaronf/httpsign v0.3.2 h1:rBYYx9eHm60noI4oC24JAD2tJuM8AUDh9ErJO/FfzBs=
github.com/yaronf/httpsign v0.3.2/go.mod h1:cYB/6toJrJnf4JTLVoo6IHzFH9/Zu1dcKmah4xfX2WA=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
gitlab.com/mstarongitlab/goap v1.1.0 h1:uN05RP+Tq2NR2IuPq6XQa5oLpfailpoEvxo1SfehxBA=
gitlab.com/mstarongitlab/goap v1.1.0/go.mod h1:rt9IYvJBPh1z6t+vvzifmxDtGjGlr8683tSPfa5dbXI=
gitlab.com/mstarongitlab/goutils v1.3.0 h1:uuxPHjIU36lyJ8/z4T2xI32zOyh53Xj0Au8K12qkaJ4=
gitlab.com/mstarongitlab/goutils v1.3.0/go.mod h1:SvqfzFxgashuZPqR9kPwQ9gFA7I1yskZjhmGmY2pAow=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
@ -534,8 +515,6 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=

View file

@ -59,6 +59,6 @@ func flagUsage() {
fmt.Fprintln(os.Stderr, "\t\tIf set, writes logging messages as json objects instead")
}
func init() {
// flag.Usage = flagUsage
}
// func init() {
// flag.Usage = flagUsage
// }

View file

@ -14,6 +14,10 @@ type FSWrapper struct {
log bool
}
// Compile time interface implementation assertion
var _ fs.FS = &FSWrapper{}
// No test, as no processing happens, only wrapping the arguments in a struct
func NewFSWrapper(wraps fs.FS, appends string, logAccess bool) *FSWrapper {
return &FSWrapper{
wrapped: wraps,
@ -22,11 +26,12 @@ func NewFSWrapper(wraps fs.FS, appends string, logAccess bool) *FSWrapper {
}
}
func (fs *FSWrapper) Open(name string) (fs.File, error) {
res, err := fs.wrapped.Open(fs.toAdd + name)
if fs.log {
// Pretty sure this can't be reliably tested
func (fw *FSWrapper) Open(name string) (fs.File, error) {
res, err := fw.wrapped.Open(fw.toAdd + name)
if fw.log {
log.Debug().
Str("prefix", fs.toAdd).
Str("prefix", fw.toAdd).
Str("filename", name).
Err(err).
Msg("fswrapper: File access result")

29
shared/fswrapper_test.go Normal file
View file

@ -0,0 +1,29 @@
package shared
import (
"io"
"os"
"reflect"
"testing"
)
func TestFSWrapper_Open(t *testing.T) {
rootFs := os.DirFS("/")
wrapper := NewFSWrapper(rootFs, "etc/", false)
f, err := wrapper.Open("hostname")
if err != nil {
t.Fatalf("failed to open /etc/hostname: %v", err)
}
defer f.Close()
data, err := os.ReadFile("/etc/hostname")
if err != nil {
t.Fatalf("failed to read with full path: %v", err)
}
wrappedData, err := io.ReadAll(f)
if err != nil {
t.Fatalf("failed to read from wrapped file: %v", err)
}
if !reflect.DeepEqual(wrappedData, data) {
t.Fatal("file contents are different")
}
}

View file

@ -6,6 +6,8 @@ package shared
import "golang.org/x/sys/unix"
// Copied from https://stackoverflow.com/a/20026945 and https://stackoverflow.com/a/49148866
// Not testable as host environment could be just about anything
// and this function is for testing the host environment
func IsWritable(path string) bool {
return unix.Access(path, unix.W_OK) == nil
}

View file

@ -3,6 +3,9 @@ package shared
import "os"
// Copied from https://stackoverflow.com/a/20026945 and https://stackoverflow.com/a/49148866
// Not testable as host environment could be just about anything
// and this function is for testing the host environment.
// Also, Windows is not supported. It may work, it may not, doesn't matter
func IsWritable(path string) bool {
info, err := os.Stat(path)
if err != nil {

View file

@ -10,8 +10,6 @@ import (
"crypto/x509"
"encoding/pem"
"errors"
"git.mstar.dev/mstar/linstrom/config"
)
const sanityCheckRawMessage = "test message for sanity checking keys"
@ -45,14 +43,14 @@ func Sign(toSign string, keyBytes []byte, keyIsRsa bool) ([]byte, error) {
if err != nil {
return nil, err
}
hasher := sha256.New()
_, err = hasher.Write([]byte(toSign))
if err != nil {
return nil, err
}
// hash := sha256.Sum256([]byte(toSign))
hash := hasher.Sum(nil)
signed, err := rsa.SignPKCS1v15(nil, key, crypto.SHA256, hash)
// hasher := sha256.New()
// _, err = hasher.Write([]byte(toSign))
// if err != nil {
// return nil, err
// }
// hash := hasher.Sum(nil)
hash := sha256.Sum256([]byte(toSign))
signed, err := rsa.SignPKCS1v15(nil, key, crypto.SHA256, hash[:])
// signed, err := key.Sign(rand.Reader, hash[:], crypto.SHA256)
return signed, err
} else {
@ -63,9 +61,9 @@ func Sign(toSign string, keyBytes []byte, keyIsRsa bool) ([]byte, error) {
}
}
func KeyBytesToPem(bytes []byte) string {
func KeyBytesToPem(bytes []byte, isEd bool) string {
var t string
if config.GlobalConfig.Experimental.UseEd25519Keys {
if isEd {
t = "PUBLIC KEY"
} else {
// t = "RSA PUBLIC KEY"
@ -79,6 +77,8 @@ func KeyBytesToPem(bytes []byte) string {
return string(pem.EncodeToMemory(&block))
}
// Helper function for sanity checking the given key pair in direct format.
// As this is a test itself, no tests for the test
func SanityCheckRawEdKeys(pub ed25519.PublicKey, priv ed25519.PrivateKey) error {
hash := sha512.Sum512([]byte(sanityCheckRawMessage))
signed, err := priv.Sign(rand.Reader, hash[:], crypto.SHA512)
@ -90,12 +90,10 @@ func SanityCheckRawEdKeys(pub ed25519.PublicKey, priv ed25519.PrivateKey) error
})
}
func SanityCheckRawByteEdKeys(pub, priv []byte) error {
pubKey := ed25519.PublicKey(pub)
privKey := ed25519.PrivateKey(priv)
return SanityCheckRawEdKeys(pubKey, privKey)
}
// Helper function for sanity checking the given key pair as stored in the database
// (priv is the byte slice version of ed25519.PrivateKey,
// pub a PKIX marshalled ed25519.PublicKey).
// As this is a test itself, no tests for the test
func SanityCheckX509dEdKeys(pub, priv []byte) error {
privKey := ed25519.PrivateKey(priv)
rawPubKey, err := x509.ParsePKIXPublicKey(pub)
@ -109,12 +107,16 @@ func SanityCheckX509dEdKeys(pub, priv []byte) error {
return SanityCheckRawEdKeys(pubKey, privKey)
}
// Helper function for sanity checking the given key pair in PEM format
// As this is a test itself, no tests for the test
func SanityCheckPemdEdKeys(pub, priv []byte) error {
privBlock, _ := pem.Decode(priv)
pubBlock, _ := pem.Decode(pub)
return SanityCheckX509dEdKeys(pubBlock.Bytes, privBlock.Bytes)
}
// Helper function for sanity checking the given key pair in direct format
// As this is a test itself, no tests for the test
func SanityCheckRawRsaKeys(pub *rsa.PublicKey, priv *rsa.PrivateKey) error {
hash := sha256.Sum256([]byte(sanityCheckRawMessage))
signed, err := priv.Sign(rand.Reader, hash[:], crypto.SHA256)
@ -124,6 +126,9 @@ func SanityCheckRawRsaKeys(pub *rsa.PublicKey, priv *rsa.PrivateKey) error {
return rsa.VerifyPKCS1v15(pub, crypto.SHA256, hash[:], signed)
}
// Helper function for sanity checking the given key pair as stored in the db.
// (priv is PKCS1 private, pub PKIX public).
// As this is a test itself, no tests for the test
func SanityCheckX509dRsaKeys(pub, priv []byte) error {
privKey, err := x509.ParsePKCS1PrivateKey(priv)
if err != nil {
@ -140,6 +145,8 @@ func SanityCheckX509dRsaKeys(pub, priv []byte) error {
return SanityCheckRawRsaKeys(pubKey, privKey)
}
// Helper function for sanity checking the given key pair in PEM format
// As this is a test itself, no tests for the test
func SanityCheckPemdRsaKeys(pub, priv []byte) error {
privBlock, _ := pem.Decode(priv)
pubBlock, _ := pem.Decode(pub)

108
shared/signing_test.go Normal file
View file

@ -0,0 +1,108 @@
package shared
import (
"crypto"
"crypto/ed25519"
"crypto/rsa"
"crypto/sha256"
"crypto/x509"
"reflect"
"testing"
)
const testStringToSign = "some random text that I made up at work and definitely has no other purpose"
func TestGenerateKeypairRSA(t *testing.T) {
publicBytes, privateBytes, err := GenerateKeypair(false)
if err != nil {
t.Fatalf("generation failed: %v", err)
}
publicUntyped, err := x509.ParsePKIXPublicKey(publicBytes)
if err != nil {
t.Fatalf("parsing public bytes into key failed: %v", err)
}
public, ok := publicUntyped.(*rsa.PublicKey)
if !ok {
t.Fatal("asserting public key as rsa.PublicKey failed")
}
private, err := x509.ParsePKCS1PrivateKey(privateBytes)
if err != nil {
t.Fatalf("parsing private bytes into key failed: %v", err)
}
if err := private.Validate(); err != nil {
t.Fatalf("validation of private key failed: %v", err)
}
genPublicRaw := private.Public()
genPublic, ok := genPublicRaw.(*rsa.PublicKey)
if !reflect.DeepEqual(*public, *genPublic) {
t.Fatal("public from generator and from private are different")
}
}
func TestGenerateKeypairED(t *testing.T) {
publicBytes, privateBytes, err := GenerateKeypair(true)
if err != nil {
t.Fatalf("generation failed: %v", err)
}
publicUntyped, err := x509.ParsePKIXPublicKey(publicBytes)
if err != nil {
t.Fatalf("parsing public bytes into key failed: %v", err)
}
public, ok := publicUntyped.(ed25519.PublicKey)
if !ok {
t.Fatal("asserting public key as ed25519.PublicKey failed")
}
private := ed25519.PrivateKey(privateBytes)
pubGenRaw := private.Public()
pubGen, ok := pubGenRaw.(ed25519.PublicKey)
if !ok {
t.Fatal("public key generated by private key is not of type ed25519.PublicKey")
}
if !reflect.DeepEqual(pubGen, public) {
t.Fatal("public from generator and from private are different")
}
}
func TestSignRSA(t *testing.T) {
publicBytes, privateBytes, err := GenerateKeypair(false)
if err != nil {
t.Fatalf("failed to generate RSA keypair: %v", err)
}
pubRaw, err := x509.ParsePKIXPublicKey(publicBytes)
if err != nil {
t.Fatalf("failed to parse public rsa key: %v", err)
}
pub, ok := pubRaw.(*rsa.PublicKey)
if !ok {
t.Fatal("parsed public key is not *rsa.PublicKey")
}
hash := sha256.Sum256([]byte(testStringToSign))
signed, err := Sign(testStringToSign, privateBytes, true)
if err != nil {
t.Fatalf("failed to sign test string: %v", err)
}
if rsa.VerifyPKCS1v15(pub, crypto.SHA256, hash[:], signed) != nil {
t.Fatal("failed to verify")
}
}
func TestKeyBytesToPem(t *testing.T) {
type args struct {
bytes []byte
}
tests := []struct {
name string
args args
want string
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := KeyBytesToPem(tt.args.bytes, true); got != tt.want {
t.Errorf("KeyBytesToPem() = %v, want %v", got, tt.want)
}
})
}
}

View file

@ -7,7 +7,7 @@ import (
"git.mstar.dev/mstar/goutils/sliceutils"
)
var tagRegex = regexp.MustCompile(`#(\w+)`)
var tagRegex = regexp.MustCompile(`#([a-zA-Z0-9\-_]+)`)
func TagsFromText(text string) []string {
matches := tagRegex.FindAllString(text, -1)

View file

@ -0,0 +1,34 @@
package shared
import (
"reflect"
"testing"
)
func TestTagsFromText(t *testing.T) {
type args struct {
text string
}
tests := []struct {
name string
args args
want []string
}{
{
name: "No tags",
args: args{"Text with no tags whatsoever"},
want: []string{},
}, {
name: "one tag",
args: args{"Text with one simple #tag"},
want: []string{"tag"},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := TagsFromText(tt.args.text); !reflect.DeepEqual(got, tt.want) {
t.Errorf("TagsFromText() = %v, want %v", got, tt.want)
}
})
}
}

View file

@ -4,6 +4,8 @@ import (
"github.com/rs/zerolog"
)
// Not testable since it focuses entirely on the side effect of
// sending a log out
func Trace(l *zerolog.Logger) *zerolog.Logger {
if e := l.Trace(); e.Enabled() {
e.Caller(2).
@ -12,6 +14,8 @@ func Trace(l *zerolog.Logger) *zerolog.Logger {
return l
}
// Not testable since it focuses entirely on the side effect of
// sending a log out
func Untrace(l *zerolog.Logger) {
if e := l.Trace(); e.Enabled() {
e.Caller(2).

View file

@ -12,10 +12,16 @@ type ZerologGormAdapter struct {
logger zerolog.Logger
}
// Compile time interface implementation enforcement
var _ logger.Interface = &ZerologGormAdapter{}
// Not worth testing as just a wrapper for putting into a struct
func NewGormLogger(zerologger zerolog.Logger) *ZerologGormAdapter {
return &ZerologGormAdapter{zerologger}
}
// Not testable since it focuses entirely on the side effect of
// configuring loglevel
func (g *ZerologGormAdapter) LogMode(newLevel logger.LogLevel) logger.Interface {
switch newLevel {
case logger.Error:
@ -29,16 +35,23 @@ func (g *ZerologGormAdapter) LogMode(newLevel logger.LogLevel) logger.Interface
}
return g
}
// Not worth testing since only a wrapper around another function call
func (g *ZerologGormAdapter) Info(ctx context.Context, format string, args ...any) {
g.logger.Info().Ctx(ctx).Msgf(format, args...)
}
// Not worth testing since only a wrapper around another function call
func (g *ZerologGormAdapter) Warn(ctx context.Context, format string, args ...any) {
g.logger.Warn().Ctx(ctx).Msgf(format, args...)
}
// Not worth testing since only a wrapper around another function call
func (g *ZerologGormAdapter) Error(ctx context.Context, format string, args ...any) {
g.logger.Error().Ctx(ctx).Msgf(format, args...)
}
// Not worth testing since only a wrapper around another function call
func (g *ZerologGormAdapter) Trace(
ctx context.Context,
begin time.Time,
@ -55,10 +68,12 @@ func (g *ZerologGormAdapter) Trace(
Send()
}
// Not worth testing since only a wrapper around another function call
func (g *ZerologGormAdapter) OverwriteLoggingLevel(new zerolog.Level) {
g.logger = g.logger.Level(new)
}
// Not worth testing since only a wrapper around another function call
func (g *ZerologGormAdapter) OverwriteLogger(new zerolog.Logger) {
g.logger = new
}

View file

@ -2,6 +2,9 @@ package shared
import "github.com/rs/zerolog/log"
// Stuff here is not actually used anymore in the new implementation
// thus also no tests needed
type ZerologWrapper struct{}
func (z *ZerologWrapper) Errorf(format string, args ...any) {

View file

@ -1,7 +1,7 @@
[general]
protocol = "https"
domain = "lhr.life"
subdomain = "9f00dbe9248b25"
domain = "serveo.net"
subdomain = "29a62d7d1dd05bd000b8f9138244df2c"
private_port = 8080
public_port = 443

View file

@ -194,7 +194,7 @@ func returnKeypair(w http.ResponseWriter, r *http.Request) {
hlog.FromRequest(r).Error().Err(err).Msg("Sanity check failed")
}
privKeyPem := pem.EncodeToMemory(&privKeyBlock)
pubKeyPen := []byte(shared.KeyBytesToPem(user.PublicKeyRsa))
pubKeyPen := []byte(shared.KeyBytesToPem(user.PublicKeyRsa, false))
err = shared.SanityCheckPemdRsaKeys(pubKeyPen, privKeyPem)
if err != nil {
hlog.FromRequest(r).Error().Err(err).Msg("Pem Sanity check failed")

View file

@ -72,9 +72,9 @@ func users(w http.ResponseWriter, r *http.Request) {
apUrl := userIdToApUrl(user.ID)
var keyBytes string
if config.GlobalConfig.Experimental.UseEd25519Keys {
keyBytes = shared.KeyBytesToPem(user.PublicKeyEd)
keyBytes = shared.KeyBytesToPem(user.PublicKeyEd, true)
} else {
keyBytes = shared.KeyBytesToPem(user.PublicKeyRsa)
keyBytes = shared.KeyBytesToPem(user.PublicKeyRsa, false)
}
data := Outbound{
Context: activitypub.BaseLdContext,

View file

@ -24,14 +24,17 @@ type Note struct {
var _ shared.Clonable = &Note{}
var _ shared.Sanitisable = &Note{}
// No test, does nothing currently
func (note *Note) Sanitize() {
}
// No test, no data processing, only copy
func (note *Note) Clone() shared.Clonable {
tmp := *note
return &tmp
}
// No test, no data processing, only copy
func (n *Note) FromModel(m *models.Note) {
n.ID = m.ID
n.CreatedAt = m.CreatedAt

View file

@ -44,11 +44,13 @@ type User struct {
var _ shared.Sanitisable = &User{}
var _ shared.Clonable = &User{}
// No test due to no fancy processing, just setting values to constants
func (u *User) Sanitize() {
u.Verified = nil
u.FinishedRegistration = nil
}
// No test, no data processing, only copy
func (u *User) Clone() shared.Clonable {
user := *u
if u.IconId != nil {
@ -83,6 +85,7 @@ func (u *User) Clone() shared.Clonable {
return &user
}
// No test, no data processing, only copy
func (u *User) FromModel(m *models.User) {
u.ID = m.ID
u.CreatedAt = m.CreatedAt

View file

@ -1,17 +1,17 @@
package webshared
import (
"crypto"
"crypto/ed25519"
"crypto/sha256"
"crypto/x509"
"encoding/base64"
"io"
"net/http"
"strings"
"time"
"git.mstar.dev/mstar/goutils/maputils"
"github.com/go-fed/httpsig"
"github.com/go-ap/httpsig"
"github.com/rs/zerolog/log"
"git.mstar.dev/mstar/linstrom/config"
@ -53,6 +53,11 @@ func SignRequest(r *http.Request, keyId string, privateKeyBytes, postBody []byte
return strings.ToLower(k), ""
}
})
// Filter for only the date, host, digest and request-target headers
mappedHeaders = maputils.FilterMap(mappedHeaders, func(k, v string) bool {
k = strings.ToLower(k)
return k == "date" || k == "host" || k == "digest" || k == "(request-target)"
})
var signedString string
var usedHeaders []string
if config.GlobalConfig.Experimental.UseEd25519Keys {
@ -80,42 +85,28 @@ func SignRequest(r *http.Request, keyId string, privateKeyBytes, postBody []byte
return nil
}
func SignWithHttpsig(r *http.Request, keyId string, privateKeyBytes, postBody []byte) error {
var privateKey crypto.PrivateKey
var preferredAlgorithm []httpsig.Algorithm
var digestMethod httpsig.DigestAlgorithm
func SignRequestWithHttpsig(
r *http.Request,
keyId string,
privateKeyBytes, postBody []byte,
) error {
keyId = config.GlobalConfig.General.GetFullPublicUrl() + "/api/activitypub/user/" + keyId
if config.GlobalConfig.Experimental.UseEd25519Keys {
log.Debug().Msg("Using ed25519")
preferredAlgorithm = []httpsig.Algorithm{httpsig.ED25519}
privateKey = ed25519.PrivateKey(privateKeyBytes)
digestMethod = httpsig.DigestSha512
key := ed25519.PrivateKey(privateKeyBytes)
signer := httpsig.NewEd25519Signer(keyId, key, nil)
if err := signer.Sign(r); err != nil {
return err
}
} else {
log.Debug().Msg("Using rsa")
preferredAlgorithm = []httpsig.Algorithm{httpsig.RSA_SHA256}
key, err := x509.ParsePKCS1PrivateKey(privateKeyBytes)
if err != nil {
return err
}
privateKey = key
digestMethod = httpsig.DigestSha256
}
headers := []string{httpsig.RequestTarget, "date", "host"}
if postBody != nil {
headers = append(headers, "digest")
}
signer, _, err := httpsig.NewSigner(
preferredAlgorithm,
digestMethod,
headers,
httpsig.Signature, time.Now().Add(time.Minute).Unix())
if err != nil {
signer := httpsig.NewRSASHA256Signer(keyId, key, nil)
if err = signer.Sign(r); err != nil {
return err
}
err = signer.SignRequest(
privateKey,
config.GlobalConfig.General.GetFullPublicUrl()+"/api/activitypub/user/"+keyId, r, postBody)
if err != nil {
return err
// r.Header.Add("Signature", strings.TrimPrefix(r.Header.Get("Authorization"), "Signature "))
}
return nil
}
@ -125,7 +116,8 @@ func applyBodyHash(headers http.Header, body []byte) error {
return nil
}
hash := sha256.Sum256(body)
headers.Set("Digest", string(hash[:]))
based := base64.StdEncoding.EncodeToString(hash[:])
headers.Set("Digest", "SHA-256="+based)
return nil
}

View file

@ -0,0 +1,56 @@
package webshared
import (
"crypto/x509"
"io"
"net/http"
"github.com/yaronf/httpsign"
"git.mstar.dev/mstar/linstrom/config"
)
/*
Links for home:
- https://pkg.go.dev/github.com/yaronf/httpsign#Client.Do
- https://www.ietf.org/archive/id/draft-richanna-http-message-signatures-00.html
- https://github.com/mastodon/mastodon/issues/29905
- https://github.com/fedify-dev/fedify/issues/208
- https://github.com/mastodon/mastodon/issues/21429
- https://github.com/go-ap/fedbox/blob/master/httpsig.go
- https://swicg.github.io/activitypub-http-signature/
- https://datatracker.ietf.org/doc/html/rfc9421
*/
func RequestSigned(
method, target string,
body io.Reader,
keyId string,
privateKeyBytes []byte,
) (*http.Response, error) {
req, err := http.NewRequest(method, target, body)
if err != nil {
return nil, err
}
var signer *httpsign.Signer
signerFields := httpsign.Headers("@request-target", "content-digest")
if config.GlobalConfig.Experimental.UseEd25519Keys {
signer, err = httpsign.NewEd25519Signer(
privateKeyBytes,
httpsign.NewSignConfig(),
signerFields,
)
} else {
key, err := x509.ParsePKCS1PrivateKey(privateKeyBytes)
if err != nil {
return nil, err
}
signer, err = httpsign.NewRSASigner(*key, httpsign.NewSignConfig(), signerFields)
}
client := httpsign.NewClient(
RequestClient,
httpsign.NewClientConfig().SetSigner(signer).SetSignatureName("sig1"),
)
res, err := client.Do(req)
return res, err
}

57
web/shared/client_test.go Normal file
View file

@ -0,0 +1,57 @@
package webshared
import (
"io"
"net/http"
"reflect"
"testing"
)
const testBody = `{
"key": "value",
"more-key": 21
}`
var testBodyHash = []byte("22a5173da554010ea25f7d2ae34032a434c3a883a55d65f34c3413fdc555bed3")
func TestSignRequest(t *testing.T) {
// TODO: Implement tests
}
func Test_applyBodyHash_WithBody(t *testing.T) {
var headers = make(http.Header, 0)
digest := "SHA-256=" + string(testBodyHash)
applyBodyHash(headers, []byte(testBody))
headerDigest := headers.Get("Digest")
if headerDigest != digest {
t.Fatalf("digests didn't match: header \"%v\" != precalc \"%v\"", headerDigest, digest)
}
}
func TestNewRequest(t *testing.T) {
type args struct {
method string
url string
body io.Reader
}
tests := []struct {
name string
args args
want *http.Request
wantErr bool
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := NewRequest(tt.args.method, tt.args.url, tt.args.body)
if (err != nil) != tt.wantErr {
t.Errorf("NewRequest() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("NewRequest() = %v, want %v", got, tt.want)
}
})
}
}