diff --git a/lib/really_simple_captcha.rb b/lib/really_simple_captcha.rb index f2da2c3..a04b726 100644 --- a/lib/really_simple_captcha.rb +++ b/lib/really_simple_captcha.rb @@ -1,5 +1,10 @@ require "really_simple_captcha/version" +require "really_simple_captcha/util" +require "really_simple_captcha/captcha/reverse_captcha" +require "really_simple_captcha/captcha/plain_captcha" + module ReallySimpleCaptcha - # Your code goes here... end + +require "really_simple_captcha/railtie" if defined?(Rails) diff --git a/lib/really_simple_captcha/captcha/plain_captcha.rb b/lib/really_simple_captcha/captcha/plain_captcha.rb new file mode 100644 index 0000000..1b39a28 --- /dev/null +++ b/lib/really_simple_captcha/captcha/plain_captcha.rb @@ -0,0 +1,79 @@ +require 'RMagick' +require 'base64' + +module ReallySimpleCaptcha::Captcha + module PlainCaptcha + include ActiveSupport::Configurable + config_accessor :implode_amount + config_accessor :wave_amplitude + config_accessor :wave_length + config_accessor :pointsize + config_accessor :fill + config_accessor :background_color + config_accessor :text_length + + config.text_length = 6 + + def self.configure(&block) + yield config + end + + module ViewHelpers + def plain_captcha_tag + session[:plain_captcha] = ReallySimpleCaptcha::Util.random_string(PlainCaptcha.text_length) + + image = PlainCaptcha.generate_image(session[:plain_captcha], { + implode_amount: PlainCaptcha.implode_amount, + wave_amplitude: PlainCaptcha.wave_amplitude, + wave_length: PlainCaptcha.wave_length, + pointsize: PlainCaptcha.pointsize, + fill: PlainCaptcha.fill, + background_color: PlainCaptcha.background_color, + }) + + content_tag :div, class: 'plain_captcha' do + html = image_tag "data:image/gif;base64,#{image}", alt: "Captcha" + html.concat text_field_tag 'plain_captcha', nil, required: 'required', autocomplete: 'off' + + html + end + end + end + + module ControllerHelpers + def plain_captcha_valid? + res = params[:plain_captcha] == session[:plain_captcha] + session[:plain_captcha] = nil + + res + end + end + + def self.generate_image(captcha_text, args={}) + wave_amplitude = args[:wave_amplitude] || 4.0 + wave_length = args[:wave_length] || 60.0 + implode_amount = args[:implode_amount] || 0.2 + + pointsize = args[:pointsize] || 22 + text_fill = args[:fill] || 'darkblue' + + background_color = args[:background_color] || 'white' + + image = ::Magick::Image.new(120, 40) do + self.background_color = background_color + end + + text = ::Magick::Draw.new do + self.pointsize = pointsize + self.gravity = ::Magick::CenterGravity + self.fill = text_fill + end + + text.annotate(image, 0, 0, 0, 0, captcha_text) + + image = image.wave(wave_amplitude, wave_length).implode(implode_amount) + + Base64.strict_encode64(image.to_blob { self.format = 'GIF' }) + end + end +end diff --git a/lib/really_simple_captcha/captcha/reverse_captcha.rb b/lib/really_simple_captcha/captcha/reverse_captcha.rb new file mode 100644 index 0000000..bd354fd --- /dev/null +++ b/lib/really_simple_captcha/captcha/reverse_captcha.rb @@ -0,0 +1,24 @@ +module ReallySimpleCaptcha::Captcha + module ReverseCaptcha + include ActiveSupport::Configurable + config_accessor :field_name + + config.field_name = :reverse_captcha + + def self.configure(&block) + yield config + end + + module ViewHelpers + def reverse_captcha_tag + content_tag :div, text_field_tag(ReverseCaptcha.field_name), class: 'reverse_captcha', style: 'display: none' + end + end + + module ControllerHelpers + def reverse_captcha_valid? + params[ReverseCaptcha.field_name].blank? + end + end + end +end diff --git a/lib/really_simple_captcha/railtie.rb b/lib/really_simple_captcha/railtie.rb new file mode 100644 index 0000000..9ec4946 --- /dev/null +++ b/lib/really_simple_captcha/railtie.rb @@ -0,0 +1,11 @@ +module ReallySimpleCaptcha + class Railtie < Rails::Railtie + initializer "really_simple_captcha.include_captcha_helpers" do + ActionView::Base.send :include, Captcha::PlainCaptcha::ViewHelpers + ActionController::Base.send :include, Captcha::PlainCaptcha::ControllerHelpers + + ActionView::Base.send :include, Captcha::ReverseCaptcha::ViewHelpers + ActionController::Base.send :include, Captcha::ReverseCaptcha::ControllerHelpers + end + end +end diff --git a/lib/really_simple_captcha/util.rb b/lib/really_simple_captcha/util.rb new file mode 100644 index 0000000..7d86d17 --- /dev/null +++ b/lib/really_simple_captcha/util.rb @@ -0,0 +1,8 @@ +module ReallySimpleCaptcha + module Util + def self.random_string(length=8) + (0...length).map{65.+(rand(26)).chr}.join + end + end +end + diff --git a/really_simple_captcha.gemspec b/really_simple_captcha.gemspec index 9b8ecd9..1651a16 100644 --- a/really_simple_captcha.gemspec +++ b/really_simple_captcha.gemspec @@ -16,4 +16,6 @@ Gem::Specification.new do |gem| gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) } gem.test_files = gem.files.grep(%r{^(test|spec|features)/}) gem.require_paths = ["lib"] + + gem.add_runtime_dependency 'rmagick' end