algoliasearch 1.2.4 → 1.2.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ChangeLog +5 -0
- data/README.md +52 -2
- data/algoliasearch.gemspec +2 -2
- data/lib/algolia/client.rb +26 -2
- data/lib/algolia/version.rb +1 -1
- data/spec/client_spec.rb +14 -0
- metadata +27 -27
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ffcea70e1e16052463f966167245f0d0412bb1d1
|
4
|
+
data.tar.gz: a37adf050adb92682c8ddd48990b093606ba800d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fc1fbead2ee31e7e503b7864d7779c9455d99f1925de7f5ca765c0a0229dc0c4b81680a9b814c029a0b06152b8729565dae1f8ecb342a07c46f650771ec4df07
|
7
|
+
data.tar.gz: 79a73010bbaa3b99227c9693ea9f71ba9c6627b02faf4dd4a9f772bef98b0cb9af637e67e65049fa797d056bd22cafa6415b6a28db23164a1810c1e7a3a3288f
|
data/ChangeLog
CHANGED
data/README.md
CHANGED
@@ -295,6 +295,8 @@ The server response will look like:
|
|
295
295
|
|
296
296
|
|
297
297
|
|
298
|
+
|
299
|
+
|
298
300
|
Get an object
|
299
301
|
-------------
|
300
302
|
|
@@ -494,13 +496,18 @@ You can also create an API Key with advanced restrictions:
|
|
494
496
|
Note: If you are sending the query through your servers, you must use the `Algolia.with_rate_limits("EndUserIP", "APIKeyWithRateLimit") do ... end` block to enable rate-limit.
|
495
497
|
|
496
498
|
* Specify the maximum number of hits this API key can retrieve in one call. Defaults to 0 (unlimited). This parameter can be used to protect you from attempts at retrieving your entire content by massively querying the index.
|
499
|
+
* Specify the list of targeted indexes. Defaults to all indexes if empty of blank.
|
497
500
|
|
498
501
|
```ruby
|
499
502
|
# Creates a new global API key that is valid for 300 seconds
|
500
503
|
res = Algolia.add_user_key(["search"], 300)
|
501
504
|
puts res['key']
|
502
|
-
# Creates a new index specific API key
|
503
|
-
|
505
|
+
# Creates a new index specific API key:
|
506
|
+
# - valid for 300 seconds
|
507
|
+
# - rate limit of 100 calls per hour per IP
|
508
|
+
# - maximum of 20 hits
|
509
|
+
# - valid on 'my_index1' and 'my_index2'
|
510
|
+
res = index.add_user_key(["search"], 300, 100, 20, ['my_index1', 'my_index2'])
|
504
511
|
puts res['key']
|
505
512
|
```
|
506
513
|
|
@@ -520,6 +527,49 @@ Algolia.delete_user_key("f420238212c54dcfad07ea0aa6d5c45f")
|
|
520
527
|
index.delete_user_key("71671c38001bf3ac857bc82052485107")
|
521
528
|
```
|
522
529
|
|
530
|
+
You may have a single index containing per-user data. In that case, all records should be tagged with their associated user_id in order to add a `tagFilters=(public,user_42)` filter at query time to retrieve only what a user has access to. If you're using the [JavaScript client](http://github.com/algolia/algoliasearch-client-js), it will result in a security breach since the user is able to modify the `tagFilters` you've set modifying the code from the browser. To keep using the JavaScript client (recommended for optimal latency) and target secured records, you can generate secured API key from your backend:
|
531
|
+
|
532
|
+
```ruby
|
533
|
+
# generate a public API key for user 42. Here, records are tagged with:
|
534
|
+
# - 'public' if they are visible by all users
|
535
|
+
# - 'user_XXXX' if they are visible by user XXXX
|
536
|
+
public_key = Algolia.generate_secured_api_key 'YourSearchOnlyApiKey', '(public,user_42)'
|
537
|
+
```
|
538
|
+
|
539
|
+
This public API key must then be used in your JavaScript code as follow:
|
540
|
+
|
541
|
+
```javascript
|
542
|
+
<script type="text/javascript">
|
543
|
+
var algolia = new AlgoliaSearch('YourApplicationID', '<%= public_api_key %>');
|
544
|
+
algolia.setSecurityTags('(public,user_42)'); // must be same than those used at generation-time
|
545
|
+
algolia.initIndex('YourIndex').search($('#q').val(), function(success, content) {
|
546
|
+
// [...]
|
547
|
+
});
|
548
|
+
</script>
|
549
|
+
```
|
550
|
+
|
551
|
+
You can mix rate limits and secured API keys setting an extra `user_token` attribute both at API key generation-time and query-time. When set, a uniq user will be identified by her `IP + user_token` instead of only her `IP`. It allows you to restrict a single user to perform maximum `N` API calls per hour, even if she share her `IP` with another user.
|
552
|
+
|
553
|
+
```ruby
|
554
|
+
# generate a public API key for user 42. Here, records are tagged with:
|
555
|
+
# - 'public' if they are visible by all users
|
556
|
+
# - 'user_XXXX' if they are visible by user XXXX
|
557
|
+
public_key = Algolia.generate_secured_api_key 'YourRateLimitedApiKey', '(public,user_42)', 'user_42'
|
558
|
+
```
|
559
|
+
|
560
|
+
This public API key must then be used in your JavaScript code as follow:
|
561
|
+
|
562
|
+
```javascript
|
563
|
+
<script type="text/javascript">
|
564
|
+
var algolia = new AlgoliaSearch('YourApplicationID', '<%= public_api_key %>');
|
565
|
+
algolia.setSecurityTags('(public,user_42)'); // must be same than those used at generation-time
|
566
|
+
algolia.setUserToken('user_42') // must be same than the one used at generation-time
|
567
|
+
algolia.initIndex('YourIndex').search($('#q').val(), function(success, content) {
|
568
|
+
// [...]
|
569
|
+
});
|
570
|
+
</script>
|
571
|
+
```
|
572
|
+
|
523
573
|
Copy or rename an index
|
524
574
|
-------------
|
525
575
|
|
data/algoliasearch.gemspec
CHANGED
@@ -6,12 +6,12 @@
|
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "algoliasearch"
|
9
|
-
s.version = "1.2.
|
9
|
+
s.version = "1.2.5"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib"]
|
13
13
|
s.authors = ["Algolia"]
|
14
|
-
s.date = "2014-02-
|
14
|
+
s.date = "2014-02-24"
|
15
15
|
s.description = "A simple Ruby client for the algolia.com REST API"
|
16
16
|
s.email = "contact@algolia.com"
|
17
17
|
s.extra_rdoc_files = [
|
data/lib/algolia/client.rb
CHANGED
@@ -148,6 +148,22 @@ module Algolia
|
|
148
148
|
end
|
149
149
|
end
|
150
150
|
|
151
|
+
#
|
152
|
+
# Generate a secured and public API Key from a list of tagFilters and an
|
153
|
+
# optional user token identifying the current user
|
154
|
+
#
|
155
|
+
# @param private_api_key your private API Key
|
156
|
+
# @param tag_filters the list of tags applied to the query (used as security)
|
157
|
+
# @param user_token an optional token identifying the current user
|
158
|
+
#
|
159
|
+
def Algolia.generate_secured_api_key(private_api_key, tag_filters, user_token = nil)
|
160
|
+
if tag_filters.is_a?(Array)
|
161
|
+
tag_filters = tag_filters.map { |t| t.is_a?(Array) ? "(#{t.join(',')})" : t }.join(',')
|
162
|
+
end
|
163
|
+
raise ArgumentError.new('Attribute "tag_filters" must be a list of tags') if !tag_filters.is_a?(String)
|
164
|
+
Digest::SHA256.hexdigest "#{private_api_key}#{tag_filters}#{user_token.to_s}"
|
165
|
+
end
|
166
|
+
|
151
167
|
#
|
152
168
|
# List all existing indexes
|
153
169
|
# return an Answer object with answer in the form
|
@@ -213,9 +229,17 @@ module Algolia
|
|
213
229
|
# @param validity the number of seconds after which the key will be automatically removed (0 means no time limit for this key)
|
214
230
|
# @param maxQueriesPerIPPerHour the maximum number of API calls allowed from an IP address per hour (0 means unlimited)
|
215
231
|
# @param maxHitsPerQuery the maximum number of hits this API key can retrieve in one call (0 means unlimited)
|
232
|
+
# @param indexes the optional list of targeted indexes
|
216
233
|
#
|
217
|
-
def Algolia.add_user_key(acls, validity = 0, maxQueriesPerIPPerHour = 0, maxHitsPerQuery = 0)
|
218
|
-
|
234
|
+
def Algolia.add_user_key(acls, validity = 0, maxQueriesPerIPPerHour = 0, maxHitsPerQuery = 0, indexes = nil)
|
235
|
+
params = {
|
236
|
+
:acl => acls,
|
237
|
+
:validity => validity.to_i,
|
238
|
+
:maxQueriesPerIPPerHour => maxQueriesPerIPPerHour.to_i,
|
239
|
+
:maxHitsPerQuery => maxHitsPerQuery.to_i
|
240
|
+
}
|
241
|
+
params[:indexes] = indexes if indexes
|
242
|
+
Algolia.client.post(Protocol.keys_uri, params.to_json)
|
219
243
|
end
|
220
244
|
|
221
245
|
# Delete an existing user key
|
data/lib/algolia/version.rb
CHANGED
data/spec/client_spec.rb
CHANGED
@@ -214,6 +214,9 @@ describe 'Client' do
|
|
214
214
|
end
|
215
215
|
|
216
216
|
it "should get logs" do
|
217
|
+
host = Algolia.client.send(:thread_local_hosts).first
|
218
|
+
puts host[:session].get(host[:base_url] + Algolia::Protocol.logs(0, 10), { :header => Algolia.client.headers }).content
|
219
|
+
|
217
220
|
res = Algolia.get_logs
|
218
221
|
|
219
222
|
res['logs'].size.should > 0
|
@@ -561,4 +564,15 @@ describe 'Client' do
|
|
561
564
|
logs['logs'][0].should have_key('sha1')
|
562
565
|
logs['logs'][0]['sha1'].should be_a(String)
|
563
566
|
end
|
567
|
+
|
568
|
+
it 'should generate secured api keys' do
|
569
|
+
key = Algolia.generate_secured_api_key('my_api_key', '(public,user1)')
|
570
|
+
key.should eq(Digest::SHA256.hexdigest 'my_api_key(public,user1)')
|
571
|
+
key = Algolia.generate_secured_api_key('my_api_key', '(public,user1)', 42)
|
572
|
+
key.should eq(Digest::SHA256.hexdigest 'my_api_key(public,user1)42')
|
573
|
+
key = Algolia.generate_secured_api_key('my_api_key', ['public'])
|
574
|
+
key.should eq(Digest::SHA256.hexdigest 'my_api_keypublic')
|
575
|
+
key = Algolia.generate_secured_api_key('my_api_key', ['public', ['premium','vip']])
|
576
|
+
key.should eq(Digest::SHA256.hexdigest 'my_api_keypublic,(premium,vip)')
|
577
|
+
end
|
564
578
|
end
|
metadata
CHANGED
@@ -1,85 +1,85 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: algoliasearch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Algolia
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-02-
|
11
|
+
date: 2014-02-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: httpclient
|
15
|
-
|
15
|
+
version_requirements: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - ~>
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '2.3'
|
20
|
-
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirement: !ruby/object:Gem::Requirement
|
23
21
|
requirements:
|
24
22
|
- - ~>
|
25
23
|
- !ruby/object:Gem::Version
|
26
24
|
version: '2.3'
|
25
|
+
prerelease: false
|
26
|
+
type: :runtime
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: json
|
29
|
-
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - '>='
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: 1.5.1
|
34
|
-
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
34
|
+
requirement: !ruby/object:Gem::Requirement
|
37
35
|
requirements:
|
38
36
|
- - '>='
|
39
37
|
- !ruby/object:Gem::Version
|
40
38
|
version: 1.5.1
|
39
|
+
prerelease: false
|
40
|
+
type: :runtime
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: travis
|
43
|
-
|
43
|
+
version_requirements: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - '>='
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
|
-
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
51
49
|
requirements:
|
52
50
|
- - '>='
|
53
51
|
- !ruby/object:Gem::Version
|
54
52
|
version: '0'
|
53
|
+
prerelease: false
|
54
|
+
type: :development
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rake
|
57
|
-
|
57
|
+
version_requirements: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - '>='
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
|
-
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
62
|
+
requirement: !ruby/object:Gem::Requirement
|
65
63
|
requirements:
|
66
64
|
- - '>='
|
67
65
|
- !ruby/object:Gem::Version
|
68
66
|
version: '0'
|
67
|
+
prerelease: false
|
68
|
+
type: :development
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rdoc
|
71
|
-
|
71
|
+
version_requirements: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - '>='
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '0'
|
76
|
-
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
76
|
+
requirement: !ruby/object:Gem::Requirement
|
79
77
|
requirements:
|
80
78
|
- - '>='
|
81
79
|
- !ruby/object:Gem::Version
|
82
80
|
version: '0'
|
81
|
+
prerelease: false
|
82
|
+
type: :development
|
83
83
|
description: A simple Ruby client for the algolia.com REST API
|
84
84
|
email: contact@algolia.com
|
85
85
|
executables: []
|
@@ -115,7 +115,7 @@ homepage: http://github.com/algolia/algoliasearch-client-ruby
|
|
115
115
|
licenses:
|
116
116
|
- MIT
|
117
117
|
metadata: {}
|
118
|
-
post_install_message:
|
118
|
+
post_install_message:
|
119
119
|
rdoc_options: []
|
120
120
|
require_paths:
|
121
121
|
- lib
|
@@ -130,9 +130,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
130
130
|
- !ruby/object:Gem::Version
|
131
131
|
version: '0'
|
132
132
|
requirements: []
|
133
|
-
rubyforge_project:
|
134
|
-
rubygems_version: 2.1
|
135
|
-
signing_key:
|
133
|
+
rubyforge_project:
|
134
|
+
rubygems_version: 2.2.1
|
135
|
+
signing_key:
|
136
136
|
specification_version: 4
|
137
137
|
summary: A simple Ruby client for the algolia.com REST API
|
138
138
|
test_files: []
|