Skip to content

Commit

Permalink
implement SNAC(0x02,0x0C) - LocateGetDirReply
Browse files Browse the repository at this point in the history
This make directory info lookup for a single user work.
  • Loading branch information
mk6i committed Sep 25, 2024
1 parent cef0bfd commit c4e0ac6
Show file tree
Hide file tree
Showing 10 changed files with 322 additions and 7 deletions.
8 changes: 4 additions & 4 deletions foodgroup/auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ func TestAuthService_BUCPLoginRequest(t *testing.T) {
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
userManager := newMockUserManager(t)
for _, params := range tc.mockParams.getUserParams {
for _, params := range tc.mockParams.userManagerParams.getUserParams {
userManager.EXPECT().
User(params.screenName).
Return(params.result, params.err)
Expand Down Expand Up @@ -800,7 +800,7 @@ func TestAuthService_FLAPLoginResponse(t *testing.T) {
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
userManager := newMockUserManager(t)
for _, params := range tc.mockParams.getUserParams {
for _, params := range tc.mockParams.userManagerParams.getUserParams {
userManager.EXPECT().
User(params.screenName).
Return(params.result, params.err)
Expand Down Expand Up @@ -980,7 +980,7 @@ func TestAuthService_BUCPChallengeRequest(t *testing.T) {
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
userManager := newMockUserManager(t)
for _, params := range tc.mockParams.getUserParams {
for _, params := range tc.mockParams.userManagerParams.getUserParams {
userManager.EXPECT().
User(params.screenName).
Return(params.result, params.err)
Expand Down Expand Up @@ -1165,7 +1165,7 @@ func TestAuthService_RegisterBOSSession(t *testing.T) {
Return(params.dataOut, nil)
}
userManager := newMockUserManager(t)
for _, params := range tc.mockParams.getUserParams {
for _, params := range tc.mockParams.userManagerParams.getUserParams {
userManager.EXPECT().
User(params.screenName).
Return(params.result, nil)
Expand Down
37 changes: 37 additions & 0 deletions foodgroup/locate.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,3 +234,40 @@ func (s LocateService) SetKeywordInfo(ctx context.Context, sess *state.Session,
},
}, nil
}

// DirInfo returns directory information for a user.
func (s LocateService) DirInfo(ctx context.Context, inFrame wire.SNACFrame, body wire.SNAC_0x02_0x0B_LocateGetDirInfo) (wire.SNACMessage, error) {
reply := wire.SNAC_0x02_0x0C_LocateGetDirReply{
Status: wire.LocateGetDirReplyOK,
TLVBlock: wire.TLVBlock{
TLVList: wire.TLVList{},
},
}

user, err := s.profileManager.User(state.NewIdentScreenName(body.WatcherScreenNames))
if err != nil {
return wire.SNACMessage{}, fmt.Errorf("User: %w", err)
}

if user != nil {
reply.Append(wire.NewTLVBE(wire.ODirTLVFirstName, user.AIMDirectoryInfo.FirstName))
reply.Append(wire.NewTLVBE(wire.ODirTLVLastName, user.AIMDirectoryInfo.LastName))
reply.Append(wire.NewTLVBE(wire.ODirTLVMiddleName, user.AIMDirectoryInfo.MiddleName))
reply.Append(wire.NewTLVBE(wire.ODirTLVMaidenName, user.AIMDirectoryInfo.MaidenName))
reply.Append(wire.NewTLVBE(wire.ODirTLVCountry, user.AIMDirectoryInfo.Country))
reply.Append(wire.NewTLVBE(wire.ODirTLVState, user.AIMDirectoryInfo.State))
reply.Append(wire.NewTLVBE(wire.ODirTLVCity, user.AIMDirectoryInfo.City))
reply.Append(wire.NewTLVBE(wire.ODirTLVNickName, user.AIMDirectoryInfo.NickName))
reply.Append(wire.NewTLVBE(wire.ODirTLVZIP, user.AIMDirectoryInfo.ZIPCode))
reply.Append(wire.NewTLVBE(wire.ODirTLVAddress, user.AIMDirectoryInfo.Address))
}

return wire.SNACMessage{
Frame: wire.SNACFrame{
FoodGroup: wire.Locate,
SubGroup: wire.LocateGetDirReply,
RequestID: inFrame.RequestID,
},
Body: reply,
}, nil
}
127 changes: 127 additions & 0 deletions foodgroup/locate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -764,3 +764,130 @@ func TestLocateService_RightsQuery(t *testing.T) {

assert.Equal(t, expectSNAC, outputSNAC)
}

func TestLocateService_DirInfo(t *testing.T) {
tests := []struct {
// name is the unit test name
name string
// userSession is the session of the user setting info
userSession *state.Session
// inputSNAC is the SNAC sent from client to server
inputSNAC wire.SNACMessage
// expectOutput is the SNAC sent from the server to client
expectOutput wire.SNACMessage
// mockParams is the list of params sent to mocks that satisfy this
// method's dependencies
mockParams mockParams
// wantErr is the expected error
wantErr error
}{
{
name: "happy path",
userSession: newTestSession("test-user"),
inputSNAC: wire.SNACMessage{
Frame: wire.SNACFrame{
RequestID: 1234,
},
Body: wire.SNAC_0x02_0x0B_LocateGetDirInfo{
WatcherScreenNames: "test-user",
},
},
expectOutput: wire.SNACMessage{
Frame: wire.SNACFrame{
FoodGroup: wire.Locate,
SubGroup: wire.LocateGetDirReply,
RequestID: 1234,
},
Body: wire.SNAC_0x02_0x0C_LocateGetDirReply{
Status: wire.LocateGetDirReplyOK,
TLVBlock: wire.TLVBlock{
TLVList: wire.TLVList{
wire.NewTLVBE(wire.ODirTLVFirstName, "John"),
wire.NewTLVBE(wire.ODirTLVLastName, "Doe"),
wire.NewTLVBE(wire.ODirTLVMiddleName, "A"),
wire.NewTLVBE(wire.ODirTLVMaidenName, "Smith"),
wire.NewTLVBE(wire.ODirTLVCountry, "USA"),
wire.NewTLVBE(wire.ODirTLVState, "CA"),
wire.NewTLVBE(wire.ODirTLVCity, "San Francisco"),
wire.NewTLVBE(wire.ODirTLVNickName, "Johnny"),
wire.NewTLVBE(wire.ODirTLVZIP, "94107"),
wire.NewTLVBE(wire.ODirTLVAddress, "123 Main St"),
},
},
},
},
mockParams: mockParams{
profileManagerParams: profileManagerParams{
getUserParams: getUserParams{
{
screenName: state.NewIdentScreenName("test-user"),
result: &state.User{
AIMDirectoryInfo: state.AIMNameAndAddr{
FirstName: "John",
LastName: "Doe",
MiddleName: "A",
MaidenName: "Smith",
Country: "USA",
State: "CA",
City: "San Francisco",
NickName: "Johnny",
ZIPCode: "94107",
Address: "123 Main St",
},
},
},
},
},
},
},
{
name: "user not found",
userSession: newTestSession("test-user"),
inputSNAC: wire.SNACMessage{
Frame: wire.SNACFrame{
RequestID: 1234,
},
Body: wire.SNAC_0x02_0x0B_LocateGetDirInfo{
WatcherScreenNames: "test-user",
},
},
expectOutput: wire.SNACMessage{
Frame: wire.SNACFrame{
FoodGroup: wire.Locate,
SubGroup: wire.LocateGetDirReply,
RequestID: 1234,
},
Body: wire.SNAC_0x02_0x0C_LocateGetDirReply{
Status: wire.LocateGetDirReplyOK,
TLVBlock: wire.TLVBlock{
TLVList: wire.TLVList{},
},
},
},
mockParams: mockParams{
profileManagerParams: profileManagerParams{
getUserParams: getUserParams{
{
screenName: state.NewIdentScreenName("test-user"),
result: nil,
},
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
profileManager := newMockProfileManager(t)
for _, params := range tt.mockParams.profileManagerParams.getUserParams {
profileManager.EXPECT().
User(params.screenName).
Return(params.result, params.err)
}
svc := NewLocateService(nil, nil, profileManager, nil)
outputSNAC, err := svc.DirInfo(nil, tt.inputSNAC.Frame, tt.inputSNAC.Body.(wire.SNAC_0x02_0x0B_LocateGetDirInfo))
assert.NoError(t, err)
assert.Equal(t, tt.expectOutput, outputSNAC)
})
}
}
58 changes: 58 additions & 0 deletions foodgroup/mock_profile_manager_test.go

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

1 change: 1 addition & 0 deletions foodgroup/test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,7 @@ type profileManagerParams struct {
findByAIMEmailParams
findByAIMKeywordParams
findByAIMNameAndAddrParams
getUserParams
interestListParams
retrieveProfileParams
setDirectoryInfoParams
Expand Down
1 change: 1 addition & 0 deletions foodgroup/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ type ProfileManager interface {
SetDirectoryInfo(name state.IdentScreenName, info state.AIMNameAndAddr) error
SetKeywords(name state.IdentScreenName, keywords [5]string) error
SetProfile(screenName state.IdentScreenName, body string) error
User(screenName state.IdentScreenName) (*state.User, error)
}

type MessageRelayer interface {
Expand Down
14 changes: 11 additions & 3 deletions server/oscar/handler/locate.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
)

type LocateService interface {
DirInfo(ctx context.Context, frame wire.SNACFrame, body wire.SNAC_0x02_0x0B_LocateGetDirInfo) (wire.SNACMessage, error)
RightsQuery(ctx context.Context, inFrame wire.SNACFrame) wire.SNACMessage
SetDirInfo(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, inBody wire.SNAC_0x02_0x09_LocateSetDirInfo) (wire.SNACMessage, error)
SetInfo(ctx context.Context, sess *state.Session, inBody wire.SNAC_0x02_0x04_LocateSetInfo) error
Expand Down Expand Up @@ -62,10 +63,17 @@ func (h LocateHandler) SetDirInfo(ctx context.Context, sess *state.Session, inFr
return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
}

func (h LocateHandler) GetDirInfo(ctx context.Context, _ *state.Session, inFrame wire.SNACFrame, r io.Reader, _ oscar.ResponseWriter) error {
func (h LocateHandler) GetDirInfo(ctx context.Context, _ *state.Session, inFrame wire.SNACFrame, r io.Reader, rw oscar.ResponseWriter) error {
inBody := wire.SNAC_0x02_0x0B_LocateGetDirInfo{}
h.LogRequest(ctx, inFrame, inBody)
return wire.UnmarshalBE(&inBody, r)
if err := wire.UnmarshalBE(&inBody, r); err != nil {
return err
}
outSNAC, err := h.LocateService.DirInfo(ctx, inFrame, inBody)
if err != nil {
return err
}
h.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
}

func (h LocateHandler) SetKeywordInfo(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, rw oscar.ResponseWriter) error {
Expand Down
17 changes: 17 additions & 0 deletions server/oscar/handler/locate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,27 @@ func TestLocateHandler_GetDirInfo(t *testing.T) {
WatcherScreenNames: "screen-name",
},
}
output := wire.SNACMessage{
Frame: wire.SNACFrame{
FoodGroup: wire.Locate,
SubGroup: wire.LocateGetDirReply,
},
Body: wire.SNAC_0x02_0x0C_LocateGetDirReply{
Status: 1,
},
}

svc := newMockLocateService(t)
svc.EXPECT().
DirInfo(mock.Anything, input.Frame, input.Body).
Return(output, nil)

h := NewLocateHandler(svc, slog.Default())

responseWriter := newMockResponseWriter(t)
responseWriter.EXPECT().
SendSNAC(output.Frame, output.Body).
Return(nil)

buf := &bytes.Buffer{}
assert.NoError(t, wire.MarshalBE(input.Body, buf))
Expand Down
Loading

0 comments on commit c4e0ac6

Please sign in to comment.