diff --git a/.pubnub.yml b/.pubnub.yml index 1a128704e..80ec4c98b 100644 --- a/.pubnub.yml +++ b/.pubnub.yml @@ -1,6 +1,13 @@ --- -version: "5.0.0" +version: "5.1.0" changelog: + - date: 2022-07-26 + version: v5.1.0 + changes: + - type: feature + text: "Add support for spaces and users permissions in grant_token." + - type: feature + text: "Add user_id and deprecate uuid when creating new pubnub instance." - date: 2022-01-13 version: v5.0.0 changes: @@ -625,7 +632,7 @@ sdks: - x86-64 - distribution-type: package distribution-repository: RubyGems - package-name: pubnub-5.0.0.gem + package-name: pubnub-5.1.0.gem location: https://rubygems.org/gems/pubnub requires: - name: addressable @@ -730,8 +737,8 @@ sdks: - x86-64 - distribution-type: library distribution-repository: GitHub release - package-name: pubnub-5.0.0.gem - location: https://github.com/pubnub/ruby/releases/download/v5.0.0/pubnub-5.0.0.gem + package-name: pubnub-5.1.0.gem + location: https://github.com/pubnub/ruby/releases/download/v5.1.0/pubnub-5.1.0.gem requires: - name: addressable min-version: 2.0.0 diff --git a/CHANGELOG.md b/CHANGELOG.md index 868cb3a69..be8b28c50 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## v5.1.0 +July 26 2022 + +#### Added +- Add support for spaces and users permissions in grant_token. +- Add user_id and deprecate uuid when creating new pubnub instance. + ## v5.0.0 January 13 2022 diff --git a/Gemfile.lock b/Gemfile.lock index 80a530263..0a5d9c34a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - pubnub (5.0.0) + pubnub (5.1.0) addressable (>= 2.0.0) concurrent-ruby (~> 1.1.5) concurrent-ruby-edge (~> 0.5.0) diff --git a/VERSION b/VERSION index 0062ac971..831446cbd 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -5.0.0 +5.1.0 diff --git a/fixtures/vcr_cassettes/examples/grant_token/1.yml b/fixtures/vcr_cassettes/examples/grant_token/1.yml new file mode 100644 index 000000000..a485162e1 --- /dev/null +++ b/fixtures/vcr_cassettes/examples/grant_token/1.yml @@ -0,0 +1,38 @@ +--- +http_interactions: +- request: + method: post + uri: http://ps.pndsn.com/v3/pam/sub-a-mock-key/grant?auth=ruby-test-auth-client-one&pnsdk=PubNub-Ruby/5.0.0&signature=v2.dOOoWVBHwrRw3kXQ37gWR1De6TlufWW_ccWaLFMhaSw×tamp=1657795717&uuid=ruby-test-user-id-client-one + body: + encoding: UTF-8 + string: '{"ttl":60,"permissions":{"uuid":"authorized_user_id","resources":{"channels":{"id":1},"groups":{},"uuids":{"user1":64}},"patterns":{"channels":{"whatever.*":3},"groups":{},"uuids":{"users.*":24}}}}' + headers: + User-Agent: + - HTTPClient/1.0 (2.8.3, ruby 2.7.1 (2020-03-31)) + Accept: + - "*/*" + Date: + - Thu, 14 Jul 2022 10:48:37 GMT + Content-Type: + - application/json + response: + status: + code: 200 + message: OK + headers: + Date: + - Thu, 14 Jul 2022 10:48:32 GMT + Content-Type: + - text/javascript; charset=UTF-8 + Transfer-Encoding: + - chunked + Connection: + - keep-alive + Cache-Control: + - no-cache, no-store, must-revalidate + body: + encoding: UTF-8 + string: '{"data":{"message":"Success","token":"qEF2AkF0GmLP9IBDdHRsGDxDcmVzpURjaGFuoWJpZAFDZ3JwoENzcGOgQ3VzcqBEdXVpZKFldXNlcjEYQENwYXSlRGNoYW6handoYXRldmVyLioDQ2dycKBDc3BjoEN1c3KgRHV1aWShZ3VzZXJzLioYGERtZXRhoER1dWlkcmF1dGhvcml6ZWRfdXNlcl9pZENzaWdYIJcNyBtPLfLcJjZfXoVY2bzAlcjAKRqoesdbaSaCRfOc"},"service":"Access + Manager","status":200}' + recorded_at: Thu, 14 Jul 2022 10:48:37 GMT +recorded_with: VCR 6.0.0 diff --git a/lib/pubnub/event.rb b/lib/pubnub/event.rb index 595bdc63c..7b7f062f6 100644 --- a/lib/pubnub/event.rb +++ b/lib/pubnub/event.rb @@ -175,7 +175,7 @@ def create_variables_from_options(options) state channel_group channel_groups compressed meta customs include_token replicate with_presence cipher_key_selector include_meta join update get add remove push_token push_gateway environment topic authorized_uuid - token + authorized_user_id token ] options = options.each_with_object({}) { |option, obj| obj[option.first.to_sym] = option.last } diff --git a/lib/pubnub/events/grant_token.rb b/lib/pubnub/events/grant_token.rb index 71db32abf..dc474eb1c 100644 --- a/lib/pubnub/events/grant_token.rb +++ b/lib/pubnub/events/grant_token.rb @@ -10,19 +10,28 @@ def initialize(options, app) @uuids = options[:uuids] || {} options[:channels] = options[:channels] || {} options[:channel_groups] = options[:channel_groups] || {} + @spaces_permissions = options[:spaces_permissions] || {} + @users_permissions = options[:users_permissions] || {} super end def fire Pubnub.logger.debug('Pubnub::GrantToken') { "Fired event #{self.class}" } + if @authorized_user_id != nil + uuid = @authorized_user_id + elsif @authorized_uuid != nil + uuid = @authorized_uuid + else + uuid = nil + end raw_body = { ttl: @ttl, permissions: { meta: @meta, - uuid: @authorized_uuid, - resources: prepare_permissions(:resource, @channels, @channel_groups, @uuids), - patterns: prepare_permissions(:pattern, @channels, @channel_groups, @uuids) + uuid: uuid, + resources: prepare_permissions(:resource, @channels, @channel_groups, @uuids, @spaces_permissions, @users_permissions), + patterns: prepare_permissions(:pattern, @channels, @channel_groups, @uuids, @spaces_permissions, @users_permissions) }.select { |_, v| v } } body = Formatter.format_message(raw_body, "", false, false) @@ -47,11 +56,11 @@ def current_operation Pubnub::Constants::OPERATION_GRANT_TOKEN end - def prepare_permissions(type, channels, groups, uuids) + def prepare_permissions(type, channels, groups, uuids, spaces_permissions, users_permissions) { - channels: prepare_single_permissions(type, channels), + channels: prepare_single_permissions(type, channels).merge!(prepare_single_permissions(type, spaces_permissions)), groups: prepare_single_permissions(type, groups), - uuids: prepare_single_permissions(type, uuids) + uuids: prepare_single_permissions(type, uuids).merge!(prepare_single_permissions(type, users_permissions)) } end diff --git a/lib/pubnub/validators/grant_token.rb b/lib/pubnub/validators/grant_token.rb index 326f4be58..829118624 100644 --- a/lib/pubnub/validators/grant_token.rb +++ b/lib/pubnub/validators/grant_token.rb @@ -12,6 +12,7 @@ def validate! validate_permissions!(@uuids, ":uuids") validate_permissions!(@channels, ":channels") validate_permissions!(@channel_groups, ":uuids") + validate_objects_entities_separation! end private @@ -45,6 +46,19 @@ def validate_permissions!(arg, name) ":#{name} has to be kind of Hash for grant token event." ) unless arg.is_a?(Hash) end + + def validate_objects_entities_separation! + entities_set = !@spaces_permissions.empty? || + !@users_permissions.empty? + objects_set = !@channels.empty? || + !@channel_groups.empty? || + !@uuids.empty? + + raise( + ArgumentError.new(object: self, message: "Can't mix entities and objects"), + "Can't mix entities and objects" + ) if (entities_set && objects_set) + end end end end diff --git a/lib/pubnub/version.rb b/lib/pubnub/version.rb index 04631a02d..9282cbdea 100644 --- a/lib/pubnub/version.rb +++ b/lib/pubnub/version.rb @@ -1,4 +1,4 @@ # Toplevel Pubnub module. module Pubnub - VERSION = '5.0.0'.freeze + VERSION = '5.1.0'.freeze end diff --git a/spec/examples/grant_token_examples_spec.rb b/spec/examples/grant_token_examples_spec.rb new file mode 100644 index 000000000..fb93c9adb --- /dev/null +++ b/spec/examples/grant_token_examples_spec.rb @@ -0,0 +1,52 @@ +require "spec_helper" + +describe Pubnub::GrantToken do + around :each do |example| + @fired = false + + @callback = -> (_envelope) do + @fired = true + end + + @pubnub = Pubnub.new( + publish_key: "pub-a-mock-key", + subscribe_key: "sub-a-mock-key", + secret_key: "sec-a-mock-key", + user_id: "ruby-test-user-id-client-one", + auth_key: "ruby-test-auth-client-one", + ) + + example.run_with_retry retry: 10 + end + + it "__channel___demo____group__nil___read__false___write__false___manage__false___ttl__300___auth_key__nil___http_sync__true___callback___block_" do + VCR.use_cassette("examples/grant_token/1", record: :none) do + Pubnub::Grant.any_instance.stub(:current_time).and_return "1657795717" + Pubnub::Grant.any_instance.stub(:signature).and_return "v2.dOOoWVBHwrRw3kXQ37gWR1De6TlufWW_ccWaLFMhaSw" + envelope = @pubnub.grant_token( + ttl: 60, + authorized_user_id: "authorized_user_id", + spaces_permissions: { + "id": Pubnub::Permissions.res(read: true), + "whatever.*": Pubnub::Permissions.pat(read: true, write: true) + }, + users_permissions: { + "user1": Pubnub::Permissions.res(update: true), + "users.*": Pubnub::Permissions.pat(create: true, delete: true), + }, + http_sync: true, + &@callback + ) + expect(envelope.is_a?(Pubnub::Envelope)).to eq true + expect(envelope.error?).to eq false + + expect(envelope.status[:code]).to eq(200) + expect(envelope.status[:category]).to eq(:ack) + expect(envelope.status[:config]).to eq({:tls => false, :uuid => "ruby-test-user-id-client-one", :auth_key => "ruby-test-auth-client-one", :origin => "ps.pndsn.com"}) + + expect(envelope.result[:code]).to eq(200) + expect(envelope.result[:operation]).to eq(:grant_token) + end + end + +end diff --git a/spec/lib/events/grant_token_spec.rb b/spec/lib/events/grant_token_spec.rb index a67665ab3..63b98cf30 100644 --- a/spec/lib/events/grant_token_spec.rb +++ b/spec/lib/events/grant_token_spec.rb @@ -18,7 +18,7 @@ ) end - let(:envelope) do + let(:envelope_with_objects) do pubnub.grant_token( ttl: 60, authorized_uuid: "authorized_uuid", @@ -28,18 +28,49 @@ ).value end - it "works" do + let(:envelope_with_entities) do + pubnub.grant_token( + ttl: 60, + authorized_uuid: "authorized_uuid", + spaces_permissions: { + "id": Pubnub::Permissions.res(read: true) + } + ).value + end + + it "raises error when mixing objects and entities" do + expect { pubnub.grant_token( + ttl: 60, + authorized_uuid: "authorized_uuid", + spaces_permissions: { + "id": Pubnub::Permissions.res(read: true) + }, + channels: { + "id": Pubnub::Permissions.res(read: true) + } + ).value }.to raise_error(Pubnub::ArgumentError) + end + + it "works with objects" do + VCR.use_cassette("lib/events/grant-token", record: :once) do + expect(envelope_with_objects.is_a?(Pubnub::ErrorEnvelope)).to eq false + expect(envelope_with_objects.status).to satisfies_schema Pubnub::Schemas::Envelope::StatusSchema.new + expect(envelope_with_objects.result).to satisfies_schema Pubnub::Schemas::Envelope::ResultSchema.new + end + end + + it "works with entities" do VCR.use_cassette("lib/events/grant-token", record: :once) do - expect(envelope.is_a?(Pubnub::ErrorEnvelope)).to eq false - expect(envelope.status).to satisfies_schema Pubnub::Schemas::Envelope::StatusSchema.new - expect(envelope.result).to satisfies_schema Pubnub::Schemas::Envelope::ResultSchema.new + expect(envelope_with_entities.is_a?(Pubnub::ErrorEnvelope)).to eq false + expect(envelope_with_entities.status).to satisfies_schema Pubnub::Schemas::Envelope::StatusSchema.new + expect(envelope_with_entities.result).to satisfies_schema Pubnub::Schemas::Envelope::ResultSchema.new end end it "forms valid ErrorEnvelope on error" do VCR.use_cassette("lib/events/grant-token-error", record: :once) do - expect(envelope.is_a?(Pubnub::ErrorEnvelope)).to eq true - expect(envelope.status).to satisfies_schema Pubnub::Schemas::Envelope::StatusSchema.new + expect(envelope_with_objects.is_a?(Pubnub::ErrorEnvelope)).to eq true + expect(envelope_with_objects.status).to satisfies_schema Pubnub::Schemas::Envelope::StatusSchema.new end end end diff --git a/spec/lib/events/publish_spec.rb b/spec/lib/events/publish_spec.rb index cd1b68833..cdfceae39 100644 --- a/spec/lib/events/publish_spec.rb +++ b/spec/lib/events/publish_spec.rb @@ -46,7 +46,7 @@ :error_callback => @error_callback, ) - @pubnub.uuid = "tester" + @pubnub.user_id = "tester" end it "works" do