Skip to content

Commit 06138ea

Browse files
committed
multi: support wild card URIs
With this commit, a user can now specify a wild card URI of the form "/frdrpc.FaradayServer/*" when specifying custom permissions for an LNC session. This URI will then be expanded to include all permissions that Lit knows about that falls under that URI.
1 parent 446d4a5 commit 06138ea

File tree

4 files changed

+145
-9
lines changed

4 files changed

+145
-9
lines changed

cmd/litcli/sessions.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,11 @@ var addSessionCommand = cli.Command{
7373
"this flag will only be used if the 'type' " +
7474
"flag is set to 'custom'. This flag can be " +
7575
"specified multiple times if multiple URIs " +
76-
"should be included",
76+
"should be included. Note that a wild-card " +
77+
"URI can also be specified to include all " +
78+
"URIs of a specific server, for example: " +
79+
"'--uri=\"/poolrpc.Trader/*\"' will include " +
80+
"all URIs that match this regex.",
7781
},
7882
},
7983
}

perms/permissions.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package perms
22

33
import (
44
"net"
5+
"regexp"
56
"strings"
67
"sync"
78

@@ -80,6 +81,8 @@ var (
8081
"RouterRPC": true,
8182
"WatchtowerClientRPC": true,
8283
}
84+
85+
wildCardURIRegex = regexp.MustCompile(`/(\w+)\.(\w+)/\*`)
8386
)
8487

8588
// subServerName is a name used to identify a particular Lit sub-server.
@@ -210,6 +213,36 @@ func (pm *Manager) URIPermissions(uri string) ([]bakery.Op, bool) {
210213
return ops, ok
211214
}
212215

216+
// ExpandWildCardURI first checks that the given URI is in-fact a wild card uri
217+
// that matches the wildCardURIRegex. If it is, then a new regex is created so
218+
// that it can be used to match on the perms that the manager has. Any
219+
// permission URI that matches the regex is returned. The return values are a
220+
// list of URIs that match the wild-card uri and the boolean represents whether
221+
// the given uri is in fact a wild card uri.
222+
func (pm *Manager) ExpandWildCardURI(wildCardUri string) ([]string, bool) {
223+
pm.permsMu.RLock()
224+
defer pm.permsMu.RUnlock()
225+
226+
if !wildCardURIRegex.MatchString(wildCardUri) {
227+
return nil, false
228+
}
229+
230+
r := regexp.MustCompile(
231+
wildCardURIRegex.ReplaceAllString(wildCardUri, "/$1.$2/.*"),
232+
)
233+
234+
var matches []string
235+
for uri := range pm.perms {
236+
if !r.MatchString(uri) {
237+
continue
238+
}
239+
240+
matches = append(matches, uri)
241+
}
242+
243+
return matches, true
244+
}
245+
213246
// ActivePermissions returns all the available active permissions that the
214247
// manager is aware of. Optionally, readOnly can be set to true if only the
215248
// read-only permissions should be returned.

perms/permissions_test.go

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package perms
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/require"
7+
"gopkg.in/macaroon-bakery.v2/bakery"
8+
)
9+
10+
// TestExpandWildCardURI tests the behaviour of the ExpandWildCardURI method
11+
// of the Manager.
12+
func TestExpandWildCardURI(t *testing.T) {
13+
// Construct a new Manager with a predefined list of perms. We include
14+
// two faraday URIs and three Lit URIs.
15+
m := &Manager{
16+
perms: map[string][]bakery.Op{
17+
"/frdrpc.FaradayServer/OutlierRecommendations": {{
18+
Entity: "recommendation",
19+
Action: "read",
20+
}},
21+
"/frdrpc.FaradayServer/ThresholdRecommendations": {{
22+
Entity: "recommendation",
23+
Action: "read",
24+
}},
25+
"/litrpc.Sessions/AddSession": {{
26+
Entity: "sessions",
27+
Action: "write",
28+
}},
29+
"/litrpc.Sessions/ListSessions": {{
30+
Entity: "sessions",
31+
Action: "read",
32+
}},
33+
"/litrpc.Sessions/RevokeSession": {{
34+
Entity: "sessions",
35+
Action: "write",
36+
}},
37+
},
38+
}
39+
40+
// Assert that a full URI is not considered a wild card.
41+
uris, isWild := m.ExpandWildCardURI("/litrpc.Sessions/RevokeSession")
42+
require.False(t, isWild)
43+
require.Empty(t, uris)
44+
45+
// Assert that the function correctly matches on a valid wild card for
46+
// litrpc URIs.
47+
uris, isWild = m.ExpandWildCardURI("/litrpc.Sessions/*")
48+
require.True(t, isWild)
49+
require.ElementsMatch(t, uris, []string{
50+
"/litrpc.Sessions/AddSession",
51+
"/litrpc.Sessions/ListSessions",
52+
"/litrpc.Sessions/RevokeSession",
53+
})
54+
55+
// Assert that the function correctly matches on a valid wild card for
56+
// faraday URIs.
57+
uris, isWild = m.ExpandWildCardURI("/frdrpc.FaradayServer/*")
58+
require.True(t, isWild)
59+
require.ElementsMatch(t, uris, []string{
60+
"/frdrpc.FaradayServer/OutlierRecommendations",
61+
"/frdrpc.FaradayServer/ThresholdRecommendations",
62+
})
63+
64+
// Assert that the function does not return any URIs for a wild card
65+
// URI that does not match on any of its perms.
66+
uris, isWild = m.ExpandWildCardURI("/poolrpc.Trader/*")
67+
require.True(t, isWild)
68+
require.Empty(t, uris)
69+
}

session_rpcserver.go

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -143,18 +143,48 @@ func (s *sessionRpcServer) AddSession(_ context.Context,
143143
}
144144

145145
for _, op := range req.MacaroonCustomPermissions {
146-
if op.Entity == macaroons.PermissionEntityCustomURI {
147-
_, ok := s.cfg.permMgr.URIPermissions(op.Action)
146+
if op.Entity != macaroons.PermissionEntityCustomURI {
147+
permissions = append(permissions, bakery.Op{
148+
Entity: op.Entity,
149+
Action: op.Action,
150+
})
151+
152+
continue
153+
}
154+
155+
// First check if this is a wildcard URI.
156+
uris, isWildCard := s.cfg.permMgr.ExpandWildCardURI(
157+
op.Action,
158+
)
159+
if !isWildCard {
160+
// This is not a wild card URI, so just check
161+
// that the permissions' manager is aware of
162+
// this URI.
163+
_, ok := s.cfg.permMgr.URIPermissions(
164+
op.Action,
165+
)
148166
if !ok {
149-
return nil, fmt.Errorf("URI %s is "+
150-
"unknown to LiT", op.Action)
167+
return nil, fmt.Errorf("URI "+
168+
"%s is unknown to LiT",
169+
op.Action)
151170
}
171+
172+
permissions = append(permissions, bakery.Op{
173+
Entity: op.Entity,
174+
Action: op.Action,
175+
})
176+
continue
152177
}
153178

154-
permissions = append(permissions, bakery.Op{
155-
Entity: op.Entity,
156-
Action: op.Action,
157-
})
179+
// Otherwise, if it is a wild card perm, then add each
180+
// of the matching URIs returned from the permissions'
181+
// manager.
182+
for _, uri := range uris {
183+
permissions = append(permissions, bakery.Op{
184+
Entity: op.Entity,
185+
Action: uri,
186+
})
187+
}
158188
}
159189

160190
// No other types are currently supported.

0 commit comments

Comments
 (0)