-
Notifications
You must be signed in to change notification settings - Fork 66
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduce interface to ease forward/access HTTP headers (#562)
A new interface ForwardHTTPHeaders that allows to typeswitch/typecast to that interface instead and simplify the code. From plugin authors perspective we have documentation for Forward OAuth identity for the logged-in user, Forward cookies for the logged-in user and soon for Forward user header and we provides instruction for accessing these forwarded headers by access the request.Headers field. This field is different for different request types: - For QueryDataRequest and CheckHealthRequest there's a map[string]string (they're suppose to hold environment context/metadata - For CallResourceRequest there's a map[string][]string (suppose to hold HTTP headers since it's HTTP proxy over gRPC basically. With these changes, rather than accessing request.Headers directly to access HTTP headers it's suggested that they use request.GetHTTPHeader(<key>) instead, e.g. request.GetHTTPHeader(backend.OAuthIdentityTokenHeaderName) or request.GetHTTPHeader(backend.OAuthIdentityIDTokenHeaderName), to access Forwarded OAuth Identity headers. Using request.GetHTTPHeader(<key>) or request.GetHTTPHeaders() would also automatically handle canonical/non-canonical form problems.
- Loading branch information
Showing
8 changed files
with
796 additions
and
12 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
package backend | ||
|
||
import ( | ||
"strings" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestQueryDataRequest(t *testing.T) { | ||
req := &QueryDataRequest{} | ||
const customHeaderName = "X-Custom" | ||
|
||
t.Run("Legacy headers", func(t *testing.T) { | ||
req.Headers = map[string]string{ | ||
"Authorization": "a", | ||
"X-ID-Token": "b", | ||
"Cookie": "c", | ||
customHeaderName: "d", | ||
} | ||
|
||
t.Run("GetHTTPHeaders canonical form", func(t *testing.T) { | ||
headers := req.GetHTTPHeaders() | ||
require.Equal(t, "a", headers.Get(OAuthIdentityTokenHeaderName)) | ||
require.Equal(t, "b", headers.Get(OAuthIdentityIDTokenHeaderName)) | ||
require.Equal(t, "c", headers.Get(CookiesHeaderName)) | ||
require.Empty(t, headers.Get(customHeaderName)) | ||
}) | ||
|
||
t.Run("GetHTTPHeader canonical form", func(t *testing.T) { | ||
require.Equal(t, "a", req.GetHTTPHeader(OAuthIdentityTokenHeaderName)) | ||
require.Equal(t, "b", req.GetHTTPHeader(OAuthIdentityIDTokenHeaderName)) | ||
require.Equal(t, "c", req.GetHTTPHeader(CookiesHeaderName)) | ||
require.Empty(t, req.GetHTTPHeader(customHeaderName)) | ||
}) | ||
|
||
t.Run("DeleteHTTPHeader canonical form", func(t *testing.T) { | ||
req.DeleteHTTPHeader(OAuthIdentityTokenHeaderName) | ||
req.DeleteHTTPHeader(OAuthIdentityIDTokenHeaderName) | ||
req.DeleteHTTPHeader(CookiesHeaderName) | ||
req.DeleteHTTPHeader(customHeaderName) | ||
require.Empty(t, req.Headers) | ||
}) | ||
}) | ||
|
||
t.Run("SetHTTPHeader canonical form", func(t *testing.T) { | ||
req.SetHTTPHeader(OAuthIdentityTokenHeaderName, "a") | ||
req.SetHTTPHeader(OAuthIdentityIDTokenHeaderName, "b") | ||
req.SetHTTPHeader(CookiesHeaderName, "c") | ||
req.SetHTTPHeader(customHeaderName, "d") | ||
|
||
t.Run("GetHTTPHeaders canonical form", func(t *testing.T) { | ||
headers := req.GetHTTPHeaders() | ||
require.Equal(t, "a", headers.Get(OAuthIdentityTokenHeaderName)) | ||
require.Equal(t, "b", headers.Get(OAuthIdentityIDTokenHeaderName)) | ||
require.Equal(t, "c", headers.Get(CookiesHeaderName)) | ||
require.Equal(t, "d", headers.Get(customHeaderName)) | ||
}) | ||
|
||
t.Run("GetHTTPHeader canonical form", func(t *testing.T) { | ||
require.Equal(t, "a", req.GetHTTPHeader(OAuthIdentityTokenHeaderName)) | ||
require.Equal(t, "b", req.GetHTTPHeader(OAuthIdentityIDTokenHeaderName)) | ||
require.Equal(t, "c", req.GetHTTPHeader(CookiesHeaderName)) | ||
require.Equal(t, "d", req.GetHTTPHeader(customHeaderName)) | ||
}) | ||
|
||
t.Run("DeleteHTTPHeader canonical form", func(t *testing.T) { | ||
req.DeleteHTTPHeader(OAuthIdentityTokenHeaderName) | ||
req.DeleteHTTPHeader(OAuthIdentityIDTokenHeaderName) | ||
req.DeleteHTTPHeader(CookiesHeaderName) | ||
req.DeleteHTTPHeader(customHeaderName) | ||
require.Empty(t, req.Headers) | ||
}) | ||
}) | ||
|
||
t.Run("SetHTTPHeader non-canonical form", func(t *testing.T) { | ||
req.SetHTTPHeader(strings.ToLower(OAuthIdentityTokenHeaderName), "a") | ||
req.SetHTTPHeader(strings.ToLower(OAuthIdentityIDTokenHeaderName), "b") | ||
req.SetHTTPHeader(strings.ToLower(CookiesHeaderName), "c") | ||
req.SetHTTPHeader(strings.ToLower(customHeaderName), "d") | ||
|
||
t.Run("GetHTTPHeaders non-canonical form", func(t *testing.T) { | ||
headers := req.GetHTTPHeaders() | ||
require.Equal(t, "a", headers.Get(strings.ToLower(OAuthIdentityTokenHeaderName))) | ||
require.Equal(t, "b", headers.Get(strings.ToLower(OAuthIdentityIDTokenHeaderName))) | ||
require.Equal(t, "c", headers.Get(strings.ToLower(CookiesHeaderName))) | ||
require.Equal(t, "d", headers.Get(strings.ToLower(customHeaderName))) | ||
}) | ||
|
||
t.Run("GetHTTPHeader non-canonical form", func(t *testing.T) { | ||
require.Equal(t, "a", req.GetHTTPHeader(strings.ToLower(OAuthIdentityTokenHeaderName))) | ||
require.Equal(t, "b", req.GetHTTPHeader(strings.ToLower(OAuthIdentityIDTokenHeaderName))) | ||
require.Equal(t, "c", req.GetHTTPHeader(strings.ToLower(CookiesHeaderName))) | ||
require.Equal(t, "d", req.GetHTTPHeader(strings.ToLower(customHeaderName))) | ||
}) | ||
|
||
t.Run("DeleteHTTPHeader non-canonical form", func(t *testing.T) { | ||
req.DeleteHTTPHeader(strings.ToLower(OAuthIdentityTokenHeaderName)) | ||
req.DeleteHTTPHeader(strings.ToLower(OAuthIdentityIDTokenHeaderName)) | ||
req.DeleteHTTPHeader(strings.ToLower(CookiesHeaderName)) | ||
req.DeleteHTTPHeader(strings.ToLower(customHeaderName)) | ||
require.Empty(t, req.Headers) | ||
}) | ||
}) | ||
} |
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,105 @@ | ||
package backend | ||
|
||
import ( | ||
"strings" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestCheckHealthRequest(t *testing.T) { | ||
req := &CheckHealthRequest{} | ||
const customHeaderName = "X-Custom" | ||
|
||
t.Run("Legacy headers", func(t *testing.T) { | ||
req.Headers = map[string]string{ | ||
"Authorization": "a", | ||
"X-ID-Token": "b", | ||
"Cookie": "c", | ||
customHeaderName: "d", | ||
} | ||
|
||
t.Run("GetHTTPHeaders canonical form", func(t *testing.T) { | ||
headers := req.GetHTTPHeaders() | ||
require.Equal(t, "a", headers.Get(OAuthIdentityTokenHeaderName)) | ||
require.Equal(t, "b", headers.Get(OAuthIdentityIDTokenHeaderName)) | ||
require.Equal(t, "c", headers.Get(CookiesHeaderName)) | ||
require.Empty(t, headers.Get(customHeaderName)) | ||
}) | ||
|
||
t.Run("GetHTTPHeader canonical form", func(t *testing.T) { | ||
require.Equal(t, "a", req.GetHTTPHeader(OAuthIdentityTokenHeaderName)) | ||
require.Equal(t, "b", req.GetHTTPHeader(OAuthIdentityIDTokenHeaderName)) | ||
require.Equal(t, "c", req.GetHTTPHeader(CookiesHeaderName)) | ||
require.Empty(t, req.GetHTTPHeader(customHeaderName)) | ||
}) | ||
|
||
t.Run("DeleteHTTPHeader canonical form", func(t *testing.T) { | ||
req.DeleteHTTPHeader(OAuthIdentityTokenHeaderName) | ||
req.DeleteHTTPHeader(OAuthIdentityIDTokenHeaderName) | ||
req.DeleteHTTPHeader(CookiesHeaderName) | ||
req.DeleteHTTPHeader(customHeaderName) | ||
require.Empty(t, req.Headers) | ||
}) | ||
}) | ||
|
||
t.Run("SetHTTPHeader canonical form", func(t *testing.T) { | ||
req.SetHTTPHeader(OAuthIdentityTokenHeaderName, "a") | ||
req.SetHTTPHeader(OAuthIdentityIDTokenHeaderName, "b") | ||
req.SetHTTPHeader(CookiesHeaderName, "c") | ||
req.SetHTTPHeader(customHeaderName, "d") | ||
|
||
t.Run("GetHTTPHeaders canonical form", func(t *testing.T) { | ||
headers := req.GetHTTPHeaders() | ||
require.Equal(t, "a", headers.Get(OAuthIdentityTokenHeaderName)) | ||
require.Equal(t, "b", headers.Get(OAuthIdentityIDTokenHeaderName)) | ||
require.Equal(t, "c", headers.Get(CookiesHeaderName)) | ||
require.Equal(t, "d", headers.Get(customHeaderName)) | ||
}) | ||
|
||
t.Run("GetHTTPHeader canonical form", func(t *testing.T) { | ||
require.Equal(t, "a", req.GetHTTPHeader(OAuthIdentityTokenHeaderName)) | ||
require.Equal(t, "b", req.GetHTTPHeader(OAuthIdentityIDTokenHeaderName)) | ||
require.Equal(t, "c", req.GetHTTPHeader(CookiesHeaderName)) | ||
require.Equal(t, "d", req.GetHTTPHeader(customHeaderName)) | ||
}) | ||
|
||
t.Run("DeleteHTTPHeader canonical form", func(t *testing.T) { | ||
req.DeleteHTTPHeader(OAuthIdentityTokenHeaderName) | ||
req.DeleteHTTPHeader(OAuthIdentityIDTokenHeaderName) | ||
req.DeleteHTTPHeader(CookiesHeaderName) | ||
req.DeleteHTTPHeader(customHeaderName) | ||
require.Empty(t, req.Headers) | ||
}) | ||
}) | ||
|
||
t.Run("SetHTTPHeader non-canonical form", func(t *testing.T) { | ||
req.SetHTTPHeader(strings.ToLower(OAuthIdentityTokenHeaderName), "a") | ||
req.SetHTTPHeader(strings.ToLower(OAuthIdentityIDTokenHeaderName), "b") | ||
req.SetHTTPHeader(strings.ToLower(CookiesHeaderName), "c") | ||
req.SetHTTPHeader(strings.ToLower(customHeaderName), "d") | ||
|
||
t.Run("GetHTTPHeaders non-canonical form", func(t *testing.T) { | ||
headers := req.GetHTTPHeaders() | ||
require.Equal(t, "a", headers.Get(strings.ToLower(OAuthIdentityTokenHeaderName))) | ||
require.Equal(t, "b", headers.Get(strings.ToLower(OAuthIdentityIDTokenHeaderName))) | ||
require.Equal(t, "c", headers.Get(strings.ToLower(CookiesHeaderName))) | ||
require.Equal(t, "d", headers.Get(strings.ToLower(customHeaderName))) | ||
}) | ||
|
||
t.Run("GetHTTPHeader non-canonical form", func(t *testing.T) { | ||
require.Equal(t, "a", req.GetHTTPHeader(strings.ToLower(OAuthIdentityTokenHeaderName))) | ||
require.Equal(t, "b", req.GetHTTPHeader(strings.ToLower(OAuthIdentityIDTokenHeaderName))) | ||
require.Equal(t, "c", req.GetHTTPHeader(strings.ToLower(CookiesHeaderName))) | ||
require.Equal(t, "d", req.GetHTTPHeader(strings.ToLower(customHeaderName))) | ||
}) | ||
|
||
t.Run("DeleteHTTPHeader non-canonical form", func(t *testing.T) { | ||
req.DeleteHTTPHeader(strings.ToLower(OAuthIdentityTokenHeaderName)) | ||
req.DeleteHTTPHeader(strings.ToLower(OAuthIdentityIDTokenHeaderName)) | ||
req.DeleteHTTPHeader(strings.ToLower(CookiesHeaderName)) | ||
req.DeleteHTTPHeader(strings.ToLower(customHeaderName)) | ||
require.Empty(t, req.Headers) | ||
}) | ||
}) | ||
} |
Oops, something went wrong.