Skip to content

Commit

Permalink
refactor InfoQuery
Browse files Browse the repository at this point in the history
  • Loading branch information
mk6i committed Sep 24, 2024
1 parent 2b88cb4 commit bd125a5
Showing 1 changed file with 49 additions and 76 deletions.
125 changes: 49 additions & 76 deletions foodgroup/odir.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,85 +40,79 @@ type ODirService struct {
// send it. It doesn't appear to make a difference, since AIM 5.x sends the
// same TLV types for each search type.
func (s ODirService) InfoQuery(_ context.Context, inFrame wire.SNACFrame, inBody wire.SNAC_0x0F_0x02_InfoQuery) (wire.SNACMessage, error) {
snac := wire.SNACMessage{
response := wire.SNACMessage{
Frame: wire.SNACFrame{
FoodGroup: wire.ODir,
SubGroup: wire.ODirInfoReply,
RequestID: inFrame.RequestID,
},
}

switch {
case inBody.HasTag(wire.ODirTLVEmailAddress):
var err error
snac.Body, err = s.searchByEmail(inBody)
// search by email address
if email, hasEmail := inBody.String(wire.ODirTLVEmailAddress); hasEmail {
foundUser, err := s.profileManager.FindByAIMEmail(email)
if err != nil {
return wire.SNACMessage{}, err
if errors.Is(err, state.ErrNoUser) {
response.Body = s.searchResponse(nil)
return response, nil
}
return wire.SNACMessage{}, fmt.Errorf("FindByAIMEmail: %w", err)
}
case inBody.HasTag(wire.ODirTLVInterest):
var err error
snac.Body, err = s.searchByInterest(inBody)
response.Body = s.searchResponse([]state.User{foundUser})
return response, nil
}

// search by interest keyword
if interest, hasInterest := inBody.String(wire.ODirTLVInterest); hasInterest {
foundUsers, err := s.profileManager.FindByAIMKeyword(interest)
if err != nil {
return wire.SNACMessage{}, err
return wire.SNACMessage{}, fmt.Errorf("FindByAIMKeyword: %w", err)
}
case inBody.HasTag(wire.ODirTLVFirstName), inBody.HasTag(wire.ODirTLVLastName):
var err error
snac.Body, err = s.searchByNameAndAddr(inBody)
response.Body = s.searchResponse(foundUsers)
return response, nil
}

// search by name and address
if inBody.HasTag(wire.ODirTLVFirstName) || inBody.HasTag(wire.ODirTLVLastName) {
foundUsers, err := s.profileManager.FindByAIMNameAndAddr(newAIMNameAndAddrFromTLVList(inBody.TLVList))
if err != nil {
return wire.SNACMessage{}, err
}
default:
snac.Body = wire.SNAC_0x0F_0x03_InfoReply{
Status: wire.ODirSearchResponseNameMissing,
return wire.SNACMessage{}, fmt.Errorf("FindByAIMNameAndAddr: %w", err)
}
response.Body = s.searchResponse(foundUsers)
return response, nil
}

return snac, nil
}

// searchByNameAndAddr performs a directory search using the user's first or
// last name and address.
func (s ODirService) searchByNameAndAddr(inBody wire.SNAC_0x0F_0x02_InfoQuery) (wire.SNAC_0x0F_0x03_InfoReply, error) {
foundUsers, err := s.profileManager.FindByAIMNameAndAddr(newAIMNameAndAddrFromTLVList(inBody.TLVList))
if err != nil {
return wire.SNAC_0x0F_0x03_InfoReply{}, fmt.Errorf("FindByAIMNameAndAddr: %w", err)
// no suitable combination of search TLVs found
response.Body = wire.SNAC_0x0F_0x03_InfoReply{
Status: wire.ODirSearchResponseNameMissing,
}
return s.searchResponse(foundUsers)
return response, nil
}

// searchByInterest performs a directory search using the user's specified
// interest keyword.
func (s ODirService) searchByInterest(inBody wire.SNAC_0x0F_0x02_InfoQuery) (wire.SNAC_0x0F_0x03_InfoReply, error) {
var foundUsers []state.User

interest, _ := inBody.String(wire.ODirTLVInterest)

foundUsers, err := s.profileManager.FindByAIMKeyword(interest)
if err != nil {
return wire.SNAC_0x0F_0x03_InfoReply{}, fmt.Errorf("FindByAIMKeyword: %w", err)
}

return s.searchResponse(foundUsers)
}

// searchByEmail performs a directory search using the user's email address.
func (s ODirService) searchByEmail(inBody wire.SNAC_0x0F_0x02_InfoQuery) (wire.SNAC_0x0F_0x03_InfoReply, error) {
email, _ := inBody.String(wire.ODirTLVEmailAddress)

result, err := s.profileManager.FindByAIMEmail(email)
// KeywordListQuery returns a list of keywords that can be searched in the user
// directory.
func (s ODirService) KeywordListQuery(_ context.Context, inFrame wire.SNACFrame) (wire.SNACMessage, error) {
interests, err := s.profileManager.InterestList()
if err != nil {
if errors.Is(err, state.ErrNoUser) {
return s.searchResponse(nil)
}
return wire.SNAC_0x0F_0x03_InfoReply{}, fmt.Errorf("FindByAIMEmail: %w", err)
return wire.SNACMessage{}, fmt.Errorf("InterestList: %w", err)
}

return s.searchResponse([]state.User{result})
return wire.SNACMessage{
Frame: wire.SNACFrame{
FoodGroup: wire.ODir,
SubGroup: wire.ODirKeywordListReply,
RequestID: inFrame.RequestID,
},
Body: wire.SNAC_0x0F_0x04_KeywordListReply{
Status: 0x01,
Interests: interests,
},
}, nil
}

// searchResponse constructs the SNAC reply based on the users found during the
// search.
func (s ODirService) searchResponse(foundUsers []state.User) (wire.SNAC_0x0F_0x03_InfoReply, error) {
func (s ODirService) searchResponse(foundUsers []state.User) wire.SNAC_0x0F_0x03_InfoReply {
body := wire.SNAC_0x0F_0x03_InfoReply{
Status: wire.ODirSearchResponseOK,
}
Expand All @@ -136,28 +130,7 @@ func (s ODirService) searchResponse(foundUsers []state.User) (wire.SNAC_0x0F_0x0
})
}

return body, nil
}

// KeywordListQuery returns a list of keywords that can be searched in the user
// directory.
func (s ODirService) KeywordListQuery(_ context.Context, inFrame wire.SNACFrame) (wire.SNACMessage, error) {
interests, err := s.profileManager.InterestList()
if err != nil {
return wire.SNACMessage{}, fmt.Errorf("InterestList: %w", err)
}

return wire.SNACMessage{
Frame: wire.SNACFrame{
FoodGroup: wire.ODir,
SubGroup: wire.ODirKeywordListReply,
RequestID: inFrame.RequestID,
},
Body: wire.SNAC_0x0F_0x04_KeywordListReply{
Status: 0x01,
Interests: interests,
},
}, nil
return body
}

// newAIMNameAndAddrFromTLVList constructs an AIMNameAndAddr structure from the
Expand Down

0 comments on commit bd125a5

Please sign in to comment.