Skip to content

Commit

Permalink
implement SNAC(15,02)/07D0/04BA - short user info
Browse files Browse the repository at this point in the history
  • Loading branch information
mk6i committed Aug 18, 2024
1 parent 784cdac commit 992caa6
Show file tree
Hide file tree
Showing 6 changed files with 258 additions and 0 deletions.
31 changes: 31 additions & 0 deletions foodgroup/icq.go
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,37 @@ func (s ICQService) SetWorkInfo(ctx context.Context, sess *state.Session, req wi
return s.reqAck(ctx, sess, seq, wire.ICQDBQueryMetaReplySetWorkInfo)
}

func (s ICQService) ShortUserInfo(ctx context.Context, sess *state.Session, req wire.ICQ_0x07D0_0x04BA_DBQueryMetaReqShortInfo, seq uint16) error {
user, err := s.userFinder.FindByUIN(req.UIN)
if err != nil {
return err
}

info := wire.ICQ_0x07DA_0x0104_DBQueryMetaReplyShortInfo{
ICQMetadata: wire.ICQMetadata{
UIN: sess.UIN(),
ReqType: wire.ICQDBQueryMetaReply,
Seq: seq,
},
ReqSubType: wire.ICQDBQueryMetaReplyShortInfo,
Success: wire.ICQStatusCodeOK,
Nickname: user.ICQBasicInfo.Nickname,
FirstName: user.ICQBasicInfo.FirstName,
LastName: user.ICQBasicInfo.LastName,
Email: user.ICQBasicInfo.EmailAddress,
Gender: uint8(user.ICQMoreInfo.Gender),
}
if user.ICQPermissions.AuthRequired {
info.Authorization = 1
}

msg := wire.ICQMessageReplyEnvelope{
Message: info,
}

return s.reply(ctx, sess, msg)
}

func (s ICQService) XMLReqData(ctx context.Context, sess *state.Session, req wire.ICQ_0x07D0_0x0898_DBQueryMetaReqXMLReq, seq uint16) error {
msg := wire.ICQMessageReplyEnvelope{
Message: wire.ICQ_0x07DA_0x08A2_DBQueryMetaReplyXMLData{
Expand Down
115 changes: 115 additions & 0 deletions foodgroup/icq_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2183,6 +2183,121 @@ func TestICQService_SetWorkInfo(t *testing.T) {
}
}

func TestICQService_ShortUserInfo(t *testing.T) {
tests := []struct {
name string
timeNow func() time.Time
seq uint16
sess *state.Session
req wire.ICQ_0x07D0_0x04BA_DBQueryMetaReqShortInfo
mockParams mockParams
wantErr error
}{
{
name: "happy path",
timeNow: func() time.Time {
return time.Date(2020, time.August, 1, 0, 0, 0, 0, time.UTC)
},
seq: 1,
sess: newTestSession("11111111", sessOptUIN(11111111)),
req: wire.ICQ_0x07D0_0x04BA_DBQueryMetaReqShortInfo{
UIN: 123456789,
},
mockParams: mockParams{
icqUserFinderParams: icqUserFinderParams{
findByUINParams: findByUINParams{
{
UIN: 123456789,
result: state.User{
IdentScreenName: state.NewIdentScreenName("123456789"),
ICQPermissions: state.ICQPermissions{
AuthRequired: true,
},
ICQMoreInfo: state.ICQMoreInfo{
Gender: 2,
},
ICQBasicInfo: state.ICQBasicInfo{
EmailAddress: "john.doe@example.com",
FirstName: "John",
LastName: "Doe",
Nickname: "CoolUser123",
},
},
},
},
},
messageRelayerParams: messageRelayerParams{
relayToScreenNameParams: relayToScreenNameParams{
{
screenName: state.NewIdentScreenName("11111111"),
message: wire.SNACMessage{
Frame: wire.SNACFrame{
FoodGroup: wire.ICQ,
SubGroup: wire.ICQDBReply,
},
Body: wire.SNAC_0x0F_0x02_DBReply{
TLVRestBlock: wire.TLVRestBlock{
TLVList: wire.TLVList{
wire.NewTLV(wire.ICQTLVTagsMetadata, wire.ICQMessageReplyEnvelope{
Message: wire.ICQ_0x07DA_0x0104_DBQueryMetaReplyShortInfo{
ICQMetadata: wire.ICQMetadata{
UIN: 11111111,
ReqType: wire.ICQDBQueryMetaReply,
Seq: 1,
},
Success: wire.ICQStatusCodeOK,
ReqSubType: wire.ICQDBQueryMetaReplyShortInfo,
Nickname: "CoolUser123",
FirstName: "John",
LastName: "Doe",
Email: "john.doe@example.com",
Authorization: 1,
Gender: 2,
},
}),
},
},
},
},
},
},
},
sessionRetrieverParams: sessionRetrieverParams{
retrieveSessionParams{
{
screenName: state.NewIdentScreenName("123456789"),
result: &state.Session{},
},
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
userFinder := newMockICQUserFinder(t)
for _, params := range tt.mockParams.findByUINParams {
userFinder.EXPECT().
FindByUIN(params.UIN).
Return(params.result, params.err)
}

messageRelayer := newMockMessageRelayer(t)
for _, params := range tt.mockParams.relayToScreenNameParams {
messageRelayer.EXPECT().RelayToScreenName(mock.Anything, params.screenName, params.message)
}

s := ICQService{
messageRelayer: messageRelayer,
timeNow: tt.timeNow,
userFinder: userFinder,
}
err := s.ShortUserInfo(nil, tt.sess, tt.req, tt.seq)
assert.NoError(t, err)
})
}
}

func TestICQService_XMLReqData(t *testing.T) {
tests := []struct {
name string
Expand Down
7 changes: 7 additions & 0 deletions server/oscar/handler/icq.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ type ICQService interface {
SetPermissions(ctx context.Context, sess *state.Session, req wire.ICQ_0x07D0_0x0424_DBQueryMetaReqSetPermissions, seq uint16) error
SetUserNotes(ctx context.Context, sess *state.Session, req wire.ICQ_0x07D0_0x0406_DBQueryMetaReqSetNotes, seq uint16) error
SetWorkInfo(ctx context.Context, sess *state.Session, req wire.ICQ_0x07D0_0x03F3_DBQueryMetaReqSetWorkInfo, seq uint16) error
ShortUserInfo(ctx context.Context, sess *state.Session, req wire.ICQ_0x07D0_0x04BA_DBQueryMetaReqShortInfo, seq uint16) error
XMLReqData(ctx context.Context, sess *state.Session, req wire.ICQ_0x07D0_0x0898_DBQueryMetaReqXMLReq, seq uint16) error
}

Expand Down Expand Up @@ -89,6 +90,12 @@ func (rt ICQHandler) DBQuery(ctx context.Context, sess *state.Session, inFrame w
"uin", sess.UIN())

switch icqMD.Optional.ReqSubType {
case wire.ICQDBQueryMetaReqShortInfo:
userInfo := wire.ICQ_0x07D0_0x04BA_DBQueryMetaReqShortInfo{}
if err := binary.Read(buf, binary.LittleEndian, &userInfo); err != nil {
return nil
}
return rt.ICQService.ShortUserInfo(ctx, sess, userInfo, icqMD.Seq)
case wire.ICQDBQueryMetaReqFullInfo, wire.ICQDBQueryMetaReqFullInfo2:
userInfo := wire.ICQ_0x07D0_0x051F_DBQueryMetaReqSearchByUIN{}
if err := binary.Read(buf, binary.LittleEndian, &userInfo); err != nil {
Expand Down
37 changes: 37 additions & 0 deletions server/oscar/handler/icq_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ func TestICQHandler_DBQuery(t *testing.T) {
setPermissions *mockParam
setUserNotes *mockParam
setWorkInfo *mockParam
shortUserInfo *mockParam
xmlReqData *mockParam
}
tests := []struct {
Expand Down Expand Up @@ -88,6 +89,38 @@ func TestICQHandler_DBQuery(t *testing.T) {
},
},
},
{
name: "MetaReqShortInfo - happy path",
reqParams: reqParams{
sess: &state.Session{},
inBody: wire.SNAC_0x0F_0x02_BQuery{
TLVRestBlock: wire.TLVRestBlock{
TLVList: wire.TLVList{
wire.NewTLV(wire.ICQTLVTagsMetadata, wire.ICQMessageReplyEnvelope{
Message: ICQMetaRequest{
ICQMetadata: wire.ICQMetadata{
ReqType: wire.ICQDBQueryMetaReq,
Seq: 1,
},
ReqSubType: wire.ICQDBQueryMetaReqShortInfo,
MetaRequest: wire.ICQ_0x07D0_0x04BA_DBQueryMetaReqShortInfo{
UIN: 123456789,
},
},
}),
},
},
},
seq: 1,
},
allMockParams: allMockParams{
shortUserInfo: &mockParam{
req: wire.ICQ_0x07D0_0x04BA_DBQueryMetaReqShortInfo{
UIN: 123456789,
},
},
},
},
{
name: "MetaReqFullInfo2 - happy path",
reqParams: reqParams{
Expand Down Expand Up @@ -723,6 +756,10 @@ func TestICQHandler_DBQuery(t *testing.T) {
icqService.EXPECT().
FullUserInfo(mock.Anything, tt.reqParams.sess, tt.allMockParams.fullUserInfo.req, tt.reqParams.seq).
Return(tt.allMockParams.fullUserInfo.wantErr)
case tt.allMockParams.shortUserInfo != nil:
icqService.EXPECT().
ShortUserInfo(mock.Anything, tt.reqParams.sess, tt.allMockParams.shortUserInfo.req, tt.reqParams.seq).
Return(tt.allMockParams.shortUserInfo.wantErr)
case tt.allMockParams.xmlReqData != nil:
icqService.EXPECT().
XMLReqData(mock.Anything, tt.reqParams.sess, tt.allMockParams.xmlReqData.req, tt.reqParams.seq).
Expand Down
49 changes: 49 additions & 0 deletions server/oscar/handler/mock_icq_service_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions wire/snacs.go
Original file line number Diff line number Diff line change
Expand Up @@ -997,6 +997,7 @@ const (
ICQDBQueryMetaReqSetInterests uint16 = 0x0410
ICQDBQueryMetaReqSetAffiliations uint16 = 0x041A
ICQDBQueryMetaReqSetPermissions uint16 = 0x0424
ICQDBQueryMetaReqShortInfo uint16 = 0x04BA
ICQDBQueryMetaReqFullInfo uint16 = 0x04B2
ICQDBQueryMetaReqFullInfo2 uint16 = 0x04D0
ICQDBQueryMetaReqSearchByDetails uint16 = 0x0515
Expand Down Expand Up @@ -1031,6 +1032,7 @@ const (
ICQDBQueryMetaReplyExtEmailInfo uint16 = 0x00EB
ICQDBQueryMetaReplyInterests uint16 = 0x00F0
ICQDBQueryMetaReplyAffiliations uint16 = 0x00FA
ICQDBQueryMetaReplyShortInfo uint16 = 0x0104
ICQDBQueryMetaReplyHomePageCat uint16 = 0x010E
ICQDBQueryMetaReplyUserFound uint16 = 0x01A4
ICQDBQueryMetaReplyLastUserFound uint16 = 0x01AE
Expand All @@ -1041,6 +1043,10 @@ type SNAC_0x0F_0x02_BQuery struct {
TLVRestBlock
}

type ICQ_0x07D0_0x04BA_DBQueryMetaReqShortInfo struct {
UIN uint32
}

type ICQ_0x07D0_0x0898_DBQueryMetaReqXMLReq struct {
XMLRequest string `oscar:"len_prefix=uint16,nullterm"`
}
Expand Down Expand Up @@ -1284,6 +1290,19 @@ func (s *ICQ_0x07DA_0x01AE_DBQueryMetaReplyLastUserFound) LastResult() {
}
}

type ICQ_0x07DA_0x0104_DBQueryMetaReplyShortInfo struct {
ICQMetadata
ReqSubType uint16
Success uint8
Nickname string `oscar:"len_prefix=uint16,nullterm"`
FirstName string `oscar:"len_prefix=uint16,nullterm"`
LastName string `oscar:"len_prefix=uint16,nullterm"`
Email string `oscar:"len_prefix=uint16,nullterm"`
Authorization uint8
Unknown uint8
Gender uint8
}

type ICQ_0x0041_DBQueryOfflineMsgReply struct {
ICQMetadata
SenderUIN uint32
Expand Down

0 comments on commit 992caa6

Please sign in to comment.