feature/increase_test_coverage #112
4 changed files with 272 additions and 45 deletions
|
@ -6,25 +6,30 @@ import (
|
|||
"archive/zip"
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"os"
|
||||
"sort"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
containerv2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/container"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/acl"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/pool"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/testcontainers/testcontainers-go"
|
||||
|
@ -47,11 +52,17 @@ func TestIntegration(t *testing.T) {
|
|||
rootCtx := context.Background()
|
||||
aioImage := "truecloudlab/frostfs-aio:"
|
||||
versions := []string{
|
||||
"1.2.7", // frostfs-storage v0.36.0 RC
|
||||
"1.2.7",
|
||||
"1.3.0",
|
||||
}
|
||||
key, err := keys.NewPrivateKeyFromHex("1dd37fba80fec4e6a6f13fd708d8dcb3b29def768017052f6c930fa1c5d90bbb")
|
||||
require.NoError(t, err)
|
||||
|
||||
file, err := os.CreateTemp("", "wallet")
|
||||
require.NoError(t, err)
|
||||
defer os.Remove(file.Name())
|
||||
makeTempWallet(t, key, file.Name())
|
||||
|
||||
var ownerID user.ID
|
||||
user.IDFromKey(&ownerID, key.PrivateKey.PublicKey)
|
||||
|
||||
|
@ -59,12 +70,16 @@ func TestIntegration(t *testing.T) {
|
|||
ctx, cancel2 := context.WithCancel(rootCtx)
|
||||
|
||||
aioContainer := createDockerContainer(ctx, t, aioImage+version)
|
||||
server, cancel := runServer()
|
||||
server, cancel := runServer(file.Name())
|
||||
clientPool := getPool(ctx, t, key)
|
||||
CID, err := createContainer(ctx, t, clientPool, ownerID, version)
|
||||
require.NoError(t, err, version)
|
||||
|
||||
token := makeBearerToken(t, key, ownerID, version)
|
||||
|
||||
t.Run("simple put "+version, func(t *testing.T) { simplePut(ctx, t, clientPool, CID, version) })
|
||||
t.Run("put with bearer token in header"+version, func(t *testing.T) { putWithBearerTokenInHeader(ctx, t, clientPool, CID, token) })
|
||||
t.Run("put with bearer token in cookie"+version, func(t *testing.T) { putWithBearerTokenInCookie(ctx, t, clientPool, CID, token) })
|
||||
t.Run("put with duplicate keys "+version, func(t *testing.T) { putWithDuplicateKeys(t, CID) })
|
||||
t.Run("simple get "+version, func(t *testing.T) { simpleGet(ctx, t, clientPool, ownerID, CID, version) })
|
||||
t.Run("get by attribute "+version, func(t *testing.T) { getByAttr(ctx, t, clientPool, ownerID, CID, version) })
|
||||
|
@ -79,10 +94,13 @@ func TestIntegration(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func runServer() (App, context.CancelFunc) {
|
||||
func runServer(pathToWallet string) (App, context.CancelFunc) {
|
||||
cancelCtx, cancel := context.WithCancel(context.Background())
|
||||
|
||||
v := getDefaultConfig()
|
||||
v.Set(cfgWalletPath, pathToWallet)
|
||||
v.Set(cfgWalletPassphrase, "")
|
||||
|
||||
l, lvl := newStdoutLogger(zapcore.DebugLevel)
|
||||
application := newApp(cancelCtx, WithConfig(v), WithLogger(l, lvl))
|
||||
go application.Serve()
|
||||
|
@ -98,7 +116,38 @@ func simplePut(ctx context.Context, t *testing.T, p *pool.Pool, CID cid.ID, vers
|
|||
makePutRequestAndCheck(ctx, t, p, CID, url)
|
||||
}
|
||||
|
||||
func putWithBearerTokenInHeader(ctx context.Context, t *testing.T, p *pool.Pool, CID cid.ID, token string) {
|
||||
url := testHost + "/upload/" + CID.String()
|
||||
|
||||
request, content, attributes := makePutRequest(t, url)
|
||||
request.Header.Set("Authorization", "Bearer "+token)
|
||||
resp, err := http.DefaultClient.Do(request)
|
||||
require.NoError(t, err)
|
||||
|
||||
checkPutResponse(ctx, t, p, CID, resp, content, attributes)
|
||||
}
|
||||
|
||||
func putWithBearerTokenInCookie(ctx context.Context, t *testing.T, p *pool.Pool, CID cid.ID, token string) {
|
||||
url := testHost + "/upload/" + CID.String()
|
||||
|
||||
request, content, attributes := makePutRequest(t, url)
|
||||
request.AddCookie(&http.Cookie{Name: "Bearer", Value: token})
|
||||
resp, err := http.DefaultClient.Do(request)
|
||||
require.NoError(t, err)
|
||||
|
||||
checkPutResponse(ctx, t, p, CID, resp, content, attributes)
|
||||
}
|
||||
|
||||
func makePutRequestAndCheck(ctx context.Context, t *testing.T, p *pool.Pool, cnrID cid.ID, url string) {
|
||||
request, content, attributes := makePutRequest(t, url)
|
||||
|
||||
resp, err := http.DefaultClient.Do(request)
|
||||
require.NoError(t, err)
|
||||
|
||||
checkPutResponse(ctx, t, p, cnrID, resp, content, attributes)
|
||||
}
|
||||
|
||||
func makePutRequest(t *testing.T, url string) (*http.Request, string, map[string]string) {
|
||||
content := "content of file"
|
||||
keyAttr, valAttr := "User-Attribute", "user value"
|
||||
attributes := map[string]string{
|
||||
|
@ -120,9 +169,10 @@ func makePutRequestAndCheck(ctx context.Context, t *testing.T, p *pool.Pool, cnr
|
|||
request.Header.Set("Content-Type", w.FormDataContentType())
|
||||
request.Header.Set("X-Attribute-"+keyAttr, valAttr)
|
||||
|
||||
resp, err := http.DefaultClient.Do(request)
|
||||
require.NoError(t, err)
|
||||
return request, content, attributes
|
||||
}
|
||||
|
||||
func checkPutResponse(ctx context.Context, t *testing.T, p *pool.Pool, cnrID cid.ID, resp *http.Response, content string, attributes map[string]string) {
|
||||
defer func() {
|
||||
err := resp.Body.Close()
|
||||
require.NoError(t, err)
|
||||
|
@ -476,3 +526,37 @@ func putObject(ctx context.Context, t *testing.T, clientPool *pool.Pool, ownerID
|
|||
|
||||
return id
|
||||
}
|
||||
|
||||
func makeBearerToken(t *testing.T, key *keys.PrivateKey, ownerID user.ID, version string) string {
|
||||
tkn := new(bearer.Token)
|
||||
tkn.ForUser(ownerID)
|
||||
tkn.SetExp(10000)
|
||||
|
||||
if version == "1.2.7" {
|
||||
tkn.SetEACLTable(*eacl.NewTable())
|
||||
} else {
|
||||
tkn.SetImpersonate(true)
|
||||
}
|
||||
|
||||
err := tkn.Sign(key.PrivateKey)
|
||||
require.NoError(t, err)
|
||||
|
||||
t64 := base64.StdEncoding.EncodeToString(tkn.Marshal())
|
||||
require.NotEmpty(t, t64)
|
||||
|
||||
return t64
|
||||
}
|
||||
|
||||
func makeTempWallet(t *testing.T, key *keys.PrivateKey, path string) {
|
||||
w, err := wallet.NewWallet(path)
|
||||
require.NoError(t, err)
|
||||
|
||||
acc := wallet.NewAccountFromPrivateKey(key)
|
||||
err = acc.Encrypt("", w.Scrypt)
|
||||
require.NoError(t, err)
|
||||
|
||||
w.AddAccount(acc)
|
||||
|
||||
err = w.Save()
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
|
10
go.mod
10
go.mod
|
@ -22,7 +22,7 @@ require (
|
|||
go.opentelemetry.io/otel/trace v1.16.0
|
||||
go.uber.org/zap v1.24.0
|
||||
golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc
|
||||
golang.org/x/net v0.10.0
|
||||
golang.org/x/net v0.23.0
|
||||
google.golang.org/grpc v1.55.0
|
||||
)
|
||||
|
||||
|
@ -103,11 +103,11 @@ require (
|
|||
go.opentelemetry.io/proto/otlp v0.19.0 // indirect
|
||||
go.uber.org/atomic v1.10.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/crypto v0.9.0 // indirect
|
||||
golang.org/x/crypto v0.21.0 // indirect
|
||||
golang.org/x/sync v0.2.0 // indirect
|
||||
golang.org/x/sys v0.8.0 // indirect
|
||||
golang.org/x/term v0.8.0 // indirect
|
||||
golang.org/x/text v0.9.0 // indirect
|
||||
golang.org/x/sys v0.18.0 // indirect
|
||||
golang.org/x/term v0.18.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
golang.org/x/time v0.3.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect
|
||||
google.golang.org/protobuf v1.30.0 // indirect
|
||||
|
|
20
go.sum
20
go.sum
|
@ -1024,8 +1024,8 @@ golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5
|
|||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
|
||||
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
|
||||
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
|
||||
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
|
@ -1118,8 +1118,8 @@ golang.org/x/net v0.0.0-20211108170745-6635138e15ea/go.mod h1:9nx3DQGgdP8bBQD5qx
|
|||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
|
||||
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
|
@ -1245,13 +1245,13 @@ golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210429154555-c04ba851c2a4/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8=
|
||||
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
@ -1261,8 +1261,8 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
|
|
|
@ -23,19 +23,29 @@ func makeTestCookie(value []byte) *fasthttp.RequestHeader {
|
|||
func makeTestHeader(value []byte) *fasthttp.RequestHeader {
|
||||
header := new(fasthttp.RequestHeader)
|
||||
if value != nil {
|
||||
header.Set(fasthttp.HeaderAuthorization, bearerTokenHdr+" "+string(value))
|
||||
header.Set(fasthttp.HeaderAuthorization, string(value))
|
||||
}
|
||||
return header
|
||||
}
|
||||
|
||||
func Test_fromCookie(t *testing.T) {
|
||||
func makeBearer(value string) string {
|
||||
return bearerTokenHdr + " " + value
|
||||
}
|
||||
|
||||
func TestBearerTokenFromCookie(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
actual []byte
|
||||
expect []byte
|
||||
}{
|
||||
{name: "empty"},
|
||||
{name: "normal", actual: []byte("TOKEN"), expect: []byte("TOKEN")},
|
||||
{
|
||||
name: "empty",
|
||||
},
|
||||
{
|
||||
name: "normal",
|
||||
actual: []byte("TOKEN"),
|
||||
expect: []byte("TOKEN"),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range cases {
|
||||
|
@ -45,14 +55,31 @@ func Test_fromCookie(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func Test_fromHeader(t *testing.T) {
|
||||
func TestBearerTokenFromHeader(t *testing.T) {
|
||||
validToken := "token"
|
||||
tokenWithoutPrefix := "invalid-token"
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
actual []byte
|
||||
expect []byte
|
||||
}{
|
||||
{name: "empty"},
|
||||
{name: "normal", actual: []byte("TOKEN"), expect: []byte("TOKEN")},
|
||||
{
|
||||
name: "empty",
|
||||
},
|
||||
{
|
||||
name: "token without the bearer prefix",
|
||||
actual: []byte(tokenWithoutPrefix),
|
||||
},
|
||||
{
|
||||
name: "token without payload",
|
||||
actual: []byte(makeBearer("")),
|
||||
},
|
||||
{
|
||||
name: "normal",
|
||||
actual: []byte(makeBearer(validToken)),
|
||||
expect: []byte(validToken),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range cases {
|
||||
|
@ -62,7 +89,7 @@ func Test_fromHeader(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func Test_fetchBearerToken(t *testing.T) {
|
||||
func TestFetchBearerToken(t *testing.T) {
|
||||
key, err := keys.NewPrivateKey()
|
||||
require.NoError(t, err)
|
||||
var uid user.ID
|
||||
|
@ -75,43 +102,77 @@ func Test_fetchBearerToken(t *testing.T) {
|
|||
require.NotEmpty(t, t64)
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
|
||||
name string
|
||||
cookie string
|
||||
header string
|
||||
|
||||
error string
|
||||
nilCtx bool
|
||||
expect *bearer.Token
|
||||
}{
|
||||
{name: "empty"},
|
||||
|
||||
{name: "bad base64 header", header: "WRONG BASE64", error: "can't base64-decode bearer token"},
|
||||
{name: "bad base64 cookie", cookie: "WRONG BASE64", error: "can't base64-decode bearer token"},
|
||||
|
||||
{name: "header token unmarshal error", header: "dGVzdAo=", error: "can't unmarshal bearer token"},
|
||||
{name: "cookie token unmarshal error", cookie: "dGVzdAo=", error: "can't unmarshal bearer token"},
|
||||
|
||||
{
|
||||
name: "empty",
|
||||
},
|
||||
{
|
||||
name: "nil context",
|
||||
nilCtx: true,
|
||||
},
|
||||
{
|
||||
name: "bad base64 header",
|
||||
header: "WRONG BASE64",
|
||||
error: "can't base64-decode bearer token",
|
||||
},
|
||||
{
|
||||
name: "bad base64 cookie",
|
||||
cookie: "WRONG BASE64",
|
||||
error: "can't base64-decode bearer token",
|
||||
},
|
||||
{
|
||||
name: "header token unmarshal error",
|
||||
header: "dGVzdAo=",
|
||||
error: "can't unmarshal bearer token",
|
||||
},
|
||||
{
|
||||
name: "cookie token unmarshal error",
|
||||
cookie: "dGVzdAo=",
|
||||
error: "can't unmarshal bearer token",
|
||||
},
|
||||
{
|
||||
name: "bad header and cookie",
|
||||
header: "WRONG BASE64",
|
||||
cookie: "dGVzdAo=",
|
||||
error: "can't unmarshal bearer token",
|
||||
},
|
||||
|
||||
{
|
||||
name: "bad header, but good cookie",
|
||||
header: "dGVzdAo=",
|
||||
cookie: t64,
|
||||
expect: tkn,
|
||||
},
|
||||
|
||||
{name: "ok for header", header: t64, expect: tkn},
|
||||
{name: "ok for cookie", cookie: t64, expect: tkn},
|
||||
{
|
||||
name: "bad cookie, but good header",
|
||||
header: t64,
|
||||
cookie: "dGVzdAo=",
|
||||
expect: tkn,
|
||||
},
|
||||
{
|
||||
name: "ok for header",
|
||||
header: t64,
|
||||
expect: tkn,
|
||||
},
|
||||
{
|
||||
name: "ok for cookie",
|
||||
cookie: t64,
|
||||
expect: tkn,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range cases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
ctx := makeTestRequest(tt.cookie, tt.header)
|
||||
var ctx *fasthttp.RequestCtx
|
||||
if !tt.nilCtx {
|
||||
ctx = makeTestRequest(tt.cookie, tt.header)
|
||||
}
|
||||
|
||||
actual, err := fetchBearerToken(ctx)
|
||||
|
||||
if tt.error == "" {
|
||||
|
@ -139,7 +200,7 @@ func makeTestRequest(cookie, header string) *fasthttp.RequestCtx {
|
|||
return ctx
|
||||
}
|
||||
|
||||
func Test_checkAndPropagateBearerToken(t *testing.T) {
|
||||
func TestCheckAndPropagateBearerToken(t *testing.T) {
|
||||
key, err := keys.NewPrivateKey()
|
||||
require.NoError(t, err)
|
||||
var uid user.ID
|
||||
|
@ -162,3 +223,85 @@ func Test_checkAndPropagateBearerToken(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
require.Equal(t, tkn, actual)
|
||||
}
|
||||
|
||||
func TestLoadBearerToken(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
token := new(bearer.Token)
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
appCtx context.Context
|
||||
error string
|
||||
}{
|
||||
{
|
||||
name: "token is missing in the context",
|
||||
appCtx: ctx,
|
||||
error: "found empty bearer token",
|
||||
},
|
||||
{
|
||||
name: "normal",
|
||||
appCtx: context.WithValue(ctx, bearerTokenKey, token),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range cases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
tkn, err := LoadBearerToken(tt.appCtx)
|
||||
|
||||
if tt.error == "" {
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, token, tkn)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
require.Contains(t, err.Error(), tt.error)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestStoreBearerTokenAppCtx(t *testing.T) {
|
||||
key, err := keys.NewPrivateKey()
|
||||
require.NoError(t, err)
|
||||
var uid user.ID
|
||||
user.IDFromKey(&uid, key.PrivateKey.PublicKey)
|
||||
|
||||
tkn := new(bearer.Token)
|
||||
tkn.ForUser(uid)
|
||||
|
||||
t64 := base64.StdEncoding.EncodeToString(tkn.Marshal())
|
||||
require.NotEmpty(t, t64)
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
req *fasthttp.RequestCtx
|
||||
error string
|
||||
}{
|
||||
{
|
||||
name: "invalid token",
|
||||
req: makeTestRequest("dGVzdAo=", ""),
|
||||
error: "can't unmarshal bearer token",
|
||||
},
|
||||
{
|
||||
name: "normal",
|
||||
req: makeTestRequest(t64, ""),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range cases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
ctx, err := StoreBearerTokenAppCtx(context.Background(), tt.req)
|
||||
|
||||
if tt.error == "" {
|
||||
require.NoError(t, err)
|
||||
actualToken, ok := ctx.Value(bearerTokenKey).(*bearer.Token)
|
||||
require.True(t, ok)
|
||||
require.Equal(t, tkn, actualToken)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
require.Contains(t, err.Error(), tt.error)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue