44 "fmt"
55 "strings"
66
7+ "github.com/lightninglabs/lightning-terminal/session"
78 "github.com/lightningnetwork/lnd/lnrpc"
9+ "google.golang.org/grpc/metadata"
810 "gopkg.in/macaroon.v2"
911)
1012
@@ -38,18 +40,27 @@ type RequestInfo struct {
3840 MetaInfo * InterceptMetaInfo
3941 Rules * InterceptRules
4042 WithPrivacy bool
43+ MDPairs metadata.MD
4144}
4245
4346// NewInfoFromRequest parses the given RPC middleware interception request and
4447// returns a RequestInfo struct.
4548func NewInfoFromRequest (req * lnrpc.RPCMiddlewareRequest ) (* RequestInfo , error ) {
49+ md := make (metadata.MD )
50+ for k , vs := range req .MetadataPairs {
51+ for _ , v := range vs .Values {
52+ md .Append (k , v )
53+ }
54+ }
55+
4656 var ri * RequestInfo
4757 switch t := req .InterceptType .(type ) {
4858 case * lnrpc.RPCMiddlewareRequest_StreamAuth :
4959 ri = & RequestInfo {
5060 MWRequestType : MWRequestTypeStreamAuth ,
5161 URI : t .StreamAuth .MethodFullUri ,
5262 Streaming : true ,
63+ MDPairs : md ,
5364 }
5465
5566 case * lnrpc.RPCMiddlewareRequest_Request :
@@ -60,6 +71,7 @@ func NewInfoFromRequest(req *lnrpc.RPCMiddlewareRequest) (*RequestInfo, error) {
6071 IsError : t .Request .IsError ,
6172 Serialized : t .Request .Serialized ,
6273 Streaming : t .Request .StreamRpc ,
74+ MDPairs : md ,
6375 }
6476
6577 case * lnrpc.RPCMiddlewareRequest_Response :
@@ -70,6 +82,7 @@ func NewInfoFromRequest(req *lnrpc.RPCMiddlewareRequest) (*RequestInfo, error) {
7082 IsError : t .Response .IsError ,
7183 Serialized : t .Response .Serialized ,
7284 Streaming : t .Response .StreamRpc ,
85+ MDPairs : md ,
7386 }
7487
7588 default :
@@ -134,3 +147,35 @@ func (ri *RequestInfo) String() string {
134147 ri .GRPCMessageType , ri .Streaming , strings .Join (ri .Caveats , "," ),
135148 ri .MetaInfo , ri .Rules )
136149}
150+
151+ func (ri * RequestInfo ) extractSessionID () (session.ID , bool , error ) {
152+ // First prize is to extract the session ID from the MD pairs.
153+ id , ok , err := session .FromGrpcMD (ri .MDPairs )
154+ if err != nil {
155+ return id , ok , err
156+ } else if ok {
157+ return id , ok , nil
158+ }
159+
160+ // TODO(elle): This is a temporary workaround to support older versions
161+ // of LND that don't attach metadata pairs to the request.
162+ // We should remove this once we have bumped our minimum compatible
163+ // LND version to one that always attaches metadata pairs.
164+ // This is because the macaroon root key ID is not a reliable way of
165+ // extracting the session ID since the macaroon root key ID may also
166+ // be the first 4 bytes of an account ID and so collisions are possible
167+ // here.
168+
169+ // Otherwise, fall back to extracting the session ID from the macaroon.
170+ if ri .Macaroon == nil {
171+ return session.ID {}, false , nil
172+ }
173+
174+ id , err = session .IDFromMacaroon (ri .Macaroon )
175+ if err != nil {
176+ return session.ID {}, false , fmt .Errorf ("could not extract " +
177+ "ID from macaroon: %w" , err )
178+ }
179+
180+ return id , true , nil
181+ }
0 commit comments