chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
package oauth
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// serveCallback drives the callback handler with the given query string and
|
||||
// returns the recorded response and the single reported result.
|
||||
func serveCallback(t *testing.T, expectedState, query string) (*httptest.ResponseRecorder, callbackResult) {
|
||||
t.Helper()
|
||||
cs := &callbackServer{results: make(chan callbackResult, 1)}
|
||||
rec := httptest.NewRecorder()
|
||||
req := httptest.NewRequest(http.MethodGet, "/callback?"+query, nil)
|
||||
|
||||
cs.handler(expectedState).ServeHTTP(rec, req)
|
||||
|
||||
select {
|
||||
case res := <-cs.results:
|
||||
return rec, res
|
||||
default:
|
||||
t.Fatal("handler did not report a result")
|
||||
return nil, callbackResult{}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCallbackHandlerSuccess(t *testing.T) {
|
||||
rec, res := serveCallback(t, "state123", "code=the-code&state=state123")
|
||||
|
||||
require.NoError(t, res.err)
|
||||
assert.Equal(t, "the-code", res.code)
|
||||
assert.Equal(t, http.StatusOK, rec.Code)
|
||||
assert.Contains(t, rec.Body.String(), "Authorization Successful")
|
||||
}
|
||||
|
||||
func TestCallbackHandlerStateMismatch(t *testing.T) {
|
||||
rec, res := serveCallback(t, "expected", "code=the-code&state=attacker")
|
||||
|
||||
require.Error(t, res.err)
|
||||
assert.Empty(t, res.code)
|
||||
assert.Contains(t, res.err.Error(), "state mismatch")
|
||||
assert.Contains(t, rec.Body.String(), "state mismatch")
|
||||
}
|
||||
|
||||
func TestCallbackHandlerMissingCode(t *testing.T) {
|
||||
_, res := serveCallback(t, "state123", "state=state123")
|
||||
|
||||
require.Error(t, res.err)
|
||||
assert.Contains(t, res.err.Error(), "no authorization code")
|
||||
}
|
||||
|
||||
func TestCallbackHandlerOAuthError(t *testing.T) {
|
||||
_, res := serveCallback(t, "state123", "error=access_denied&error_description=user+said+no")
|
||||
|
||||
require.Error(t, res.err)
|
||||
assert.Contains(t, res.err.Error(), "access_denied")
|
||||
assert.Contains(t, res.err.Error(), "user said no")
|
||||
}
|
||||
|
||||
func TestCallbackHandlerEscapesError(t *testing.T) {
|
||||
rec, _ := serveCallback(t, "state123", "error=evil&error_description=%3Cscript%3Ealert(1)%3C%2Fscript%3E")
|
||||
|
||||
body := rec.Body.String()
|
||||
assert.NotContains(t, body, "<script>", "error message must be HTML-escaped")
|
||||
assert.Contains(t, body, "<script>")
|
||||
}
|
||||
|
||||
func TestListenCallbackRandomPortIsLoopback(t *testing.T) {
|
||||
listener, err := listenCallback(0, false)
|
||||
require.NoError(t, err)
|
||||
defer listener.Close()
|
||||
|
||||
addr, ok := listener.Addr().(*net.TCPAddr)
|
||||
require.True(t, ok)
|
||||
assert.True(t, addr.IP.IsLoopback(), "default bind must be loopback only, got %s", addr.IP)
|
||||
assert.NotZero(t, addr.Port)
|
||||
}
|
||||
|
||||
func TestListenCallbackBindAllForContainer(t *testing.T) {
|
||||
listener, err := listenCallback(0, true)
|
||||
require.NoError(t, err)
|
||||
defer listener.Close()
|
||||
|
||||
addr, ok := listener.Addr().(*net.TCPAddr)
|
||||
require.True(t, ok)
|
||||
assert.True(t, addr.IP.IsUnspecified(), "bindAll must bind all interfaces, got %s", addr.IP)
|
||||
}
|
||||
Reference in New Issue
Block a user