538 lines
24 KiB
Go
538 lines
24 KiB
Go
package g8
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
const (
|
|
FirstTestProviderClientPermission = "permission-1"
|
|
SecondTestProviderClientPermission = "permission-2"
|
|
TestProviderClientToken = "client-token-from-provider"
|
|
TestProviderClientData = "client-data-from-provider"
|
|
)
|
|
|
|
var (
|
|
mockClientProvider = NewClientProvider(func(token string) *Client {
|
|
// We'll pretend that there's only one token that's valid in the client provider, every other token
|
|
// returns nil
|
|
if token == TestProviderClientToken {
|
|
return &Client{
|
|
Token: TestProviderClientToken,
|
|
Data: TestProviderClientData,
|
|
Permissions: []string{FirstTestProviderClientPermission, SecondTestProviderClientPermission},
|
|
}
|
|
}
|
|
return nil
|
|
})
|
|
)
|
|
|
|
type testHandler struct {
|
|
}
|
|
|
|
func (handler *testHandler) ServeHTTP(writer http.ResponseWriter, _ *http.Request) {
|
|
writer.WriteHeader(http.StatusOK)
|
|
}
|
|
|
|
func testHandlerFunc(writer http.ResponseWriter, _ *http.Request) {
|
|
writer.WriteHeader(http.StatusOK)
|
|
}
|
|
|
|
func TestUsability(t *testing.T) {
|
|
gate := New().WithAuthorizationService(NewAuthorizationService().WithToken("good-token"))
|
|
|
|
var handler http.Handler = &testHandler{}
|
|
handlerFunc := func(writer http.ResponseWriter, request *http.Request) {
|
|
writer.WriteHeader(http.StatusOK)
|
|
}
|
|
|
|
router := http.NewServeMux()
|
|
router.Handle("/handle", handler)
|
|
router.Handle("/handle-protected", gate.Protect(handler))
|
|
router.HandleFunc("/handlefunc", handlerFunc)
|
|
router.HandleFunc("/handlefunc-protected", gate.ProtectFunc(handlerFunc))
|
|
}
|
|
|
|
func TestNewGate(t *testing.T) {
|
|
gate := NewGate(nil)
|
|
if gate == nil {
|
|
t.Error("gate should not be nil")
|
|
}
|
|
}
|
|
|
|
func TestUnprotectedHandler(t *testing.T) {
|
|
request, _ := http.NewRequest("GET", "/handle", http.NoBody)
|
|
request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", "bad-token"))
|
|
responseRecorder := httptest.NewRecorder()
|
|
|
|
router := http.NewServeMux()
|
|
router.Handle("/handle", &testHandler{})
|
|
router.ServeHTTP(responseRecorder, request)
|
|
|
|
if responseRecorder.Code != http.StatusOK {
|
|
t.Errorf("%s %s should have returned %d, but returned %d instead", request.Method, request.URL, http.StatusOK, responseRecorder.Code)
|
|
}
|
|
}
|
|
|
|
func TestGate_ProtectWithInvalidToken(t *testing.T) {
|
|
gate := New().WithAuthorizationService(NewAuthorizationService().WithToken("good-token"))
|
|
request, _ := http.NewRequest("GET", "/handle", http.NoBody)
|
|
request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", "bad-token"))
|
|
responseRecorder := httptest.NewRecorder()
|
|
|
|
router := http.NewServeMux()
|
|
router.Handle("/handle", gate.Protect(&testHandler{}))
|
|
router.ServeHTTP(responseRecorder, request)
|
|
|
|
if responseRecorder.Code != http.StatusUnauthorized {
|
|
t.Errorf("%s %s should have returned %d, but returned %d instead", request.Method, request.URL, http.StatusUnauthorized, responseRecorder.Code)
|
|
}
|
|
}
|
|
|
|
func TestGate_ProtectWithValidToken(t *testing.T) {
|
|
gate := New().WithAuthorizationService(NewAuthorizationService().WithToken("good-token"))
|
|
request, _ := http.NewRequest("GET", "/handle", http.NoBody)
|
|
request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", "good-token"))
|
|
responseRecorder := httptest.NewRecorder()
|
|
|
|
router := http.NewServeMux()
|
|
router.Handle("/handle", gate.Protect(&testHandler{}))
|
|
router.ServeHTTP(responseRecorder, request)
|
|
|
|
if responseRecorder.Code != http.StatusOK {
|
|
t.Errorf("%s %s should have returned %d, but returned %d instead", request.Method, request.URL, http.StatusOK, responseRecorder.Code)
|
|
}
|
|
}
|
|
|
|
func TestGate_ProtectMultipleTimes(t *testing.T) {
|
|
gate := New().WithAuthorizationService(NewAuthorizationService().WithToken("good-token"))
|
|
request, _ := http.NewRequest("GET", "/handle", http.NoBody)
|
|
request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", "good-token"))
|
|
badRequest, _ := http.NewRequest("GET", "/handle", http.NoBody)
|
|
badRequest.Header.Add("Authorization", fmt.Sprintf("Bearer %s", "bad-token"))
|
|
|
|
router := http.NewServeMux()
|
|
router.Handle("/handle", gate.Protect(&testHandler{}))
|
|
|
|
for i := 0; i < 100; i++ {
|
|
responseRecorder := httptest.NewRecorder()
|
|
router.ServeHTTP(responseRecorder, request)
|
|
if responseRecorder.Code != http.StatusOK {
|
|
t.Errorf("%s %s should have returned %d, but returned %d instead", request.Method, request.URL, http.StatusOK, responseRecorder.Code)
|
|
}
|
|
responseRecorder = httptest.NewRecorder()
|
|
router.ServeHTTP(responseRecorder, badRequest)
|
|
if responseRecorder.Code != http.StatusUnauthorized {
|
|
t.Errorf("%s %s should have returned %d, but returned %d instead", badRequest.Method, badRequest.URL, http.StatusOK, responseRecorder.Code)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestGate_ProtectWithValidTokenExposedThroughClientProvider(t *testing.T) {
|
|
gate := New().WithAuthorizationService(NewAuthorizationService().WithClientProvider(mockClientProvider))
|
|
request, _ := http.NewRequest("GET", "/handle", http.NoBody)
|
|
request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", TestProviderClientToken))
|
|
responseRecorder := httptest.NewRecorder()
|
|
|
|
router := http.NewServeMux()
|
|
router.Handle("/handle", gate.Protect(&testHandler{}))
|
|
router.ServeHTTP(responseRecorder, request)
|
|
|
|
if responseRecorder.Code != http.StatusOK {
|
|
t.Errorf("%s %s should have returned %d, but returned %d instead", request.Method, request.URL, http.StatusOK, responseRecorder.Code)
|
|
}
|
|
}
|
|
|
|
func TestGate_ProtectWithValidTokenExposedThroughClientProviderWithCache(t *testing.T) {
|
|
gate := New().WithAuthorizationService(NewAuthorizationService().WithClientProvider(mockClientProvider.WithCache(60*time.Minute, 70000)))
|
|
request, _ := http.NewRequest("GET", "/handle", http.NoBody)
|
|
request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", TestProviderClientToken))
|
|
responseRecorder := httptest.NewRecorder()
|
|
|
|
router := http.NewServeMux()
|
|
router.Handle("/handle", gate.Protect(&testHandler{}))
|
|
router.ServeHTTP(responseRecorder, request)
|
|
|
|
if responseRecorder.Code != http.StatusOK {
|
|
t.Errorf("%s %s should have returned %d, but returned %d instead", request.Method, request.URL, http.StatusOK, responseRecorder.Code)
|
|
}
|
|
}
|
|
|
|
func TestGate_ProtectWithInvalidTokenWhenUsingClientProvider(t *testing.T) {
|
|
gate := New().WithAuthorizationService(NewAuthorizationService().WithClientProvider(mockClientProvider))
|
|
request, _ := http.NewRequest("GET", "/handle", http.NoBody)
|
|
request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", "bad-token"))
|
|
responseRecorder := httptest.NewRecorder()
|
|
|
|
router := http.NewServeMux()
|
|
router.Handle("/handle", gate.Protect(&testHandler{}))
|
|
router.ServeHTTP(responseRecorder, request)
|
|
|
|
if responseRecorder.Code != http.StatusUnauthorized {
|
|
t.Errorf("%s %s should have returned %d, but returned %d instead", request.Method, request.URL, http.StatusUnauthorized, responseRecorder.Code)
|
|
}
|
|
}
|
|
|
|
func TestGate_ProtectWithPermissionsWhenValidTokenAndSufficientPermissionsWhileUsingClientProvider(t *testing.T) {
|
|
gate := New().WithAuthorizationService(NewAuthorizationService().WithClientProvider(mockClientProvider))
|
|
request, _ := http.NewRequest("GET", "/handle", http.NoBody)
|
|
request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", TestProviderClientToken))
|
|
responseRecorder := httptest.NewRecorder()
|
|
|
|
router := http.NewServeMux()
|
|
router.Handle("/handle", gate.ProtectWithPermissions(&testHandler{}, []string{SecondTestProviderClientPermission}))
|
|
router.ServeHTTP(responseRecorder, request)
|
|
|
|
// Since the client returned from the mockClientProvider has FirstTestProviderClientPermission and
|
|
// SecondTestProviderClientPermission and the testHandler is protected by SecondTestProviderClientPermission,
|
|
// the request should be authorized
|
|
if responseRecorder.Code != http.StatusOK {
|
|
t.Errorf("%s %s should have returned %d, but returned %d instead", request.Method, request.URL, http.StatusOK, responseRecorder.Code)
|
|
}
|
|
}
|
|
|
|
func TestGate_ProtectWithPermissionsWhenValidTokenAndInsufficientPermissionsWhileUsingClientProvider(t *testing.T) {
|
|
gate := New().WithAuthorizationService(NewAuthorizationService().WithClientProvider(mockClientProvider))
|
|
request, _ := http.NewRequest("GET", "/handle", http.NoBody)
|
|
request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", TestProviderClientToken))
|
|
responseRecorder := httptest.NewRecorder()
|
|
|
|
router := http.NewServeMux()
|
|
router.Handle("/handle", gate.ProtectWithPermissions(&testHandler{}, []string{"unrelated-permission"}))
|
|
router.ServeHTTP(responseRecorder, request)
|
|
|
|
// Since the client returned from the mockClientProvider has FirstTestProviderClientPermission and
|
|
// SecondTestProviderClientPermission and the testHandler is protected by a permission that the client does not
|
|
// have, the request should be not be authorized
|
|
if responseRecorder.Code != http.StatusUnauthorized {
|
|
t.Errorf("%s %s should have returned %d, but returned %d instead", request.Method, request.URL, http.StatusUnauthorized, responseRecorder.Code)
|
|
}
|
|
}
|
|
|
|
func TestGate_ProtectWithPermissionsWhenClientHasSufficientPermissions(t *testing.T) {
|
|
gate := New().WithAuthorizationService(NewAuthorizationService().WithClient(NewClient("token").WithPermission("admin")))
|
|
request, _ := http.NewRequest("GET", "/handle", http.NoBody)
|
|
request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", "token"))
|
|
responseRecorder := httptest.NewRecorder()
|
|
|
|
router := http.NewServeMux()
|
|
router.Handle("/handle", gate.ProtectWithPermissions(&testHandler{}, []string{"admin"}))
|
|
router.ServeHTTP(responseRecorder, request)
|
|
|
|
// Since the client registered directly in the AuthorizationService has the permission "admin" and the testHandler
|
|
// is protected by the permission "admin", the request should be authorized
|
|
if responseRecorder.Code != http.StatusOK {
|
|
t.Errorf("%s %s should have returned %d, but returned %d instead", request.Method, request.URL, http.StatusOK, responseRecorder.Code)
|
|
}
|
|
}
|
|
|
|
func TestGate_ProtectWithPermissionsWhenClientHasInsufficientPermissions(t *testing.T) {
|
|
gate := New().WithAuthorizationService(NewAuthorizationService().WithClient(NewClientWithPermissions("token", []string{"mod"})))
|
|
request, _ := http.NewRequest("GET", "/handle", http.NoBody)
|
|
request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", "token"))
|
|
responseRecorder := httptest.NewRecorder()
|
|
|
|
router := http.NewServeMux()
|
|
router.Handle("/handle", gate.ProtectWithPermissions(&testHandler{}, []string{"admin"}))
|
|
router.ServeHTTP(responseRecorder, request)
|
|
|
|
// Since the client registered directly in the AuthorizationService has the permission "mod" and the
|
|
// testHandler is protected by the permission "admin", the request should be not be authorized
|
|
if responseRecorder.Code != http.StatusUnauthorized {
|
|
t.Errorf("%s %s should have returned %d, but returned %d instead", request.Method, request.URL, http.StatusUnauthorized, responseRecorder.Code)
|
|
}
|
|
}
|
|
|
|
func TestGate_ProtectWithPermissions(t *testing.T) {
|
|
gate := New().WithAuthorizationService(NewAuthorizationService().WithClient(NewClient("mytoken").WithPermissions([]string{"create", "read", "update", "delete"})))
|
|
|
|
router := http.NewServeMux()
|
|
router.Handle("/create", gate.ProtectWithPermissions(&testHandler{}, []string{"create"}))
|
|
router.Handle("/read", gate.ProtectWithPermissions(&testHandler{}, []string{"read"}))
|
|
router.Handle("/update", gate.ProtectWithPermissions(&testHandler{}, []string{"update"}))
|
|
router.Handle("/delete", gate.ProtectWithPermissions(&testHandler{}, []string{"delete"}))
|
|
router.Handle("/crud", gate.ProtectWithPermissions(&testHandler{}, []string{"create", "read", "update", "delete"}))
|
|
router.Handle("/backup", gate.ProtectWithPermissions(&testHandler{}, []string{"read", "backup"}))
|
|
|
|
checkRouterOutput := func(t *testing.T, router *http.ServeMux, url string, expectedResponseCode int) {
|
|
t.Run(strings.TrimPrefix(url, "/"), func(t *testing.T) {
|
|
request, _ := http.NewRequest("GET", url, http.NoBody)
|
|
request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", "mytoken"))
|
|
responseRecorder := httptest.NewRecorder()
|
|
router.ServeHTTP(responseRecorder, request)
|
|
if responseRecorder.Code != expectedResponseCode {
|
|
t.Errorf("%s %s should have returned %d, but returned %d instead", request.Method, request.URL, expectedResponseCode, responseRecorder.Code)
|
|
}
|
|
})
|
|
}
|
|
|
|
checkRouterOutput(t, router, "/create", http.StatusOK)
|
|
checkRouterOutput(t, router, "/read", http.StatusOK)
|
|
checkRouterOutput(t, router, "/update", http.StatusOK)
|
|
checkRouterOutput(t, router, "/delete", http.StatusOK)
|
|
checkRouterOutput(t, router, "/crud", http.StatusOK)
|
|
checkRouterOutput(t, router, "/backup", http.StatusUnauthorized)
|
|
}
|
|
|
|
func TestGate_ProtectWithPermissionWhenClientHasSufficientPermissions(t *testing.T) {
|
|
gate := New().WithAuthorizationService(NewAuthorizationService().WithClient(NewClient("token").WithPermission("admin")))
|
|
request, _ := http.NewRequest("GET", "/handle", http.NoBody)
|
|
request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", "token"))
|
|
responseRecorder := httptest.NewRecorder()
|
|
|
|
router := http.NewServeMux()
|
|
router.Handle("/handle", gate.ProtectWithPermission(&testHandler{}, "admin"))
|
|
router.ServeHTTP(responseRecorder, request)
|
|
|
|
// Since the client registered directly in the AuthorizationService has the permission "admin" and the testHandler
|
|
// is protected by the permission "admin", the request should be authorized
|
|
if responseRecorder.Code != http.StatusOK {
|
|
t.Errorf("%s %s should have returned %d, but returned %d instead", request.Method, request.URL, http.StatusOK, responseRecorder.Code)
|
|
}
|
|
}
|
|
|
|
func TestGate_ProtectWithPermissionWhenClientHasInsufficientPermissions(t *testing.T) {
|
|
gate := New().WithAuthorizationService(NewAuthorizationService().WithClient(NewClientWithPermissions("token", []string{"mod"})))
|
|
request, _ := http.NewRequest("GET", "/handle", http.NoBody)
|
|
request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", "token"))
|
|
responseRecorder := httptest.NewRecorder()
|
|
|
|
router := http.NewServeMux()
|
|
router.Handle("/handle", gate.ProtectWithPermission(&testHandler{}, "admin"))
|
|
router.ServeHTTP(responseRecorder, request)
|
|
|
|
// Since the client registered directly in the AuthorizationService has the permission "mod" and the
|
|
// testHandler is protected by the permission "admin", the request should be not be authorized
|
|
if responseRecorder.Code != http.StatusUnauthorized {
|
|
t.Errorf("%s %s should have returned %d, but returned %d instead", request.Method, request.URL, http.StatusUnauthorized, responseRecorder.Code)
|
|
}
|
|
}
|
|
|
|
func TestGate_PermissionMiddlewareWhenClientHasSufficientPermissions(t *testing.T) {
|
|
gate := New().WithAuthorizationService(NewAuthorizationService().WithClient(NewClient("token").WithPermission("admin")))
|
|
request, _ := http.NewRequest("GET", "/handle", http.NoBody)
|
|
request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", "token"))
|
|
responseRecorder := httptest.NewRecorder()
|
|
|
|
router := http.NewServeMux()
|
|
router.Handle("/handle", gate.PermissionMiddleware("admin")(&testHandler{}))
|
|
router.ServeHTTP(responseRecorder, request)
|
|
|
|
// Since the client registered directly in the AuthorizationService has the permission "admin" and the testHandler
|
|
// is protected by the permission "admin", the request should be authorized
|
|
if responseRecorder.Code != http.StatusOK {
|
|
t.Errorf("%s %s should have returned %d, but returned %d instead", request.Method, request.URL, http.StatusOK, responseRecorder.Code)
|
|
}
|
|
}
|
|
|
|
func TestGate_PermissionMiddlewareWhenClientHasInsufficientPermissions(t *testing.T) {
|
|
gate := New().WithAuthorizationService(NewAuthorizationService().WithClient(NewClientWithPermissions("token", []string{"mod"})))
|
|
request, _ := http.NewRequest("GET", "/handle", http.NoBody)
|
|
request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", "token"))
|
|
responseRecorder := httptest.NewRecorder()
|
|
|
|
router := http.NewServeMux()
|
|
router.Handle("/handle", gate.PermissionMiddleware("admin")(&testHandler{}))
|
|
router.ServeHTTP(responseRecorder, request)
|
|
|
|
// Since the client registered directly in the AuthorizationService has the permission "mod" and the
|
|
// testHandler is protected by the permission "admin", the request should be not be authorized
|
|
if responseRecorder.Code != http.StatusUnauthorized {
|
|
t.Errorf("%s %s should have returned %d, but returned %d instead", request.Method, request.URL, http.StatusUnauthorized, responseRecorder.Code)
|
|
}
|
|
}
|
|
|
|
func TestGate_ProtectFuncWithInvalidToken(t *testing.T) {
|
|
gate := New().WithAuthorizationService(NewAuthorizationService().WithToken("good-token"))
|
|
request, _ := http.NewRequest("GET", "/handle", http.NoBody)
|
|
request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", "bad-token"))
|
|
responseRecorder := httptest.NewRecorder()
|
|
|
|
router := http.NewServeMux()
|
|
router.Handle("/handle", gate.ProtectFunc(testHandlerFunc))
|
|
router.ServeHTTP(responseRecorder, request)
|
|
|
|
if responseRecorder.Code != http.StatusUnauthorized {
|
|
t.Errorf("%s %s should have returned %d, but returned %d instead", request.Method, request.URL, http.StatusUnauthorized, responseRecorder.Code)
|
|
}
|
|
}
|
|
|
|
func TestGate_ProtectFuncWithValidToken(t *testing.T) {
|
|
gate := New().WithAuthorizationService(NewAuthorizationService().WithToken("good-token"))
|
|
request, _ := http.NewRequest("GET", "/handle", http.NoBody)
|
|
request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", "good-token"))
|
|
responseRecorder := httptest.NewRecorder()
|
|
|
|
router := http.NewServeMux()
|
|
router.Handle("/handle", gate.ProtectFunc(testHandlerFunc))
|
|
router.ServeHTTP(responseRecorder, request)
|
|
|
|
if responseRecorder.Code != http.StatusOK {
|
|
t.Errorf("%s %s should have returned %d, but returned %d instead", request.Method, request.URL, http.StatusOK, responseRecorder.Code)
|
|
}
|
|
}
|
|
|
|
func TestGate_ProtectFuncWithPermissionWhenClientHasSufficientPermissions(t *testing.T) {
|
|
gate := New().WithAuthorizationService(NewAuthorizationService().WithClient(NewClient("token").WithPermission("admin")))
|
|
request, _ := http.NewRequest("GET", "/handle", http.NoBody)
|
|
request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", "token"))
|
|
responseRecorder := httptest.NewRecorder()
|
|
|
|
router := http.NewServeMux()
|
|
router.HandleFunc("/handle", gate.ProtectFuncWithPermission(testHandlerFunc, "admin"))
|
|
router.ServeHTTP(responseRecorder, request)
|
|
|
|
// Since the client registered directly in the AuthorizationService has the permission "admin" and the testHandler
|
|
// is protected by the permission "admin", the request should be authorized
|
|
if responseRecorder.Code != http.StatusOK {
|
|
t.Errorf("%s %s should have returned %d, but returned %d instead", request.Method, request.URL, http.StatusOK, responseRecorder.Code)
|
|
}
|
|
}
|
|
|
|
func TestGate_ProtectFuncWithPermissionWhenClientHasInsufficientPermissions(t *testing.T) {
|
|
gate := New().WithAuthorizationService(NewAuthorizationService().WithClient(NewClientWithPermissions("token", []string{"mod"})))
|
|
request, _ := http.NewRequest("GET", "/handle", http.NoBody)
|
|
request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", "token"))
|
|
responseRecorder := httptest.NewRecorder()
|
|
|
|
router := http.NewServeMux()
|
|
router.HandleFunc("/handle", gate.ProtectFuncWithPermission(testHandlerFunc, "admin"))
|
|
router.ServeHTTP(responseRecorder, request)
|
|
|
|
// Since the client registered directly in the AuthorizationService has the permission "mod" and the
|
|
// testHandler is protected by the permission "admin", the request should be not be authorized
|
|
if responseRecorder.Code != http.StatusUnauthorized {
|
|
t.Errorf("%s %s should have returned %d, but returned %d instead", request.Method, request.URL, http.StatusUnauthorized, responseRecorder.Code)
|
|
}
|
|
}
|
|
|
|
func TestGate_WithCustomUnauthorizedResponseBody(t *testing.T) {
|
|
gate := New().WithAuthorizationService(NewAuthorizationService()).WithCustomUnauthorizedResponseBody([]byte("test"))
|
|
request, _ := http.NewRequest("GET", "/handle", http.NoBody)
|
|
request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", "bad-token"))
|
|
responseRecorder := httptest.NewRecorder()
|
|
|
|
router := http.NewServeMux()
|
|
router.Handle("/handle", gate.Protect(&testHandler{}))
|
|
router.ServeHTTP(responseRecorder, request)
|
|
|
|
if responseRecorder.Code != http.StatusUnauthorized {
|
|
t.Errorf("%s %s should have returned %d, but returned %d instead", request.Method, request.URL, http.StatusUnauthorized, responseRecorder.Code)
|
|
}
|
|
if responseBody, _ := io.ReadAll(responseRecorder.Body); string(responseBody) != "test" {
|
|
t.Errorf("%s %s should have returned %s, but returned %s instead", request.Method, request.URL, "test", string(responseBody))
|
|
}
|
|
}
|
|
|
|
func TestGate_ProtectWithNoAuthorizationService(t *testing.T) {
|
|
gate := New()
|
|
request, _ := http.NewRequest("GET", "/handle", http.NoBody)
|
|
responseRecorder := httptest.NewRecorder()
|
|
|
|
router := http.NewServeMux()
|
|
router.Handle("/handle", gate.Protect(&testHandler{}))
|
|
router.ServeHTTP(responseRecorder, request)
|
|
|
|
if responseRecorder.Code != http.StatusOK {
|
|
t.Errorf("%s %s should have returned %d, but returned %d instead", request.Method, request.URL, http.StatusOK, responseRecorder.Code)
|
|
}
|
|
}
|
|
|
|
func TestGate_ProtectWithRateLimit(t *testing.T) {
|
|
gate := New().WithRateLimit(2)
|
|
request, _ := http.NewRequest("GET", "/handle", http.NoBody)
|
|
router := http.NewServeMux()
|
|
router.Handle("/handle", gate.Protect(&testHandler{}))
|
|
|
|
responseRecorder := httptest.NewRecorder()
|
|
router.ServeHTTP(responseRecorder, request)
|
|
if responseRecorder.Code != http.StatusOK {
|
|
t.Errorf("%s %s should have returned %d, but returned %d instead", request.Method, request.URL, http.StatusOK, responseRecorder.Code)
|
|
}
|
|
|
|
responseRecorder = httptest.NewRecorder()
|
|
router.ServeHTTP(responseRecorder, request)
|
|
if responseRecorder.Code != http.StatusOK {
|
|
t.Errorf("%s %s should have returned %d, but returned %d instead", request.Method, request.URL, http.StatusOK, responseRecorder.Code)
|
|
}
|
|
|
|
responseRecorder = httptest.NewRecorder()
|
|
router.ServeHTTP(responseRecorder, request)
|
|
if responseRecorder.Code != http.StatusTooManyRequests {
|
|
t.Errorf("%s %s should have returned %d, but returned %d instead", request.Method, request.URL, http.StatusTooManyRequests, responseRecorder.Code)
|
|
}
|
|
|
|
// Wait for rate limit time window to pass
|
|
time.Sleep(time.Second)
|
|
|
|
responseRecorder = httptest.NewRecorder()
|
|
router.ServeHTTP(responseRecorder, request)
|
|
if responseRecorder.Code != http.StatusOK {
|
|
t.Errorf("%s %s should have returned %d, but returned %d instead", request.Method, request.URL, http.StatusOK, responseRecorder.Code)
|
|
}
|
|
}
|
|
|
|
func TestGate_WithCustomTokenExtractor(t *testing.T) {
|
|
authorizationService := NewAuthorizationService().WithClientProvider(mockClientProvider)
|
|
customTokenExtractorFunc := func(request *http.Request) string {
|
|
sessionCookie, err := request.Cookie("session")
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
return sessionCookie.Value
|
|
}
|
|
gate := New().WithAuthorizationService(authorizationService).WithCustomTokenExtractor(customTokenExtractorFunc)
|
|
|
|
request, _ := http.NewRequest("GET", "/handle", http.NoBody)
|
|
request.AddCookie(&http.Cookie{Name: "session", Value: TestProviderClientToken})
|
|
responseRecorder := httptest.NewRecorder()
|
|
|
|
router := http.NewServeMux()
|
|
router.Handle("/handle", gate.ProtectFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
if r.Context().Value(TokenContextKey) != TestProviderClientToken {
|
|
t.Errorf("token should have been passed to the request context")
|
|
}
|
|
if r.Context().Value(DataContextKey) != TestProviderClientData {
|
|
t.Errorf("data should have been passed to the request context")
|
|
}
|
|
w.WriteHeader(http.StatusOK)
|
|
}))
|
|
router.ServeHTTP(responseRecorder, request)
|
|
|
|
if responseRecorder.Code != http.StatusOK {
|
|
t.Errorf("%s %s should have returned %d, but returned %d instead", request.Method, request.URL, http.StatusOK, responseRecorder.Code)
|
|
}
|
|
}
|
|
|
|
func TestGateWithCustomHeader(t *testing.T) {
|
|
authorizationService := NewAuthorizationService().WithClientProvider(mockClientProvider)
|
|
customTokenExtractorFunc := func(request *http.Request) string {
|
|
return request.Header.Get("X-API-Token")
|
|
}
|
|
gate := New().WithAuthorizationService(authorizationService).WithCustomTokenExtractor(customTokenExtractorFunc)
|
|
|
|
request, _ := http.NewRequest("GET", "/handle", http.NoBody)
|
|
request.Header.Add("X-API-Token", TestProviderClientToken)
|
|
responseRecorder := httptest.NewRecorder()
|
|
|
|
router := http.NewServeMux()
|
|
router.Handle("/handle", gate.ProtectFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
if r.Context().Value(TokenContextKey) != TestProviderClientToken {
|
|
t.Errorf("token should have been passed to the request context")
|
|
}
|
|
if r.Context().Value(DataContextKey) != TestProviderClientData {
|
|
t.Errorf("data should have been passed to the request context")
|
|
}
|
|
w.WriteHeader(http.StatusOK)
|
|
}))
|
|
router.ServeHTTP(responseRecorder, request)
|
|
|
|
if responseRecorder.Code != http.StatusOK {
|
|
t.Errorf("%s %s should have returned %d, but returned %d instead", request.Method, request.URL, http.StatusOK, responseRecorder.Code)
|
|
}
|
|
}
|