From 61d98647a3add0542b5e55f8dde2db0bf8384bc4 Mon Sep 17 00:00:00 2001 From: Gergely Brautigam <182850+Skarlso@users.noreply.github.com> Date: Wed, 19 Jun 2024 16:00:21 +0200 Subject: [PATCH] added fixed name and creating a new client for each request --- .../charts/bitwarden-sdk-server/values.yaml | 4 +- docs/release_notes/v0.1.2.md | 3 + go.mod | 4 + go.sum | 8 ++ hack/bitwarden-certificate.yaml | 1 + hack/cluster_issuer.yaml | 1 + pkg/bitwarden/bitwarden.go | 12 +-- pkg/bitwarden/bitwarden_test.go | 88 +++++++++++++++++++ 8 files changed, 109 insertions(+), 12 deletions(-) create mode 100644 docs/release_notes/v0.1.2.md create mode 100644 pkg/bitwarden/bitwarden_test.go diff --git a/deploy/charts/bitwarden-sdk-server/values.yaml b/deploy/charts/bitwarden-sdk-server/values.yaml index 0ce5008..f0424af 100644 --- a/deploy/charts/bitwarden-sdk-server/values.yaml +++ b/deploy/charts/bitwarden-sdk-server/values.yaml @@ -27,8 +27,8 @@ image: path: "ca.pem" imagePullSecrets: [] -nameOverride: "" -fullnameOverride: "" +nameOverride: "bitwarden-sdk-server" +fullnameOverride: "bitwarden-sdk-server" serviceAccount: # Specifies whether a service account should be created diff --git a/docs/release_notes/v0.1.2.md b/docs/release_notes/v0.1.2.md new file mode 100644 index 0000000..b2f9074 --- /dev/null +++ b/docs/release_notes/v0.1.2.md @@ -0,0 +1,3 @@ +# Release v0.1.2 + +Overwriting the client if it exists to prevent using a potentially closed client. diff --git a/go.mod b/go.mod index 9ae48ee..9b226dc 100644 --- a/go.mod +++ b/go.mod @@ -6,9 +6,13 @@ require ( github.com/bitwarden/sdk-go v0.1.1 github.com/go-chi/chi/v5 v5.0.12 github.com/spf13/cobra v1.8.1 + github.com/stretchr/testify v1.9.0 ) require ( + github.com/davecgh/go-spew v1.1.1 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect github.com/spf13/pflag v1.0.5 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 461cd14..91873ff 100644 --- a/go.sum +++ b/go.sum @@ -1,14 +1,22 @@ github.com/bitwarden/sdk-go v0.1.1 h1:Fn7d0SuThIEwaIecg3SRBM6RUbUyQQ7x7Ex+qrcLbMA= github.com/bitwarden/sdk-go v0.1.1/go.mod h1:Gp2ADXAL0XQ3GO3zxAv503xSlL6ORPf0VZg2J+yQ6jU= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +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/go-chi/chi/v5 v5.0.12 h1:9euLV5sTrTNTRUU9POmDUvfxyj6LAABLUcEWO+JJb4s= github.com/go-chi/chi/v5 v5.0.12/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +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/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +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= +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= diff --git a/hack/bitwarden-certificate.yaml b/hack/bitwarden-certificate.yaml index 3953e5e..3af9f25 100644 --- a/hack/bitwarden-certificate.yaml +++ b/hack/bitwarden-certificate.yaml @@ -7,6 +7,7 @@ spec: secretName: bitwarden-tls-certs dnsNames: - bitwarden-sdk-server.default.svc.cluster.local + - external-secrets-bitwarden-sdk-server.default.svc.cluster.local - localhost ipAddresses: - 127.0.0.1 diff --git a/hack/cluster_issuer.yaml b/hack/cluster_issuer.yaml index c62e8f5..7b28103 100644 --- a/hack/cluster_issuer.yaml +++ b/hack/cluster_issuer.yaml @@ -19,6 +19,7 @@ spec: organizations: - external-secrets.io dnsNames: + - external-secrets-bitwarden-sdk-server.default.svc.cluster.local - bitwarden-sdk-server.default.svc.cluster.local - localhost ipAddresses: diff --git a/pkg/bitwarden/bitwarden.go b/pkg/bitwarden/bitwarden.go index d975370..bfdbb60 100644 --- a/pkg/bitwarden/bitwarden.go +++ b/pkg/bitwarden/bitwarden.go @@ -99,15 +99,6 @@ func Login(req *LoginRequest) (sdk.BitwardenClientInterface, error) { // we know that calls are authenticated. func Warden(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - if ctx.Value(ContextClientKey) != nil { - next.ServeHTTP(w, r.WithContext(ctx)) - - return - } - - defer r.Body.Close() - token := r.Header.Get(WardenHeaderAccessToken) if token == "" { http.Error(w, "Missing Warden access token", http.StatusUnauthorized) @@ -124,6 +115,7 @@ func Warden(next http.Handler) http.Handler { StatePath: r.Header.Get(WardenHeaderStatePath), } + // Make sure every request gets its own client that it will close after it's done. client, err := Login(loginRequest) if err != nil { http.Error(w, "failed to login to bitwarden using access token: "+err.Error(), http.StatusBadRequest) @@ -131,7 +123,7 @@ func Warden(next http.Handler) http.Handler { return } - ctx = context.WithValue(ctx, ContextClientKey, client) + ctx := context.WithValue(r.Context(), ContextClientKey, client) next.ServeHTTP(w, r.WithContext(ctx)) }) } diff --git a/pkg/bitwarden/bitwarden_test.go b/pkg/bitwarden/bitwarden_test.go new file mode 100644 index 0000000..eea98b8 --- /dev/null +++ b/pkg/bitwarden/bitwarden_test.go @@ -0,0 +1,88 @@ +/* +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 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package bitwarden + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "net/http" + "net/http/httptest" + "testing" + + "github.com/bitwarden/sdk-go" + "github.com/go-chi/chi/v5" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +// This is a valid test token that has been generated and then revoked. The important +// bit is that it is in valid format. If ever this needs to be changed, it has to be +// regenerated by a valid bitwarden secret manager machine account. +const testToken = "0.0f0a8a7e-d737-498d-be6a-b1930064c31c.Rjqj7Vt7ZcDADtpbuzgx0hqbNJFPho:RZbls0Ka2gwIVKaLvSG3eA==" + +// TODO: I need to figure out what the command requires as a response. It seems like it doesn't like +// whatever I throw at it. +func XTestWardenWithToken(t *testing.T) { + // this is the bitwarden server mock + success := sdk.APIKeyLoginResponse{ + Authenticated: true, + } + marshal, _ := json.Marshal(success) + message := json.RawMessage(marshal) + wrapper := struct { + Success bool `json:"success"` + ErrorMessage *string `json:"errorMessage"` + Data *json.RawMessage `json:"data"` + }{ + Success: true, + ErrorMessage: nil, + Data: &message, + } + + bitwardenServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + wr, _ := json.Marshal(wrapper) + w.Write(wr) + w.WriteHeader(http.StatusAccepted) + })) + defer bitwardenServer.Close() + + // this is our warden test mock + r := chi.NewRouter() + r.Use(Warden) + r.Get("/", func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte("test")) + w.WriteHeader(http.StatusOK) + }) + server := httptest.NewServer(r) + defer server.Close() + + url := server.URL + "/" + client := server.Client() + req, err := http.NewRequest(http.MethodGet, url, bytes.NewBuffer([]byte(`{}`))) + require.NoError(t, err) + req.Header.Set(WardenHeaderAccessToken, testToken) + req.Header.Set(WardenHeaderAPIURL, bitwardenServer.URL) + req.Header.Set(WardenHeaderIdentityURL, bitwardenServer.URL) + resp, err := client.Do(req) + require.NoError(t, err) + defer resp.Body.Close() + content, err := io.ReadAll(resp.Body) + require.NoError(t, err) + fmt.Println(string(content)) + + assert.Equal(t, http.StatusOK, resp.StatusCode) +}