@@ -138,6 +138,7 @@ var (
138
138
supportsUIPasswordOnLndPort bool
139
139
supportsUIPasswordOnLitPort bool
140
140
grpcWebURI string
141
+ restWebURI string
141
142
}{{
142
143
name : "lnrpc" ,
143
144
macaroonFn : lndMacaroonFn ,
@@ -148,6 +149,7 @@ var (
148
149
supportsUIPasswordOnLndPort : false ,
149
150
supportsUIPasswordOnLitPort : true ,
150
151
grpcWebURI : "/lnrpc.Lightning/GetInfo" ,
152
+ restWebURI : "/v1/getinfo" ,
151
153
}, {
152
154
name : "frdrpc" ,
153
155
macaroonFn : faradayMacaroonFn ,
@@ -158,6 +160,7 @@ var (
158
160
supportsUIPasswordOnLndPort : false ,
159
161
supportsUIPasswordOnLitPort : true ,
160
162
grpcWebURI : "/frdrpc.FaradayServer/RevenueReport" ,
163
+ restWebURI : "/v1/faraday/revenue" ,
161
164
}, {
162
165
name : "looprpc" ,
163
166
macaroonFn : loopMacaroonFn ,
@@ -168,6 +171,7 @@ var (
168
171
supportsUIPasswordOnLndPort : false ,
169
172
supportsUIPasswordOnLitPort : true ,
170
173
grpcWebURI : "/looprpc.SwapClient/ListSwaps" ,
174
+ restWebURI : "/v1/loop/swaps" ,
171
175
}, {
172
176
name : "poolrpc" ,
173
177
macaroonFn : poolMacaroonFn ,
@@ -178,6 +182,7 @@ var (
178
182
supportsUIPasswordOnLndPort : false ,
179
183
supportsUIPasswordOnLitPort : true ,
180
184
grpcWebURI : "/poolrpc.Trader/GetInfo" ,
185
+ restWebURI : "/v1/pool/info" ,
181
186
}, {
182
187
name : "litrpc" ,
183
188
macaroonFn : nil ,
@@ -326,6 +331,27 @@ func testModeIntegrated(net *NetworkHarness, t *harnessTest) {
326
331
})
327
332
}
328
333
})
334
+
335
+ t .t .Run ("REST auth" , func (tt * testing.T ) {
336
+ cfg := net .Alice .Cfg
337
+
338
+ for _ , endpoint := range endpoints {
339
+ endpoint := endpoint
340
+
341
+ if endpoint .restWebURI == "" {
342
+ continue
343
+ }
344
+
345
+ tt .Run (endpoint .name + " lit port" , func (ttt * testing.T ) {
346
+ runRESTAuthTest (
347
+ ttt , cfg .LitAddr (), cfg .UIPassword ,
348
+ endpoint .macaroonFn (cfg ),
349
+ endpoint .restWebURI ,
350
+ endpoint .successPattern ,
351
+ )
352
+ })
353
+ }
354
+ })
329
355
}
330
356
331
357
// runCertificateCheck checks that the TLS certificates presented to clients are
@@ -513,6 +539,58 @@ func runGRPCWebAuthTest(t *testing.T, hostPort, uiPassword, grpcWebURI string) {
513
539
require .Contains (t , body , "grpc-status: 0" )
514
540
}
515
541
542
+ // runRESTAuthTest tests authentication of the given REST interface.
543
+ func runRESTAuthTest (t * testing.T , hostPort , uiPassword , macaroonPath , restURI ,
544
+ successPattern string ) {
545
+
546
+ basicAuth := base64 .StdEncoding .EncodeToString (
547
+ []byte (fmt .Sprintf ("%s:%s" , uiPassword , uiPassword )),
548
+ )
549
+ basicAuthHeader := http.Header {
550
+ "authorization" : []string {fmt .Sprintf ("Basic %s" , basicAuth )},
551
+ }
552
+ url := fmt .Sprintf ("https://%s%s" , hostPort , restURI )
553
+
554
+ // First test a REST call without authorization, which should fail.
555
+ body , responseHeader , err := callURL (url , "GET" , nil , nil , false )
556
+ require .NoError (t , err )
557
+
558
+ require .Equal (
559
+ t , "application/grpc" ,
560
+ responseHeader .Get ("grpc-metadata-content-type" ),
561
+ )
562
+ require .Equal (
563
+ t , "application/json" ,
564
+ responseHeader .Get ("content-type" ),
565
+ )
566
+ require .Contains (
567
+ t , body ,
568
+ "expected 1 macaroon, got 0" ,
569
+ )
570
+
571
+ // Now add the UI password which should make the request succeed.
572
+ body , responseHeader , err = callURL (
573
+ url , "GET" , nil , basicAuthHeader , false ,
574
+ )
575
+ require .NoError (t , err )
576
+ require .Contains (t , body , successPattern )
577
+
578
+ // And finally, try with the given macaroon.
579
+ macBytes , err := ioutil .ReadFile (macaroonPath )
580
+ require .NoError (t , err )
581
+
582
+ macaroonHeader := http.Header {
583
+ "grpc-metadata-macaroon" : []string {
584
+ hex .EncodeToString (macBytes ),
585
+ },
586
+ }
587
+ body , responseHeader , err = callURL (
588
+ url , "GET" , nil , macaroonHeader , false ,
589
+ )
590
+ require .NoError (t , err )
591
+ require .Contains (t , body , successPattern )
592
+ }
593
+
516
594
// getURL retrieves the body of a given URL, ignoring any TLS certificate the
517
595
// server might present.
518
596
func getURL (url string ) (string , error ) {
@@ -538,7 +616,15 @@ func getURL(url string) (string, error) {
538
616
func postURL (url string , postBody []byte , header http.Header ) (string ,
539
617
http.Header , error ) {
540
618
541
- req , err := http .NewRequest ("POST" , url , bytes .NewReader (postBody ))
619
+ return callURL (url , "POST" , postBody , header , true )
620
+ }
621
+
622
+ // callURL does a HTTP call to the given URL, ignoring any TLS certificate the
623
+ // server might present.
624
+ func callURL (url , method string , postBody []byte , header http.Header ,
625
+ expectOk bool ) (string , http.Header , error ) {
626
+
627
+ req , err := http .NewRequest (method , url , bytes .NewReader (postBody ))
542
628
if err != nil {
543
629
return "" , nil , err
544
630
}
@@ -552,7 +638,7 @@ func postURL(url string, postBody []byte, header http.Header) (string,
552
638
return "" , nil , err
553
639
}
554
640
555
- if resp .StatusCode != 200 {
641
+ if expectOk && resp .StatusCode != 200 {
556
642
return "" , nil , fmt .Errorf ("request failed, got status code " +
557
643
"%d (%s)" , resp .StatusCode , resp .Status )
558
644
}
0 commit comments