@@ -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"
@@ -67,7 +68,8 @@ func (e *proxyErr) Unwrap() error {
6768// component.
6869func newRpcProxy (cfg * Config , validator macaroons.MacaroonValidator ,
6970 superMacValidator session.SuperMacaroonValidator ,
70- permsMgr * perms.Manager , subServerMgr * subservers.Manager ) * rpcProxy {
71+ permsMgr * perms.Manager , subServerMgr * subservers.Manager ,
72+ statusMgr * litstatus.Manager ) * rpcProxy {
7173
7274 // The gRPC web calls are protected by HTTP basic auth which is defined
7375 // by base64(username:password). Because we only have a password, we
@@ -88,6 +90,7 @@ func newRpcProxy(cfg *Config, validator macaroons.MacaroonValidator,
8890 macValidator : validator ,
8991 superMacValidator : superMacValidator ,
9092 subServerMgr : subServerMgr ,
93+ statusMgr : statusMgr ,
9194 }
9295 p .grpcServer = grpc .NewServer (
9396 // From the grpxProxy doc: This codec is *crucial* to the
@@ -162,6 +165,7 @@ type rpcProxy struct {
162165 basicAuth string
163166 permsMgr * perms.Manager
164167 subServerMgr * subservers.Manager
168+ statusMgr * litstatus.Manager
165169
166170 bakeSuperMac bakeSuperMac
167171
@@ -333,6 +337,10 @@ func (p *rpcProxy) makeDirector(allowLitRPC bool) func(ctx context.Context,
333337 }
334338 }
335339
340+ if err := p .checkSubSystemStarted (requestURI ); err != nil {
341+ return outCtx , nil , err
342+ }
343+
336344 // Direct the call to the correct backend. All gRPC calls end up
337345 // here since our gRPC server instance doesn't have any handlers
338346 // registered itself. So all daemon calls that are remote are
@@ -359,12 +367,6 @@ func (p *rpcProxy) makeDirector(allowLitRPC bool) func(ctx context.Context,
359367 )
360368 }
361369
362- // If the rpcProxy has not started yet, then the lnd connection
363- // will not be initialised yet.
364- if ! p .hasStarted () {
365- return outCtx , nil , ErrWaitingToStart
366- }
367-
368370 return outCtx , p .lndConn , nil
369371 }
370372}
@@ -375,15 +377,15 @@ func (p *rpcProxy) UnaryServerInterceptor(ctx context.Context, req interface{},
375377 info * grpc.UnaryServerInfo , handler grpc.UnaryHandler ) (interface {},
376378 error ) {
377379
378- if ! p .hasStarted () && ! isStatusReq (info .FullMethod ) {
379- return nil , ErrWaitingToStart
380- }
381-
382380 uriPermissions , ok := p .permsMgr .URIPermissions (info .FullMethod )
383381 if ! ok {
384382 return nil , ErrUnknownRequest
385383 }
386384
385+ if err := p .checkSubSystemStarted (info .FullMethod ); err != nil {
386+ return nil , err
387+ }
388+
387389 // For now, basic authentication is just a quick fix until we
388390 // have proper macaroon support implemented in the UI. We allow
389391 // gRPC web requests to have it and "convert" the auth into a
@@ -419,15 +421,15 @@ func (p *rpcProxy) StreamServerInterceptor(srv interface{},
419421 ss grpc.ServerStream , info * grpc.StreamServerInfo ,
420422 handler grpc.StreamHandler ) error {
421423
422- if ! p .hasStarted () && ! isStatusReq (info .FullMethod ) {
423- return ErrWaitingToStart
424- }
425-
426424 uriPermissions , ok := p .permsMgr .URIPermissions (info .FullMethod )
427425 if ! ok {
428426 return ErrUnknownRequest
429427 }
430428
429+ if err := p .checkSubSystemStarted (info .FullMethod ); err != nil {
430+ return err
431+ }
432+
431433 // For now, basic authentication is just a quick fix until we
432434 // have proper macaroon support implemented in the UI. We allow
433435 // gRPC web requests to have it and "convert" the auth into a
@@ -604,6 +606,53 @@ func (p *rpcProxy) convertSuperMacaroon(ctx context.Context, macHex string,
604606 return nil , nil
605607}
606608
609+ // checkSubSystemStarted checks if the subsystem responsible for handling the
610+ // given URI has started.
611+ func (p * rpcProxy ) checkSubSystemStarted (requestURI string ) error {
612+ // A request to Lit's status server is always allowed.
613+ if isStatusReq (requestURI ) {
614+ return nil
615+ }
616+
617+ // Check if the rpcProxy has started yet.
618+ if ! p .hasStarted () {
619+ return ErrWaitingToStart
620+ }
621+
622+ // Currently, Lit and LND are not registered with the sub-server
623+ // manager, so we let any request for them through.
624+ if p .permsMgr .IsSubServerURI (subservers .LIT , requestURI ) ||
625+ p .permsMgr .IsSubServerURI (subservers .LND , requestURI ) {
626+
627+ return nil
628+ }
629+
630+ // Check that the sub-server manager does have a sub-server registered
631+ // that can handle the given URI.
632+ handled , system := p .subServerMgr .Handles (requestURI )
633+ if ! handled {
634+ return fmt .Errorf ("unknown gRPC web request: %v" , requestURI )
635+ }
636+
637+ // Check with the status manger to see if the sub-server is ready to
638+ // handle the request.
639+ serverStatus , err := p .statusMgr .GetStatus (system )
640+ if err != nil {
641+ return err
642+ }
643+
644+ if serverStatus .Disabled {
645+ return fmt .Errorf ("%s has been disabled" , system )
646+ }
647+
648+ if ! serverStatus .Running {
649+ return fmt .Errorf ("%s is not running: %s" , system ,
650+ serverStatus .Err )
651+ }
652+
653+ return nil
654+ }
655+
607656// readMacaroon tries to read the macaroon file at the specified path and create
608657// gRPC dial options from it.
609658func readMacaroon (macPath string ) ([]byte , error ) {
0 commit comments