@@ -15,6 +15,7 @@ import (
1515 "github.com/lightninglabs/lightning-terminal/litrpc"
1616 "github.com/lightninglabs/lightning-terminal/perms"
1717 "github.com/lightninglabs/lightning-terminal/session"
18+ litstatus "github.com/lightninglabs/lightning-terminal/status"
1819 "github.com/lightninglabs/lightning-terminal/subservers"
1920 "github.com/lightningnetwork/lnd/lncfg"
2021 "github.com/lightningnetwork/lnd/macaroons"
@@ -61,7 +62,8 @@ func (e *proxyErr) Unwrap() error {
6162// component.
6263func newRpcProxy (cfg * Config , validator macaroons.MacaroonValidator ,
6364 superMacValidator session.SuperMacaroonValidator ,
64- permsMgr * perms.Manager , subServerMgr * subservers.Manager ) * rpcProxy {
65+ permsMgr * perms.Manager , subServerMgr * subservers.Manager ,
66+ statusMgr * litstatus.Manager ) * rpcProxy {
6567
6668 // The gRPC web calls are protected by HTTP basic auth which is defined
6769 // by base64(username:password). Because we only have a password, we
@@ -82,6 +84,7 @@ func newRpcProxy(cfg *Config, validator macaroons.MacaroonValidator,
8284 macValidator : validator ,
8385 superMacValidator : superMacValidator ,
8486 subServerMgr : subServerMgr ,
87+ statusMgr : statusMgr ,
8588 }
8689 p .grpcServer = grpc .NewServer (
8790 // From the grpxProxy doc: This codec is *crucial* to the
@@ -156,6 +159,7 @@ type rpcProxy struct {
156159 basicAuth string
157160 permsMgr * perms.Manager
158161 subServerMgr * subservers.Manager
162+ statusMgr * litstatus.Manager
159163
160164 macValidator macaroons.MacaroonValidator
161165 superMacValidator session.SuperMacaroonValidator
@@ -297,6 +301,10 @@ func (p *rpcProxy) makeDirector(allowLitRPC bool) func(ctx context.Context,
297301 }
298302 }
299303
304+ if err := p .checkSubSystemStarted (requestURI ); err != nil {
305+ return outCtx , nil , err
306+ }
307+
300308 // Direct the call to the correct backend. All gRPC calls end up
301309 // here since our gRPC server instance doesn't have any handlers
302310 // registered itself. So all daemon calls that are remote are
@@ -323,12 +331,6 @@ func (p *rpcProxy) makeDirector(allowLitRPC bool) func(ctx context.Context,
323331 )
324332 }
325333
326- // If the rpcProxy has not started yet, then the lnd connection
327- // will not be initialised yet.
328- if ! p .hasStarted () {
329- return outCtx , nil , ErrWaitingToStart
330- }
331-
332334 return outCtx , p .lndConn , nil
333335 }
334336}
@@ -339,8 +341,8 @@ func (p *rpcProxy) UnaryServerInterceptor(ctx context.Context, req interface{},
339341 info * grpc.UnaryServerInfo , handler grpc.UnaryHandler ) (interface {},
340342 error ) {
341343
342- if ! p . hasStarted () && ! isStatusReq ( info .FullMethod ) {
343- return nil , ErrWaitingToStart
344+ if err := p . checkSubSystemStarted ( info .FullMethod ); err != nil {
345+ return nil , err
344346 }
345347
346348 uriPermissions , ok := p .permsMgr .URIPermissions (info .FullMethod )
@@ -384,8 +386,8 @@ func (p *rpcProxy) StreamServerInterceptor(srv interface{},
384386 ss grpc.ServerStream , info * grpc.StreamServerInfo ,
385387 handler grpc.StreamHandler ) error {
386388
387- if ! p . hasStarted () && ! isStatusReq ( info .FullMethod ) {
388- return ErrWaitingToStart
389+ if err := p . checkSubSystemStarted ( info .FullMethod ); err != nil {
390+ return err
389391 }
390392
391393 uriPermissions , ok := p .permsMgr .URIPermissions (info .FullMethod )
@@ -572,6 +574,44 @@ func (p *rpcProxy) convertSuperMacaroon(ctx context.Context, macHex string,
572574 return nil , nil
573575}
574576
577+ // checkSubSystemStarted checks if the subsystem responsible for handling the
578+ // given URI has started.
579+ func (p * rpcProxy ) checkSubSystemStarted (requestURI string ) error {
580+ // A request to Lit's status server is always allowed.
581+ if isStatusReq (requestURI ) {
582+ return nil
583+ }
584+
585+ // Check if the rpcProxy has started yet.
586+ if ! p .hasStarted () {
587+ return ErrWaitingToStart
588+ }
589+
590+ // Currently, Lit and LND are not registered with the sub-server
591+ // manager, so we let any request for them through.
592+ if p .permsMgr .IsSubServerURI (subservers .LIT , requestURI ) ||
593+ p .permsMgr .IsSubServerURI (subservers .LND , requestURI ) {
594+
595+ return nil
596+ }
597+
598+ // Check that the sub-server manager does have a sub-server registered
599+ // that can handle the given URI.
600+ handled , system := p .subServerMgr .Handles (requestURI )
601+ if ! handled {
602+ return fmt .Errorf ("unknown gRPC web request: %v" , requestURI )
603+ }
604+
605+ // Check with the status manger to see if the sub-server is ready to
606+ // handle the request.
607+ started , startErr := p .statusMgr .GetStatus (system )
608+ if ! started {
609+ return fmt .Errorf ("%s is not running: %s" , system , startErr )
610+ }
611+
612+ return nil
613+ }
614+
575615// readMacaroon tries to read the macaroon file at the specified path and create
576616// gRPC dial options from it.
577617func readMacaroon (macPath string ) ([]byte , error ) {
0 commit comments