Skip to content

Commit a35ace7

Browse files
authored
Merge pull request #9739 from ellemouton/rpcInterceptorMD
lnrpc+rpcperms: add ctx metadata pairs to RPCMiddlewareRequest
2 parents 1aad61c + 0417877 commit a35ace7

File tree

6 files changed

+958
-781
lines changed

6 files changed

+958
-781
lines changed

docs/release-notes/release-notes-0.19.0.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,10 @@ close transaction.
307307

308308
* [Allow custom lock ID and
309309
duration in FundPsbt](https://github.com/lightningnetwork/lnd/pull/9724) RPC.
310+
311+
* Expand the [lnrpc.RPCMiddlewareRequest](https://github.com/lightningnetwork/lnd/pull/9739)
312+
to include any [gRPC metadata](https://grpc.io/docs/guides/metadata) pairs
313+
that are passed to the initial request via the `context.Context`.
310314

311315
## lncli Updates
312316

itest/lnd_rpc_middleware_interceptor_test.go

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"github.com/lightningnetwork/lnd/macaroons"
1414
"github.com/lightningnetwork/lnd/zpay32"
1515
"github.com/stretchr/testify/require"
16+
"google.golang.org/grpc/metadata"
1617
"google.golang.org/protobuf/proto"
1718
"gopkg.in/macaroon.v2"
1819
)
@@ -223,6 +224,18 @@ func middlewareInterceptionTest(t *testing.T,
223224
ctxc, cancel := context.WithTimeout(ctxb, defaultTimeout)
224225
defer cancel()
225226

227+
// Add some gRPC metadata pairs to the context that we use for one of
228+
// the calls. This is so that we can test that the interceptor does
229+
// properly receive the pairs via the interceptor request.
230+
requestMetadata := metadata.MD{
231+
"itest-metadata-key": []string{"itest-metadata-value"},
232+
"itest-metadata-key2": []string{
233+
"itest-metadata-value1",
234+
"itest-metadata-value2",
235+
},
236+
}
237+
ctxm := metadata.NewOutgoingContext(ctxc, requestMetadata)
238+
226239
// Create a client connection that we'll use to simulate user requests
227240
// to lnd with.
228241
cleanup, client := macaroonClient(t, node, userMac)
@@ -234,10 +247,11 @@ func middlewareInterceptionTest(t *testing.T,
234247
req := &lnrpc.ListChannelsRequest{ActiveOnly: true}
235248
go registration.interceptUnary(
236249
"/lnrpc.Lightning/ListChannels", req, nil, readOnly, false,
250+
requestMetadata,
237251
)
238252

239253
// Do the actual call now and wait for the interceptor to do its thing.
240-
resp, err := client.ListChannels(ctxc, req)
254+
resp, err := client.ListChannels(ctxm, req)
241255
require.NoError(t, err)
242256

243257
// Did we receive the correct intercept message?
@@ -252,7 +266,7 @@ func middlewareInterceptionTest(t *testing.T,
252266
}
253267
go registration.interceptUnary(
254268
"/lnrpc.Lightning/ListChannels", invalidReq, nil, readOnly,
255-
false,
269+
false, nil,
256270
)
257271

258272
// Do the actual call now and wait for the interceptor to do its thing.
@@ -384,7 +398,7 @@ func middlewareResponseManipulationTest(t *testing.T,
384398
req := &lnrpc.ListChannelsRequest{ActiveOnly: true}
385399
go registration.interceptUnary(
386400
"/lnrpc.Lightning/ListChannels", req, replacementResponse,
387-
readOnly, false,
401+
readOnly, false, nil,
388402
)
389403

390404
// Do the actual call now and wait for the interceptor to do its thing.
@@ -408,7 +422,7 @@ func middlewareResponseManipulationTest(t *testing.T,
408422
}
409423
go registration.interceptUnary(
410424
"/lnrpc.Lightning/ListChannels", invalidReq, betterError,
411-
readOnly, false,
425+
readOnly, false, nil,
412426
)
413427

414428
// Do the actual call now and wait for the interceptor to do its thing.
@@ -500,7 +514,7 @@ func middlewareRequestManipulationTest(t *testing.T, node *node.HarnessNode,
500514
}
501515
go registration.interceptUnary(
502516
"/lnrpc.Lightning/AddInvoice", req, replacementRequest,
503-
readOnly, true,
517+
readOnly, true, nil,
504518
)
505519

506520
// Do the actual call now and wait for the interceptor to do its thing.
@@ -717,12 +731,28 @@ func registerMiddleware(t *testing.T, node *node.HarnessNode,
717731
// read from the response channel.
718732
func (h *middlewareHarness) interceptUnary(methodURI string,
719733
expectedRequest proto.Message, responseReplacement interface{},
720-
readOnly bool, replaceRequest bool) {
734+
readOnly bool, replaceRequest bool, expectedMetadata metadata.MD) {
721735

722736
// Read intercept message and make sure it's for an RPC request.
723737
reqIntercept, err := h.stream.Recv()
724738
require.NoError(h.t, err)
725739

740+
// Check that we have the expected metadata in the request.
741+
if len(expectedMetadata) > 0 {
742+
require.GreaterOrEqual(
743+
h.t, len(reqIntercept.MetadataPairs),
744+
len(expectedMetadata),
745+
)
746+
747+
for key := range expectedMetadata {
748+
require.Contains(h.t, reqIntercept.MetadataPairs, key)
749+
require.Equal(
750+
h.t, expectedMetadata[key],
751+
reqIntercept.MetadataPairs[key].Values,
752+
)
753+
}
754+
}
755+
726756
// Make sure the custom condition is populated correctly (if we're using
727757
// a macaroon with a custom condition).
728758
if !readOnly {

0 commit comments

Comments
 (0)