Skip to content

Commit 4a132f1

Browse files
committed
itest: run full auth suite with UI disabled
1 parent 15ccc09 commit 4a132f1

File tree

2 files changed

+151
-48
lines changed

2 files changed

+151
-48
lines changed

itest/litd_mode_integrated_test.go

Lines changed: 112 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ var (
243243
name: "litrpc-accounts",
244244
macaroonFn: litMacaroonFn,
245245
requestFn: litAccountRequestFn,
246-
successPattern: "\"accounts\":[]",
246+
successPattern: "\"accounts\":[",
247247
allowedThroughLNC: false,
248248
grpcWebURI: "/litrpc.Accounts/ListAccounts",
249249
}, {
@@ -270,25 +270,72 @@ var (
270270
}
271271
)
272272

273+
// testSuite defines the signature of a test suite. The boolean parameter
274+
// indicates if the UI password is set or disabled.
275+
type testSuite func(context.Context, *NetworkHarness, *testing.T, bool, int)
276+
277+
// testWithAndWithoutUIPassword runs the given test suite against the given node
278+
// both with the UI password set and without the UI password with the UI
279+
// disabled.
280+
func testWithAndWithoutUIPassword(ctx context.Context, net *NetworkHarness,
281+
t *testing.T, test testSuite, node *HarnessNode) {
282+
283+
t.Run("with UI password", func(t *testing.T) {
284+
test(ctx, net, t, false, 1)
285+
})
286+
287+
// Restart the node without the ui password and disable the UI.
288+
err := net.RestartNode(
289+
node, nil, []LitArgOption{
290+
WithoutLitArg("uipassword"),
291+
WithLitArg("disableui", ""),
292+
},
293+
)
294+
require.NoError(t, err)
295+
296+
if !node.Cfg.RemoteMode {
297+
// Reconnect Alice and Bob so that tests can continue to assert
298+
// that the nodes each have one peer at start up. This is only
299+
// required if the node is running in integrated mode since in
300+
// remote mode, the peers would never have disconnected.
301+
net.ConnectNodes(t, net.Alice, net.Bob)
302+
}
303+
304+
t.Run("without UI password", func(t *testing.T) {
305+
test(ctx, net, t, true, 2)
306+
})
307+
}
308+
273309
// testModeIntegrated makes sure that in integrated mode all daemons work
274-
// correctly.
310+
// correctly. It tests the full integrated mode test suite with the ui password
311+
// set and then again with no ui password and a disabled UI.
275312
func testModeIntegrated(ctx context.Context, net *NetworkHarness,
276313
t *harnessTest) {
277314

315+
testWithAndWithoutUIPassword(
316+
ctx, net, t.t, integratedTestSuite, net.Alice,
317+
)
318+
}
319+
320+
// integratedTestSuite makes sure that in integrated mode all daemons work
321+
// correctly.
322+
func integratedTestSuite(ctx context.Context, net *NetworkHarness, t *testing.T,
323+
withoutUIPassword bool, runNum int) {
324+
278325
// Some very basic functionality tests to make sure lnd is working fine
279326
// in integrated mode.
280-
net.SendCoins(t.t, btcutil.SatoshiPerBitcoin, net.Alice)
327+
net.SendCoins(t, btcutil.SatoshiPerBitcoin, net.Alice)
281328

282329
// We expect a non-empty alias (truncated node ID) to be returned.
283330
resp, err := net.Alice.GetInfo(ctx, &lnrpc.GetInfoRequest{})
284-
require.NoError(t.t, err)
285-
require.NotEmpty(t.t, resp.Alias)
286-
require.Contains(t.t, resp.Alias, "0")
331+
require.NoError(t, err)
332+
require.NotEmpty(t, resp.Alias)
333+
require.Contains(t, resp.Alias, "0")
287334

288-
t.t.Run("certificate check", func(tt *testing.T) {
335+
t.Run("certificate check", func(tt *testing.T) {
289336
runCertificateCheck(tt, net.Alice)
290337
})
291-
t.t.Run("gRPC macaroon auth check", func(tt *testing.T) {
338+
t.Run("gRPC macaroon auth check", func(tt *testing.T) {
292339
cfg := net.Alice.Cfg
293340

294341
for _, endpoint := range endpoints {
@@ -313,7 +360,7 @@ func testModeIntegrated(ctx context.Context, net *NetworkHarness,
313360
}
314361
})
315362

316-
t.t.Run("UI password auth check", func(tt *testing.T) {
363+
t.Run("UI password auth check", func(tt *testing.T) {
317364
cfg := net.Alice.Cfg
318365

319366
for _, endpoint := range endpoints {
@@ -327,20 +374,28 @@ func testModeIntegrated(ctx context.Context, net *NetworkHarness,
327374
})
328375

329376
tt.Run(endpoint.name+" lit port", func(ttt *testing.T) {
377+
shouldFailWithoutMacaroon := false
378+
if withoutUIPassword {
379+
shouldFailWithoutMacaroon = true
380+
}
381+
330382
runUIPasswordCheck(
331383
ttt, cfg.LitAddr(), cfg.LitTLSCertPath,
332384
cfg.UIPassword, endpoint.requestFn,
333-
false, endpoint.successPattern,
385+
shouldFailWithoutMacaroon,
386+
endpoint.successPattern,
334387
)
335388
})
336389
}
337390
})
338391

339-
t.t.Run("UI index page fallback", func(tt *testing.T) {
340-
runIndexPageCheck(tt, net.Alice.Cfg.LitAddr())
392+
t.Run("UI index page fallback", func(tt *testing.T) {
393+
runIndexPageCheck(
394+
tt, net.Alice.Cfg.LitAddr(), withoutUIPassword,
395+
)
341396
})
342397

343-
t.t.Run("grpc-web auth", func(tt *testing.T) {
398+
t.Run("grpc-web auth", func(tt *testing.T) {
344399
cfg := net.Alice.Cfg
345400

346401
for _, endpoint := range endpoints {
@@ -349,12 +404,13 @@ func testModeIntegrated(ctx context.Context, net *NetworkHarness,
349404
runGRPCWebAuthTest(
350405
ttt, cfg.LitAddr(), cfg.UIPassword,
351406
endpoint.grpcWebURI,
407+
withoutUIPassword,
352408
)
353409
})
354410
}
355411
})
356412

357-
t.t.Run("gRPC super macaroon auth check", func(tt *testing.T) {
413+
t.Run("gRPC super macaroon auth check", func(tt *testing.T) {
358414
cfg := net.Alice.Cfg
359415

360416
superMacFile, err := bakeSuperMacaroon(cfg, true)
@@ -386,7 +442,7 @@ func testModeIntegrated(ctx context.Context, net *NetworkHarness,
386442
}
387443
})
388444

389-
t.t.Run("REST auth", func(tt *testing.T) {
445+
t.Run("REST auth", func(tt *testing.T) {
390446
cfg := net.Alice.Cfg
391447

392448
for _, endpoint := range endpoints {
@@ -403,20 +459,21 @@ func testModeIntegrated(ctx context.Context, net *NetworkHarness,
403459
endpoint.restWebURI,
404460
endpoint.successPattern,
405461
endpoint.restPOST,
462+
withoutUIPassword,
406463
)
407464
})
408465
}
409466
})
410467

411-
t.t.Run("lnc auth", func(tt *testing.T) {
468+
t.Run("lnc auth", func(tt *testing.T) {
412469
cfg := net.Alice.Cfg
413470

414471
ctx := context.Background()
415472
ctxt, cancel := context.WithTimeout(ctx, defaultTimeout)
416473
defer cancel()
417474

418475
rawLNCConn := setUpLNCConn(
419-
ctxt, t.t, cfg.LitAddr(), cfg.LitTLSCertPath,
476+
ctxt, t, cfg.LitAddr(), cfg.LitTLSCertPath,
420477
cfg.LitMacPath,
421478
litrpc.SessionType_TYPE_MACAROON_READONLY, nil,
422479
)
@@ -435,7 +492,7 @@ func testModeIntegrated(ctx context.Context, net *NetworkHarness,
435492
}
436493
})
437494

438-
t.t.Run("gRPC super macaroon account system test", func(tt *testing.T) {
495+
t.Run("gRPC super macaroon account system test", func(tt *testing.T) {
439496
cfg := net.Alice.Cfg
440497

441498
superMacFile, err := bakeSuperMacaroon(cfg, false)
@@ -448,15 +505,15 @@ func testModeIntegrated(ctx context.Context, net *NetworkHarness,
448505
ht := newHarnessTest(tt, net)
449506
runAccountSystemTest(
450507
ht, net.Alice, cfg.LitAddr(), cfg.LitTLSCertPath,
451-
superMacFile, 1,
508+
superMacFile, (runNum*2)-1,
452509
)
453510
runAccountSystemTest(
454511
ht, net.Alice, cfg.LitAddr(), cfg.LitTLSCertPath,
455-
superMacFile, 2,
512+
superMacFile, runNum*2,
456513
)
457514
})
458515

459-
t.t.Run("lnc auth custom mac perms", func(tt *testing.T) {
516+
t.Run("lnc auth custom mac perms", func(tt *testing.T) {
460517
cfg := net.Alice.Cfg
461518

462519
ctx := context.Background()
@@ -478,7 +535,7 @@ func testModeIntegrated(ctx context.Context, net *NetworkHarness,
478535
}
479536

480537
rawLNCConn := setUpLNCConn(
481-
ctxt, t.t, cfg.LitAddr(), cfg.LitTLSCertPath,
538+
ctxt, t, cfg.LitAddr(), cfg.LitTLSCertPath,
482539
cfg.LitMacPath,
483540
litrpc.SessionType_TYPE_MACAROON_CUSTOM, customPerms,
484541
)
@@ -665,21 +722,28 @@ func runUIPasswordCheck(t *testing.T, hostPort, tlsCertPath, uiPassword string,
665722
}
666723

667724
// runIndexPageCheck makes sure the index page is returned correctly.
668-
func runIndexPageCheck(t *testing.T, hostPort string) {
725+
func runIndexPageCheck(t *testing.T, hostPort string, uiDisabled bool) {
726+
expect := indexHtmlMarker
727+
if uiDisabled {
728+
expect = ""
729+
}
730+
669731
body, err := getURL(fmt.Sprintf("https://%s/index.html", hostPort))
670732
require.NoError(t, err)
671-
require.Contains(t, body, indexHtmlMarker)
733+
require.Contains(t, body, expect)
672734

673735
// The UI implements "virtual" pages by using the browser history API.
674736
// Any URL that looks like a directory should fall back to the main
675737
// index.html file as well.
676738
body, err = getURL(fmt.Sprintf("https://%s/loop", hostPort))
677739
require.NoError(t, err)
678-
require.Contains(t, body, indexHtmlMarker)
740+
require.Contains(t, body, expect)
679741
}
680742

681743
// runGRPCWebAuthTest tests authentication of the given gRPC interface.
682-
func runGRPCWebAuthTest(t *testing.T, hostPort, uiPassword, grpcWebURI string) {
744+
func runGRPCWebAuthTest(t *testing.T, hostPort, uiPassword, grpcWebURI string,
745+
shouldFailWithUIPassword bool) {
746+
683747
basicAuth := base64.StdEncoding.EncodeToString(
684748
[]byte(fmt.Sprintf("%s:%s", uiPassword, uiPassword)),
685749
)
@@ -709,6 +773,18 @@ func runGRPCWebAuthTest(t *testing.T, hostPort, uiPassword, grpcWebURI string) {
709773
body, responseHeader, err := postURL(url, emptyGrpcWebRequest, header)
710774
require.NoError(t, err)
711775

776+
if shouldFailWithUIPassword {
777+
require.Equal(
778+
t, "expected 1 macaroon, got 0",
779+
responseHeader.Get("grpc-message"),
780+
)
781+
require.Equal(
782+
t, fmt.Sprintf("%d", codes.Unknown),
783+
responseHeader.Get("grpc-status"),
784+
)
785+
return
786+
}
787+
712788
require.Empty(t, responseHeader.Get("grpc-message"))
713789
require.Empty(t, responseHeader.Get("grpc-status"))
714790

@@ -718,7 +794,7 @@ func runGRPCWebAuthTest(t *testing.T, hostPort, uiPassword, grpcWebURI string) {
718794

719795
// runRESTAuthTest tests authentication of the given REST interface.
720796
func runRESTAuthTest(t *testing.T, hostPort, uiPassword, macaroonPath, restURI,
721-
successPattern string, usePOST bool) {
797+
successPattern string, usePOST, shouldFailWithUIPassword bool) {
722798

723799
basicAuth := base64.StdEncoding.EncodeToString(
724800
[]byte(fmt.Sprintf("%s:%s", uiPassword, uiPassword)),
@@ -756,7 +832,15 @@ func runRESTAuthTest(t *testing.T, hostPort, uiPassword, macaroonPath, restURI,
756832
url, method, nil, basicAuthHeader, false,
757833
)
758834
require.NoError(t, err)
759-
require.Contains(t, body, successPattern)
835+
836+
if shouldFailWithUIPassword {
837+
require.Contains(
838+
t, body,
839+
"expected 1 macaroon, got 0",
840+
)
841+
} else {
842+
require.Contains(t, body, successPattern)
843+
}
760844

761845
// And finally, try with the given macaroon.
762846
macBytes, err := ioutil.ReadFile(macaroonPath)

0 commit comments

Comments
 (0)