ably 0.7.6 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +11 -7
- data/SPEC.md +310 -269
- data/lib/ably/auth.rb +177 -127
- data/lib/ably/models/presence_message.rb +1 -1
- data/lib/ably/models/protocol_message.rb +1 -2
- data/lib/ably/models/token_details.rb +101 -0
- data/lib/ably/models/token_request.rb +108 -0
- data/lib/ably/modules/http_helpers.rb +1 -1
- data/lib/ably/realtime.rb +2 -6
- data/lib/ably/realtime/channel.rb +14 -8
- data/lib/ably/realtime/client.rb +2 -6
- data/lib/ably/realtime/connection.rb +4 -2
- data/lib/ably/rest.rb +2 -6
- data/lib/ably/rest/channel.rb +10 -6
- data/lib/ably/rest/client.rb +15 -16
- data/lib/ably/rest/presence.rb +12 -10
- data/lib/ably/version.rb +1 -1
- data/spec/acceptance/realtime/client_spec.rb +15 -15
- data/spec/acceptance/realtime/connection_failures_spec.rb +3 -3
- data/spec/acceptance/realtime/connection_spec.rb +9 -9
- data/spec/acceptance/rest/auth_spec.rb +248 -172
- data/spec/acceptance/rest/base_spec.rb +8 -6
- data/spec/acceptance/rest/channel_spec.rb +9 -2
- data/spec/acceptance/rest/client_spec.rb +21 -21
- data/spec/acceptance/rest/presence_spec.rb +12 -5
- data/spec/acceptance/rest/stats_spec.rb +4 -4
- data/spec/rspec_config.rb +3 -2
- data/spec/shared/client_initializer_behaviour.rb +21 -24
- data/spec/support/api_helper.rb +3 -3
- data/spec/support/test_app.rb +9 -9
- data/spec/unit/auth_spec.rb +17 -0
- data/spec/unit/models/token_details_spec.rb +111 -0
- data/spec/unit/models/token_request_spec.rb +110 -0
- data/spec/unit/rest/client_spec.rb +1 -1
- metadata +8 -5
- data/lib/ably/models/token.rb +0 -74
- data/spec/unit/models/token_spec.rb +0 -86
@@ -0,0 +1,110 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'shared/model_behaviour'
|
3
|
+
|
4
|
+
describe Ably::Models::TokenRequest do
|
5
|
+
subject { Ably::Models::TokenRequest }
|
6
|
+
|
7
|
+
it_behaves_like 'a model', with_simple_attributes: %w(key_name client_id nonce mac) do
|
8
|
+
let(:model_args) { [] }
|
9
|
+
end
|
10
|
+
|
11
|
+
context 'attributes' do
|
12
|
+
context '#capability' do
|
13
|
+
let(:capability) { { "value" => random_str } }
|
14
|
+
let(:capability_str) { JSON.dump(capability) }
|
15
|
+
|
16
|
+
subject { Ably::Models::TokenRequest.new({ capability: capability_str }) }
|
17
|
+
|
18
|
+
it 'retrieves attribute :capability as parsed JSON' do
|
19
|
+
expect(subject.capability).to eql(capability)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "#timestamp" do
|
24
|
+
let(:time) { Time.now }
|
25
|
+
|
26
|
+
context 'with :timestamp option as milliseconds in constructor' do
|
27
|
+
subject { Ably::Models::TokenRequest.new(timestamp: time.to_i * 1000) }
|
28
|
+
|
29
|
+
it "retrieves attribute :timestamp as Time" do
|
30
|
+
expect(subject.timestamp).to be_a(Time)
|
31
|
+
expect(subject.timestamp.to_i).to eql(time.to_i)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'with :timestamp option as Time in constructor' do
|
36
|
+
subject { Ably::Models::TokenRequest.new(timestamp: time) }
|
37
|
+
|
38
|
+
it "retrieves attribute :timestamp as Time" do
|
39
|
+
expect(subject.timestamp).to be_a(Time)
|
40
|
+
expect(subject.timestamp.to_i).to eql(time.to_i)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'when converted to JSON' do
|
45
|
+
subject { Ably::Models::TokenRequest.new(timestamp: time) }
|
46
|
+
|
47
|
+
it "is in milliseconds since epoch" do
|
48
|
+
expect(JSON.parse(JSON.dump(subject))['timestamp']).to eql((time.to_f * 1000).round)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context "#ttl" do
|
54
|
+
let(:ttl) { 500 }
|
55
|
+
|
56
|
+
context 'with :ttl option as milliseconds in constructor' do
|
57
|
+
subject { Ably::Models::TokenRequest.new(ttl: ttl * 1000) }
|
58
|
+
|
59
|
+
it "retrieves attribute :ttl as seconds" do
|
60
|
+
expect(subject.ttl).to be_a(Integer)
|
61
|
+
expect(subject.ttl).to eql(ttl)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'when converted to JSON' do
|
66
|
+
subject { Ably::Models::TokenRequest.new(ttl: ttl * 1000) }
|
67
|
+
|
68
|
+
it "is in milliseconds since epoch" do
|
69
|
+
expect(JSON.parse(JSON.dump(subject))['ttl']).to eql(ttl * 1000)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context '==' do
|
76
|
+
let(:token_attributes) { { client_id: random_str } }
|
77
|
+
|
78
|
+
it 'is true when attributes are the same' do
|
79
|
+
new_token = -> { Ably::Models::TokenRequest.new(token_attributes) }
|
80
|
+
expect(new_token[]).to eq(new_token[])
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'is false when attributes are not the same' do
|
84
|
+
expect(Ably::Models::TokenRequest.new(client_id: 1)).to_not eq(Ably::Models::TokenRequest.new(client_id: 2))
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'is false when class type differs' do
|
88
|
+
expect(Ably::Models::TokenRequest.new(client_id: 1)).to_not eq(nil)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context 'TokenRequest conversion methods', :api_private do
|
93
|
+
context 'with a TokenRequest object' do
|
94
|
+
let(:token_request) { Ably::Models::TokenRequest.new(client_id: random_str) }
|
95
|
+
|
96
|
+
it 'returns the TokenRequest object' do
|
97
|
+
expect(Ably::Models::TokenRequest(token_request)).to eql(token_request)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context 'with a JSON object' do
|
102
|
+
let(:client_id) { random_str }
|
103
|
+
let(:token_request_json) { { client_id: client_id } }
|
104
|
+
|
105
|
+
it 'returns a new TokenRequest object from the JSON' do
|
106
|
+
expect(Ably::Models::TokenRequest(token_request_json).client_id).to eql(client_id)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -40,7 +40,7 @@ describe Ably::Rest::Client do
|
|
40
40
|
end
|
41
41
|
|
42
42
|
context 'set to true' do
|
43
|
-
context 'without an key or
|
43
|
+
context 'without an key or token' do
|
44
44
|
let(:client_options) { { use_token_auth: true, key: true } }
|
45
45
|
|
46
46
|
it 'fails as an key is required to issue tokens' do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ably
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lewis Marshall
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-04-
|
12
|
+
date: 2015-04-23 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: eventmachine
|
@@ -257,7 +257,8 @@ files:
|
|
257
257
|
- lib/ably/models/protocol_message.rb
|
258
258
|
- lib/ably/models/stat.rb
|
259
259
|
- lib/ably/models/stats_types.rb
|
260
|
-
- lib/ably/models/
|
260
|
+
- lib/ably/models/token_details.rb
|
261
|
+
- lib/ably/models/token_request.rb
|
261
262
|
- lib/ably/modules/ably.rb
|
262
263
|
- lib/ably/modules/async_wrapper.rb
|
263
264
|
- lib/ably/modules/channels_collection.rb
|
@@ -356,7 +357,8 @@ files:
|
|
356
357
|
- spec/unit/models/presence_message_spec.rb
|
357
358
|
- spec/unit/models/protocol_message_spec.rb
|
358
359
|
- spec/unit/models/stats_spec.rb
|
359
|
-
- spec/unit/models/
|
360
|
+
- spec/unit/models/token_details_spec.rb
|
361
|
+
- spec/unit/models/token_request_spec.rb
|
360
362
|
- spec/unit/modules/async_wrapper_spec.rb
|
361
363
|
- spec/unit/modules/conversions_spec.rb
|
362
364
|
- spec/unit/modules/enum_spec.rb
|
@@ -449,7 +451,8 @@ test_files:
|
|
449
451
|
- spec/unit/models/presence_message_spec.rb
|
450
452
|
- spec/unit/models/protocol_message_spec.rb
|
451
453
|
- spec/unit/models/stats_spec.rb
|
452
|
-
- spec/unit/models/
|
454
|
+
- spec/unit/models/token_details_spec.rb
|
455
|
+
- spec/unit/models/token_request_spec.rb
|
453
456
|
- spec/unit/modules/async_wrapper_spec.rb
|
454
457
|
- spec/unit/modules/conversions_spec.rb
|
455
458
|
- spec/unit/modules/enum_spec.rb
|
data/lib/ably/models/token.rb
DELETED
@@ -1,74 +0,0 @@
|
|
1
|
-
module Ably::Models
|
2
|
-
# Authentication token issued by Ably in response to an token request
|
3
|
-
class Token
|
4
|
-
include Ably::Modules::ModelCommon
|
5
|
-
|
6
|
-
DEFAULTS = {
|
7
|
-
capability: { '*' => ['*'] },
|
8
|
-
ttl: 60 * 60 # 1 hour
|
9
|
-
}
|
10
|
-
|
11
|
-
# Buffer in seconds given to the use of a token prior to it being considered unusable
|
12
|
-
# For example, if buffer is 10s, the token can no longer be used for new requests 9s before it expires
|
13
|
-
TOKEN_EXPIRY_BUFFER = 5
|
14
|
-
|
15
|
-
def initialize(attributes)
|
16
|
-
@hash_object = IdiomaticRubyWrapper(attributes.clone.freeze)
|
17
|
-
end
|
18
|
-
|
19
|
-
# @!attribute [r] id
|
20
|
-
# @return [String] Unique token ID used to authenticate requests
|
21
|
-
def id
|
22
|
-
hash.fetch(:id)
|
23
|
-
end
|
24
|
-
|
25
|
-
# @!attribute [r] key_id
|
26
|
-
# @return [String] Key ID used to create this token
|
27
|
-
def key_id
|
28
|
-
hash.fetch(:key)
|
29
|
-
end
|
30
|
-
|
31
|
-
# @!attribute [r] issued_at
|
32
|
-
# @return [Time] Time the token was issued
|
33
|
-
def issued_at
|
34
|
-
as_time_from_epoch(hash.fetch(:issued_at), granularity: :s)
|
35
|
-
end
|
36
|
-
|
37
|
-
# @!attribute [r] expires_at
|
38
|
-
# @return [Time] Time the token expires
|
39
|
-
def expires_at
|
40
|
-
as_time_from_epoch(hash.fetch(:expires), granularity: :s)
|
41
|
-
end
|
42
|
-
|
43
|
-
# @!attribute [r] capability
|
44
|
-
# @return [Hash] Capabilities assigned to this token
|
45
|
-
def capability
|
46
|
-
hash.fetch(:capability)
|
47
|
-
end
|
48
|
-
|
49
|
-
# @!attribute [r] client_id
|
50
|
-
# @return [String] Optional client ID assigned to this token
|
51
|
-
def client_id
|
52
|
-
hash[:client_id]
|
53
|
-
end
|
54
|
-
|
55
|
-
# @!attribute [r] nonce
|
56
|
-
# @return [String] unique nonce used to generate Token and ensure token generation cannot be replayed
|
57
|
-
def nonce
|
58
|
-
hash.fetch(:nonce)
|
59
|
-
end
|
60
|
-
|
61
|
-
# Returns true if token is expired or about to expire
|
62
|
-
#
|
63
|
-
# @return [Boolean]
|
64
|
-
def expired?
|
65
|
-
expires_at < Time.now + TOKEN_EXPIRY_BUFFER
|
66
|
-
end
|
67
|
-
|
68
|
-
# @!attribute [r] hash
|
69
|
-
# @return [Hash] Access the token Hash object ruby'fied to use symbolized keys
|
70
|
-
def hash
|
71
|
-
@hash_object
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
@@ -1,86 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Ably::Models::Token do
|
4
|
-
subject { Ably::Models::Token }
|
5
|
-
|
6
|
-
it_behaves_like 'a model', with_simple_attributes: %w(id capability client_id nonce) do
|
7
|
-
let(:model_args) { [] }
|
8
|
-
end
|
9
|
-
|
10
|
-
context 'defaults' do
|
11
|
-
let(:one_hour) { 60 * 60 }
|
12
|
-
let(:all_capabilities) { { "*" => ["*"] } }
|
13
|
-
|
14
|
-
it 'should default TTL to 1 hour' do
|
15
|
-
expect(Ably::Models::Token::DEFAULTS[:ttl]).to eql(one_hour)
|
16
|
-
end
|
17
|
-
|
18
|
-
it 'should default capability to all' do
|
19
|
-
expect(Ably::Models::Token::DEFAULTS[:capability]).to eql(all_capabilities)
|
20
|
-
end
|
21
|
-
|
22
|
-
it 'should only have defaults for :ttl and :capability' do
|
23
|
-
expect(Ably::Models::Token::DEFAULTS.keys).to contain_exactly(:ttl, :capability)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
context 'attributes' do
|
28
|
-
let(:unique_value) { 'unique_value' }
|
29
|
-
|
30
|
-
context '#key_id' do
|
31
|
-
subject { Ably::Models::Token.new({ key: unique_value }) }
|
32
|
-
it 'retrieves attribute :key' do
|
33
|
-
expect(subject.key_id).to eql(unique_value)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
{ :issued_at => :issued_at, :expires_at => :expires }.each do |method_name, attribute|
|
38
|
-
let(:time) { Time.now }
|
39
|
-
context "##{method_name}" do
|
40
|
-
subject { Ably::Models::Token.new({ attribute.to_sym => time.to_i }) }
|
41
|
-
|
42
|
-
it "retrieves attribute :#{attribute} as Time" do
|
43
|
-
expect(subject.public_send(method_name)).to be_a(Time)
|
44
|
-
expect(subject.public_send(method_name).to_i).to eql(time.to_i)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
context '#expired?' do
|
50
|
-
let(:expire_time) { Time.now + Ably::Models::Token::TOKEN_EXPIRY_BUFFER }
|
51
|
-
|
52
|
-
context 'once grace period buffer has passed' do
|
53
|
-
subject { Ably::Models::Token.new(expires: expire_time - 1) }
|
54
|
-
|
55
|
-
it 'is true' do
|
56
|
-
expect(subject.expired?).to eql(true)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
context 'within grace period buffer' do
|
61
|
-
subject { Ably::Models::Token.new(expires: expire_time + 1) }
|
62
|
-
|
63
|
-
it 'is false' do
|
64
|
-
expect(subject.expired?).to eql(false)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
context '==' do
|
71
|
-
let(:token_attributes) { { id: 'unique' } }
|
72
|
-
|
73
|
-
it 'is true when attributes are the same' do
|
74
|
-
new_token = -> { Ably::Models::Token.new(token_attributes) }
|
75
|
-
expect(new_token[]).to eq(new_token[])
|
76
|
-
end
|
77
|
-
|
78
|
-
it 'is false when attributes are not the same' do
|
79
|
-
expect(Ably::Models::Token.new(id: 1)).to_not eq(Ably::Models::Token.new(id: 2))
|
80
|
-
end
|
81
|
-
|
82
|
-
it 'is false when class type differs' do
|
83
|
-
expect(Ably::Models::Token.new(id: 1)).to_not eq(nil)
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|