Skip to content

Commit dac2080

Browse files
committed
itest: add test for Status server endpoint
1 parent 4688947 commit dac2080

2 files changed

Lines changed: 135 additions & 24 deletions

File tree

itest/litd_mode_integrated_test.go

Lines changed: 122 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,9 @@ var (
138138
loopMacaroonFn = func(cfg *LitNodeConfig) string {
139139
return cfg.LoopMacPath
140140
}
141+
emptyMacaroonFn = func(_ *LitNodeConfig) string {
142+
return ""
143+
}
141144
poolRequestFn = func(ctx context.Context,
142145
c grpc.ClientConnInterface) (proto.Message, error) {
143146

@@ -182,6 +185,14 @@ var (
182185
litConn := litrpc.NewProxyClient(c)
183186
return litConn.GetInfo(ctx, &litrpc.GetInfoRequest{})
184187
}
188+
statusRequestFn = func(ctx context.Context,
189+
c grpc.ClientConnInterface) (proto.Message, error) {
190+
191+
litConn := litrpc.NewStatusClient(c)
192+
return litConn.SubServerStatus(
193+
ctx, &litrpc.SubServerStatusReq{},
194+
)
195+
}
185196
litMacaroonFn = func(cfg *LitNodeConfig) string {
186197
return cfg.LitMacPath
187198
}
@@ -201,6 +212,9 @@ var (
201212
// Lit's grpc server and so will never be accessible via the
202213
// LND port.
203214
litOnly bool
215+
216+
// noAuth is true if the call does not require a macaroon.
217+
noAuth bool
204218
}{{
205219
name: "lnrpc",
206220
macaroonFn: lndMacaroonFn,
@@ -298,6 +312,16 @@ var (
298312
grpcWebURI: "/litrpc.Proxy/GetInfo",
299313
restWebURI: "/v1/proxy/info",
300314
litOnly: true,
315+
}, {
316+
name: "litrpc-status",
317+
macaroonFn: emptyMacaroonFn,
318+
requestFn: statusRequestFn,
319+
successPattern: "\"sub_servers\":",
320+
allowedThroughLNC: true,
321+
grpcWebURI: "/litrpc.Status/SubServerStatus",
322+
restWebURI: "/v1/status",
323+
noAuth: true,
324+
litOnly: true,
301325
}}
302326

303327
// customURIs is a map of endpoint URIs that we want to allow via a
@@ -420,6 +444,7 @@ func integratedTestSuite(ctx context.Context, net *NetworkHarness, t *testing.T,
420444
runGRPCAuthTest(
421445
ttt, cfg.RPCAddr(), cfg.TLSCertPath,
422446
endpoint.macaroonFn(cfg),
447+
endpoint.noAuth,
423448
endpoint.requestFn,
424449
endpoint.successPattern,
425450
endpointDisabled || endpoint.litOnly,
@@ -431,6 +456,7 @@ func integratedTestSuite(ctx context.Context, net *NetworkHarness, t *testing.T,
431456
runGRPCAuthTest(
432457
ttt, cfg.LitAddr(), cfg.LitTLSCertPath,
433458
endpoint.macaroonFn(cfg),
459+
endpoint.noAuth,
434460
endpoint.requestFn,
435461
endpoint.successPattern,
436462
endpointDisabled,
@@ -452,7 +478,8 @@ func integratedTestSuite(ctx context.Context, net *NetworkHarness, t *testing.T,
452478
runUIPasswordCheck(
453479
ttt, cfg.RPCAddr(), cfg.TLSCertPath,
454480
cfg.UIPassword, endpoint.requestFn,
455-
true, endpoint.successPattern,
481+
endpoint.noAuth, true,
482+
endpoint.successPattern,
456483
endpointDisabled || endpoint.litOnly,
457484
"Unimplemented desc = unknown service",
458485
)
@@ -467,6 +494,7 @@ func integratedTestSuite(ctx context.Context, net *NetworkHarness, t *testing.T,
467494
runUIPasswordCheck(
468495
ttt, cfg.LitAddr(), cfg.LitTLSCertPath,
469496
cfg.UIPassword, endpoint.requestFn,
497+
endpoint.noAuth,
470498
shouldFailWithoutMacaroon,
471499
endpoint.successPattern,
472500
endpointDisabled,
@@ -496,6 +524,7 @@ func integratedTestSuite(ctx context.Context, net *NetworkHarness, t *testing.T,
496524
endpoint.grpcWebURI,
497525
withoutUIPassword, endpointDisabled,
498526
"unknown gRPC web request",
527+
endpoint.noAuth,
499528
)
500529
})
501530
}
@@ -519,7 +548,7 @@ func integratedTestSuite(ctx context.Context, net *NetworkHarness, t *testing.T,
519548
tt.Run(endpoint.name+" lnd port", func(ttt *testing.T) {
520549
runGRPCAuthTest(
521550
ttt, cfg.RPCAddr(), cfg.TLSCertPath,
522-
superMacFile,
551+
superMacFile, endpoint.noAuth,
523552
endpoint.requestFn,
524553
endpoint.successPattern,
525554
endpointDisabled || endpoint.litOnly,
@@ -530,7 +559,7 @@ func integratedTestSuite(ctx context.Context, net *NetworkHarness, t *testing.T,
530559
tt.Run(endpoint.name+" lit port", func(ttt *testing.T) {
531560
runGRPCAuthTest(
532561
ttt, cfg.LitAddr(), cfg.LitTLSCertPath,
533-
superMacFile,
562+
superMacFile, endpoint.noAuth,
534563
endpoint.requestFn,
535564
endpoint.successPattern,
536565
endpointDisabled,
@@ -556,6 +585,7 @@ func integratedTestSuite(ctx context.Context, net *NetworkHarness, t *testing.T,
556585
endpoint.successPattern,
557586
endpoint.restPOST,
558587
withoutUIPassword, endpointDisabled,
588+
endpoint.noAuth,
559589
)
560590
})
561591
}
@@ -587,6 +617,7 @@ func integratedTestSuite(ctx context.Context, net *NetworkHarness, t *testing.T,
587617
endpoint.allowedThroughLNC,
588618
"unknown service",
589619
endpointDisabled,
620+
endpoint.noAuth,
590621
)
591622
})
592623
}
@@ -646,13 +677,20 @@ func integratedTestSuite(ctx context.Context, net *NetworkHarness, t *testing.T,
646677
endpointDisabled := subServersDisabled &&
647678
endpoint.canDisable
648679

680+
expectedErr := "permission denied"
681+
if endpoint.noAuth {
682+
expectedErr = "unknown service"
683+
}
684+
649685
tt.Run(endpoint.name+" lit port", func(ttt *testing.T) {
650686
allowed := customURIs[endpoint.grpcWebURI]
687+
651688
runLNCAuthTest(
652689
ttt, rawLNCConn, endpoint.requestFn,
653690
endpoint.successPattern,
654-
allowed, "permission denied",
691+
allowed, expectedErr,
655692
endpointDisabled,
693+
endpoint.noAuth,
656694
)
657695
})
658696
}
@@ -717,7 +755,7 @@ func runCertificateCheck(t *testing.T, node *HarnessNode) {
717755

718756
// runGRPCAuthTest tests authentication of the given gRPC interface.
719757
func runGRPCAuthTest(t *testing.T, hostPort, tlsCertPath, macPath string,
720-
makeRequest requestFn, successContent string, disabled bool,
758+
noMac bool, makeRequest requestFn, successContent string, disabled bool,
721759
disabledErr string) {
722760

723761
ctxb := context.Background()
@@ -728,6 +766,21 @@ func runGRPCAuthTest(t *testing.T, hostPort, tlsCertPath, macPath string,
728766
require.NoError(t, err)
729767
defer rawConn.Close()
730768

769+
if noMac {
770+
resp, err := makeRequest(ctxt, rawConn)
771+
if disabled {
772+
require.ErrorContains(t, err, disabledErr)
773+
return
774+
}
775+
require.NoError(t, err)
776+
777+
json, err := marshalOptions.Marshal(resp)
778+
require.NoError(t, err)
779+
require.Contains(t, string(json), successContent)
780+
781+
return
782+
}
783+
731784
// We have a connection without any macaroon. A call should fail.
732785
_, err = makeRequest(ctxt, rawConn)
733786
if disabled {
@@ -769,9 +822,9 @@ func runGRPCAuthTest(t *testing.T, hostPort, tlsCertPath, macPath string,
769822
resp, err := makeRequest(ctxm, rawConn)
770823
if disabled {
771824
require.ErrorContains(t, err, disabledErr)
772-
} else {
773-
require.NoError(t, err)
825+
return
774826
}
827+
require.NoError(t, err)
775828

776829
json, err := marshalOptions.Marshal(resp)
777830
require.NoError(t, err)
@@ -780,7 +833,7 @@ func runGRPCAuthTest(t *testing.T, hostPort, tlsCertPath, macPath string,
780833

781834
// runUIPasswordCheck tests UI password authentication.
782835
func runUIPasswordCheck(t *testing.T, hostPort, tlsCertPath, uiPassword string,
783-
makeRequest requestFn, shouldFailWithoutMacaroon bool,
836+
makeRequest requestFn, noAuth, shouldFailWithoutMacaroon bool,
784837
successContent string, disabled bool, disabledErr string) {
785838

786839
ctxb := context.Background()
@@ -791,11 +844,23 @@ func runUIPasswordCheck(t *testing.T, hostPort, tlsCertPath, uiPassword string,
791844
require.NoError(t, err)
792845
defer rawConn.Close()
793846

794-
// Make sure that a call without any metadata results in an error.
795-
_, err = makeRequest(ctxt, rawConn)
796-
if disabled {
847+
// Make sure that a call without any metadata results in an error unless
848+
// this is a call that is allowed to be un-authenticated in which case
849+
// we expect it to succeed.
850+
resp, err := makeRequest(ctxt, rawConn)
851+
switch {
852+
case disabled:
797853
require.ErrorContains(t, err, disabledErr)
798-
} else {
854+
case noAuth:
855+
require.NoError(t, err)
856+
857+
json, err := marshalOptions.Marshal(resp)
858+
require.NoError(t, err)
859+
require.Contains(t, string(json), successContent)
860+
861+
return
862+
863+
default:
799864
require.ErrorContains(t, err, "expected 1 macaroon, got 0")
800865
}
801866

@@ -834,7 +899,7 @@ func runUIPasswordCheck(t *testing.T, hostPort, tlsCertPath, uiPassword string,
834899
// Using the correct UI password should work for all requests unless the
835900
// request is for a disabled sub-server.
836901
ctxm = uiPasswordContext(ctxt, uiPassword, false)
837-
resp, err := makeRequest(ctxm, rawConn)
902+
resp, err = makeRequest(ctxm, rawConn)
838903

839904
// On lnd's gRPC interface we don't support using the UI password.
840905
if shouldFailWithoutMacaroon {
@@ -906,7 +971,8 @@ func runIndexPageCheck(t *testing.T, hostPort string, uiDisabled bool) {
906971

907972
// runGRPCWebAuthTest tests authentication of the given gRPC interface.
908973
func runGRPCWebAuthTest(t *testing.T, hostPort, uiPassword, grpcWebURI string,
909-
shouldFailWithUIPassword, disabled bool, disableErr string) {
974+
shouldFailWithUIPassword, disabled bool, disableErr string,
975+
noAuth bool) {
910976

911977
basicAuth := base64.StdEncoding.EncodeToString(
912978
[]byte(fmt.Sprintf("%s:%s", uiPassword, uiPassword)),
@@ -919,15 +985,27 @@ func runGRPCWebAuthTest(t *testing.T, hostPort, uiPassword, grpcWebURI string,
919985

920986
url := fmt.Sprintf("https://%s%s", hostPort, grpcWebURI)
921987

922-
// First test a grpc-web call without authorization, which should fail.
923-
_, responseHeader, err := postURL(url, emptyGrpcWebRequest, header)
988+
// First test a grpc-web call without authorization, which should fail
989+
// unless this call does not require authentication.
990+
body, responseHeader, err := postURL(url, emptyGrpcWebRequest, header)
924991
require.NoError(t, err)
925992

926-
if disabled {
993+
switch {
994+
case disabled:
927995
require.Contains(
928996
t, responseHeader.Get("grpc-message"), disableErr,
929997
)
930-
} else {
998+
999+
case noAuth:
1000+
require.Empty(t, responseHeader.Get("grpc-message"))
1001+
require.Empty(t, responseHeader.Get("grpc-status"))
1002+
1003+
// We get the status encoded as trailer in the response.
1004+
require.Contains(t, body, "grpc-status: 0")
1005+
1006+
return
1007+
1008+
default:
9311009
require.Equal(
9321010
t, "expected 1 macaroon, got 0",
9331011
responseHeader.Get("grpc-message"),
@@ -941,7 +1019,7 @@ func runGRPCWebAuthTest(t *testing.T, hostPort, uiPassword, grpcWebURI string,
9411019

9421020
// Now add the basic auth and try again.
9431021
header["authorization"] = []string{fmt.Sprintf("Basic %s", basicAuth)}
944-
body, responseHeader, err := postURL(url, emptyGrpcWebRequest, header)
1022+
body, responseHeader, err = postURL(url, emptyGrpcWebRequest, header)
9451023
require.NoError(t, err)
9461024

9471025
if shouldFailWithUIPassword {
@@ -976,7 +1054,7 @@ func runGRPCWebAuthTest(t *testing.T, hostPort, uiPassword, grpcWebURI string,
9761054
// runRESTAuthTest tests authentication of the given REST interface.
9771055
func runRESTAuthTest(t *testing.T, hostPort, uiPassword, macaroonPath, restURI,
9781056
successPattern string, usePOST, shouldFailWithUIPassword,
979-
disabled bool) {
1057+
disabled, noMac bool) {
9801058

9811059
basicAuth := base64.StdEncoding.EncodeToString(
9821060
[]byte(fmt.Sprintf("%s:%s", uiPassword, uiPassword)),
@@ -991,7 +1069,9 @@ func runRESTAuthTest(t *testing.T, hostPort, uiPassword, macaroonPath, restURI,
9911069
method = "POST"
9921070
}
9931071

994-
// First test a REST call without authorization, which should fail.
1072+
// First test a REST call without authorization, which should fail
1073+
// unless this is a call for an endpoint that does not require
1074+
// authorization.
9951075
body, responseHeader, err := callURL(url, method, nil, nil, false)
9961076
require.NoError(t, err)
9971077

@@ -1000,6 +1080,11 @@ func runRESTAuthTest(t *testing.T, hostPort, uiPassword, macaroonPath, restURI,
10001080
responseHeader.Get("content-type"),
10011081
)
10021082

1083+
if noMac {
1084+
require.Contains(t, body, successPattern)
1085+
return
1086+
}
1087+
10031088
if disabled {
10041089
require.Empty(
10051090
t, responseHeader.Get("grpc-metadata-content-type"),
@@ -1029,7 +1114,6 @@ func runRESTAuthTest(t *testing.T, hostPort, uiPassword, macaroonPath, restURI,
10291114

10301115
default:
10311116
require.Contains(t, body, successPattern)
1032-
10331117
}
10341118

10351119
// And finally, try with the given macaroon.
@@ -1057,7 +1141,7 @@ func runRESTAuthTest(t *testing.T, hostPort, uiPassword, macaroonPath, restURI,
10571141
// through Lightning Node Connect.
10581142
func runLNCAuthTest(t *testing.T, rawLNCConn grpc.ClientConnInterface,
10591143
makeRequest requestFn, successContent string, callAllowed bool,
1060-
expectErrContains string, disabled bool) {
1144+
expectErrContains string, disabled, noMac bool) {
10611145

10621146
ctxt, cancel := context.WithTimeout(
10631147
context.Background(), defaultTimeout,
@@ -1070,6 +1154,21 @@ func runLNCAuthTest(t *testing.T, rawLNCConn grpc.ClientConnInterface,
10701154
// macaroon permissions properly set up).
10711155
resp, err := makeRequest(ctxt, rawLNCConn)
10721156

1157+
if noMac {
1158+
if disabled {
1159+
require.ErrorContains(t, err, "unknown gRPC web "+
1160+
"request")
1161+
return
1162+
}
1163+
require.NoError(t, err)
1164+
1165+
json, err := marshalOptions.Marshal(resp)
1166+
require.NoError(t, err)
1167+
require.Contains(t, string(json), successContent)
1168+
1169+
return
1170+
}
1171+
10731172
// Is this a disallowed call?
10741173
if !callAllowed {
10751174
if disabled {

0 commit comments

Comments
 (0)