-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add auth token propagation for metrics reader (#3341)
* Add auth token propagation for metrics reader Signed-off-by: albertteoh <[email protected]> * Consolidate token propagation code Signed-off-by: albertteoh <[email protected]> * Rename to use PropagationHandler for consistency Signed-off-by: albertteoh <[email protected]> * Split and move common transports Signed-off-by: albertteoh <[email protected]> * Give bearerToken value less meaning Signed-off-by: albertteoh <[email protected]> * Fix import grouping Signed-off-by: albertteoh <[email protected]> * Give token value less meaning Signed-off-by: albertteoh <[email protected]> * make fmt Signed-off-by: albertteoh <[email protected]> * Remove functional options Signed-off-by: albertteoh <[email protected]> * Fix build Signed-off-by: albertteoh <[email protected]> * Address review comments Signed-off-by: albertteoh <[email protected]> * Fix staticcheck err Signed-off-by: albertteoh <[email protected]>
- Loading branch information
1 parent
c4a3904
commit 4aa436b
Showing
15 changed files
with
247 additions
and
76 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
// Copyright (c) 2021 The Jaeger Authors. | ||
// | ||
// 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 bearertoken | ||
|
||
import ( | ||
"errors" | ||
"net/http" | ||
) | ||
|
||
// RoundTripper wraps another http.RoundTripper and injects | ||
// an authentication header with bearer token into requests. | ||
type RoundTripper struct { | ||
// Transport is the underlying http.RoundTripper being wrapped. Required. | ||
Transport http.RoundTripper | ||
|
||
// StaticToken is the pre-configured bearer token. Optional. | ||
StaticToken string | ||
|
||
// OverrideFromCtx enables reading bearer token from Context. | ||
OverrideFromCtx bool | ||
} | ||
|
||
// RoundTrip injects the outbound Authorization header with the | ||
// token provided in the inbound request. | ||
func (tr RoundTripper) RoundTrip(r *http.Request) (*http.Response, error) { | ||
if tr.Transport == nil { | ||
return nil, errors.New("no http.RoundTripper provided") | ||
} | ||
token := tr.StaticToken | ||
if tr.OverrideFromCtx { | ||
headerToken, _ := GetBearerToken(r.Context()) | ||
if headerToken != "" { | ||
token = headerToken | ||
} | ||
} | ||
if token != "" { | ||
r.Header.Set("Authorization", "Bearer "+token) | ||
} | ||
return tr.Transport.RoundTrip(r) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
// Copyright (c) 2021 The Jaeger Authors. | ||
// | ||
// 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 bearertoken | ||
|
||
import ( | ||
"context" | ||
"net/http" | ||
"net/http/httptest" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
type roundTripFunc func(r *http.Request) (*http.Response, error) | ||
|
||
func (s roundTripFunc) RoundTrip(r *http.Request) (*http.Response, error) { | ||
return s(r) | ||
} | ||
|
||
func TestRoundTripper(t *testing.T) { | ||
for _, tc := range []struct { | ||
name string | ||
staticToken string | ||
overrideFromCtx bool | ||
wrappedTransport http.RoundTripper | ||
requestContext context.Context | ||
wantError bool | ||
}{ | ||
{ | ||
name: "Default RoundTripper and request context set should have empty Bearer token", | ||
wrappedTransport: roundTripFunc(func(r *http.Request) (*http.Response, error) { | ||
assert.Empty(t, r.Header.Get("Authorization")) | ||
return &http.Response{ | ||
StatusCode: http.StatusOK, | ||
}, nil | ||
}), | ||
requestContext: ContextWithBearerToken(context.Background(), "tokenFromContext"), | ||
}, | ||
{ | ||
name: "Override from context provided, and request context set should use request context token", | ||
overrideFromCtx: true, | ||
wrappedTransport: roundTripFunc(func(r *http.Request) (*http.Response, error) { | ||
assert.Equal(t, "Bearer tokenFromContext", r.Header.Get("Authorization")) | ||
return &http.Response{ | ||
StatusCode: http.StatusOK, | ||
}, nil | ||
}), | ||
requestContext: ContextWithBearerToken(context.Background(), "tokenFromContext"), | ||
}, | ||
{ | ||
name: "Allow override from context and token provided, and request context unset should use defaultToken", | ||
overrideFromCtx: true, | ||
staticToken: "initToken", | ||
wrappedTransport: roundTripFunc(func(r *http.Request) (*http.Response, error) { | ||
assert.Equal(t, "Bearer initToken", r.Header.Get("Authorization")) | ||
return &http.Response{}, nil | ||
}), | ||
requestContext: context.Background(), | ||
}, | ||
{ | ||
name: "Allow override from context and token provided, and request context set should use context token", | ||
overrideFromCtx: true, | ||
staticToken: "initToken", | ||
wrappedTransport: roundTripFunc(func(r *http.Request) (*http.Response, error) { | ||
assert.Equal(t, "Bearer tokenFromContext", r.Header.Get("Authorization")) | ||
return &http.Response{}, nil | ||
}), | ||
requestContext: ContextWithBearerToken(context.Background(), "tokenFromContext"), | ||
}, | ||
{ | ||
name: "Nil roundTripper provided should return an error", | ||
requestContext: context.Background(), | ||
wantError: true, | ||
}, | ||
} { | ||
t.Run(tc.name, func(t *testing.T) { | ||
server := httptest.NewServer(nil) | ||
defer server.Close() | ||
req, err := http.NewRequestWithContext(tc.requestContext, "GET", server.URL, nil) | ||
require.NoError(t, err) | ||
|
||
tr := RoundTripper{ | ||
Transport: tc.wrappedTransport, | ||
OverrideFromCtx: tc.overrideFromCtx, | ||
StaticToken: tc.staticToken, | ||
} | ||
resp, err := tr.RoundTrip(req) | ||
|
||
if tc.wantError { | ||
assert.Nil(t, resp) | ||
assert.Error(t, err) | ||
} else { | ||
assert.NotNil(t, resp) | ||
assert.NoError(t, err) | ||
} | ||
}) | ||
} | ||
} |
Oops, something went wrong.