Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 54 additions & 2 deletions user/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package user
import (
"context"
"encoding/json"
"strings"

"github.com/keys-pub/keys"
"github.com/keys-pub/keys/docs"
Expand All @@ -20,9 +21,11 @@ type SearchRequest struct {
type SearchResult struct {
KID keys.ID
Result *Result
// Field we matched on (if not the user).
Field string
}

func (u *Store) search(ctx context.Context, query string, limit int) ([]*SearchResult, error) {
func (u *Store) searchUsers(ctx context.Context, query string, limit int) ([]*SearchResult, error) {
logger.Infof("Searching users %q", query)
iter, err := u.ds.DocumentIterator(ctx, indexUser, docs.Prefix(query))
if err != nil {
Expand Down Expand Up @@ -56,6 +59,41 @@ func (u *Store) search(ctx context.Context, query string, limit int) ([]*SearchR
return results, nil
}

func (u *Store) searchKIDs(ctx context.Context, query string, limit int) ([]*SearchResult, error) {
logger.Infof("Searching kid %q", query)
iter, err := u.ds.DocumentIterator(ctx, indexKID, docs.Prefix(query))
if err != nil {
return nil, err
}

results := make([]*SearchResult, 0, limit)
for {
doc, err := iter.Next()
if err != nil {
return nil, err
}
if doc == nil {
break
}
if len(results) >= limit {
break
}
var keyDoc keyDocument
if err := json.Unmarshal(doc.Data, &keyDoc); err != nil {
return nil, err
}

results = append(results, &SearchResult{
KID: keyDoc.KID,
Result: keyDoc.Result,
Field: "kid",
})
}
iter.Release()
logger.Infof("Found %d user results", len(results))
return results, nil
}

// Search for users.
func (u *Store) Search(ctx context.Context, req *SearchRequest) ([]*SearchResult, error) {
logger.Infof("Search users, query=%q, limit=%d", req.Query, req.Limit)
Expand All @@ -64,5 +102,19 @@ func (u *Store) Search(ctx context.Context, req *SearchRequest) ([]*SearchResult
limit = 100
}

return u.search(ctx, req.Query, limit)
res, err := u.searchUsers(ctx, req.Query, limit)
if err != nil {
return nil, err
}

// Search kid's if prefix is kex1
if strings.HasPrefix(req.Query, "kex1") {
resKIDs, err := u.searchKIDs(ctx, req.Query, limit-len(res))
if err != nil {
return nil, err
}
res = append(res, resKIDs...)
}

return res, nil
}
16 changes: 16 additions & 0 deletions user/search_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ func TestSearchUsers(t *testing.T) {

_, err = ust.Update(ctx, alice.ID())
require.NoError(t, err)

// Search "alic"
results, err = ust.Search(ctx, &user.SearchRequest{Query: "alic"})
require.NoError(t, err)
require.Equal(t, 1, len(results))
Expand All @@ -62,6 +64,20 @@ func TestSearchUsers(t *testing.T) {
require.Equal(t, int64(1234567890028), results[0].Result.VerifiedAt)
require.Equal(t, int64(1234567890028), results[0].Result.Timestamp)

// Search "kex132yw8ht5p8cetl2jmvknewjawt9xwzdlrk2pyxlnwjyqrdq0dawqqph077"
results, err = ust.Search(ctx, &user.SearchRequest{Query: "kex132yw8ht5p8cetl2jmvknewjawt9xwzdlrk2pyxlnwjyqrdq0dawqqph077"})
require.NoError(t, err)
require.Equal(t, 1, len(results))
require.NotNil(t, results[0].Result)
require.Equal(t, alice.ID(), results[0].Result.User.KID)

// Search "kex132yw8h"
results, err = ust.Search(ctx, &user.SearchRequest{Query: "kex132yw8h"})
require.NoError(t, err)
require.Equal(t, 1, len(results))
require.NotNil(t, results[0].Result)
require.Equal(t, alice.ID(), results[0].Result.User.KID)

// Revoke alice, update
sc, err := scs.Sigchain(alice.ID())
require.NoError(t, err)
Expand Down