typesense 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8c74454a48a4f170bbb99bb5e382199c8842e84ec5d2fbd6198106df89b45977
4
- data.tar.gz: ca4772c87e84fabe0cef3af42bfb6e1bb889e305b402d9a2e2f83b10bdbe6d1b
3
+ metadata.gz: ec69deb240d0c343346d128161aa74fe12ab18e7f79007dfa24ac16738c46237
4
+ data.tar.gz: e681fcd5f9b1241054f3c786ee5e6eebad45c1ddc1705311bf7a45ea6551a23f
5
5
  SHA512:
6
- metadata.gz: d1ab99d6e52d15257c8e664d765b1debb063d151d364916b273cef1658537dadcd0241e76fffa5807be50b15c83891b76c2aaef7105c875be2c3bb70728b88e0
7
- data.tar.gz: db20bce0c42a7713a3c5fa25ca1c7a17bb6724bd8949b5dc16202d11538b348d806d960f0def0712e118d856184da8650a3b12ba861037754e20e172856d38c0
6
+ metadata.gz: f6dd0dfd751499e1ec32cfd45935038df7ad219c498f433745fd8855439ef5136a7df7c47491f37fa9940d8bc1f1d02cfcc5aa77f6c4a154256f6ebe4dcb5c32
7
+ data.tar.gz: 7ef2d64aa701054a756222bc18dc19c9b3e282dbb6cc8789a47fe901d5716d67faaacf0c8fe1ed5b3de7cf1f06a1af11621e77ec633a4dfb6722e5bb0ed6908f
@@ -11,3 +11,6 @@ Metrics/BlockLength:
11
11
  - 'spec/**/*'
12
12
  - 'Gemfile'
13
13
  - 'typesense.gemspec'
14
+
15
+ Style/Documentation:
16
+ Enabled: false
@@ -17,6 +17,7 @@ Lint/SuppressedException:
17
17
  Exclude:
18
18
  - 'examples/collections_and_documents.rb'
19
19
  - 'examples/search.rb'
20
+ - 'examples/keys.rb'
20
21
 
21
22
  # Offense count: 3
22
23
  # Configuration parameters: IgnoredMethods.
@@ -49,6 +50,8 @@ RSpec/ExampleLength:
49
50
  Exclude:
50
51
  - 'spec/typesense/alias_spec.rb'
51
52
  - 'spec/typesense/aliases_spec.rb'
53
+ - 'spec/typesense/key_spec.rb'
54
+ - 'spec/typesense/keys_spec.rb'
52
55
  - 'spec/typesense/api_call_spec.rb'
53
56
  - 'spec/typesense/collection_spec.rb'
54
57
  - 'spec/typesense/collections_spec.rb'
data/README.md CHANGED
@@ -33,8 +33,9 @@ Tests are also a good place to know how the the library works internally: [spec]
33
33
 
34
34
  | Typesense Server | typesense-ruby |
35
35
  |------------------|----------------|
36
+ | \>= v0.12.1 | \>= v0.5.0 |
37
+ | \>= v0.12.0 | \>= v0.4.0 |
36
38
  | <= v0.11 | <= v0.3.0 |
37
- | \>= v0.12 | \>= v0.4.0 |
38
39
 
39
40
  ## Development
40
41
 
@@ -11,7 +11,7 @@ AwesomePrint.defaults = {
11
11
  ## Setup
12
12
  #
13
13
  ### Option 1: Start a single-node cluster
14
- # $ docker run -i -p 8108:8108 -v/tmp/typesense-server-data-1b/:/data -v`pwd`/typesense-server-peers:/typesense-server-peers typesense/typesense:0.12.rc9 --data-dir /data --api-key=xyz --search-only-api-key=abcd --listen-port 8108 --enable-cors
14
+ # $ docker run -i -p 8108:8108 -v/tmp/typesense-server-data-1b/:/data -v`pwd`/typesense-server-peers:/typesense-server-peers typesense/typesense:0.12.1.rc1 --data-dir /data --api-key=xyz --listen-port 8108 --enable-cors
15
15
  #
16
16
  ### Option 2: Start a 3-node cluster
17
17
  #
@@ -19,13 +19,13 @@ AwesomePrint.defaults = {
19
19
  # $ echo '172.17.0.2:8107:8108,172.17.0.3:7107:7108,172.17.0.4:9107:9108' > `pwd`/typesense-server-peers
20
20
  #
21
21
  # Start node 1:
22
- # $ docker run -i -p 8108:8108 -p 8107:8107 -v/tmp/typesense-server-data-1b/:/data -v`pwd`/typesense-server-peers:/typesense-server-peers typesense/typesense:0.12.rc9 --data-dir /data --api-key=xyz --search-only-api-key=abcd --listen-port 8108 --peering-port 8107 --enable-cors --nodes=/typesense-server-peers
22
+ # $ docker run -i -p 8108:8108 -p 8107:8107 -v/tmp/typesense-server-data-1b/:/data -v`pwd`/typesense-server-peers:/typesense-server-peers typesense/typesense:0.12.1.rc1 --data-dir /data --api-key=xyz --listen-port 8108 --peering-port 8107 --enable-cors --nodes=/typesense-server-peers
23
23
  #
24
24
  # Start node 2:
25
- # $ docker run -i -p 7108:7108 -p 7107:7107 -v/tmp/.typesense-server-data-2b/:/data -v`pwd`/typesense-server-peers:/typesense-server-peers typesense/typesense:0.12.rc9 --data-dir /data --api-key=xyz --search-only-api-key=abcd --listen-port 7108 --peering-port 7107 --enable-cors --nodes=/typesense-server-peers
25
+ # $ docker run -i -p 7108:7108 -p 7107:7107 -v/tmp/.typesense-server-data-2b/:/data -v`pwd`/typesense-server-peers:/typesense-server-peers typesense/typesense:0.12.1.rc1 --data-dir /data --api-key=xyz --listen-port 7108 --peering-port 7107 --enable-cors --nodes=/typesense-server-peers
26
26
  #
27
27
  # Start node 3:
28
- # $ docker run -i -p 9108:9108 -p 9107:9107 -v/tmp/.typesense-server-data-3b/:/data -v`pwd`/typesense-server-peers:/typesense-server-peers typesense/typesense:0.12.rc9 --data-dir /data --api-key=xyz --search-only-api-key=abcd --listen-port 9108 --peering-port 9107 --enable-cors --nodes=/typesense-server-peers
28
+ # $ docker run -i -p 9108:9108 -p 9107:9107 -v/tmp/.typesense-server-data-3b/:/data -v`pwd`/typesense-server-peers:/typesense-server-peers typesense/typesense:0.12.1.rc1 --data-dir /data --api-key=xyz --listen-port 9108 --peering-port 9107 --enable-cors --nodes=/typesense-server-peers
29
29
  #
30
30
  # Note: Be sure to add `--license-key=<>` at the end when starting a Typesense Premium server
31
31
 
@@ -0,0 +1,127 @@
1
+ # frozen_string_literal: true
2
+
3
+ ##
4
+ # These examples walk you through operations to manage API Keys
5
+
6
+ require_relative './client_initialization'
7
+
8
+ # Let's setup some test data for this example
9
+ schema = {
10
+ 'name' => 'users',
11
+ 'fields' => [
12
+ {
13
+ 'name' => 'company_id',
14
+ 'type' => 'int32',
15
+ 'facet' => false
16
+ },
17
+ {
18
+ 'name' => 'user_name',
19
+ 'type' => 'string',
20
+ 'facet' => false
21
+ },
22
+ {
23
+ 'name' => 'login_count',
24
+ 'type' => 'int32',
25
+ 'facet' => false
26
+ },
27
+ {
28
+ 'name' => 'country',
29
+ 'type' => 'string',
30
+ 'facet' => true
31
+ }
32
+ ],
33
+ 'default_sorting_field' => 'company_id'
34
+ }
35
+
36
+ # We have four users, belonging to two companies: 124 and 126
37
+ documents = [
38
+ {
39
+ 'company_id' => 124,
40
+ 'user_name' => 'Hilary Bradford',
41
+ 'login_count' => 10,
42
+ 'country' => 'USA'
43
+ },
44
+ {
45
+ 'company_id' => 124,
46
+ 'user_name' => 'Nile Carty',
47
+ 'login_count' => 100,
48
+ 'country' => 'USA'
49
+ },
50
+ {
51
+ 'company_id' => 126,
52
+ 'user_name' => 'Tahlia Maxwell',
53
+ 'login_count' => 1,
54
+ 'country' => 'France'
55
+ },
56
+ {
57
+ 'company_id' => 126,
58
+ 'user_name' => 'Karl Roy',
59
+ 'login_count' => 2,
60
+ 'country' => 'Germany'
61
+ }
62
+ ]
63
+
64
+ # Delete if the collection already exists from a previous example run
65
+ begin
66
+ @typesense.collections['users'].delete
67
+ rescue Typesense::Error::ObjectNotFound
68
+ end
69
+
70
+ # create a collection
71
+ @typesense.collections.create(schema)
72
+
73
+ # Index documents
74
+ documents.each do |document|
75
+ @typesense.collections['users'].documents.create(document)
76
+ end
77
+
78
+ # Generate an API key and restrict it to only allow searches
79
+ # You want to use this API Key in the browser instead of the master API Key
80
+ unscoped_search_only_api_key_response = @typesense.keys.create({
81
+ 'description' => 'Search-only key.',
82
+ 'actions' => ['documents:search'],
83
+ 'collections' => ['*']
84
+ })
85
+ ap unscoped_search_only_api_key_response
86
+
87
+ # Save the key returned, since this will be the only time the full API Key is returned, for security purposes
88
+ unscoped_search_only_api_key = unscoped_search_only_api_key_response['value']
89
+
90
+ # Side note: you can also retrieve metadata of API keys using the ID returned in the above response
91
+ unscoped_search_only_api_key_response = @typesense.keys[unscoped_search_only_api_key_response['id']].retrieve
92
+ ap unscoped_search_only_api_key_response
93
+
94
+ # We'll now use this search-only API key to generate a scoped search API key that can only access documents that have company_id:124
95
+ # This is useful when you store multi-tenant data in a single Typesense server, but you only want
96
+ # a particular tenant to access their own data. You'd generate one scoped search key per tenant.
97
+ # IMPORTANT: scoped search keys should only be generated *server-side*, so as to not leak the unscoped main search key to clients
98
+ scoped_search_only_api_key = @typesense.keys.generate_scoped_search_key(unscoped_search_only_api_key, { 'filter_by': 'company_id:124' })
99
+ ap "scoped_search_only_api_key: #{scoped_search_only_api_key}"
100
+
101
+ # Now let's search the data using the scoped API Key for company_id:124
102
+ # You can do searches with this scoped_search_only_api_key from the server-side or client-side
103
+ scoped_typesense_client = Typesense::Client.new({
104
+ 'nodes': [{
105
+ 'host': 'localhost',
106
+ 'port': '8108',
107
+ 'protocol': 'http'
108
+ }],
109
+ 'api_key': scoped_search_only_api_key
110
+ })
111
+
112
+ search_results = scoped_typesense_client.collections['users'].documents.search({
113
+ 'q' => 'Hilary',
114
+ 'query_by' => 'user_name'
115
+ })
116
+ ap search_results
117
+
118
+ # Search for a user that exists, but is outside the current key's scope
119
+ search_results = scoped_typesense_client.collections['users'].documents.search({
120
+ 'q': 'Maxwell',
121
+ 'query_by': 'user_name'
122
+ })
123
+ ap search_results # Will return empty result set
124
+
125
+ # Now let's delete the unscoped_search_only_api_key. You'd want to do this when you need to rotate keys for example.
126
+ results = @typesense.keys[unscoped_search_only_api_key_response['id']].delete
127
+ ap results
@@ -15,5 +15,7 @@ require_relative 'typesense/overrides'
15
15
  require_relative 'typesense/override'
16
16
  require_relative 'typesense/aliases'
17
17
  require_relative 'typesense/alias'
18
+ require_relative 'typesense/keys'
19
+ require_relative 'typesense/key'
18
20
  require_relative 'typesense/debug'
19
21
  require_relative 'typesense/error'
@@ -5,6 +5,7 @@ module Typesense
5
5
  attr_reader :configuration
6
6
  attr_reader :collections
7
7
  attr_reader :aliases
8
+ attr_reader :keys
8
9
  attr_reader :debug
9
10
 
10
11
  def initialize(options = {})
@@ -12,6 +13,7 @@ module Typesense
12
13
  @api_call = ApiCall.new(@configuration)
13
14
  @collections = Collections.new(@api_call)
14
15
  @aliases = Aliases.new(@api_call)
16
+ @keys = Keys.new(@api_call)
15
17
  @debug = Debug.new(@api_call)
16
18
  end
17
19
  end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Typesense
4
+ class Key
5
+ def initialize(id, api_call)
6
+ @id = id
7
+ @api_call = api_call
8
+ end
9
+
10
+ def retrieve
11
+ @api_call.get(endpoint_path)
12
+ end
13
+
14
+ def delete
15
+ @api_call.delete(endpoint_path)
16
+ end
17
+
18
+ private
19
+
20
+ def endpoint_path
21
+ "#{Keys::RESOURCE_PATH}/#{@id}"
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'base64'
4
+
5
+ module Typesense
6
+ class Keys
7
+ RESOURCE_PATH = '/keys'
8
+
9
+ def initialize(api_call)
10
+ @api_call = api_call
11
+ @keys = {}
12
+ end
13
+
14
+ def create(parameters)
15
+ @api_call.post(RESOURCE_PATH, parameters)
16
+ end
17
+
18
+ def retrieve
19
+ @api_call.get(RESOURCE_PATH)
20
+ end
21
+
22
+ def generate_scoped_search_key(search_key, parameters)
23
+ parameters_json = JSON.dump(parameters)
24
+ digest = Base64.encode64(OpenSSL::HMAC.digest('sha256', search_key, parameters_json)).gsub("\n", '')
25
+ key_prefix = search_key[0...4]
26
+ raw_scoped_key = "#{digest}#{key_prefix}#{parameters_json}"
27
+ Base64.encode64(raw_scoped_key).gsub("\n", '')
28
+ end
29
+
30
+ def [](id)
31
+ @keys[id] ||= Key.new(id, @api_call)
32
+ end
33
+ end
34
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Typesense
4
- VERSION = '0.4.0'
4
+ VERSION = '0.5.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: typesense
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Typesense, Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-05-23 00:00:00.000000000 Z
11
+ date: 2020-05-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: awesome_print
@@ -229,6 +229,7 @@ files:
229
229
  - examples/aliases.rb
230
230
  - examples/client_initialization.rb
231
231
  - examples/collections_and_documents.rb
232
+ - examples/keys.rb
232
233
  - examples/overrides.rb
233
234
  - examples/search.rb
234
235
  - lib/typesense.rb
@@ -243,6 +244,8 @@ files:
243
244
  - lib/typesense/document.rb
244
245
  - lib/typesense/documents.rb
245
246
  - lib/typesense/error.rb
247
+ - lib/typesense/key.rb
248
+ - lib/typesense/keys.rb
246
249
  - lib/typesense/override.rb
247
250
  - lib/typesense/overrides.rb
248
251
  - lib/typesense/version.rb