11package session
22
33import (
4+ "context"
5+ "fmt"
46 "testing"
57 "time"
68
79 "github.com/btcsuite/btcd/btcec/v2"
10+ "github.com/lightninglabs/lightning-terminal/accounts"
811 "github.com/lightningnetwork/lnd/clock"
12+ "github.com/lightningnetwork/lnd/fn"
13+ "github.com/lightningnetwork/lnd/macaroons"
914 "github.com/stretchr/testify/require"
15+ "gopkg.in/macaroon-bakery.v2/bakery/checkers"
16+ "gopkg.in/macaroon.v2"
1017)
1118
1219var testTime = time .Date (2020 , 1 , 1 , 0 , 0 , 0 , 0 , time .UTC )
@@ -324,9 +331,49 @@ func TestStateShift(t *testing.T) {
324331 require .ErrorContains (t , err , "illegal session state transition" )
325332}
326333
334+ // TestLinkedAccount tests that linking a session to an account works as
335+ // expected.
336+ func TestLinkedAccount (t * testing.T ) {
337+ t .Parallel ()
338+ ctx := context .Background ()
339+ clock := clock .NewTestClock (testTime )
340+
341+ accts := accounts .NewTestDB (t , clock )
342+ db := NewTestDBWithAccounts (t , clock , accts )
343+
344+ // Reserve a session. Link it to an account that does not yet exist.
345+ // This should fail.
346+ acctID := accounts.AccountID {1 , 2 , 3 , 4 }
347+ _ , err := reserveSession (db , "session 1" , withAccount (acctID ))
348+ require .ErrorIs (t , err , accounts .ErrAccNotFound )
349+
350+ // Now, add a new account
351+ acct , err := accts .NewAccount (ctx , 1234 , clock .Now ().Add (time .Hour ), "" )
352+ require .NoError (t , err )
353+
354+ // Reserve a session. Link it to the account that was just created.
355+ // This should succeed.
356+
357+ s1 , err := reserveSession (db , "session 1" , withAccount (acct .ID ))
358+ require .NoError (t , err )
359+ require .True (t , s1 .AccountID .IsSome ())
360+ s1 .AccountID .WhenSome (func (id accounts.AccountID ) {
361+ require .Equal (t , acct .ID , id )
362+ })
363+
364+ // Make sure that a fetched session includes the account ID.
365+ s1 , err = db .GetSessionByID (s1 .ID )
366+ require .NoError (t , err )
367+ require .True (t , s1 .AccountID .IsSome ())
368+ s1 .AccountID .WhenSome (func (id accounts.AccountID ) {
369+ require .Equal (t , acct .ID , id )
370+ })
371+ }
372+
327373type testSessionOpts struct {
328374 groupID * ID
329375 sessType Type
376+ account fn.Option [accounts.AccountID ]
330377}
331378
332379func defaultTestSessOpts () * testSessionOpts {
@@ -352,6 +399,12 @@ func withType(t Type) testSessionModifier {
352399 }
353400}
354401
402+ func withAccount (alias accounts.AccountID ) testSessionModifier {
403+ return func (s * testSessionOpts ) {
404+ s .account = fn .Some (alias )
405+ }
406+ }
407+
355408func reserveSession (db Store , label string ,
356409 mods ... testSessionModifier ) (* Session , error ) {
357410
@@ -360,10 +413,25 @@ func reserveSession(db Store, label string,
360413 mod (opts )
361414 }
362415
363- return db .NewSession (label , opts .sessType ,
416+ var caveats []macaroon.Caveat
417+ opts .account .WhenSome (func (id accounts.AccountID ) {
418+ // For now, we manually add the account caveat for bbolt
419+ // compatibility.
420+ accountCaveat := checkers .Condition (
421+ macaroons .CondLndCustom ,
422+ fmt .Sprintf ("%s %x" , accounts .CondAccount , id [:]),
423+ )
424+
425+ caveats = append (caveats , macaroon.Caveat {
426+ Id : []byte (accountCaveat ),
427+ })
428+ })
429+
430+ return db .NewSession (
431+ label , opts .sessType ,
364432 time .Date (99999 , 1 , 1 , 0 , 0 , 0 , 0 , time .UTC ),
365- "foo.bar.baz:1234" , true , nil , nil , nil , true , opts .groupID ,
366- []PrivacyFlag {ClearPubkeys },
433+ "foo.bar.baz:1234" , true , nil , caveats , nil , true , opts .groupID ,
434+ []PrivacyFlag {ClearPubkeys }, opts . account ,
367435 )
368436}
369437
0 commit comments