lib/submodules/ably-ruby/spec/acceptance/rest/auth_spec.rb in ably-rest-0.8.9 vs lib/submodules/ably-ruby/spec/acceptance/rest/auth_spec.rb in ably-rest-0.8.13

- old
+ new

@@ -610,10 +610,91 @@ it 'issues a new token if option :force => true' do expect { auth.authorise(force: true) }.to change { auth.current_token_details } end end + context 'query_time: true' do + let(:local_time) { @now - 60 } + let(:server_time) { @now } + + before do + @now = Time.now + allow(Time).to receive(:now).and_return(local_time) + end + + it 'only queries the server time once and then works out the offset, query_time option is never persisted' do + expect(client).to receive(:time).once.and_return(server_time) + + auth.authorise({}, query_time: true) + auth.authorise({}, force: true) + expect(auth.auth_options).to_not have_key(:query_time) + end + end + + context 'TokenParams argument' do + let(:default_token_params) { { ttl: 23 } } + + before do + auth.authorise default_token_params + end + + it 'has no effect on the defaults when null and TokenParam defaults remain the same' do + old_token = auth.current_token_details + auth.authorise(nil, force: true) + expect(old_token).to_not eql(auth.current_token_details) + expect(auth.token_params[:ttl]).to eql(23) + end + + it 'updates defaults when present and all previous configured TokenParams are discarded' do + old_token = auth.current_token_details + auth.authorise({ client_id: 'bob' }, { force: true }) + expect(old_token).to_not eql(auth.current_token_details) + expect(auth.token_params[:ttl]).to_not eql(23) + expect(auth.token_params[:client_id]).to eql('bob') + end + + it 'updates Auth#token_params attribute with an immutable hash' do + auth.authorise({ client_id: 'bob' }, { force: true }) + expect { auth.token_params['key_name'] = 'new_name' }.to raise_error RuntimeError, /can't modify frozen.*Hash/ + end + end + + context 'AuthOptions argument' do + let(:token_ttl) { 2 } + let(:auth_callback) { Proc.new do + auth.create_token_request(ttl: token_ttl) + end } + let(:default_auth_options) { { auth_callback: auth_callback } } + + before do + stub_const 'Ably::Models::TokenDetails::TOKEN_EXPIRY_BUFFER', 0 # allow token to be used even if about to expire + stub_const 'Ably::Auth::TOKEN_DEFAULTS', Ably::Auth::TOKEN_DEFAULTS.merge(renew_token_buffer: 0) # Ensure tokens issued expire immediately after issue + + auth.authorise(nil, default_auth_options) + @old_token = auth.current_token_details + sleep token_ttl + 0.5 + end + + it 'has no effect on the defaults when null and AuthOptions defaults remain the same' do + auth.authorise(nil, nil) + expect(@old_token).to_not eql(auth.current_token_details) + expect(auth.options[:auth_callback]).to eql(auth_callback) + end + + it 'updates defaults when present and all previous configured AuthOptions are discarded' do + auth.authorise(nil, auth_method: :post) + expect(@old_token).to_not eql(auth.current_token_details) + expect(auth.options[:auth_callback]).to be_nil + expect(auth.options[:auth_method]).to eql(:post) + end + + it 'updates Auth#options attribute with an immutable hash' do + auth.authorise(nil, auth_callback: Proc.new { '1231232.12321:12321312' }) + expect { auth.options['key_name'] = 'new_name' }.to raise_error RuntimeError, /can't modify frozen.*Hash/ + end + end + context 'with previous authorisation' do before do auth.authorise expect(auth.current_token_details).to_not be_expired end @@ -638,14 +719,14 @@ expect(auth.token_params[:ttl]).to_not eql(26) auth.authorise(ttl: 26) expect(auth.token_params[:ttl]).to eql(26) end - it 'updates the persisted token params that are then used for subsequent authorise requests' do - expect(auth.options[:query_time]).to_not eql(true) - auth.authorise({}, query_time: true) - expect(auth.options[:query_time]).to eql(true) + it 'updates the persisted auth options that are then used for subsequent authorise requests' do + expect(auth.options[:authUrl]).to be_nil + auth.authorise({}, authUrl: 'http://foo.com') + expect(auth.options[:authUrl]).to eql('http://foo.com') end context 'with a Proc for the :auth_callback option' do let(:client_id) { random_str } let!(:token) do @@ -890,9 +971,46 @@ end it 'generates a valid HMAC' do hmac = hmac_for(Ably::Models::TokenRequest(token_request_attributes).attributes, key_secret) expect(subject['mac']).to eql(hmac) + end + + context 'lexicographic ordering of channels and operations' do + let(:token_attributes) do + { + key_name: key_name, + ttl: 600, + capability: { + "channel2" => ["subscribe", "publish"], + "channel1" => ["subscribe", "history"] + }, + client_id: random_str, + nonce: random_str, + timestamp: Time.now.to_i + } + end + + let(:token_attributes_ordered) do + token_attributes.merge(capability: { + "channel1" => ["history", "subscribe"], + "channel2" => ["publish", "subscribe"] + }) + end + + specify 'HMAC is lexicographic ordered and thus the HMAC is identical' do + hmac = auth.create_token_request(token_attributes).mac + hmac_ordered = auth.create_token_request(token_attributes_ordered).mac + expect(hmac).to eql(hmac_ordered) + end + + it 'is valid when used for authentication' do + auth_callback = Proc.new do + auth.create_token_request(token_attributes) + end + client = Ably::Rest::Client.new(auth_callback: auth_callback, environment: environment, protocol: protocol) + client.auth.authorise + end end end end context 'using token authentication' do