@@ -2,12 +2,18 @@ package session
22
33import (
44 "context"
5+ "fmt"
56 "testing"
67 "time"
78
89 "github.com/btcsuite/btcd/btcec/v2"
10+ "github.com/lightninglabs/lightning-terminal/accounts"
911 "github.com/lightningnetwork/lnd/clock"
12+ "github.com/lightningnetwork/lnd/fn"
13+ "github.com/lightningnetwork/lnd/macaroons"
1014 "github.com/stretchr/testify/require"
15+ "gopkg.in/macaroon-bakery.v2/bakery/checkers"
16+ "gopkg.in/macaroon.v2"
1117)
1218
1319var testTime = time .Date (2020 , 1 , 1 , 0 , 0 , 0 , 0 , time .UTC )
@@ -324,9 +330,49 @@ func TestStateShift(t *testing.T) {
324330 require .ErrorContains (t , err , "illegal session state transition" )
325331}
326332
333+ // TestLinkedAccount tests that linking a session to an account works as
334+ // expected.
335+ func TestLinkedAccount (t * testing.T ) {
336+ t .Parallel ()
337+ ctx := context .Background ()
338+ clock := clock .NewTestClock (testTime )
339+
340+ accts := accounts .NewTestDB (t , clock )
341+ db := NewTestDBWithAccounts (t , clock , accts )
342+
343+ // Reserve a session. Link it to an account that does not yet exist.
344+ // This should fail.
345+ acctID := accounts.AccountID {1 , 2 , 3 , 4 }
346+ _ , err := reserveSession (db , "session 1" , withAccount (acctID ))
347+ require .ErrorIs (t , err , accounts .ErrAccNotFound )
348+
349+ // Now, add a new account
350+ acct , err := accts .NewAccount (ctx , 1234 , clock .Now ().Add (time .Hour ), "" )
351+ require .NoError (t , err )
352+
353+ // Reserve a session. Link it to the account that was just created.
354+ // This should succeed.
355+
356+ s1 , err := reserveSession (db , "session 1" , withAccount (acct .ID ))
357+ require .NoError (t , err )
358+ require .True (t , s1 .AccountID .IsSome ())
359+ s1 .AccountID .WhenSome (func (id accounts.AccountID ) {
360+ require .Equal (t , acct .ID , id )
361+ })
362+
363+ // Make sure that a fetched session includes the account ID.
364+ s1 , err = db .GetSessionByID (ctx , s1 .ID )
365+ require .NoError (t , err )
366+ require .True (t , s1 .AccountID .IsSome ())
367+ s1 .AccountID .WhenSome (func (id accounts.AccountID ) {
368+ require .Equal (t , acct .ID , id )
369+ })
370+ }
371+
327372type testSessionOpts struct {
328373 groupID * ID
329374 sessType Type
375+ account fn.Option [accounts.AccountID ]
330376}
331377
332378func defaultTestSessOpts () * testSessionOpts {
@@ -352,6 +398,12 @@ func withType(t Type) testSessionModifier {
352398 }
353399}
354400
401+ func withAccount (alias accounts.AccountID ) testSessionModifier {
402+ return func (s * testSessionOpts ) {
403+ s .account = fn .Some (alias )
404+ }
405+ }
406+
355407func reserveSession (db Store , label string ,
356408 mods ... testSessionModifier ) (* Session , error ) {
357409
@@ -360,13 +412,35 @@ func reserveSession(db Store, label string,
360412 mod (opts )
361413 }
362414
363- return db .NewSession (
364- context .Background (), label , opts .sessType ,
365- time .Date (9999 , 1 , 1 , 0 , 0 , 0 , 0 , time .UTC ),
366- "foo.bar.baz:1234" ,
415+ options := []Option {
367416 WithDevServer (),
368417 WithPrivacy (PrivacyFlags {ClearPubkeys }),
369418 WithLinkedGroupID (opts .groupID ),
419+ }
420+
421+ opts .account .WhenSome (func (id accounts.AccountID ) {
422+ // For now, we manually add the account caveat for bbolt
423+ // compatibility.
424+ accountCaveat := checkers .Condition (
425+ macaroons .CondLndCustom ,
426+ fmt .Sprintf ("%s %x" , accounts .CondAccount , id [:]),
427+ )
428+
429+ caveats := append (caveats , macaroon.Caveat {
430+ Id : []byte (accountCaveat ),
431+ })
432+
433+ options = append (
434+ options ,
435+ WithAccount (id ),
436+ WithMacaroonRecipe (caveats , nil ),
437+ )
438+ })
439+
440+ return db .NewSession (
441+ context .Background (), label , opts .sessType ,
442+ time .Date (9999 , 1 , 1 , 0 , 0 , 0 , 0 , time .UTC ),
443+ "foo.bar.baz:1234" , options ... ,
370444 )
371445}
372446
0 commit comments