mirror of
https://github.com/lightninglabs/aperture.git
synced 2025-12-18 17:44:20 +01:00
proxy+auth: fix post request
This commit is contained in:
@@ -83,8 +83,8 @@ const (
|
|||||||
// complete.
|
// complete.
|
||||||
//
|
//
|
||||||
// NOTE: This is part of the Authenticator interface.
|
// NOTE: This is part of the Authenticator interface.
|
||||||
func (l *L402Authenticator) FreshChallengeHeader(r *http.Request,
|
func (l *L402Authenticator) FreshChallengeHeader(serviceName string,
|
||||||
serviceName string, servicePrice int64) (http.Header, error) {
|
servicePrice int64) (http.Header, error) {
|
||||||
|
|
||||||
service := l402.Service{
|
service := l402.Service{
|
||||||
Name: serviceName,
|
Name: serviceName,
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ type Authenticator interface {
|
|||||||
|
|
||||||
// FreshChallengeHeader returns a header containing a challenge for the
|
// FreshChallengeHeader returns a header containing a challenge for the
|
||||||
// user to complete.
|
// user to complete.
|
||||||
FreshChallengeHeader(*http.Request, string, int64) (http.Header, error)
|
FreshChallengeHeader(string, int64) (http.Header, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Minter is an entity that is able to mint and verify L402s for a set of
|
// Minter is an entity that is able to mint and verify L402s for a set of
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ func (a MockAuthenticator) Accept(header *http.Header, _ string) bool {
|
|||||||
|
|
||||||
// FreshChallengeHeader returns a header containing a challenge for the user to
|
// FreshChallengeHeader returns a header containing a challenge for the user to
|
||||||
// complete.
|
// complete.
|
||||||
func (a MockAuthenticator) FreshChallengeHeader(r *http.Request,
|
func (a MockAuthenticator) FreshChallengeHeader(string, int64) (http.Header,
|
||||||
_ string, _ int64) (http.Header, error) {
|
error) {
|
||||||
|
|
||||||
header := http.Header{
|
header := http.Header{
|
||||||
"Content-Type": []string{"application/grpc"},
|
"Content-Type": []string{"application/grpc"},
|
||||||
|
|||||||
@@ -399,7 +399,7 @@ func (p *Proxy) handlePaymentRequired(w http.ResponseWriter, r *http.Request,
|
|||||||
serviceName string, servicePrice int64) {
|
serviceName string, servicePrice int64) {
|
||||||
|
|
||||||
header, err := p.authenticator.FreshChallengeHeader(
|
header, err := p.authenticator.FreshChallengeHeader(
|
||||||
r, serviceName, servicePrice,
|
serviceName, servicePrice,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Error creating new challenge header: %v", err)
|
log.Errorf("Error creating new challenge header: %v", err)
|
||||||
|
|||||||
@@ -101,15 +101,19 @@ func TestProxyHTTP(t *testing.T) {
|
|||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
tc := tc
|
tc := tc
|
||||||
|
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name+" GET", func(t *testing.T) {
|
||||||
runHTTPTest(t, tc)
|
runHTTPTest(t, tc, "GET")
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run(tc.name+" POST", func(t *testing.T) {
|
||||||
|
runHTTPTest(t, tc, "POST")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestProxyHTTP tests that the proxy can forward HTTP requests to a backend
|
// TestProxyHTTP tests that the proxy can forward HTTP requests to a backend
|
||||||
// service and handle L402 authentication correctly.
|
// service and handle L402 authentication correctly.
|
||||||
func runHTTPTest(t *testing.T, tc *testCase) {
|
func runHTTPTest(t *testing.T, tc *testCase, method string) {
|
||||||
// Create a list of services to proxy between.
|
// Create a list of services to proxy between.
|
||||||
services := []*proxy.Service{{
|
services := []*proxy.Service{{
|
||||||
Address: testTargetServiceAddress,
|
Address: testTargetServiceAddress,
|
||||||
@@ -148,11 +152,25 @@ func runHTTPTest(t *testing.T, tc *testCase) {
|
|||||||
// Authorization header set.
|
// Authorization header set.
|
||||||
client := &http.Client{}
|
client := &http.Client{}
|
||||||
url := fmt.Sprintf("http://%s/http/test", testProxyAddr)
|
url := fmt.Sprintf("http://%s/http/test", testProxyAddr)
|
||||||
resp, err := client.Get(url)
|
|
||||||
|
req, err := http.NewRequest(method, url, nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
if method == "POST" {
|
||||||
|
req.Header.Add("Content-Type", "application/json")
|
||||||
|
req.Body = io.NopCloser(strings.NewReader(`{}`))
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := client.Do(req)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
require.Equal(t, "402 Payment Required", resp.Status)
|
require.Equal(t, "402 Payment Required", resp.Status)
|
||||||
|
|
||||||
|
bodyContent, err := io.ReadAll(resp.Body)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, "payment required\n", string(bodyContent))
|
||||||
|
require.EqualValues(t, len(bodyContent), resp.ContentLength)
|
||||||
|
|
||||||
authHeader := resp.Header.Get("Www-Authenticate")
|
authHeader := resp.Header.Get("Www-Authenticate")
|
||||||
require.Regexp(t, "(LSAT|L402)", authHeader)
|
require.Regexp(t, "(LSAT|L402)", authHeader)
|
||||||
_ = resp.Body.Close()
|
_ = resp.Body.Close()
|
||||||
@@ -161,7 +179,7 @@ func runHTTPTest(t *testing.T, tc *testCase) {
|
|||||||
// get the 402 response.
|
// get the 402 response.
|
||||||
if len(tc.authWhitelist) > 0 {
|
if len(tc.authWhitelist) > 0 {
|
||||||
url = fmt.Sprintf("http://%s/http/white", testProxyAddr)
|
url = fmt.Sprintf("http://%s/http/white", testProxyAddr)
|
||||||
req, err := http.NewRequest("GET", url, nil)
|
req, err := http.NewRequest(method, url, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
resp, err = client.Do(req)
|
resp, err = client.Do(req)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -174,11 +192,12 @@ func runHTTPTest(t *testing.T, tc *testCase) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
require.Equal(t, testHTTPResponseBody, string(bodyBytes))
|
require.Equal(t, testHTTPResponseBody, string(bodyBytes))
|
||||||
|
require.EqualValues(t, len(bodyBytes), resp.ContentLength)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure that if the Auth header is set, the client's request is
|
// Make sure that if the Auth header is set, the client's request is
|
||||||
// proxied to the backend service.
|
// proxied to the backend service.
|
||||||
req, err := http.NewRequest("GET", url, nil)
|
req, err = http.NewRequest(method, url, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
req.Header.Add("Authorization", "foobar")
|
req.Header.Add("Authorization", "foobar")
|
||||||
|
|
||||||
@@ -193,6 +212,7 @@ func runHTTPTest(t *testing.T, tc *testCase) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
require.Equal(t, testHTTPResponseBody, string(bodyBytes))
|
require.Equal(t, testHTTPResponseBody, string(bodyBytes))
|
||||||
|
require.EqualValues(t, len(bodyBytes), resp.ContentLength)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestProxyHTTP tests that the proxy can forward gRPC requests to a backend
|
// TestProxyHTTP tests that the proxy can forward gRPC requests to a backend
|
||||||
@@ -313,9 +333,7 @@ func runGRPCTest(t *testing.T, tc *testCase) {
|
|||||||
|
|
||||||
// We expect the WWW-Authenticate header field to be set to an L402
|
// We expect the WWW-Authenticate header field to be set to an L402
|
||||||
// auth response.
|
// auth response.
|
||||||
expectedHeaderContent, _ := mockAuth.FreshChallengeHeader(&http.Request{
|
expectedHeaderContent, _ := mockAuth.FreshChallengeHeader("", 0)
|
||||||
Header: map[string][]string{},
|
|
||||||
}, "", 0)
|
|
||||||
capturedHeader := captureMetadata.Get("WWW-Authenticate")
|
capturedHeader := captureMetadata.Get("WWW-Authenticate")
|
||||||
require.Len(t, capturedHeader, 2)
|
require.Len(t, capturedHeader, 2)
|
||||||
require.Equal(
|
require.Equal(
|
||||||
|
|||||||
Reference in New Issue
Block a user