From f1f242f8d4a49ce68dc4d51dcdf1da94c0528a1f Mon Sep 17 00:00:00 2001 From: harishmallow Date: Wed, 15 May 2019 15:34:21 +0530 Subject: [PATCH 1/6] feat: Added support for spam check --- lib/cleantalk.rb | 2 ++ lib/cleantalk/request.rb | 17 +++++++++++++++++ lib/cleantalk/spam_check.rb | 16 ++++++++++++++++ lib/cleantalk/spam_check_result.rb | 5 +++++ 4 files changed, 40 insertions(+) create mode 100644 lib/cleantalk/spam_check.rb create mode 100644 lib/cleantalk/spam_check_result.rb diff --git a/lib/cleantalk.rb b/lib/cleantalk.rb index 45ecbd7..a547ae8 100644 --- a/lib/cleantalk.rb +++ b/lib/cleantalk.rb @@ -33,6 +33,8 @@ def self.auth_key= value require 'cleantalk/request' require 'cleantalk/check_newuser' require 'cleantalk/check_message' +require 'cleantalk/spam_check' require 'cleantalk/result' require 'cleantalk/check_newuser_result' require 'cleantalk/check_message_result' +require 'cleantalk/spam_check_result' \ No newline at end of file diff --git a/lib/cleantalk/request.rb b/lib/cleantalk/request.rb index f9fc2ca..ec43561 100644 --- a/lib/cleantalk/request.rb +++ b/lib/cleantalk/request.rb @@ -36,6 +36,23 @@ def http_request_without_parse response.entity end + def spam_check_http_request_without_parse + valid? + uri = URI.parse('https://api.cleantalk.org') + self.instance_variables.inject({}) do |params, var_name| + param_key = var_name.to_s.sub('@', '') + new_query_ar = URI.decode_www_form(uri.query || '') << [params, send(param_key)] + uri.query = URI.encode_www_form(new_query_ar) + end + + http = Net::HTTP.new(uri.host, uri.port) + http.use_ssl = true + req = Net::HTTP::Get.new(uri) + response = http.request(req) + + response.entity + end + # Remote Call def http_request JSON.parse http_request_without_parse diff --git a/lib/cleantalk/spam_check.rb b/lib/cleantalk/spam_check.rb new file mode 100644 index 0000000..4a4d0a0 --- /dev/null +++ b/lib/cleantalk/spam_check.rb @@ -0,0 +1,16 @@ +require 'net/http' +require 'json' + +class Cleantalk::SpamCheck < Cleantalk::Request + attr_accessor :ip, :email, :date + + def result + @result ||= Cleantalk::SpamCheckResult.new(spam_check_http_request_without_parse) + end + + def spammed? + self.result.appears == 1 + end + + METHOD = 'spam_check'.freeze +end diff --git a/lib/cleantalk/spam_check_result.rb b/lib/cleantalk/spam_check_result.rb new file mode 100644 index 0000000..ed7e99b --- /dev/null +++ b/lib/cleantalk/spam_check_result.rb @@ -0,0 +1,5 @@ +class Cleantalk::SpamCheckResult < Cleantalk::Result + attr_reader :data, :id, :appears, :sha256, :network_type, + :spam_rate, :frequency, :frequency_time_10m, + :frequency_time_1h, :frequency_time_24h +end From 2bfab21e30bf3d97bb7d3285d09586da06e48892 Mon Sep 17 00:00:00 2001 From: harishmallow Date: Wed, 15 May 2019 17:42:16 +0530 Subject: [PATCH 2/6] fix: changed params instead of param key --- lib/cleantalk/request.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/cleantalk/request.rb b/lib/cleantalk/request.rb index ec43561..fb4e28e 100644 --- a/lib/cleantalk/request.rb +++ b/lib/cleantalk/request.rb @@ -41,7 +41,7 @@ def spam_check_http_request_without_parse uri = URI.parse('https://api.cleantalk.org') self.instance_variables.inject({}) do |params, var_name| param_key = var_name.to_s.sub('@', '') - new_query_ar = URI.decode_www_form(uri.query || '') << [params, send(param_key)] + new_query_ar = URI.decode_www_form(uri.query || '') << [param_key, send(param_key)] uri.query = URI.encode_www_form(new_query_ar) end From 2c1bc118e5fa43a533f955e3c110ebcaf3f8db01 Mon Sep 17 00:00:00 2001 From: harishmallow Date: Wed, 15 May 2019 17:58:32 +0530 Subject: [PATCH 3/6] chore: Added blacklist? method to check for value is blacklist or not --- lib/cleantalk/spam_check.rb | 5 +++-- lib/cleantalk/spam_check_result.rb | 7 ++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/cleantalk/spam_check.rb b/lib/cleantalk/spam_check.rb index 4a4d0a0..1e0ad6f 100644 --- a/lib/cleantalk/spam_check.rb +++ b/lib/cleantalk/spam_check.rb @@ -8,8 +8,9 @@ def result @result ||= Cleantalk::SpamCheckResult.new(spam_check_http_request_without_parse) end - def spammed? - self.result.appears == 1 + def blacklist?(email_or_ip) + return nil if self.result[email_or_ip].nil? + self.result[email_or_ip]['appears'] == 1 end METHOD = 'spam_check'.freeze diff --git a/lib/cleantalk/spam_check_result.rb b/lib/cleantalk/spam_check_result.rb index ed7e99b..b1bf1dd 100644 --- a/lib/cleantalk/spam_check_result.rb +++ b/lib/cleantalk/spam_check_result.rb @@ -1,5 +1,6 @@ class Cleantalk::SpamCheckResult < Cleantalk::Result - attr_reader :data, :id, :appears, :sha256, :network_type, - :spam_rate, :frequency, :frequency_time_10m, - :frequency_time_1h, :frequency_time_24h + attr_reader :data + # :id, :appears, :sha256, :network_type, + # :spam_rate, :frequency, :frequency_time_10m, + # :frequency_time_1h, :frequency_time_24h end From 1ab5adb9ea8b56125eecbd9ee48026b3eddf0a80 Mon Sep 17 00:00:00 2001 From: harishmallow Date: Wed, 15 May 2019 18:04:20 +0530 Subject: [PATCH 4/6] fix: Check for data in blacklist --- lib/cleantalk/spam_check.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/cleantalk/spam_check.rb b/lib/cleantalk/spam_check.rb index 1e0ad6f..f97f195 100644 --- a/lib/cleantalk/spam_check.rb +++ b/lib/cleantalk/spam_check.rb @@ -9,8 +9,8 @@ def result end def blacklist?(email_or_ip) - return nil if self.result[email_or_ip].nil? - self.result[email_or_ip]['appears'] == 1 + return nil if self.result.data.present? && self.result.data[email_or_ip].nil? + self.result.data[email_or_ip]['appears'] == 1 end METHOD = 'spam_check'.freeze From b3461274a772d6e151a67532c2bfb802491456c8 Mon Sep 17 00:00:00 2001 From: harishmallow Date: Thu, 16 May 2019 12:48:59 +0530 Subject: [PATCH 5/6] fix: Added specs for spam check --- lib/cleantalk/request.rb | 52 ++++++------- lib/cleantalk/spam_check.rb | 6 +- spec/spam_check_result_spec.rb | 64 ++++++++++++++++ spec/spam_check_spec.rb | 132 +++++++++++++++++++++++++++++++++ 4 files changed, 226 insertions(+), 28 deletions(-) create mode 100644 spec/spam_check_result_spec.rb create mode 100644 spec/spam_check_spec.rb diff --git a/lib/cleantalk/request.rb b/lib/cleantalk/request.rb index fb4e28e..abb04b1 100644 --- a/lib/cleantalk/request.rb +++ b/lib/cleantalk/request.rb @@ -19,37 +19,37 @@ def initialize(params = {}) end end - def http_request_without_parse + def http_request_without_parse(api = nil, request_type = 'post') valid? - form_data = self.instance_variables.inject({}) do |params, var_name| - param_key = var_name.to_s.sub('@','') - params[param_key] = send(param_key) - params - end - - req = Net::HTTP::Post.new(API_URI, API_HEADERS) - req.body = JSON.generate(form_data) - response = Net::HTTP.start(API_URI.hostname, API_URI.port, use_ssl: true) do |http| - http.request(req) + if api.nil? + form_data = self.instance_variables.inject({}) do |params, var_name| + param_key = var_name.to_s.sub('@', '') + params[param_key] = send(param_key) + params + end + else + uri = URI.parse(api) + self.instance_variables.inject({}) do |params, var_name| + param_key = var_name.to_s.sub('@', '') + new_query_ar = URI.decode_www_form(uri.query || '') << [param_key, send(param_key)] + uri.query = URI.encode_www_form(new_query_ar) + end end - response.entity - end - - def spam_check_http_request_without_parse - valid? - uri = URI.parse('https://api.cleantalk.org') - self.instance_variables.inject({}) do |params, var_name| - param_key = var_name.to_s.sub('@', '') - new_query_ar = URI.decode_www_form(uri.query || '') << [param_key, send(param_key)] - uri.query = URI.encode_www_form(new_query_ar) + case request_type + when 'post' + req = Net::HTTP::Post.new(API_URI, API_HEADERS) + req.body = JSON.generate(form_data) + response = Net::HTTP.start(API_URI.hostname, API_URI.port, use_ssl: true) do |http| + http.request(req) + end + when 'get' + http = Net::HTTP.new(uri.host, uri.port) + http.use_ssl = true + req = Net::HTTP::Get.new(uri) + response = http.request(req) end - http = Net::HTTP.new(uri.host, uri.port) - http.use_ssl = true - req = Net::HTTP::Get.new(uri) - response = http.request(req) - response.entity end diff --git a/lib/cleantalk/spam_check.rb b/lib/cleantalk/spam_check.rb index f97f195..8b02dee 100644 --- a/lib/cleantalk/spam_check.rb +++ b/lib/cleantalk/spam_check.rb @@ -5,13 +5,15 @@ class Cleantalk::SpamCheck < Cleantalk::Request attr_accessor :ip, :email, :date def result - @result ||= Cleantalk::SpamCheckResult.new(spam_check_http_request_without_parse) + @result ||= Cleantalk::SpamCheckResult.new(http_request_without_parse(SPAMCHECK_API, REQUEST_TYPE)) end def blacklist?(email_or_ip) - return nil if self.result.data.present? && self.result.data[email_or_ip].nil? + return nil if !self.result.data.empty? && self.result.data[email_or_ip].nil? self.result.data[email_or_ip]['appears'] == 1 end + SPAMCHECK_API = 'https://api.cleantalk.org'.freeze + REQUEST_TYPE = 'get'.freeze METHOD = 'spam_check'.freeze end diff --git a/spec/spam_check_result_spec.rb b/spec/spam_check_result_spec.rb new file mode 100644 index 0000000..a048573 --- /dev/null +++ b/spec/spam_check_result_spec.rb @@ -0,0 +1,64 @@ +require 'spec_helper' + +describe Cleantalk::SpamCheckResult do + let :clean_init_values do + {"data" => + { + "test@example.org" => + { + "appears" => 0, + "sha256" => '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08', + "network_type" => 'public', + "spam_rate" => '3', + "frequency" => '5', + "frequency_time_10m" => '1', + "frequency_time_1h" => '2', + "frequency_time_24h" => '4' + }, + "127.0.0.1" => + { + "appears" => 0, + "sha256" => '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08', + "network_type" => 'hosting', + "spam_rate" => '4', + "frequency" => '1', + "frequency_time_10m" => '3', + "frequency_time_1h" => '2', + "frequency_time_24h" => '1' + } + } + + } + end + let :init_values do + clean_init_values.merge({ + "lalilulelo" => "patriot" + }) + end + + describe "#initialize" do + it 'pass all result from an Hash' do + instance = described_class.new(init_values) + + clean_init_values.each do |key, value| + expect(instance.send(key)).to eql(value) + end + + expect do + instance.lalilulelo + end.to raise_error(NoMethodError) + end + end + + it 'pass all result from JSON string' do + instance = described_class.new(JSON.fast_generate(init_values)) + + clean_init_values.each do |key, value| + expect(instance.send(key)).to eql(value) + end + + expect do + instance.lalilulelo + end.to raise_error(NoMethodError) + end +end diff --git a/spec/spam_check_spec.rb b/spec/spam_check_spec.rb new file mode 100644 index 0000000..e6fcb61 --- /dev/null +++ b/spec/spam_check_spec.rb @@ -0,0 +1,132 @@ +require 'spec_helper' + +describe Cleantalk::SpamCheck do + # Testing values + let :headers do + { + 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'Content-Type' => 'application/json', 'User-Agent' => 'Ruby', 'Host' => 'api.cleantalk.org' + } + end + + let :res_body_spam do + {"data" => + { + "test@example.org" => + { + "appears" => 1, + "sha256" => '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08', + "network_type" => 'public', + "spam_rate" => '3', + "frequency" => '5', + "frequency_time_10m" => '1', + "frequency_time_1h" => '2', + "frequency_time_24h" => '4' + }, + "127.0.0.1" => + { + "appears" => 1, + "sha256" => '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08', + "network_type" => 'hosting', + "spam_rate" => '4', + "frequency" => '1', + "frequency_time_10m" => '3', + "frequency_time_1h" => '2', + "frequency_time_24h" => '1' + } + } + + } + end + + let :res_body_not_spam do + {"data" => + { + "test@example.org" => + { + "appears" => 0, + "sha256" => '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08', + "network_type" => 'hosting', + "spam_rate" => '0', + "frequency" => '0', + "frequency_time_10m" => '0', + "frequency_time_1h" => '0', + "frequency_time_24h" => '0' + }, + "127.0.0.1" => + { + "appears" => 0, + "sha256" => '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08', + "network_type" => 'hosting', + "spam_rate" => '0', + "frequency" => '0', + "frequency_time_10m" => '0', + "frequency_time_1h" => '0', + "frequency_time_24h" => '0' + } + } + } + end + + let :base_parameters do + {method_name: "spam_check", auth_key: 'test', email: 'test@example.org', ip: '127.0.0.1'} + end + + let :request do + described_class.new(base_parameters.merge({method_name: "unknow_method"})) + end + +# Specs + it 'create a request' do + subject.auth_key = 'test' + expect(subject.auth_key).to eql('test') + expect(subject.is_a? Cleantalk::Request).to eql(true) + expect(subject.method_name).to eql("spam_check") + end + + describe "#initialize" do + it 'can pass params definition' do + expect(request.auth_key).to eql('test') + expect(request.email).to eql('test@example.org') + expect(request.is_a? Cleantalk::Request).to eql(true) + expect(request.method_name).to eql("spam_check") + expect(request.ip).to eql(base_parameters[:ip]) + end + end + + describe "#blacklist?" do + it "call one time request and return true when blacklisted" do + stub_request(:get, "https://api.cleantalk.org/?auth_key=test&email=test@example.org&ip=127.0.0.1&method_name=spam_check"). + with( + headers: { + 'Accept' => '*/*', + 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'Host' => 'api.cleantalk.org', + 'User-Agent' => 'Ruby' + }). + to_return(status: 200, body: JSON.dump(res_body_spam), headers: {}) + + expect(request.blacklist?('test@example.org')).to eql(true) + expect_any_instance_of(described_class).to_not receive(:spam_check_http_request_without_parse) + expect(request.blacklist?('127.0.0.1')).to eql(true) + expect(request.blacklist?('randomtext')).to eql(nil) + end + + it "call one time request and return false when not_blacklisted" do + stub_request(:get, "https://api.cleantalk.org/?auth_key=test&email=test@example.org&ip=127.0.0.1&method_name=spam_check"). + with( + headers: { + 'Accept' => '*/*', + 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'Host' => 'api.cleantalk.org', + 'User-Agent' => 'Ruby' + }). + to_return(status: 200, body: JSON.dump(res_body_not_spam), headers: {}) + + expect(request.blacklist?('test@example.org')).to eql(false) + expect_any_instance_of(described_class).to_not receive(:spam_check_http_request_without_parse) + expect(request.blacklist?('127.0.0.1')).to eql(false) + expect(request.blacklist?('randomtext')).to eql(nil) + end + end +end From f30c4d68345ef3cf538745a6ccf5f57bc5fd229d Mon Sep 17 00:00:00 2001 From: harishmallow Date: Thu, 16 May 2019 18:34:16 +0530 Subject: [PATCH 6/6] feat: raise error if it has error no or error message --- lib/cleantalk/result.rb | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/cleantalk/result.rb b/lib/cleantalk/result.rb index 55a5401..ff4dad5 100644 --- a/lib/cleantalk/result.rb +++ b/lib/cleantalk/result.rb @@ -1,11 +1,23 @@ class Cleantalk::Result attr_reader :id, :version, :inactive, :js_disabled, :blacklisted, - :comment, :codes,:fast_submit, :account_status, :allow + :comment, :codes, :fast_submit, :account_status, :allow, + :error_no, :error_message def initialize body body = body.is_a?(String) ? JSON.parse(body) : body body.each do |meth, value| instance_variable_set("@#{meth}", value) if respond_to? meth end + raise_error? end + + private + + def raise_error? + if send(:error_no).present? || send(:error_message).present? + raise Cleantalk::Result::ApiErrors, "Error no: #{send(:error_no)}, Error Message: #{send(:error_message)}" + end + end + + class Cleantalk::Result::ApiErrors < StandardError; end end