smartcaptcha 0.0.2
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 +7 -0
- data/lib/smartcaptcha/adapters/controller_methods.rb +50 -0
- data/lib/smartcaptcha/adapters/view_methods.rb +20 -0
- data/lib/smartcaptcha/configuration.rb +37 -0
- data/lib/smartcaptcha/railtie.rb +13 -0
- data/lib/smartcaptcha/version.rb +5 -0
- data/lib/smartcaptcha.rb +68 -0
- metadata +49 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 14c706d26bfe6f1532c4fcb320ef0c60cd7fb6b75f8dd3d4c532bde584e9dceb
|
4
|
+
data.tar.gz: cabb6a4c6a308b2d6948f4c7d11b196e5bd0a1ccaa434017f3682107f6709b82
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9db6a96f28593565d67f42a6a6ba8477f6e4396ddaaa1eeee11a620130d90edbaf2d06ec0a12d23d178826830ded44d35df19ad15b533dcddc1f209fbd043279
|
7
|
+
data.tar.gz: fa0947803486dcf4721b3cb43942ef1be48dfcd47a8837822dd9ca9dee208518fea305ae09164c4e84f1414fa1d3236eb234c0a59041d60cb3bbc331233ef10f
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Smartcaptcha
|
4
|
+
module Adapters
|
5
|
+
module ControllerMethods
|
6
|
+
|
7
|
+
private
|
8
|
+
|
9
|
+
def verify_smartcaptcha(options = {})
|
10
|
+
return true if Smartcaptcha.skip_env?
|
11
|
+
|
12
|
+
model = options[:model]
|
13
|
+
attribute = options.fetch(:attribute, :base)
|
14
|
+
options[:host] = request.host unless options.key?(:host)
|
15
|
+
options[:ip] = request.remote_ip
|
16
|
+
smartcaptcha_response = options[:response] || smartcaptcha_response_token(options[:action])
|
17
|
+
verified = Smartcaptcha.verify_via_api_call(smartcaptcha_response, options)
|
18
|
+
unless verified
|
19
|
+
smartcaptcha_error(
|
20
|
+
model,
|
21
|
+
attribute,
|
22
|
+
options.fetch(:message) { Smartcaptcha.error_message(:verification_failed) }
|
23
|
+
)
|
24
|
+
end
|
25
|
+
verified
|
26
|
+
end
|
27
|
+
|
28
|
+
def smartcaptcha_response_token(action = nil)
|
29
|
+
response_param = params['smart-token']
|
30
|
+
if response_param&.respond_to?(:to_h)
|
31
|
+
response_param[action].to_s
|
32
|
+
else
|
33
|
+
response_param.to_s
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def smartcaptcha_error(model, attribute, message)
|
38
|
+
if model
|
39
|
+
model.errors.add(attribute, message)
|
40
|
+
elsif smartcaptcha_flash_supported?
|
41
|
+
flash[:smartcaptcha_error] = message
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def smartcaptcha_flash_supported?
|
46
|
+
request.respond_to?(:format) && request.format == :html && respond_to?(:flash)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Smartcaptcha
|
4
|
+
module Adapters
|
5
|
+
module ViewMethods
|
6
|
+
def smartcaptcha_tags(options = {})
|
7
|
+
server_url = Smartcaptcha.configuration.server_url
|
8
|
+
attributes = {
|
9
|
+
sitekey: options.delete(:client_key) || Smartcaptcha.configuration.client_key!
|
10
|
+
}
|
11
|
+
tag_attributes = attributes.merge(options).map { |k, v| %(data-#{k}="#{v}") }.join(" ")
|
12
|
+
html = <<-HTML
|
13
|
+
<script src="#{server_url}" defer></script>
|
14
|
+
<div class="smart-captcha" #{tag_attributes}></div>
|
15
|
+
HTML
|
16
|
+
html.respond_to?(:html_safe) ? html.html_safe : html
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Smartcaptcha
|
4
|
+
class Configuration
|
5
|
+
DEFAULTS = {
|
6
|
+
'server_url' => 'https://smartcaptcha.yandexcloud.net/captcha.js',
|
7
|
+
'verify_url' => 'https://smartcaptcha.yandexcloud.net/validate'
|
8
|
+
}.freeze
|
9
|
+
|
10
|
+
attr_accessor :default_env, :skip_verify_env, :server_key, :client_key, :hostname
|
11
|
+
attr_writer :server_url, :verify_url
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
@default_env = ENV['RAILS_ENV'] || ENV['RACK_ENV'] || (Rails.env if defined? Rails.env)
|
15
|
+
@skip_verify_env = %w[test cucumber]
|
16
|
+
|
17
|
+
@server_key = ENV['SMARTCAPTCHA_SERVER_KEY']
|
18
|
+
@client_key = ENV['SMARTCAPTCHA_CLIENT_KEY']
|
19
|
+
end
|
20
|
+
|
21
|
+
def server_key!
|
22
|
+
server_key || raise(SmartcaptchaError, "No server key specified.")
|
23
|
+
end
|
24
|
+
|
25
|
+
def client_key!
|
26
|
+
client_key || raise(SmartcaptchaError, "No client key specified.")
|
27
|
+
end
|
28
|
+
|
29
|
+
def server_url
|
30
|
+
@server_url || DEFAULTS.fetch('server_url')
|
31
|
+
end
|
32
|
+
|
33
|
+
def verify_url
|
34
|
+
@verify_url || DEFAULTS.fetch('verify_url')
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Smartcaptcha
|
4
|
+
class Railtie < Rails::Railtie
|
5
|
+
ActiveSupport.on_load(:action_view) do
|
6
|
+
include Smartcaptcha::Adapters::ViewMethods
|
7
|
+
end
|
8
|
+
|
9
|
+
ActiveSupport.on_load(:action_controller) do
|
10
|
+
include Smartcaptcha::Adapters::ControllerMethods
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/smartcaptcha.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'net/http'
|
5
|
+
require 'uri'
|
6
|
+
|
7
|
+
require 'smartcaptcha/configuration'
|
8
|
+
require 'smartcaptcha/adapters/view_methods'
|
9
|
+
require 'smartcaptcha/adapters/controller_methods'
|
10
|
+
if defined?(Rails)
|
11
|
+
require 'smartcaptcha/railtie'
|
12
|
+
end
|
13
|
+
|
14
|
+
module Smartcaptcha
|
15
|
+
class SmartcaptchaError < StandardError
|
16
|
+
end
|
17
|
+
|
18
|
+
DEFAULT_ERRORS = {
|
19
|
+
verification_failed: 'SmartCaptcha verification failed, please try again'
|
20
|
+
}
|
21
|
+
|
22
|
+
def self.configuration
|
23
|
+
@configuration ||= Configuration.new
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.configure
|
27
|
+
config = configuration
|
28
|
+
yield(config)
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.verify_via_api_call(response, options)
|
32
|
+
server_key = options.fetch(:server_key) { configuration.server_key! }
|
33
|
+
verify_hash = { 'secret' => server_key, 'token' => response }
|
34
|
+
verify_hash['ip'] = options[:ip] if options.key?(:ip)
|
35
|
+
reply = api_verification(verify_hash)
|
36
|
+
success = reply['status'] == 'ok' &&
|
37
|
+
host_valid?(reply['host'], options[:host])
|
38
|
+
success
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.host_valid?(hostname, validation)
|
42
|
+
hostname.sub!(/:\d+$/, '')
|
43
|
+
case validation
|
44
|
+
when nil, FalseClass then true
|
45
|
+
when String then validation == hostname
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.api_verification(verify_hash)
|
50
|
+
query = URI.encode_www_form(verify_hash)
|
51
|
+
uri = URI.parse("#{configuration.verify_url}?#{query}")
|
52
|
+
request = Net::HTTP::Get.new(uri.request_uri)
|
53
|
+
http_client = Net::HTTP.new(uri.host, uri.port)
|
54
|
+
http_client.use_ssl = true if uri.port == 443
|
55
|
+
JSON.parse(http_client.request(request).body)
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.error_message(key)
|
59
|
+
default = DEFAULT_ERRORS.fetch(key)
|
60
|
+
return default unless defined?(I18n)
|
61
|
+
|
62
|
+
I18n.translate("smartcaptcha.errors.#{key}", default: default)
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.skip_env?
|
66
|
+
configuration.skip_verify_env.include?(configuration.default_env)
|
67
|
+
end
|
68
|
+
end
|
metadata
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: smartcaptcha
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Alexey Yanchenko
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2025-03-31 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Ruby helpers for Yandex smartcaptcha
|
14
|
+
email:
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- lib/smartcaptcha.rb
|
20
|
+
- lib/smartcaptcha/adapters/controller_methods.rb
|
21
|
+
- lib/smartcaptcha/adapters/view_methods.rb
|
22
|
+
- lib/smartcaptcha/configuration.rb
|
23
|
+
- lib/smartcaptcha/railtie.rb
|
24
|
+
- lib/smartcaptcha/version.rb
|
25
|
+
homepage: https://github.com/maildealer/smartcaptcha
|
26
|
+
licenses:
|
27
|
+
- MIT
|
28
|
+
metadata:
|
29
|
+
source_code_uri: https://github.com/maildealer/smartcaptcha
|
30
|
+
post_install_message:
|
31
|
+
rdoc_options: []
|
32
|
+
require_paths:
|
33
|
+
- lib
|
34
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
35
|
+
requirements:
|
36
|
+
- - ">="
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '0'
|
39
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
requirements: []
|
45
|
+
rubygems_version: 3.4.10
|
46
|
+
signing_key:
|
47
|
+
specification_version: 4
|
48
|
+
summary: Ruby helpers for Yandex smartcaptcha
|
49
|
+
test_files: []
|