Skip to content

Commit

Permalink
fix broken QIP login sequence
Browse files Browse the repository at this point in the history
On first login, QIP sends a FeedbagClassIdPdinfo feedbag item
without setting FeedbagAttributesPdMode. Login fails because
FeedbagUpsert returns an error when this occurrs. Now let's just
set a default mode and move on in order to avoid a runtime error.
  • Loading branch information
mk6i committed Dec 7, 2024
1 parent 65ef0fe commit a4604bc
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 33 deletions.
3 changes: 2 additions & 1 deletion state/user_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -745,7 +745,8 @@ func (f SQLiteUserStore) FeedbagUpsert(screenName IdentScreenName, items []wire.
var hasMode bool
pdMode, hasMode = item.Uint8(wire.FeedbagAttributesPdMode)
if !hasMode {
return fmt.Errorf("pd info doesn't have mode")
// by default, QIP sends a PD info item entry with no mode
pdMode = uint8(wire.FeedbagPDModePermitAll)
}
}
_, err := f.db.Exec(q,
Expand Down
133 changes: 101 additions & 32 deletions state/user_store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,44 +16,113 @@ import (

const testFile string = "aim_test.db"

func TestUserStore(t *testing.T) {
func TestSQLiteUserStore_FeedbagUpsert(t *testing.T) {
t.Run("buddy screen name is converted to ident screen name", func(t *testing.T) {
defer func() {
assert.NoError(t, os.Remove(testFile))
}()

screenName := NewIdentScreenName("sn2day")
f, err := NewSQLiteUserStore(testFile)
assert.NoError(t, err)

defer func() {
assert.NoError(t, os.Remove(testFile))
}()
given := []wire.FeedbagItem{
{
GroupID: 0,
ItemID: 1805,
ClassID: wire.FeedbagClassIdBuddy,
Name: "my Friend Bill",
TLVLBlock: wire.TLVLBlock{},
},
{
GroupID: 0x0A,
ItemID: 0,
ClassID: wire.FeedbagClassIdGroup,
Name: "Friends",
},
}
expect := []wire.FeedbagItem{
{
GroupID: 0,
ItemID: 1805,
ClassID: wire.FeedbagClassIdBuddy,
Name: "myfriendbill",
TLVLBlock: wire.TLVLBlock{},
},
{
GroupID: 0x0A,
ItemID: 0,
ClassID: wire.FeedbagClassIdGroup,
Name: "Friends",
},
}

f, err := NewSQLiteUserStore(testFile)
assert.NoError(t, err)
me := NewIdentScreenName("me")
if err := f.FeedbagUpsert(me, given); err != nil {
t.Fatalf("failed to upsert: %s", err.Error())
}

itemsIn := []wire.FeedbagItem{
{
GroupID: 0,
ItemID: 1805,
ClassID: 3,
Name: "spimmer1234",
TLVLBlock: wire.TLVLBlock{},
},
{
GroupID: 0x0A,
ItemID: 0,
ClassID: 1,
Name: "Friends",
},
}
if err := f.FeedbagUpsert(screenName, itemsIn); err != nil {
t.Fatalf("failed to upsert: %s", err.Error())
}
have, err := f.Feedbag(me)
assert.NoError(t, err)
assert.ElementsMatch(t, expect, have)
})

itemsOut, err := f.Feedbag(screenName)
if err != nil {
t.Fatalf("failed to retrieve: %s", err.Error())
}
t.Run("upsert PD info with mode", func(t *testing.T) {
defer func() {
assert.NoError(t, os.Remove(testFile))
}()

if !reflect.DeepEqual(itemsIn, itemsOut) {
t.Fatalf("items did not match:\n in: %v\n out: %v", itemsIn, itemsOut)
}
f, err := NewSQLiteUserStore(testFile)
assert.NoError(t, err)

given := []wire.FeedbagItem{
{
GroupID: 0x0A,
ItemID: 0,
ClassID: wire.FeedbagClassIdPdinfo,
TLVLBlock: wire.TLVLBlock{
TLVList: wire.TLVList{
wire.NewTLVBE(wire.FeedbagAttributesPdMode, wire.FeedbagPDModePermitSome),
},
},
},
}

me := NewIdentScreenName("me")
err = f.FeedbagUpsert(me, given)
assert.NoError(t, err)

var pdMode uint8
err = f.db.QueryRow(`SELECT pdMode from feedbag WHERE screenName = ?`, me.String()).Scan(&pdMode)
assert.NoError(t, err)
assert.Equal(t, wire.FeedbagPDMode(pdMode), wire.FeedbagPDModePermitSome)
})

t.Run("upsert PD info without mode (QIP behavior)", func(t *testing.T) {
defer func() {
assert.NoError(t, os.Remove(testFile))
}()

f, err := NewSQLiteUserStore(testFile)
assert.NoError(t, err)

given := []wire.FeedbagItem{
{
GroupID: 0x0A,
ItemID: 0,
ClassID: wire.FeedbagClassIdPdinfo,
TLVLBlock: wire.TLVLBlock{},
},
}

me := NewIdentScreenName("me")
err = f.FeedbagUpsert(me, given)
assert.NoError(t, err)

var pdMode uint8
err = f.db.QueryRow(`SELECT pdMode from feedbag WHERE screenName = ?`, me.String()).Scan(&pdMode)
assert.NoError(t, err)
assert.Equal(t, wire.FeedbagPDMode(pdMode), wire.FeedbagPDModePermitAll)
})
}

func TestFeedbagDelete(t *testing.T) {
Expand Down

0 comments on commit a4604bc

Please sign in to comment.