First commit.
This commit is contained in:
parent
ed7a8910cf
commit
981308e839
|
@ -0,0 +1,4 @@
|
||||||
|
0.0.1
|
||||||
|
-----
|
||||||
|
|
||||||
|
- First release.
|
|
@ -0,0 +1,65 @@
|
||||||
|
# RuCaptcha
|
||||||
|
|
||||||
|
|
||||||
|
This is a Captcha gem for Rails Application. It base on [mini_magick](https://github.com/minimagick/minimagick) to run ImageMagick command to draw Captcha image.
|
||||||
|
|
||||||
|
So it's NO performance issue, and memory leak issue.
|
||||||
|
|
||||||
|
Idea by: https://ruby-china.org/topics/20558#reply4
|
||||||
|
|
||||||
|
### Requirements
|
||||||
|
|
||||||
|
- ImageMagick
|
||||||
|
- [mini_magick](https://github.com/minimagick/minimagick)
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
|
||||||
|
Put rucaptcha in your `Gemfile`:
|
||||||
|
|
||||||
|
```
|
||||||
|
gem 'rucaptcha'
|
||||||
|
```
|
||||||
|
|
||||||
|
Create `config/initializes/rucaptcha.rb`
|
||||||
|
|
||||||
|
```rb
|
||||||
|
RuCaptcha.configure do
|
||||||
|
# Number of chars, default: 4
|
||||||
|
self.len = 4
|
||||||
|
# Image width, default: 180
|
||||||
|
self.width = 180
|
||||||
|
# Image height, default: 48
|
||||||
|
self.height = 48
|
||||||
|
# Font size, default: 38
|
||||||
|
self.font_size = 38
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
Controller `app/controller/account_controller.rb`
|
||||||
|
|
||||||
|
```rb
|
||||||
|
class AccountController < ApplicationController
|
||||||
|
def create
|
||||||
|
@user = User.new(params[:user])
|
||||||
|
if verify_rucaptcha?(@user) && @user.save
|
||||||
|
redirect_to root_path, notice: 'Sign up successed.'
|
||||||
|
else
|
||||||
|
render 'account/new'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
View `app/views/account/new.html.erb`
|
||||||
|
|
||||||
|
```erb
|
||||||
|
<form>
|
||||||
|
...
|
||||||
|
<div class="form-group">
|
||||||
|
<%= rucaptcha_input_tag(class: 'form-control', placeholder: 'Input Captcha') %>
|
||||||
|
<%= rucaptcha_image_tag(alt: 'Captcha') %>
|
||||||
|
</div>
|
||||||
|
...
|
||||||
|
</form>
|
||||||
|
```
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
module RuCaptcha
|
||||||
|
class CaptchaController < ActionController::Base
|
||||||
|
def index
|
||||||
|
headers['Cache-Control'] = 'no-cache, no-store, max-age=0, must-revalidate'
|
||||||
|
headers['Pragma'] = 'no-cache'
|
||||||
|
|
||||||
|
send_data generate_rucaptcha, disposition: 'inline', type: 'image/png'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,3 @@
|
||||||
|
RuCaptcha::Engine.routes.draw do
|
||||||
|
root to: 'captcha#index'
|
||||||
|
end
|
|
@ -0,0 +1,28 @@
|
||||||
|
require 'active_support/core_ext'
|
||||||
|
require_relative 'rucaptcha/version'
|
||||||
|
require_relative 'rucaptcha/configuration'
|
||||||
|
require_relative 'rucaptcha/controller_helpers'
|
||||||
|
require_relative 'rucaptcha/view_helpers'
|
||||||
|
require_relative 'rucaptcha/engine'
|
||||||
|
|
||||||
|
module RuCaptcha
|
||||||
|
class << self
|
||||||
|
def config
|
||||||
|
return @config if defined?(@config)
|
||||||
|
@config = Configuration.new
|
||||||
|
@config.len = 4
|
||||||
|
@config.width = 180
|
||||||
|
@config.height = 48
|
||||||
|
@config.font_size = 38
|
||||||
|
@config
|
||||||
|
end
|
||||||
|
|
||||||
|
def configure(&block)
|
||||||
|
config.instance_exec(&block)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
ActionController::Base.send :include, RuCaptcha::ControllerHelpers
|
||||||
|
ActionView::Base.send :include, RuCaptcha::ViewHelpers
|
|
@ -0,0 +1,24 @@
|
||||||
|
require 'posix-spawn'
|
||||||
|
|
||||||
|
module RuCaptcha
|
||||||
|
class Captcha
|
||||||
|
class << self
|
||||||
|
def create(code)
|
||||||
|
color = "rgba(#{rand(100)},#{rand(100)},#{rand(100)}, 1)"
|
||||||
|
size = "#{RuCaptcha.config.width}x#{RuCaptcha.config.height}"
|
||||||
|
command = <<-CODE
|
||||||
|
convert -size #{size} -fill "#{color}" -background white \
|
||||||
|
-draw 'stroke #{color} line #{rand(20)},#{rand(28)} #{rand(30) + 10},#{rand(48)}' \
|
||||||
|
-draw 'stroke #{color} line #{rand(50)},#{rand(28)} #{rand(180)},#{rand(48)}' \
|
||||||
|
-wave #{2 + rand(2)}x#{80 + rand(20)} \
|
||||||
|
-gravity Center -sketch 2x19+#{rand(6)} -pointsize #{RuCaptcha.config.font_size} -implode 0.3 label:#{code.upcase} png:-
|
||||||
|
CODE
|
||||||
|
command.strip!
|
||||||
|
# puts command
|
||||||
|
pid, stdin, stdout, stderr = POSIX::Spawn.popen4(command)
|
||||||
|
Process.waitpid(pid)
|
||||||
|
stdout.read
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,5 @@
|
||||||
|
module RuCaptcha
|
||||||
|
class Configuration
|
||||||
|
attr_accessor :width, :height, :font_size, :len
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,22 @@
|
||||||
|
module RuCaptcha
|
||||||
|
module ControllerHelpers
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
included do
|
||||||
|
helper_method :verify_rucaptcha?
|
||||||
|
end
|
||||||
|
|
||||||
|
def generate_rucaptcha
|
||||||
|
session[:_rucaptcha] = SecureRandom.hex(RuCaptcha.config.len / 2)
|
||||||
|
return Captcha.create(session[:_rucaptcha])
|
||||||
|
end
|
||||||
|
|
||||||
|
def verify_rucaptcha?(resource = nil)
|
||||||
|
right = params[:_rucaptcha].strip == session[:_rucaptcha]
|
||||||
|
if resource && resource.respond_to?(:errors)
|
||||||
|
resource.errors.add('rucaptcha', 'invalid') unless right
|
||||||
|
end
|
||||||
|
right
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,5 @@
|
||||||
|
module RuCaptcha
|
||||||
|
class Engine < ::Rails::Engine
|
||||||
|
isolate_namespace RuCaptcha
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,4 @@
|
||||||
|
module RuCaptcha
|
||||||
|
VERSION = '0.0.1'
|
||||||
|
end
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
module RuCaptcha
|
||||||
|
module ViewHelpers
|
||||||
|
def rucaptcha_input_tag(opts = {})
|
||||||
|
opts[:name] = '_rucaptcha'
|
||||||
|
tag(:input, opts)
|
||||||
|
end
|
||||||
|
|
||||||
|
def rucaptcha_image_tag(opts = {})
|
||||||
|
opts[:class] = opts[:class] || 'rucaptcha-image'
|
||||||
|
image_tag(ru_captcha.root_path, opts)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,21 @@
|
||||||
|
lib = File.expand_path('../lib/', __FILE__)
|
||||||
|
$:.unshift lib unless $:.include?(lib)
|
||||||
|
|
||||||
|
require "rucaptcha/version"
|
||||||
|
|
||||||
|
Gem::Specification.new do |s|
|
||||||
|
s.name = 'rucaptcha'
|
||||||
|
s.version = RuCaptcha::VERSION
|
||||||
|
s.authors = ['Jason Lee']
|
||||||
|
s.email = 'huacnlee@gmail.com'
|
||||||
|
s.files = Dir.glob("lib/**/*") + Dir.glob("app/**/*") + Dir.glob("config/**/*") + %w(README.md CHANGELOG.md)
|
||||||
|
s.homepage = 'https://github.com/huacnlee/rucaptcha'
|
||||||
|
s.require_paths = ['lib']
|
||||||
|
s.summary = 'Captcha gem for Rails Application. It base on mini_magick to run ImageMagick command to draw Captcha image.'
|
||||||
|
|
||||||
|
s.add_dependency 'mini_magick', '>= 4.0.0'
|
||||||
|
s.add_dependency 'posix-spawn', '>= 0.3.0'
|
||||||
|
|
||||||
|
s.add_development_dependency 'rake'
|
||||||
|
s.add_development_dependency 'rspec', '>= 3.3.0'
|
||||||
|
end
|
Loading…
Reference in New Issue