diff --git a/lib/ldclient-rb/ldclient.rb b/lib/ldclient-rb/ldclient.rb index 6e031aaf..c34b16e6 100644 --- a/lib/ldclient-rb/ldclient.rb +++ b/lib/ldclient-rb/ldclient.rb @@ -134,6 +134,7 @@ def toggle?(key, user, default = false) @config.logger.error("[LDClient] Must specify user") return default end + sanitize_user(user) if @config.stream? && !@stream_processor.started? @stream_processor.start @@ -176,6 +177,7 @@ def add_event(event) # @param [Hash] The user to register # def identify(user) + sanitize_user(user) add_event(kind: "identify", key: user[:key], user: user) end @@ -200,6 +202,7 @@ def is_offline? # # @return [void] def track(event_name, user, data) + sanitize_user(user) add_event(kind: "custom", key: event_name, user: user, data: data) end @@ -406,9 +409,15 @@ def log_exception(caller, exn) @config.logger.error(error) end + def sanitize_user(user) + if user[:key] + user[:key] = user[:key].to_s + end + end + private :post_flushed_events, :add_event, :get_streamed_flag, :get_flag_stream, :get_flag_int, :make_request, :param_for_user, :match_target?, :match_user?, :match_variation?, :evaluate, - :create_worker, :log_timings, :log_exception + :create_worker, :log_timings, :log_exception, :sanitize_user end end diff --git a/spec/fixtures/numeric_key_user.json b/spec/fixtures/numeric_key_user.json new file mode 100644 index 00000000..2a7ec475 --- /dev/null +++ b/spec/fixtures/numeric_key_user.json @@ -0,0 +1,9 @@ +{ + "key": 33, + "custom":{ + "groups":[ + "microsoft", + "google" + ] + } +} diff --git a/spec/fixtures/sanitized_numeric_key_user.json b/spec/fixtures/sanitized_numeric_key_user.json new file mode 100644 index 00000000..874e0067 --- /dev/null +++ b/spec/fixtures/sanitized_numeric_key_user.json @@ -0,0 +1,9 @@ +{ + "key": "33", + "custom":{ + "groups":[ + "microsoft", + "google" + ] + } +} diff --git a/spec/ldclient_spec.rb b/spec/ldclient_spec.rb index 2e48969a..2ed0d545 100644 --- a/spec/ldclient_spec.rb +++ b/spec/ldclient_spec.rb @@ -14,6 +14,14 @@ data = File.read(File.join("spec", "fixtures", "user.json")) JSON.parse(data, symbolize_names: true) end + let(:numeric_key_user) do + data = File.read(File.join("spec", "fixtures", "numeric_key_user.json")) + JSON.parse(data, symbolize_names: true) + end + let(:sanitized_numeric_key_user) do + data = File.read(File.join("spec", "fixtures", "sanitized_numeric_key_user.json")) + JSON.parse(data, symbolize_names: true) + end context 'user flag settings' do describe '#update_user_flag_setting' do @@ -85,6 +93,10 @@ result = client.toggle?(feature[:key], nil, "default") expect(result).to eq "default" end + it "sanitizes the user in the event" do + expect(client).to receive(:add_event).with(hash_including(user: sanitized_numeric_key_user)) + client.toggle?(feature[:key], numeric_key_user, "default") + end it "returns value from streamed flag if available" do expect(client.instance_variable_get(:@config)).to receive(:stream?).and_return(true).twice expect(client.instance_variable_get(:@stream_processor)).to receive(:started?).and_return true @@ -103,6 +115,28 @@ end end + describe '#identify' do + it "queues up an identify event" do + expect(client).to receive(:add_event).with(hash_including(kind: "identify", key: user[:key], user: user)) + client.identify(user) + end + it "sanitizes the user in the event" do + expect(client).to receive(:add_event).with(hash_including(user: sanitized_numeric_key_user)) + client.identify(numeric_key_user) + end + end + + describe '#track' do + it "queues up an custom event" do + expect(client).to receive(:add_event).with(hash_including(kind: "custom", key: "custom_event_name", user: user, data: 42)) + client.track("custom_event_name", user, 42) + end + it "sanitizes the user in the event" do + expect(client).to receive(:add_event).with(hash_including(user: sanitized_numeric_key_user)) + client.track("custom_event_name", numeric_key_user, nil) + end + end + describe '#get_streamed_flag' do it "will not check the polled flag normally" do expect(client).to receive(:get_flag_stream).and_return true