From a6e35c8c77e1f202097b13ef56099a700ca2c653 Mon Sep 17 00:00:00 2001 From: Gabriel Handford Date: Wed, 29 Jul 2020 17:31:14 -0700 Subject: [PATCH] user: Search kid --- user/search.go | 56 +++++++++++++++++++++++++++++++++++++++++++-- user/search_test.go | 16 +++++++++++++ 2 files changed, 70 insertions(+), 2 deletions(-) diff --git a/user/search.go b/user/search.go index a28f2a7..720219e 100644 --- a/user/search.go +++ b/user/search.go @@ -3,6 +3,7 @@ package user import ( "context" "encoding/json" + "strings" "github.com/keys-pub/keys" "github.com/keys-pub/keys/docs" @@ -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 { @@ -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) @@ -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 } diff --git a/user/search_test.go b/user/search_test.go index 8595c10..6af9de7 100644 --- a/user/search_test.go +++ b/user/search_test.go @@ -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)) @@ -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)