Skip to content

multi: modularise subserver handling #539

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
May 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -328,17 +328,19 @@ func loadAndValidateConfig(interceptor signal.Interceptor) (*Config, error) {
os.Exit(0)
}

// Before we validate the config, we first hook up our own loggers.
// This must be done before the config is validated if LND is running
// in integrated mode so that the log levels for various non-LND related
// subsystems can be set via the `lnd.debuglevel` flag.
SetupLoggers(preCfg.Lnd.LogWriter, interceptor)

// Load the main configuration file and parse any command line options.
// This function will also set up logging properly.
cfg, err := loadConfigFile(preCfg, interceptor)
if err != nil {
return nil, err
}

// With the validated config obtained, we now know that the root logging
// system of lnd is initialized and we can hook up our own loggers now.
SetupLoggers(cfg.Lnd.LogWriter, interceptor)

// Translate the more user friendly string modes into the more developer
// friendly internal bool variables now.
cfg.lndRemote = cfg.LndMode == ModeRemote
Expand Down
10 changes: 10 additions & 0 deletions itest/litd_mode_integrated_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,16 @@ import (
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcutil"
"github.com/lightninglabs/faraday/frdrpc"
faraday "github.com/lightninglabs/faraday/frdrpcserver/perms"
"github.com/lightninglabs/lightning-node-connect/mailbox"
terminal "github.com/lightninglabs/lightning-terminal"
"github.com/lightninglabs/lightning-terminal/litrpc"
"github.com/lightninglabs/lightning-terminal/perms"
"github.com/lightninglabs/lightning-terminal/session"
"github.com/lightninglabs/lightning-terminal/subservers"
loop "github.com/lightninglabs/loop/loopd/perms"
"github.com/lightninglabs/loop/looprpc"
pool "github.com/lightninglabs/pool/perms"
"github.com/lightninglabs/pool/poolrpc"
"github.com/lightningnetwork/lnd/keychain"
"github.com/lightningnetwork/lnd/lnrpc"
Expand Down Expand Up @@ -1090,6 +1094,12 @@ func bakeSuperMacaroon(cfg *LitNodeConfig, readOnly bool) (string, error) {
return "", err
}

permsMgr.RegisterSubServer(subservers.LOOP, loop.RequiredPermissions)
permsMgr.RegisterSubServer(subservers.POOL, pool.RequiredPermissions)
permsMgr.RegisterSubServer(
subservers.FARADAY, faraday.RequiredPermissions,
)

superMacPermissions := permsMgr.ActivePermissions(readOnly)
nullID := [4]byte{}
superMacHex, err := terminal.BakeSuperMacaroon(
Expand Down
100 changes: 25 additions & 75 deletions perms/manager.go
Original file line number Diff line number Diff line change
@@ -1,25 +1,18 @@
package perms

import (
"fmt"
"regexp"
"strings"
"sync"

faraday "github.com/lightninglabs/faraday/frdrpcserver/perms"
loop "github.com/lightninglabs/loop/loopd/perms"
pool "github.com/lightninglabs/pool/perms"
"github.com/lightningnetwork/lnd"
"github.com/lightningnetwork/lnd/lnrpc"
"gopkg.in/macaroon-bakery.v2/bakery"
)

const (
poolPerms string = "pool"
loopPerms string = "loop"
faradayPerms string = "faraday"
litPerms string = "lit"
lndPerms string = "lnd"
litPerms string = "lit"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! A little bit less duplication 🎉

lndPerms string = "lnd"
)

// Manager manages the permission lists that Lit requires.
Expand Down Expand Up @@ -54,9 +47,6 @@ type Manager struct {
// was compiled with and then only the corresponding permissions will be added.
func NewManager(withAllSubServers bool) (*Manager, error) {
permissions := make(map[string]map[string][]bakery.Op)
permissions[faradayPerms] = faraday.RequiredPermissions
permissions[loopPerms] = loop.RequiredPermissions
permissions[poolPerms] = pool.RequiredPermissions
permissions[litPerms] = RequiredPermissions
permissions[lndPerms] = lnd.MainRPCServerPermissions()
for k, v := range whiteListedLNDMethods {
Expand Down Expand Up @@ -106,6 +96,21 @@ func NewManager(withAllSubServers bool) (*Manager, error) {
}, nil
}

// RegisterSubServer adds the permissions of a given sub-server to the set
// managed by the Manager.
func (pm *Manager) RegisterSubServer(name string,
permissions map[string][]bakery.Op) {

pm.permsMu.Lock()
defer pm.permsMu.Unlock()

pm.fixedPerms[name] = permissions

for uri, ops := range permissions {
pm.perms[uri] = ops
}
}

// OnLNDBuildTags should be called once a list of LND build tags has been
// obtained. It then uses those build tags to decide which of the LND sub-server
// permissions to add to the main permissions list. This method should only
Expand Down Expand Up @@ -225,50 +230,19 @@ func (pm *Manager) ActivePermissions(readOnly bool) []bakery.Op {
// _except_ for any LND permissions. In other words, this returns permissions
// for which the external validator of Lit is responsible.
func (pm *Manager) GetLitPerms() map[string][]bakery.Op {
mapSize := len(pm.fixedPerms[litPerms]) +
len(pm.fixedPerms[faradayPerms]) +
len(pm.fixedPerms[loopPerms]) + len(pm.fixedPerms[poolPerms])
result := make(map[string][]bakery.Op)
for subserver, ops := range pm.fixedPerms {
if subserver == lndPerms {
continue
}

result := make(map[string][]bakery.Op, mapSize)
for key, value := range pm.fixedPerms[faradayPerms] {
result[key] = value
}
for key, value := range pm.fixedPerms[loopPerms] {
result[key] = value
}
for key, value := range pm.fixedPerms[poolPerms] {
result[key] = value
}
for key, value := range pm.fixedPerms[litPerms] {
result[key] = value
for key, value := range ops {
result[key] = value
}
}
return result
}

// SubServerHandler returns the name of the subserver that should handle the
// given URI.
func (pm *Manager) SubServerHandler(uri string) (string, error) {
switch {
case pm.IsSubServerURI(lndPerms, uri):
return lndPerms, nil

case pm.IsSubServerURI(faradayPerms, uri):
return faradayPerms, nil

case pm.IsSubServerURI(loopPerms, uri):
return loopPerms, nil

case pm.IsSubServerURI(poolPerms, uri):
return poolPerms, nil

case pm.IsSubServerURI(litPerms, uri):
return litPerms, nil

default:
return "", fmt.Errorf("unknown gRPC web request: %v", uri)
}
}

// IsSubServerURI if the given URI belongs to the RPC of the given server.
func (pm *Manager) IsSubServerURI(name string, uri string) bool {
if name == lndPerms {
Expand All @@ -292,27 +266,3 @@ func (pm *Manager) isLndURI(uri string) bool {
_, lndCall := pm.fixedPerms[lndPerms][uri]
return lndCall || lndSubServerCall
}

// IsLoopURI returns true if the given URI belongs to an RPC of loopd.
func (pm *Manager) IsLoopURI(uri string) bool {
_, ok := pm.fixedPerms[loopPerms][uri]
return ok
}

// IsFaradayURI returns true if the given URI belongs to an RPC of faraday.
func (pm *Manager) IsFaradayURI(uri string) bool {
_, ok := pm.fixedPerms[faradayPerms][uri]
return ok
}

// IsPoolURI returns true if the given URI belongs to an RPC of poold.
func (pm *Manager) IsPoolURI(uri string) bool {
_, ok := pm.fixedPerms[poolPerms][uri]
return ok
}

// IsLitURI returns true if the given URI belongs to an RPC of LiT.
func (pm *Manager) IsLitURI(uri string) bool {
_, ok := pm.fixedPerms[litPerms][uri]
return ok
}
Loading