-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: fleshed out all the unit tests surrounding authorization heade…
…r parsing
- Loading branch information
Showing
6 changed files
with
231 additions
and
60 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,124 @@ | ||
// SPDX-FileCopyrightText: 2024 Comcast Cable Communications Management, LLC | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package basculehttp | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/suite" | ||
"github.com/xmidt-org/bascule/v1" | ||
) | ||
|
||
// withAuthorizationParserOptionErr is an option that returns an error. | ||
// These tests need this since no options currently return errors | ||
// for an AuthorizationParser. | ||
func withAuthorizationParserOptionErr(err error) AuthorizationParserOption { | ||
return authorizationParserOptionFunc(func(*AuthorizationParser) error { | ||
return err | ||
}) | ||
} | ||
|
||
type AuthorizationTestSuite struct { | ||
TestSuite | ||
} | ||
|
||
// newAuthorizationParser produces a parser from a set of options that must assert as valid. | ||
func (suite *AuthorizationTestSuite) newAuthorizationParser(opts ...AuthorizationParserOption) *AuthorizationParser { | ||
ap, err := NewAuthorizationParser(opts...) | ||
suite.Require().NoError(err) | ||
suite.Require().NotNil(ap) | ||
return ap | ||
} | ||
|
||
func (suite *AuthorizationTestSuite) TestBasicAuthSuccess() { | ||
suite.Run("DefaultHeader", func() { | ||
var ( | ||
ap = suite.newAuthorizationParser( | ||
WithBasic(), | ||
) | ||
|
||
request = suite.newBasicAuthRequest() | ||
) | ||
|
||
token, err := ap.Parse(context.Background(), request) | ||
suite.NoError(err) | ||
suite.assertBasicToken(token) | ||
}) | ||
|
||
suite.Run("Custom", func() { | ||
var ( | ||
ap = suite.newAuthorizationParser( | ||
WithAuthorizationHeader("Auth-Custom"), | ||
WithScheme(Scheme("Custom"), BasicTokenParser{}), | ||
) | ||
|
||
request = suite.newRequest() | ||
) | ||
|
||
request.Header.Set("Auth-Custom", "Custom "+suite.basicAuth()) | ||
token, err := ap.Parse(context.Background(), request) | ||
suite.NoError(err) | ||
suite.assertBasicToken(token) | ||
}) | ||
} | ||
|
||
func (suite *AuthorizationTestSuite) TestMissingCredentials() { | ||
var ( | ||
ap = suite.newAuthorizationParser( | ||
WithBasic(), | ||
) | ||
|
||
request = suite.newRequest() | ||
) | ||
|
||
token, err := ap.Parse(context.Background(), request) | ||
suite.ErrorIs(err, bascule.ErrMissingCredentials) | ||
suite.Nil(token) | ||
} | ||
|
||
func (suite *AuthorizationTestSuite) TestInvalidCredentials() { | ||
var ( | ||
ap = suite.newAuthorizationParser( | ||
WithBasic(), | ||
) | ||
|
||
request = suite.newRequest() | ||
) | ||
|
||
request.Header.Set(DefaultAuthorizationHeader, "\t") | ||
token, err := ap.Parse(context.Background(), request) | ||
suite.ErrorIs(err, bascule.ErrInvalidCredentials) | ||
suite.Nil(token) | ||
} | ||
|
||
func (suite *AuthorizationTestSuite) TestUnsupportedScheme() { | ||
var ( | ||
ap = suite.newAuthorizationParser( | ||
WithBasic(), | ||
) | ||
|
||
request = suite.newRequest() | ||
) | ||
|
||
request.Header.Set(DefaultAuthorizationHeader, "Unsupported xyz") | ||
token, err := ap.Parse(context.Background(), request) | ||
suite.Nil(token) | ||
|
||
var use *UnsupportedSchemeError | ||
suite.Require().ErrorAs(err, &use) | ||
suite.Equal(Scheme("Unsupported"), use.Scheme) | ||
} | ||
|
||
func (suite *AuthorizationTestSuite) TestOptionError() { | ||
expectedErr := errors.New("expected") | ||
ap, err := NewAuthorizationParser(withAuthorizationParserOptionErr(expectedErr)) | ||
suite.ErrorIs(err, expectedErr) | ||
suite.Nil(ap) | ||
} | ||
|
||
func TestAuthorization(t *testing.T) { | ||
suite.Run(t, new(AuthorizationTestSuite)) | ||
} |
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,28 @@ | ||
// SPDX-FileCopyrightText: 2024 Comcast Cable Communications Management, LLC | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package basculehttp | ||
|
||
import ( | ||
"net/http" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/suite" | ||
) | ||
|
||
type SchemeTestSuite struct { | ||
suite.Suite | ||
} | ||
|
||
func (suite *SchemeTestSuite) TestUnsupportedSchemeError() { | ||
use := &UnsupportedSchemeError{ | ||
Scheme: Scheme("Unsupported"), | ||
} | ||
|
||
suite.Equal(http.StatusUnauthorized, use.StatusCode()) | ||
suite.Contains(use.Error(), "Unsupported") | ||
} | ||
|
||
func TestScheme(t *testing.T) { | ||
suite.Run(t, new(SchemeTestSuite)) | ||
} |
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,64 @@ | ||
// SPDX-FileCopyrightText: 2024 Comcast Cable Communications Management, LLC | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package basculehttp | ||
|
||
import ( | ||
"net/http" | ||
"net/http/httptest" | ||
|
||
"github.com/stretchr/testify/suite" | ||
"github.com/xmidt-org/bascule/v1" | ||
) | ||
|
||
const ( | ||
expectedPrincipal = "testPrincipal" | ||
expectedPassword = "test_password" | ||
) | ||
|
||
// TestSuite is a common suite that exposes some useful behaviors. | ||
type TestSuite struct { | ||
suite.Suite | ||
} | ||
|
||
// newRequest creates a standardized test request, devoid of any authorization. | ||
func (suite *TestSuite) newRequest() *http.Request { | ||
return httptest.NewRequest("GET", "/test", nil) | ||
} | ||
|
||
// assertRequest asserts that the given request matches the one created by newRequest. | ||
func (suite *TestSuite) assertBasicAuthRequest(request *http.Request) { | ||
suite.Require().NotNil(request) | ||
suite.Equal("GET", request.Method) | ||
suite.Equal("/test", request.URL.String()) | ||
} | ||
|
||
// newBasicAuthRequest creates a new test request configured with valid basic auth. | ||
func (suite *TestSuite) newBasicAuthRequest() *http.Request { | ||
request := suite.newRequest() | ||
request.SetBasicAuth(expectedPrincipal, expectedPassword) | ||
return request | ||
} | ||
|
||
// basicAuth produces a formatted basic authorization string using this suite's expectations. | ||
func (suite *TestSuite) basicAuth() string { | ||
return BasicAuth(expectedPrincipal, expectedPassword) | ||
} | ||
|
||
// assertBasicToken asserts that the token matches the one created by newBasicToken. | ||
func (suite *TestSuite) assertBasicToken(token bascule.Token) { | ||
suite.Require().NotNil(token) | ||
suite.Equal(expectedPrincipal, token.Principal()) | ||
suite.Require().Implements((*BasicToken)(nil), token) | ||
suite.Equal(expectedPrincipal, token.(BasicToken).UserName()) | ||
suite.Equal(expectedPassword, token.(BasicToken).Password()) | ||
} | ||
|
||
// newAuthorizationParser creates an AuthorizationParser that is expected to be valid. | ||
// Assertions as to validity are made prior to returning. | ||
func (suite *TestSuite) newAuthorizationParser(opts ...AuthorizationParserOption) *AuthorizationParser { | ||
ap, err := NewAuthorizationParser(opts...) | ||
suite.Require().NoError(err) | ||
suite.Require().NotNil(ap) | ||
return ap | ||
} |