From 397630da50266b978ed08ece1912736edb9b9536 Mon Sep 17 00:00:00 2001 From: Preston Vasquez Date: Thu, 22 May 2025 10:34:37 -0600 Subject: [PATCH 1/8] GODRIVER-3567 Setup module and CI pipeline --- etc/run-mongodb-aws-test.sh | 1 + go.work | 3 +- internal/cmd/testmongoaws/go.mod | 25 +++++++++ internal/cmd/testmongoaws/go.sum | 46 +++++++++++++++++ internal/cmd/testmongoaws/main.go | 44 ++++++++++++++++ x/mongo/driver/auth/mongoaws/go.mod | 15 ++++++ x/mongo/driver/auth/mongoaws/go.sum | 48 ++++++++++++++++++ x/mongo/driver/auth/mongoaws/mongoaws.go | 64 ++++++++++++++++++++++++ 8 files changed, 245 insertions(+), 1 deletion(-) create mode 100644 internal/cmd/testmongoaws/go.mod create mode 100644 internal/cmd/testmongoaws/go.sum create mode 100644 internal/cmd/testmongoaws/main.go create mode 100644 x/mongo/driver/auth/mongoaws/go.mod create mode 100644 x/mongo/driver/auth/mongoaws/go.sum create mode 100644 x/mongo/driver/auth/mongoaws/mongoaws.go diff --git a/etc/run-mongodb-aws-test.sh b/etc/run-mongodb-aws-test.sh index 6438b5810b..35058388f7 100755 --- a/etc/run-mongodb-aws-test.sh +++ b/etc/run-mongodb-aws-test.sh @@ -32,3 +32,4 @@ set -x # For Go 1.16+, Go builds requires a go.mod file in the current working directory or a parent # directory. Spawn a new subshell, "cd" to the project directory, then run "go run". (cd ${PROJECT_DIRECTORY} && go run "./internal/cmd/testaws/main.go" | tee test.suite) +(cd ${PROJECT_DIRECTORY} && go run "./internal/cmd/testmongoaws/main.go" | tee test.suite) diff --git a/go.work b/go.work index 23ad2ff8a7..e4b1c439bf 100644 --- a/go.work +++ b/go.work @@ -1,4 +1,4 @@ -go 1.23 +go 1.23.1 use ( . @@ -9,4 +9,5 @@ use ( ./internal/cmd/compilecheck ./internal/cmd/faas/awslambda/mongodb ./internal/test/goleak + ./internal/cmd/testmongoaws ) diff --git a/internal/cmd/testmongoaws/go.mod b/internal/cmd/testmongoaws/go.mod new file mode 100644 index 0000000000..7cb65fb0fb --- /dev/null +++ b/internal/cmd/testmongoaws/go.mod @@ -0,0 +1,25 @@ +module go.mongodb.go/mongo-driver/internal/cmd/testmongoaws + +go 1.23.1 + +replace ( + go.mongodb.org/mongo-driver/v2 => ../../../ + go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/mongoaws => ../../../x/mongo/driver/auth/mongoaws +) + +require ( + go.mongodb.org/mongo-driver/v2 v2.3.4 + go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/mongoaws v1.2.3 +) + +require ( + github.com/golang/snappy v1.0.0 // indirect + github.com/klauspost/compress v1.16.7 // indirect + github.com/xdg-go/pbkdf2 v1.0.0 // indirect + github.com/xdg-go/scram v1.1.2 // indirect + github.com/xdg-go/stringprep v1.0.4 // indirect + github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect + golang.org/x/crypto v0.33.0 // indirect + golang.org/x/sync v0.11.0 // indirect + golang.org/x/text v0.22.0 // indirect +) diff --git a/internal/cmd/testmongoaws/go.sum b/internal/cmd/testmongoaws/go.sum new file mode 100644 index 0000000000..c1d6ceceaf --- /dev/null +++ b/internal/cmd/testmongoaws/go.sum @@ -0,0 +1,46 @@ +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/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= +github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= +github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= +github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= +github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY= +github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= +github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8= +github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= +github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM= +github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus= +golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= +golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/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-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/internal/cmd/testmongoaws/main.go b/internal/cmd/testmongoaws/main.go new file mode 100644 index 0000000000..fd6ae56b51 --- /dev/null +++ b/internal/cmd/testmongoaws/main.go @@ -0,0 +1,44 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + +package main + +import ( + "context" + "errors" + "fmt" + "os" + + "go.mongodb.org/mongo-driver/v2/bson" + "go.mongodb.org/mongo-driver/v2/mongo" + "go.mongodb.org/mongo-driver/v2/mongo/options" + "go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth" + "go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/mongoaws" +) + +func main() { + auth.RegisterAuthenticatorFactory(auth.MongoDBAWS, mongoaws.NewAuthenticator) + + uri := os.Getenv("MONGODB_URI") + ctx := context.Background() + + client, err := mongo.Connect(options.Client().ApplyURI(uri)) + if err != nil { + panic(fmt.Sprintf("Connect error: %v", err)) + } + + defer func() { + if err = client.Disconnect(ctx); err != nil { + panic(fmt.Sprintf("Disconnect error: %v", err)) + } + }() + + db := client.Database("aws") + coll := db.Collection("test") + if err = coll.FindOne(ctx, bson.D{{"x", 1}}).Err(); err != nil && !errors.Is(err, mongo.ErrNoDocuments) { + panic(fmt.Sprintf("FindOne error: %v", err)) + } +} diff --git a/x/mongo/driver/auth/mongoaws/go.mod b/x/mongo/driver/auth/mongoaws/go.mod new file mode 100644 index 0000000000..68844c1209 --- /dev/null +++ b/x/mongo/driver/auth/mongoaws/go.mod @@ -0,0 +1,15 @@ +module go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/mongoaws + +go 1.23 + +require go.mongodb.org/mongo-driver/v2 v2.2.1 + +require ( + github.com/golang/snappy v1.0.0 // indirect + github.com/klauspost/compress v1.16.7 // indirect + github.com/xdg-go/pbkdf2 v1.0.0 // indirect + github.com/xdg-go/scram v1.1.2 // indirect + github.com/xdg-go/stringprep v1.0.4 // indirect + golang.org/x/sync v0.11.0 // indirect + golang.org/x/text v0.22.0 // indirect +) diff --git a/x/mongo/driver/auth/mongoaws/go.sum b/x/mongo/driver/auth/mongoaws/go.sum new file mode 100644 index 0000000000..e8f55b11a3 --- /dev/null +++ b/x/mongo/driver/auth/mongoaws/go.sum @@ -0,0 +1,48 @@ +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/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= +github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= +github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= +github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= +github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY= +github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= +github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8= +github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= +github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM= +github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +go.mongodb.org/mongo-driver/v2 v2.2.1 h1:w5xra3yyu/sGrziMzK1D0cRRaH/b7lWCSsoN6+WV6AM= +go.mongodb.org/mongo-driver/v2 v2.2.1/go.mod h1:qQkDMhCGWl3FN509DfdPd4GRBLU/41zqF/k8eTRceps= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus= +golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= +golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/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-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/x/mongo/driver/auth/mongoaws/mongoaws.go b/x/mongo/driver/auth/mongoaws/mongoaws.go new file mode 100644 index 0000000000..075dd26f52 --- /dev/null +++ b/x/mongo/driver/auth/mongoaws/mongoaws.go @@ -0,0 +1,64 @@ +package mongoaws + +import ( + "context" + "errors" + "net/http" + + "go.mongodb.org/mongo-driver/v2/x/mongo/driver" + "go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth" +) + +const sourceExternal = "$external" + +// Authenticator is an authenticator that uses the AWS SDK rather than the +// lightweight AWS package used internally by the driver. +type Authenticator struct{} + +var _ driver.Authenticator = (*Authenticator)(nil) + +// NewAuthenticator creates a new AWS SDK authenticator. It loads the AWS +// SDK config (honoring AWS_STS_REGIONAL_ENDPOINTS & AWS_REGION) and returns an +// Authenticator that uses it. +func NewAuthenticator(*auth.Cred, *http.Client) (driver.Authenticator, error) { + return &Authenticator{}, nil +} + +var _ auth.AuthenticatorFactory = NewAuthenticator + +// Auth starts the SASL conversation by constructing a custom SASL adapter that +// uses the AWS SDK for singing. +func (a *Authenticator) Auth(ctx context.Context, cfg *driver.AuthConfig) error { + // Build a SASL adapter that uses AWS SDK for signing. + adapter := &awsSdkSaslClient{} + + return auth.ConductSaslConversation(ctx, cfg, sourceExternal, adapter) +} + +// REauth is not supported for AWS SDK authentication. +func (a *Authenticator) Reauth(context.Context, *driver.AuthConfig) error { + return errors.New("AWS reauthentication not supported") +} + +// awsSdkSaslClient is a SASL client that uses the AWS SDK for signing. +type awsSdkSaslClient struct{} + +var _ auth.SaslClient = (*awsSdkSaslClient)(nil) + +// Start will create the client-first SASL message. +// { p: 110, r: <32-byte nonce>}; per the current Go Driver behavior. +func (a *awsSdkSaslClient) Start() (string, []byte, error) { + return "", nil, nil +} + +// Next handles the server's "server-first" message, then builds and returns the +// "client-final" payload containing the SigV4-signed STS GetCallerIdentity +// request. +func (a *awsSdkSaslClient) Next(ctx context.Context, challenge []byte) ([]byte, error) { + return nil, nil +} + +// complete signals that the SASL conversation is done. +func (a *awsSdkSaslClient) Completed() bool { + return false +} From 119551b20462e91e2739a82692d865e00f8d40b7 Mon Sep 17 00:00:00 2001 From: Preston Vasquez Date: Thu, 22 May 2025 11:28:45 -0600 Subject: [PATCH 2/8] GODRIVER-3567 Move aws test into interna/test path --- etc/run-mongodb-aws-test.sh | 2 +- go.work | 2 +- .../testmongoaws => test/mongoaws}/go.mod | 3 ++- .../testmongoaws => test/mongoaws}/go.sum | 0 .../mongoaws/mongoaws_test.go} | 22 ++++++------------- 5 files changed, 11 insertions(+), 18 deletions(-) rename internal/{cmd/testmongoaws => test/mongoaws}/go.mod (87%) rename internal/{cmd/testmongoaws => test/mongoaws}/go.sum (100%) rename internal/{cmd/testmongoaws/main.go => test/mongoaws/mongoaws_test.go} (57%) diff --git a/etc/run-mongodb-aws-test.sh b/etc/run-mongodb-aws-test.sh index 35058388f7..b63d897592 100755 --- a/etc/run-mongodb-aws-test.sh +++ b/etc/run-mongodb-aws-test.sh @@ -32,4 +32,4 @@ set -x # For Go 1.16+, Go builds requires a go.mod file in the current working directory or a parent # directory. Spawn a new subshell, "cd" to the project directory, then run "go run". (cd ${PROJECT_DIRECTORY} && go run "./internal/cmd/testaws/main.go" | tee test.suite) -(cd ${PROJECT_DIRECTORY} && go run "./internal/cmd/testmongoaws/main.go" | tee test.suite) +(cd ${PROJECT_DIRECTORY} && go test "./internal/cmd/testmongoaws/main.go" -v | tee test.suite) diff --git a/go.work b/go.work index e4b1c439bf..78088699af 100644 --- a/go.work +++ b/go.work @@ -9,5 +9,5 @@ use ( ./internal/cmd/compilecheck ./internal/cmd/faas/awslambda/mongodb ./internal/test/goleak - ./internal/cmd/testmongoaws + ./internal/test/mongoaws ) diff --git a/internal/cmd/testmongoaws/go.mod b/internal/test/mongoaws/go.mod similarity index 87% rename from internal/cmd/testmongoaws/go.mod rename to internal/test/mongoaws/go.mod index 7cb65fb0fb..99bd9d7223 100644 --- a/internal/cmd/testmongoaws/go.mod +++ b/internal/test/mongoaws/go.mod @@ -1,4 +1,4 @@ -module go.mongodb.go/mongo-driver/internal/cmd/testmongoaws +module go.mongodb.go/mongo-driver/internal/test/mongoaws go 1.23.1 @@ -13,6 +13,7 @@ require ( ) require ( + github.com/davecgh/go-spew v1.1.1 // indirect github.com/golang/snappy v1.0.0 // indirect github.com/klauspost/compress v1.16.7 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect diff --git a/internal/cmd/testmongoaws/go.sum b/internal/test/mongoaws/go.sum similarity index 100% rename from internal/cmd/testmongoaws/go.sum rename to internal/test/mongoaws/go.sum diff --git a/internal/cmd/testmongoaws/main.go b/internal/test/mongoaws/mongoaws_test.go similarity index 57% rename from internal/cmd/testmongoaws/main.go rename to internal/test/mongoaws/mongoaws_test.go index fd6ae56b51..17b3fa4416 100644 --- a/internal/cmd/testmongoaws/main.go +++ b/internal/test/mongoaws/mongoaws_test.go @@ -1,17 +1,12 @@ -// Copyright (C) MongoDB, Inc. 2017-present. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 - package main import ( "context" "errors" - "fmt" "os" + "testing" + "github.com/stretchr/testify/require" "go.mongodb.org/mongo-driver/v2/bson" "go.mongodb.org/mongo-driver/v2/mongo" "go.mongodb.org/mongo-driver/v2/mongo/options" @@ -19,26 +14,23 @@ import ( "go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/mongoaws" ) -func main() { +func TestMongoAWS(t *testing.T) { auth.RegisterAuthenticatorFactory(auth.MongoDBAWS, mongoaws.NewAuthenticator) uri := os.Getenv("MONGODB_URI") ctx := context.Background() client, err := mongo.Connect(options.Client().ApplyURI(uri)) - if err != nil { - panic(fmt.Sprintf("Connect error: %v", err)) - } + require.NoError(t, err, "Connect error") defer func() { - if err = client.Disconnect(ctx); err != nil { - panic(fmt.Sprintf("Disconnect error: %v", err)) - } + err = client.Disconnect(ctx) + require.NoError(t, err, "Disconnect error") }() db := client.Database("aws") coll := db.Collection("test") if err = coll.FindOne(ctx, bson.D{{"x", 1}}).Err(); err != nil && !errors.Is(err, mongo.ErrNoDocuments) { - panic(fmt.Sprintf("FindOne error: %v", err)) + t.Fatalf("FindOne error: %v", err) } } From e23bfe9b8e21c40f9c8fba10c11c1b6475a4c3d4 Mon Sep 17 00:00:00 2001 From: Preston Vasquez Date: Thu, 22 May 2025 15:35:22 -0600 Subject: [PATCH 3/8] GODRIVER-3567 Fill in mongoaws skeleton --- etc/run-mongodb-aws-test.sh | 4 +- x/mongo/driver/auth/mongoaws/go.mod | 17 ++- x/mongo/driver/auth/mongoaws/go.sum | 26 ++++ x/mongo/driver/auth/mongoaws/mongoaws.go | 175 +++++++++++++++++++++-- 4 files changed, 208 insertions(+), 14 deletions(-) diff --git a/etc/run-mongodb-aws-test.sh b/etc/run-mongodb-aws-test.sh index b63d897592..3a5693458b 100755 --- a/etc/run-mongodb-aws-test.sh +++ b/etc/run-mongodb-aws-test.sh @@ -31,5 +31,5 @@ set -x # For Go 1.16+, Go builds requires a go.mod file in the current working directory or a parent # directory. Spawn a new subshell, "cd" to the project directory, then run "go run". -(cd ${PROJECT_DIRECTORY} && go run "./internal/cmd/testaws/main.go" | tee test.suite) -(cd ${PROJECT_DIRECTORY} && go test "./internal/cmd/testmongoaws/main.go" -v | tee test.suite) +#(cd ${PROJECT_DIRECTORY} && go run "./internal/cmd/testaws/main.go" | tee test.suite) +(cd ${PROJECT_DIRECTORY} && go test "./internal/test/mongoaws" -v | tee test.suite) diff --git a/x/mongo/driver/auth/mongoaws/go.mod b/x/mongo/driver/auth/mongoaws/go.mod index 68844c1209..684cd80ace 100644 --- a/x/mongo/driver/auth/mongoaws/go.mod +++ b/x/mongo/driver/auth/mongoaws/go.mod @@ -2,9 +2,24 @@ module go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/mongoaws go 1.23 -require go.mongodb.org/mongo-driver/v2 v2.2.1 +require ( + github.com/aws/aws-sdk-go-v2 v1.36.3 + github.com/aws/aws-sdk-go-v2/config v1.29.14 + go.mongodb.org/mongo-driver/v2 v2.2.1 +) require ( + github.com/aws/aws-sdk-go-v2/credentials v1.17.67 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.25.3 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.33.19 // indirect + github.com/aws/smithy-go v1.22.2 // indirect github.com/golang/snappy v1.0.0 // indirect github.com/klauspost/compress v1.16.7 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect diff --git a/x/mongo/driver/auth/mongoaws/go.sum b/x/mongo/driver/auth/mongoaws/go.sum index e8f55b11a3..e8cf9aa484 100644 --- a/x/mongo/driver/auth/mongoaws/go.sum +++ b/x/mongo/driver/auth/mongoaws/go.sum @@ -1,3 +1,29 @@ +github.com/aws/aws-sdk-go-v2 v1.36.3 h1:mJoei2CxPutQVxaATCzDUjcZEjVRdpsiiXi2o38yqWM= +github.com/aws/aws-sdk-go-v2 v1.36.3/go.mod h1:LLXuLpgzEbD766Z5ECcRmi8AzSwfZItDtmABVkRLGzg= +github.com/aws/aws-sdk-go-v2/config v1.29.14 h1:f+eEi/2cKCg9pqKBoAIwRGzVb70MRKqWX4dg1BDcSJM= +github.com/aws/aws-sdk-go-v2/config v1.29.14/go.mod h1:wVPHWcIFv3WO89w0rE10gzf17ZYy+UVS1Geq8Iei34g= +github.com/aws/aws-sdk-go-v2/credentials v1.17.67 h1:9KxtdcIA/5xPNQyZRgUSpYOE6j9Bc4+D7nZua0KGYOM= +github.com/aws/aws-sdk-go-v2/credentials v1.17.67/go.mod h1:p3C44m+cfnbv763s52gCqrjaqyPikj9Sg47kUVaNZQQ= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 h1:x793wxmUWVDhshP8WW2mlnXuFrO4cOd3HLBroh1paFw= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30/go.mod h1:Jpne2tDnYiFascUEs2AWHJL9Yp7A5ZVy3TNyxaAjD6M= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 h1:ZK5jHhnrioRkUNOc+hOgQKlUL5JeC3S6JgLxtQ+Rm0Q= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34/go.mod h1:p4VfIceZokChbA9FzMbRGz5OV+lekcVtHlPKEO0gSZY= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 h1:SZwFm17ZUNNg5Np0ioo/gq8Mn6u9w19Mri8DnJ15Jf0= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34/go.mod h1:dFZsC0BLo346mvKQLWmoJxT+Sjp+qcVR1tRVHQGOH9Q= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 h1:eAh2A4b5IzM/lum78bZ590jy36+d/aFLgKF/4Vd1xPE= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3/go.mod h1:0yKJC/kb8sAnmlYa6Zs3QVYqaC8ug2AbnNChv5Ox3uA= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 h1:dM9/92u2F1JbDaGooxTq18wmmFzbJRfXfVfy96/1CXM= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15/go.mod h1:SwFBy2vjtA0vZbjjaFtfN045boopadnoVPhu4Fv66vY= +github.com/aws/aws-sdk-go-v2/service/sso v1.25.3 h1:1Gw+9ajCV1jogloEv1RRnvfRFia2cL6c9cuKV2Ps+G8= +github.com/aws/aws-sdk-go-v2/service/sso v1.25.3/go.mod h1:qs4a9T5EMLl/Cajiw2TcbNt2UNo/Hqlyp+GiuG4CFDI= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1 h1:hXmVKytPfTy5axZ+fYbR5d0cFmC3JvwLm5kM83luako= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1/go.mod h1:MlYRNmYu/fGPoxBQVvBYr9nyr948aY/WLUvwBMBJubs= +github.com/aws/aws-sdk-go-v2/service/sts v1.33.19 h1:1XuUZ8mYJw9B6lzAkXhqHlJd/XvaX32evhproijJEZY= +github.com/aws/aws-sdk-go-v2/service/sts v1.33.19/go.mod h1:cQnB8CUnxbMU82JvlqjKR2HBOm3fe9pWorWBza6MBJ4= +github.com/aws/smithy-go v1.22.2 h1:6D9hW43xKFrRx/tXXfAlIZc4JI+yQe6snnWcQyxSyLQ= +github.com/aws/smithy-go v1.22.2/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= 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/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= diff --git a/x/mongo/driver/auth/mongoaws/mongoaws.go b/x/mongo/driver/auth/mongoaws/mongoaws.go index 075dd26f52..779c029e2c 100644 --- a/x/mongo/driver/auth/mongoaws/mongoaws.go +++ b/x/mongo/driver/auth/mongoaws/mongoaws.go @@ -1,27 +1,59 @@ package mongoaws import ( + "bytes" "context" + "crypto/rand" + "encoding/base64" "errors" + "fmt" "net/http" + "strings" + "time" + "github.com/aws/aws-sdk-go-v2/aws" + awsv4 "github.com/aws/aws-sdk-go-v2/aws/signer/v4" + "github.com/aws/aws-sdk-go-v2/config" + "go.mongodb.org/mongo-driver/v2/bson" + "go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore" "go.mongodb.org/mongo-driver/v2/x/mongo/driver" "go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth" ) -const sourceExternal = "$external" +const ( + sourceExternal = "$external" + responceNonceLength = 64 + amzDateFormat = "20060102T150405Z" + awsSessionToken = "AWS_SESSION_TOKEN" + defaultRegion = "us-east-1" + maxHostLength = 255 +) // Authenticator is an authenticator that uses the AWS SDK rather than the // lightweight AWS package used internally by the driver. -type Authenticator struct{} +type Authenticator struct { + userCred *auth.Cred // MongoDB TLS credentials with AWS keys + awsCfg aws.Config // AWS SDK config + signer *awsv4.Signer // SigV4 signer +} var _ driver.Authenticator = (*Authenticator)(nil) // NewAuthenticator creates a new AWS SDK authenticator. It loads the AWS // SDK config (honoring AWS_STS_REGIONAL_ENDPOINTS & AWS_REGION) and returns an // Authenticator that uses it. -func NewAuthenticator(*auth.Cred, *http.Client) (driver.Authenticator, error) { - return &Authenticator{}, nil +func NewAuthenticator(cred *auth.Cred, _ *http.Client) (driver.Authenticator, error) { + // Load AWS SDK config from environment variables / credentials files. + awsCfg, err := config.LoadDefaultConfig(context.Background(), config.WithRegion("us-east-1")) + if err != nil { + return nil, fmt.Errorf("failed to load AWS SDK config: %w", err) + } + + return &Authenticator{ + userCred: cred, + awsCfg: awsCfg, + signer: awsv4.NewSigner(), + }, nil } var _ auth.AuthenticatorFactory = NewAuthenticator @@ -30,7 +62,11 @@ var _ auth.AuthenticatorFactory = NewAuthenticator // uses the AWS SDK for singing. func (a *Authenticator) Auth(ctx context.Context, cfg *driver.AuthConfig) error { // Build a SASL adapter that uses AWS SDK for signing. - adapter := &awsSdkSaslClient{} + adapter := &awsSdkSaslClient{ + userCred: a.userCred, + awsCfg: a.awsCfg, + signer: a.signer, + } return auth.ConductSaslConversation(ctx, cfg, sourceExternal, adapter) } @@ -40,25 +76,142 @@ func (a *Authenticator) Reauth(context.Context, *driver.AuthConfig) error { return errors.New("AWS reauthentication not supported") } +type conversationState uint8 + +const ( + conversationStateStart conversationState = 1 // before sending anything. + conversationStateServerFirst conversationState = 2 // after sending client-first, awaiting server reply. + conversationStateDone conversationState = 3 // after sending client-final. +) + // awsSdkSaslClient is a SASL client that uses the AWS SDK for signing. -type awsSdkSaslClient struct{} +type awsSdkSaslClient struct { + state conversationState // handshake state machine + nonce []byte // client nonce + userCred *auth.Cred // MongoDB TLS credentials with AWS keys + awsCfg aws.Config // AWS SDK config + signer *awsv4.Signer // SigV4 signer +} var _ auth.SaslClient = (*awsSdkSaslClient)(nil) // Start will create the client-first SASL message. // { p: 110, r: <32-byte nonce>}; per the current Go Driver behavior. -func (a *awsSdkSaslClient) Start() (string, []byte, error) { - return "", nil, nil +func (client *awsSdkSaslClient) Start() (string, []byte, error) { + client.state = conversationStateServerFirst + client.nonce = make([]byte, 32) + _, _ = rand.Read(client.nonce) + + idx, msg := bsoncore.AppendDocumentStart(nil) + msg = bsoncore.AppendInt32Element(msg, "p", 110) + msg = bsoncore.AppendBinaryElement(msg, "r", 0x00, client.nonce) + msg, _ = bsoncore.AppendDocumentEnd(msg, idx) + + return auth.MongoDBAWS, msg, nil +} + +func getRegion(host string) (string, error) { + region := defaultRegion + + if len(host) == 0 { + return "", errors.New("invalid STS host: empty") + } + if len(host) > maxHostLength { + return "", errors.New("invalid STS host: too large") + } + // The implicit region for sts.amazonaws.com is us-east-1 + if host == "sts.amazonaws.com" { + return region, nil + } + if strings.HasPrefix(host, ".") || strings.HasSuffix(host, ".") || strings.Contains(host, "..") { + return "", errors.New("invalid STS host: empty part") + } + + // If the host has multiple parts, the second part is the region + parts := strings.Split(host, ".") + if len(parts) >= 2 { + region = parts[1] + } + + return region, nil } // Next handles the server's "server-first" message, then builds and returns the // "client-final" payload containing the SigV4-signed STS GetCallerIdentity // request. -func (a *awsSdkSaslClient) Next(ctx context.Context, challenge []byte) ([]byte, error) { +func (client *awsSdkSaslClient) Next(ctx context.Context, challenge []byte) ([]byte, error) { + if client.state != conversationStateServerFirst { + return nil, fmt.Errorf("invalid state: %v", client.state) + } + client.state = conversationStateDone + + // Unmarhal the server's BSON: { s: , h: ""} + var sm struct { + Nonce bson.Binary `bson:"s"` + Host string `bson:"h"` + } + + if err := bson.Unmarshal(challenge, &sm); err != nil { + return nil, err + } + + // Check nonce prefix + if sm.Nonce.Subtype != 0x00 { + return nil, errors.New("server reply contained unexpected binary subtype") + } + + if len(sm.Nonce.Data) != responceNonceLength { + return nil, fmt.Errorf("server reply nonce was not %v bytes", responceNonceLength) + } + + if !bytes.HasPrefix(sm.Nonce.Data, client.nonce) { + return nil, errors.New("server nonce did not extend client nonce") + } + + currentTime := time.Now().UTC() + body := "Action=GetCallerIdentity&Version=2011-06-15" + + // Create http.Request + req, _ := http.NewRequest("POST", "/", strings.NewReader(body)) + req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + req.Header.Set("Content-Length", "43") + req.Host = sm.Host + req.Header.Set("X-Amz-Date", currentTime.Format(amzDateFormat)) + + // Include session token if present. + if tok := client.userCred.Props[awsSessionToken]; tok != "" { + req.Header.Set("X-Amz-Security-Token", tok) + } + + req.Header.Set("X-MongoDB-Server-Nonce", base64.StdEncoding.EncodeToString(sm.Nonce.Data)) + req.Header.Set("X-MongoDB-GS2-CB-Flag", "n") + + // Retrieve AWS creds and sign the request using AWS SDK v4. + creds, err := client.awsCfg.Credentials.Retrieve(ctx) + if err != nil { + return nil, fmt.Errorf("failed to retrieve AWS credentials: %w", err) + } + + // Create signer with credentials + err = client.signer.SignHTTP(ctx, creds, req, body, "sts", sm.Host, currentTime) + if err != nil { + return nil, fmt.Errorf("failed to sign request: %w", err) + } + + // create message + // { a: Authorization, d: X-Amz-Date, t: X-Amz-Security-Token } + idx, msg := bsoncore.AppendDocumentStart(nil) + msg = bsoncore.AppendStringElement(msg, "a", req.Header.Get("Authorization")) + msg = bsoncore.AppendStringElement(msg, "d", req.Header.Get("X-Amz-Date")) + if tok := req.Header.Get("X-Amz-Security-Token"); tok != "" { + msg = bsoncore.AppendStringElement(msg, "t", tok) + } + msg, _ = bsoncore.AppendDocumentEnd(msg, idx) + return nil, nil } // complete signals that the SASL conversation is done. -func (a *awsSdkSaslClient) Completed() bool { - return false +func (client *awsSdkSaslClient) Completed() bool { + return client.state == conversationStateDone } From 561470982c742796e6797de3182457fdc6c85c6f Mon Sep 17 00:00:00 2001 From: Preston Vasquez Date: Thu, 22 May 2025 17:09:37 -0600 Subject: [PATCH 4/8] Continue working through sanity check --- x/mongo/driver/auth/mongoaws/mongoaws.go | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/x/mongo/driver/auth/mongoaws/mongoaws.go b/x/mongo/driver/auth/mongoaws/mongoaws.go index 779c029e2c..3582e141bb 100644 --- a/x/mongo/driver/auth/mongoaws/mongoaws.go +++ b/x/mongo/driver/auth/mongoaws/mongoaws.go @@ -7,6 +7,7 @@ import ( "encoding/base64" "errors" "fmt" + "log" "net/http" "strings" "time" @@ -140,6 +141,7 @@ func getRegion(host string) (string, error) { // "client-final" payload containing the SigV4-signed STS GetCallerIdentity // request. func (client *awsSdkSaslClient) Next(ctx context.Context, challenge []byte) ([]byte, error) { + log.Println("challenge received") if client.state != conversationStateServerFirst { return nil, fmt.Errorf("invalid state: %v", client.state) } @@ -155,6 +157,8 @@ func (client *awsSdkSaslClient) Next(ctx context.Context, challenge []byte) ([]b return nil, err } + log.Printf("SASL h (sts host): %s", sm.Host) + // Check nonce prefix if sm.Nonce.Subtype != 0x00 { return nil, errors.New("server reply contained unexpected binary subtype") @@ -175,6 +179,7 @@ func (client *awsSdkSaslClient) Next(ctx context.Context, challenge []byte) ([]b req, _ := http.NewRequest("POST", "/", strings.NewReader(body)) req.Header.Set("Content-Type", "application/x-www-form-urlencoded") req.Header.Set("Content-Length", "43") + req.URL.Scheme = "https" req.Host = sm.Host req.Header.Set("X-Amz-Date", currentTime.Format(amzDateFormat)) @@ -186,29 +191,41 @@ func (client *awsSdkSaslClient) Next(ctx context.Context, challenge []byte) ([]b req.Header.Set("X-MongoDB-Server-Nonce", base64.StdEncoding.EncodeToString(sm.Nonce.Data)) req.Header.Set("X-MongoDB-GS2-CB-Flag", "n") + region, err := getRegion(sm.Host) + if err != nil { + return nil, fmt.Errorf("failed to get AWS region: %w", err) + } + // Retrieve AWS creds and sign the request using AWS SDK v4. creds, err := client.awsCfg.Credentials.Retrieve(ctx) if err != nil { return nil, fmt.Errorf("failed to retrieve AWS credentials: %w", err) } + log.Printf("SASL r (region): %s", region) + // Create signer with credentials - err = client.signer.SignHTTP(ctx, creds, req, body, "sts", sm.Host, currentTime) + err = client.signer.SignHTTP(ctx, creds, req, body, "sts", region, currentTime) if err != nil { return nil, fmt.Errorf("failed to sign request: %w", err) } + for k, v := range req.Header { + log.Printf("Header %q: %s", k, v) + } + // create message // { a: Authorization, d: X-Amz-Date, t: X-Amz-Security-Token } idx, msg := bsoncore.AppendDocumentStart(nil) msg = bsoncore.AppendStringElement(msg, "a", req.Header.Get("Authorization")) msg = bsoncore.AppendStringElement(msg, "d", req.Header.Get("X-Amz-Date")) if tok := req.Header.Get("X-Amz-Security-Token"); tok != "" { + log.Println("token received") msg = bsoncore.AppendStringElement(msg, "t", tok) } msg, _ = bsoncore.AppendDocumentEnd(msg, idx) - return nil, nil + return msg, nil } // complete signals that the SASL conversation is done. From 5536619d25fcb9a29abdd3cde69ba71bd0b44a18 Mon Sep 17 00:00:00 2001 From: Preston Vasquez Date: Thu, 22 May 2025 21:05:30 -0600 Subject: [PATCH 5/8] GODRIVER-3567 specify v2 in module --- internal/test/mongoaws/go.mod | 4 +-- internal/test/mongoaws/mongoaws_test.go | 4 +-- .../auth/{mongoaws => mongoawsv2}/go.mod | 2 +- .../auth/{mongoaws => mongoawsv2}/go.sum | 0 .../mongoaws.go => mongoawsv2/mongoawsv2.go} | 27 +++++++++---------- 5 files changed, 17 insertions(+), 20 deletions(-) rename x/mongo/driver/auth/{mongoaws => mongoawsv2}/go.mod (99%) rename x/mongo/driver/auth/{mongoaws => mongoawsv2}/go.sum (100%) rename x/mongo/driver/auth/{mongoaws/mongoaws.go => mongoawsv2/mongoawsv2.go} (93%) diff --git a/internal/test/mongoaws/go.mod b/internal/test/mongoaws/go.mod index 99bd9d7223..f7de898631 100644 --- a/internal/test/mongoaws/go.mod +++ b/internal/test/mongoaws/go.mod @@ -4,12 +4,12 @@ go 1.23.1 replace ( go.mongodb.org/mongo-driver/v2 => ../../../ - go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/mongoaws => ../../../x/mongo/driver/auth/mongoaws + go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/mongoawsv2 => ../../../x/mongo/driver/auth/mongoawsv2 ) require ( go.mongodb.org/mongo-driver/v2 v2.3.4 - go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/mongoaws v1.2.3 + go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/mongoawsv2 v1.2.3 ) require ( diff --git a/internal/test/mongoaws/mongoaws_test.go b/internal/test/mongoaws/mongoaws_test.go index 17b3fa4416..e80b16be1c 100644 --- a/internal/test/mongoaws/mongoaws_test.go +++ b/internal/test/mongoaws/mongoaws_test.go @@ -11,11 +11,11 @@ import ( "go.mongodb.org/mongo-driver/v2/mongo" "go.mongodb.org/mongo-driver/v2/mongo/options" "go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth" - "go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/mongoaws" + "go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/mongoawsv2" ) func TestMongoAWS(t *testing.T) { - auth.RegisterAuthenticatorFactory(auth.MongoDBAWS, mongoaws.NewAuthenticator) + auth.RegisterAuthenticatorFactory(auth.MongoDBAWS, mongoawsv2.NewAuthenticator) uri := os.Getenv("MONGODB_URI") ctx := context.Background() diff --git a/x/mongo/driver/auth/mongoaws/go.mod b/x/mongo/driver/auth/mongoawsv2/go.mod similarity index 99% rename from x/mongo/driver/auth/mongoaws/go.mod rename to x/mongo/driver/auth/mongoawsv2/go.mod index 684cd80ace..45a330ebba 100644 --- a/x/mongo/driver/auth/mongoaws/go.mod +++ b/x/mongo/driver/auth/mongoawsv2/go.mod @@ -1,4 +1,4 @@ -module go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/mongoaws +module go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/mongoawsv2 go 1.23 diff --git a/x/mongo/driver/auth/mongoaws/go.sum b/x/mongo/driver/auth/mongoawsv2/go.sum similarity index 100% rename from x/mongo/driver/auth/mongoaws/go.sum rename to x/mongo/driver/auth/mongoawsv2/go.sum diff --git a/x/mongo/driver/auth/mongoaws/mongoaws.go b/x/mongo/driver/auth/mongoawsv2/mongoawsv2.go similarity index 93% rename from x/mongo/driver/auth/mongoaws/mongoaws.go rename to x/mongo/driver/auth/mongoawsv2/mongoawsv2.go index 3582e141bb..5787efd662 100644 --- a/x/mongo/driver/auth/mongoaws/mongoaws.go +++ b/x/mongo/driver/auth/mongoawsv2/mongoawsv2.go @@ -1,13 +1,15 @@ -package mongoaws +package mongoawsv2 import ( "bytes" "context" "crypto/rand" + "crypto/sha256" "encoding/base64" + "encoding/hex" "errors" "fmt" - "log" + "io" "net/http" "strings" "time" @@ -141,7 +143,6 @@ func getRegion(host string) (string, error) { // "client-final" payload containing the SigV4-signed STS GetCallerIdentity // request. func (client *awsSdkSaslClient) Next(ctx context.Context, challenge []byte) ([]byte, error) { - log.Println("challenge received") if client.state != conversationStateServerFirst { return nil, fmt.Errorf("invalid state: %v", client.state) } @@ -157,8 +158,6 @@ func (client *awsSdkSaslClient) Next(ctx context.Context, challenge []byte) ([]b return nil, err } - log.Printf("SASL h (sts host): %s", sm.Host) - // Check nonce prefix if sm.Nonce.Subtype != 0x00 { return nil, errors.New("server reply contained unexpected binary subtype") @@ -173,13 +172,14 @@ func (client *awsSdkSaslClient) Next(ctx context.Context, challenge []byte) ([]b } currentTime := time.Now().UTC() - body := "Action=GetCallerIdentity&Version=2011-06-15" + //body := "Action=GetCallerIdentity&Version=2011-06-15" + body := strings.NewReader("Action=GetCallerIdentity&Version=2011-06-15") // Create http.Request - req, _ := http.NewRequest("POST", "/", strings.NewReader(body)) + req, _ := http.NewRequestWithContext(ctx, "POST", "/", body) req.Header.Set("Content-Type", "application/x-www-form-urlencoded") req.Header.Set("Content-Length", "43") - req.URL.Scheme = "https" + req.Host = sm.Host req.Header.Set("X-Amz-Date", currentTime.Format(amzDateFormat)) @@ -202,25 +202,22 @@ func (client *awsSdkSaslClient) Next(ctx context.Context, challenge []byte) ([]b return nil, fmt.Errorf("failed to retrieve AWS credentials: %w", err) } - log.Printf("SASL r (region): %s", region) + h := sha256.New() + _, _ = io.Copy(h, body) + payloadHash := hex.EncodeToString(h.Sum(nil)) // Create signer with credentials - err = client.signer.SignHTTP(ctx, creds, req, body, "sts", region, currentTime) + err = client.signer.SignHTTP(ctx, creds, req, payloadHash, "sts", region, currentTime) if err != nil { return nil, fmt.Errorf("failed to sign request: %w", err) } - for k, v := range req.Header { - log.Printf("Header %q: %s", k, v) - } - // create message // { a: Authorization, d: X-Amz-Date, t: X-Amz-Security-Token } idx, msg := bsoncore.AppendDocumentStart(nil) msg = bsoncore.AppendStringElement(msg, "a", req.Header.Get("Authorization")) msg = bsoncore.AppendStringElement(msg, "d", req.Header.Get("X-Amz-Date")) if tok := req.Header.Get("X-Amz-Security-Token"); tok != "" { - log.Println("token received") msg = bsoncore.AppendStringElement(msg, "t", tok) } msg, _ = bsoncore.AppendDocumentEnd(msg, idx) From e6f01b30f61f040c95355064d32712cee38737ee Mon Sep 17 00:00:00 2001 From: Preston Vasquez Date: Thu, 22 May 2025 21:25:02 -0600 Subject: [PATCH 6/8] GODRIVER-3567 Add v1 for future consideration --- etc/run-mongodb-aws-test.sh | 7 ++++++- x/mongo/driver/auth/mongoawsv1/go.mod | 3 +++ x/mongo/driver/auth/mongoawsv1/mongoawsv1.go | 4 ++++ x/mongo/driver/auth/mongoawsv2/mongoawsv2.go | 2 +- 4 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 x/mongo/driver/auth/mongoawsv1/go.mod create mode 100644 x/mongo/driver/auth/mongoawsv1/mongoawsv1.go diff --git a/etc/run-mongodb-aws-test.sh b/etc/run-mongodb-aws-test.sh index 3a5693458b..bdc61381e3 100755 --- a/etc/run-mongodb-aws-test.sh +++ b/etc/run-mongodb-aws-test.sh @@ -29,7 +29,12 @@ fi # show test output set -x +# Region is required for the v2 AWS SDK +if [ -z "$AWS_REGION" ]; then + export AWS_REGION="us-east-1" +fi + # For Go 1.16+, Go builds requires a go.mod file in the current working directory or a parent # directory. Spawn a new subshell, "cd" to the project directory, then run "go run". -#(cd ${PROJECT_DIRECTORY} && go run "./internal/cmd/testaws/main.go" | tee test.suite) +(cd ${PROJECT_DIRECTORY} && go run "./internal/cmd/testaws/main.go" | tee test.suite) (cd ${PROJECT_DIRECTORY} && go test "./internal/test/mongoaws" -v | tee test.suite) diff --git a/x/mongo/driver/auth/mongoawsv1/go.mod b/x/mongo/driver/auth/mongoawsv1/go.mod new file mode 100644 index 0000000000..167b8621aa --- /dev/null +++ b/x/mongo/driver/auth/mongoawsv1/go.mod @@ -0,0 +1,3 @@ +module go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/mongoawsv1 + +go 1.23 diff --git a/x/mongo/driver/auth/mongoawsv1/mongoawsv1.go b/x/mongo/driver/auth/mongoawsv1/mongoawsv1.go new file mode 100644 index 0000000000..6878a72052 --- /dev/null +++ b/x/mongo/driver/auth/mongoawsv1/mongoawsv1.go @@ -0,0 +1,4 @@ +package mongoawsv1 + +// TODO +// v1 is EOL August 01, 2025 diff --git a/x/mongo/driver/auth/mongoawsv2/mongoawsv2.go b/x/mongo/driver/auth/mongoawsv2/mongoawsv2.go index 5787efd662..9661244874 100644 --- a/x/mongo/driver/auth/mongoawsv2/mongoawsv2.go +++ b/x/mongo/driver/auth/mongoawsv2/mongoawsv2.go @@ -47,7 +47,7 @@ var _ driver.Authenticator = (*Authenticator)(nil) // Authenticator that uses it. func NewAuthenticator(cred *auth.Cred, _ *http.Client) (driver.Authenticator, error) { // Load AWS SDK config from environment variables / credentials files. - awsCfg, err := config.LoadDefaultConfig(context.Background(), config.WithRegion("us-east-1")) + awsCfg, err := config.LoadDefaultConfig(context.Background()) if err != nil { return nil, fmt.Errorf("failed to load AWS SDK config: %w", err) } From 191c387bbcd1b9929e25b7eacff561a948e73f98 Mon Sep 17 00:00:00 2001 From: Preston Vasquez Date: Thu, 22 May 2025 21:41:38 -0600 Subject: [PATCH 7/8] GODRIVER-3567 Add licenses --- internal/test/mongoaws/mongoaws_test.go | 6 ++++++ x/mongo/driver/auth/mongoawsv1/mongoawsv1.go | 6 ++++++ x/mongo/driver/auth/mongoawsv2/mongoawsv2.go | 6 ++++++ 3 files changed, 18 insertions(+) diff --git a/internal/test/mongoaws/mongoaws_test.go b/internal/test/mongoaws/mongoaws_test.go index e80b16be1c..fd87a562a4 100644 --- a/internal/test/mongoaws/mongoaws_test.go +++ b/internal/test/mongoaws/mongoaws_test.go @@ -1,3 +1,9 @@ +// Copyright (C) MongoDB, Inc. 2025-present. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + package main import ( diff --git a/x/mongo/driver/auth/mongoawsv1/mongoawsv1.go b/x/mongo/driver/auth/mongoawsv1/mongoawsv1.go index 6878a72052..249140607a 100644 --- a/x/mongo/driver/auth/mongoawsv1/mongoawsv1.go +++ b/x/mongo/driver/auth/mongoawsv1/mongoawsv1.go @@ -1,3 +1,9 @@ +// Copyright (C) MongoDB, Inc. 2025-present. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + package mongoawsv1 // TODO diff --git a/x/mongo/driver/auth/mongoawsv2/mongoawsv2.go b/x/mongo/driver/auth/mongoawsv2/mongoawsv2.go index 9661244874..6bf3946e55 100644 --- a/x/mongo/driver/auth/mongoawsv2/mongoawsv2.go +++ b/x/mongo/driver/auth/mongoawsv2/mongoawsv2.go @@ -1,3 +1,9 @@ +// Copyright (C) MongoDB, Inc. 2025-present. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + package mongoawsv2 import ( From 6764892161d789ae095a12b180694299a402ae81 Mon Sep 17 00:00:00 2001 From: Preston Vasquez Date: Fri, 23 May 2025 08:05:16 -0600 Subject: [PATCH 8/8] GODRIVER-3567 update test go.mod --- internal/test/mongoaws/go.mod | 16 ++++++++++++++++ internal/test/mongoaws/go.sum | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/internal/test/mongoaws/go.mod b/internal/test/mongoaws/go.mod index f7de898631..3c8e555251 100644 --- a/internal/test/mongoaws/go.mod +++ b/internal/test/mongoaws/go.mod @@ -8,14 +8,29 @@ replace ( ) require ( + github.com/stretchr/testify v1.10.0 go.mongodb.org/mongo-driver/v2 v2.3.4 go.mongodb.org/mongo-driver/v2/x/mongo/driver/auth/mongoawsv2 v1.2.3 ) require ( + github.com/aws/aws-sdk-go-v2 v1.36.3 // indirect + github.com/aws/aws-sdk-go-v2/config v1.29.14 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.17.67 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.25.3 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.33.19 // indirect + github.com/aws/smithy-go v1.22.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/golang/snappy v1.0.0 // indirect github.com/klauspost/compress v1.16.7 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/scram v1.1.2 // indirect github.com/xdg-go/stringprep v1.0.4 // indirect @@ -23,4 +38,5 @@ require ( golang.org/x/crypto v0.33.0 // indirect golang.org/x/sync v0.11.0 // indirect golang.org/x/text v0.22.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/internal/test/mongoaws/go.sum b/internal/test/mongoaws/go.sum index c1d6ceceaf..85a8eec6ac 100644 --- a/internal/test/mongoaws/go.sum +++ b/internal/test/mongoaws/go.sum @@ -1,3 +1,29 @@ +github.com/aws/aws-sdk-go-v2 v1.36.3 h1:mJoei2CxPutQVxaATCzDUjcZEjVRdpsiiXi2o38yqWM= +github.com/aws/aws-sdk-go-v2 v1.36.3/go.mod h1:LLXuLpgzEbD766Z5ECcRmi8AzSwfZItDtmABVkRLGzg= +github.com/aws/aws-sdk-go-v2/config v1.29.14 h1:f+eEi/2cKCg9pqKBoAIwRGzVb70MRKqWX4dg1BDcSJM= +github.com/aws/aws-sdk-go-v2/config v1.29.14/go.mod h1:wVPHWcIFv3WO89w0rE10gzf17ZYy+UVS1Geq8Iei34g= +github.com/aws/aws-sdk-go-v2/credentials v1.17.67 h1:9KxtdcIA/5xPNQyZRgUSpYOE6j9Bc4+D7nZua0KGYOM= +github.com/aws/aws-sdk-go-v2/credentials v1.17.67/go.mod h1:p3C44m+cfnbv763s52gCqrjaqyPikj9Sg47kUVaNZQQ= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 h1:x793wxmUWVDhshP8WW2mlnXuFrO4cOd3HLBroh1paFw= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30/go.mod h1:Jpne2tDnYiFascUEs2AWHJL9Yp7A5ZVy3TNyxaAjD6M= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 h1:ZK5jHhnrioRkUNOc+hOgQKlUL5JeC3S6JgLxtQ+Rm0Q= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34/go.mod h1:p4VfIceZokChbA9FzMbRGz5OV+lekcVtHlPKEO0gSZY= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 h1:SZwFm17ZUNNg5Np0ioo/gq8Mn6u9w19Mri8DnJ15Jf0= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34/go.mod h1:dFZsC0BLo346mvKQLWmoJxT+Sjp+qcVR1tRVHQGOH9Q= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 h1:eAh2A4b5IzM/lum78bZ590jy36+d/aFLgKF/4Vd1xPE= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3/go.mod h1:0yKJC/kb8sAnmlYa6Zs3QVYqaC8ug2AbnNChv5Ox3uA= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 h1:dM9/92u2F1JbDaGooxTq18wmmFzbJRfXfVfy96/1CXM= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15/go.mod h1:SwFBy2vjtA0vZbjjaFtfN045boopadnoVPhu4Fv66vY= +github.com/aws/aws-sdk-go-v2/service/sso v1.25.3 h1:1Gw+9ajCV1jogloEv1RRnvfRFia2cL6c9cuKV2Ps+G8= +github.com/aws/aws-sdk-go-v2/service/sso v1.25.3/go.mod h1:qs4a9T5EMLl/Cajiw2TcbNt2UNo/Hqlyp+GiuG4CFDI= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1 h1:hXmVKytPfTy5axZ+fYbR5d0cFmC3JvwLm5kM83luako= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1/go.mod h1:MlYRNmYu/fGPoxBQVvBYr9nyr948aY/WLUvwBMBJubs= +github.com/aws/aws-sdk-go-v2/service/sts v1.33.19 h1:1XuUZ8mYJw9B6lzAkXhqHlJd/XvaX32evhproijJEZY= +github.com/aws/aws-sdk-go-v2/service/sts v1.33.19/go.mod h1:cQnB8CUnxbMU82JvlqjKR2HBOm3fe9pWorWBza6MBJ4= +github.com/aws/smithy-go v1.22.2 h1:6D9hW43xKFrRx/tXXfAlIZc4JI+yQe6snnWcQyxSyLQ= +github.com/aws/smithy-go v1.22.2/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= 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/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= @@ -6,6 +32,10 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +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/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY= @@ -44,3 +74,7 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=