Skip to content

Commit e78ca24

Browse files
committed
wasm: update HasPermissions to account for custom perms
This commit updates the HasPermissions function to account for the case where the session has custom permissions which would specify "uri" as the permission entity and the actual URI as the permission action.
1 parent 4127398 commit e78ca24

File tree

2 files changed

+48
-4
lines changed

2 files changed

+48
-4
lines changed

cmd/wasm-client/main.go

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import (
3535
"github.com/lightningnetwork/lnd/lnrpc/walletrpc"
3636
"github.com/lightningnetwork/lnd/lnrpc/watchtowerrpc"
3737
"github.com/lightningnetwork/lnd/lnrpc/wtclientrpc"
38+
"github.com/lightningnetwork/lnd/macaroons"
3839
"github.com/lightningnetwork/lnd/signal"
3940
"google.golang.org/grpc"
4041
"gopkg.in/macaroon-bakery.v2/bakery"
@@ -119,6 +120,7 @@ func main() {
119120
callbacks.Set("wasmClientGetExpiry", js.FuncOf(wc.GetExpiry))
120121
callbacks.Set("wasmClientHasPerms", js.FuncOf(wc.HasPermissions))
121122
callbacks.Set("wasmClientIsReadOnly", js.FuncOf(wc.IsReadOnly))
123+
callbacks.Set("wasmClientIsCustom", js.FuncOf(wc.IsCustom))
122124
js.Global().Set(cfg.NameSpace, callbacks)
123125

124126
for _, registration := range registrations {
@@ -353,6 +355,32 @@ func (w *wasmClient) IsReadOnly(_ js.Value, _ []js.Value) interface{} {
353355
return js.ValueOf(isReadOnly(macOps))
354356
}
355357

358+
func (w *wasmClient) IsCustom(_ js.Value, _ []js.Value) interface{} {
359+
if w.mac == nil {
360+
log.Errorf("macaroon not obtained yet. IsCustom should " +
361+
"only be called once the connection is complete")
362+
return js.ValueOf(false)
363+
}
364+
365+
macOps, err := extractMacaroonOps(w.mac)
366+
if err != nil {
367+
log.Errorf("could not extract macaroon ops: %v", err)
368+
return js.ValueOf(false)
369+
}
370+
371+
// We consider a session type to be "custom" if it has any permissions
372+
// with the "uri" entity.
373+
var isCustom bool
374+
for _, op := range macOps {
375+
if op.Entity == macaroons.PermissionEntityCustomURI {
376+
isCustom = true
377+
break
378+
}
379+
}
380+
381+
return js.ValueOf(isCustom)
382+
}
383+
356384
func (w *wasmClient) HasPermissions(_ js.Value, args []js.Value) interface{} {
357385
if len(args) != 1 {
358386
return js.ValueOf(false)
@@ -385,7 +413,7 @@ func (w *wasmClient) HasPermissions(_ js.Value, args []js.Value) interface{} {
385413

386414
// Check that the macaroon contains each of the required permissions
387415
// for the given URI.
388-
return js.ValueOf(hasPermissions(macOps, ops))
416+
return js.ValueOf(hasPermissions(uri, macOps, ops))
389417
}
390418

391419
// extractMacaroonOps is a helper function that extracts operations from the
@@ -421,14 +449,27 @@ func isReadOnly(ops []*lnrpc.Op) bool {
421449

422450
// hasPermissions returns true if all the operations in requiredOps can also be
423451
// found in macOps.
424-
func hasPermissions(macOps []*lnrpc.Op, requiredOps []bakery.Op) bool {
452+
func hasPermissions(uri string, macOps []*lnrpc.Op,
453+
requiredOps []bakery.Op) bool {
454+
425455
// Create a lookup map of the macaroon operations.
426456
macOpsMap := make(map[string]map[string]bool)
427457
for _, op := range macOps {
428458
macOpsMap[op.Entity] = make(map[string]bool)
429459

430460
for _, action := range op.Actions {
431461
macOpsMap[op.Entity][action] = true
462+
463+
// We account here for the special case where the
464+
// operation gives access to an entire URI. This is the
465+
// case when the Entity is equal to the "uri" keyword
466+
// and when the Action is equal to the URI that access
467+
// is being granted to.
468+
if op.Entity == macaroons.PermissionEntityCustomURI &&
469+
action == uri {
470+
471+
return true
472+
}
432473
}
433474
}
434475

example/index.html

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,8 +189,11 @@
189189
}
190190

191191
// Determine if the session is a read only session.
192-
let readOnly = window[namespace].wasmClientIsReadOnly();
193-
if (readOnly) {
192+
let readOnlySession = window[namespace].wasmClientIsReadOnly();
193+
let customSession = window[namespace].wasmClientIsCustom();
194+
if (customSession) {
195+
document.getElementById('sessiontype').textContent = "This is a Custom Session"
196+
} else if (readOnlySession) {
194197
document.getElementById('sessiontype').textContent = "This is a Read-Only Session"
195198
} else {
196199
document.getElementById('sessiontype').textContent = "This is an Admin Session"

0 commit comments

Comments
 (0)