Allow change chars length and disable strikethrough (#57)
This commit is contained in:
parent
2ec5e9e8a6
commit
3939d1bb02
|
@ -1,7 +1,7 @@
|
|||
PATH
|
||||
remote: .
|
||||
specs:
|
||||
rucaptcha (2.1.3)
|
||||
rucaptcha (2.1.4)
|
||||
railties (>= 3.2)
|
||||
|
||||
GEM
|
||||
|
|
10
README.md
10
README.md
|
@ -20,7 +20,6 @@ This is a Captcha gem for Rails Applications which generates captcha image by C
|
|||
- High performance.
|
||||
|
||||
## Usage
|
||||
|
||||
Put rucaptcha in your `Gemfile`:
|
||||
|
||||
```
|
||||
|
@ -42,6 +41,10 @@ RuCaptcha.configure do
|
|||
# 默认:会从 Rails 配置的 cache_store 里面读取相同的配置信息,并尝试用可以运行的方式,用于存储验证码字符
|
||||
# 但如果是 [:null_store, :memory_store, :file_store] 之类的,你可以通过下面的配置项单独给 RuCaptcha 配置 cache_store
|
||||
self.cache_store = :mem_cache_store
|
||||
# 验证码长度 length, 默认是 5, allows: [3,4,5,6,7]
|
||||
# self.length = 5
|
||||
# 验证码横线 line, 默认显示横线, default: true, allows: [true, false], 设置为false时, 横线不是显示, 验证码识别度高.
|
||||
# self.line = true
|
||||
end
|
||||
```
|
||||
|
||||
|
@ -53,7 +56,7 @@ RuCaptcha 没有使用 Rails Session 来存储验证码信息,因为 Rails 的
|
|||
|
||||
所以,我建议大家使用的时候,配置上 `cache_store` (详见 [Rails Guides 缓存配置部分](https://ruby-china.github.io/rails-guides/caching_with_rails.html#%E9%85%8D%E7%BD%AE)的文档)到一个 Memcached 或 Redis,这才是最佳实践。
|
||||
|
||||
#
|
||||
#
|
||||
(RuCaptha do not use Rails Session to store captcha information. As the default session is stored in Cookie in Rails, there's a [Replay attack](https://en.wikipedia.org/wiki/Replay_attack) bug which may causes capthcha being destroyed if we store captcha in Rails Session.
|
||||
|
||||
So in my design I require RuCaptcha to configure a distributed backend storage scheme, such as Memcached, Redis or other cache_store schemes which support distribution.
|
||||
|
@ -61,7 +64,8 @@ So in my design I require RuCaptcha to configure a distributed backend storage s
|
|||
Meanwhile, for the ease of use, RuCapthca would try to use `:file_store` by default and store the capthca in `tmp/cache/rucaptcha/session` directory (kindly note that it's not working if deploy on multiple machine).
|
||||
|
||||
For recommendation, configure the `cache_store`(more details on [Rails Guides Configuration of Cache Stores](http://guides.rubyonrails.org/caching_with_rails.html#configuration)) to Memcached or Redis, that would be the best practice.)
|
||||
#
|
||||
|
||||
#
|
||||
|
||||
Controller `app/controller/account_controller.rb`
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// http://github.com/ITikhonov/captcha
|
||||
const int gifsize;
|
||||
void captcha(unsigned char im[70*200], unsigned char l[6]);
|
||||
void captcha(unsigned char im[70*200], unsigned char l[8], int length, int i_line);
|
||||
void makegif(unsigned char im[70*200], unsigned char gif[gifsize], int style);
|
||||
|
||||
#include <unistd.h>
|
||||
|
@ -152,18 +152,37 @@ static void filter(unsigned char im[70*200]) {
|
|||
|
||||
static const char *letters="abcdafahijklmnopqrstuvwxyz";
|
||||
|
||||
void captcha(unsigned char im[70*200], unsigned char l[6]) {
|
||||
void captcha(unsigned char im[70*200], unsigned char l[8], int length, int i_line) {
|
||||
unsigned char swr[200];
|
||||
uint8_t s1,s2;
|
||||
|
||||
int f=open("/dev/urandom",O_RDONLY);
|
||||
read(f,l,5); read(f,swr,200); read(f,dr,sizeof(dr)); read(f,&s1,1); read(f,&s2,1);
|
||||
close(f);
|
||||
memset(im,0xff,200*70); s1=s1&0x7f; s2=s2&0x3f;
|
||||
|
||||
memset(im,0xff,200*70); s1=s1&0x7f; s2=s2&0x3f; l[0]%=25; l[1]%=25; l[2]%=25; l[3]%=25; l[4]%=25; l[5]=0;
|
||||
int p=30; p=letter(l[0],p,im,swr,s1,s2); p=letter(l[1],p,im,swr,s1,s2); p=letter(l[2],p,im,swr,s1,s2); p=letter(l[3],p,im,swr,s1,s2); letter(l[4],p,im,swr,s1,s2);
|
||||
line(im,swr,s1); dots(im); // blur(im); // filter(im);
|
||||
l[0]=letters[l[0]]; l[1]=letters[l[1]]; l[2]=letters[l[2]]; l[3]=letters[l[3]]; l[4]=letters[l[4]];
|
||||
int x;
|
||||
for(x=0;x<length;x++){
|
||||
l[x]%=25;
|
||||
}
|
||||
for(x=length;x<8;x++){
|
||||
l[length]=0;
|
||||
}
|
||||
//l[0]%=25; l[1]%=25; l[2]%=25; l[3]%=25; l[4]=0; // l[4]%=25; l[5]=0;
|
||||
int p=30;
|
||||
for(x=0;x<length;x++){
|
||||
p=letter(l[x],p,im,swr,s1,s2);
|
||||
}
|
||||
//p=letter(l[0],p,im,swr,s1,s2); p=letter(l[1],p,im,swr,s1,s2); p=letter(l[2],p,im,swr,s1,s2); p=letter(l[3],p,im,swr,s1,s2); //letter(l[4],p,im,swr,s1,s2);
|
||||
if (i_line == 1) {
|
||||
line(im,swr,s1);
|
||||
}
|
||||
dots(im); // blur(im); // filter(im);
|
||||
|
||||
for(x=0;x<length;x++){
|
||||
l[x]=letters[l[x]];
|
||||
}
|
||||
//l[1]=letters[l[1]]; l[2]=letters[l[2]]; l[3]=letters[l[3]]; //l[4]=letters[l[4]];
|
||||
}
|
||||
|
||||
// #ifdef CAPTCHA
|
||||
|
@ -188,20 +207,22 @@ VALUE RuCaptcha = Qnil;
|
|||
|
||||
void Init_rucaptcha();
|
||||
|
||||
VALUE create(VALUE self, VALUE style);
|
||||
VALUE create(VALUE self, VALUE style, VALUE length, VALUE line);
|
||||
|
||||
void Init_rucaptcha() {
|
||||
RuCaptcha = rb_define_module("RuCaptcha");
|
||||
rb_define_singleton_method(RuCaptcha, "create", create, 1);
|
||||
rb_define_singleton_method(RuCaptcha, "create", create, 3);
|
||||
}
|
||||
|
||||
VALUE create(VALUE self, VALUE style) {
|
||||
char l[6];
|
||||
VALUE create(VALUE self, VALUE style, VALUE length, VALUE line) {
|
||||
char l[8];
|
||||
unsigned char im[80*200];
|
||||
unsigned char gif[gifsize];
|
||||
int i_style = FIX2INT(style);
|
||||
int i_length = FIX2INT(length);
|
||||
int i_line = FIX2INT(line);
|
||||
|
||||
captcha(im, l);
|
||||
captcha(im, l, i_length, i_line);
|
||||
makegif(im, gif, i_style);
|
||||
|
||||
VALUE result = rb_ary_new2(2);
|
||||
|
@ -211,4 +232,3 @@ VALUE create(VALUE self, VALUE style) {
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ require 'rucaptcha/controller_helpers'
|
|||
require 'rucaptcha/view_helpers'
|
||||
require 'rucaptcha/cache'
|
||||
require 'rucaptcha/engine'
|
||||
require 'rucaptcha/errors/configuration'
|
||||
|
||||
module RuCaptcha
|
||||
class << self
|
||||
|
@ -15,6 +16,8 @@ module RuCaptcha
|
|||
return @config if defined?(@config)
|
||||
@config = Configuration.new
|
||||
@config.style = :colorful
|
||||
@config.length = 5
|
||||
@config.line = true
|
||||
@config.expires_in = 2.minutes
|
||||
if Rails.application
|
||||
@config.cache_store = Rails.application.config.cache_store
|
||||
|
@ -31,7 +34,10 @@ module RuCaptcha
|
|||
|
||||
def generate()
|
||||
style = config.style == :colorful ? 1 : 0
|
||||
self.create(style)
|
||||
length = config.length
|
||||
raise Rucaptcha::Errors::Configuration, 'length config error, value must in 3..7' unless length.in?(3..7)
|
||||
line = config.line ? 1 : 0
|
||||
self.create(style, length, line)
|
||||
end
|
||||
|
||||
def check_cache_store!
|
||||
|
|
|
@ -7,5 +7,10 @@ module RuCaptcha
|
|||
attr_accessor :expires_in
|
||||
# Color style, default: :colorful, allows: [:colorful, :black_white]
|
||||
attr_accessor :style
|
||||
# Captcha Digits: default 5, allows: [3,4,5,6,7]
|
||||
attr_accessor :length
|
||||
# rucaptcha line, default: true, allows: [true, false]
|
||||
attr_accessor :line
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
module Rucaptcha
|
||||
module Errors
|
||||
class Configuration < StandardError; end
|
||||
end
|
||||
end
|
|
@ -1,3 +1,3 @@
|
|||
module RuCaptcha
|
||||
VERSION = '2.1.3'
|
||||
VERSION = '2.1.4'
|
||||
end
|
||||
|
|
|
@ -12,17 +12,88 @@ describe RuCaptcha do
|
|||
|
||||
describe '.create' do
|
||||
it 'should len equal config.len' do
|
||||
res = RuCaptcha.create(0)
|
||||
res = RuCaptcha.create(0, 5, 1)
|
||||
expect(res.length).to eq(2)
|
||||
expect(res[0].length).to eq(5)
|
||||
expect(res[1]).not_to eq(nil)
|
||||
end
|
||||
|
||||
it 'should work with color style' do
|
||||
res = RuCaptcha.create(1)
|
||||
res = RuCaptcha.create(1, 5, 1)
|
||||
expect(res.length).to eq(2)
|
||||
expect(res[0].length).to eq(5)
|
||||
expect(res[1]).not_to eq(nil)
|
||||
end
|
||||
|
||||
it 'should raise when length not in 3..7 ' do
|
||||
RuCaptcha.configure do
|
||||
self.length = 2
|
||||
end
|
||||
#expect(RuCaptcha.generate()).to raise_error('length config error, value must in 3..7')
|
||||
expect { RuCaptcha.generate() }.
|
||||
to raise_error('length config error, value must in 3..7')
|
||||
RuCaptcha.configure do
|
||||
self.length = 5
|
||||
end
|
||||
end
|
||||
|
||||
it 'should work when length in 3..7 ' do
|
||||
RuCaptcha.configure do
|
||||
self.length = 5
|
||||
end
|
||||
res = RuCaptcha.generate()
|
||||
expect(res.length).to eq(2)
|
||||
expect(res[0].length).to eq(5)
|
||||
expect(res[1]).not_to eq(nil)
|
||||
end
|
||||
|
||||
it 'should len equal 3' do
|
||||
res = RuCaptcha.create(1, 3, 1)
|
||||
expect(res.length).to eq(2)
|
||||
expect(res[0].length).to eq(3)
|
||||
expect(res[1]).not_to eq(nil)
|
||||
end
|
||||
|
||||
it 'should len equal 4' do
|
||||
res = RuCaptcha.create(1, 4, 1)
|
||||
expect(res.length).to eq(2)
|
||||
expect(res[0].length).to eq(4)
|
||||
expect(res[1]).not_to eq(nil)
|
||||
end
|
||||
|
||||
it 'should len equal 5' do
|
||||
res = RuCaptcha.create(1, 5, 1)
|
||||
expect(res.length).to eq(2)
|
||||
expect(res[0].length).to eq(5)
|
||||
expect(res[1]).not_to eq(nil)
|
||||
end
|
||||
|
||||
it 'should len equal 6' do
|
||||
res = RuCaptcha.create(1, 6, 1)
|
||||
expect(res.length).to eq(2)
|
||||
expect(res[0].length).to eq(6)
|
||||
expect(res[1]).not_to eq(nil)
|
||||
end
|
||||
|
||||
it 'should len equal 7' do
|
||||
res = RuCaptcha.create(1, 7, 0)
|
||||
expect(res.length).to eq(2)
|
||||
expect(res[0].length).to eq(7)
|
||||
expect(res[1]).not_to eq(nil)
|
||||
end
|
||||
|
||||
it 'should work with line true' do
|
||||
res = RuCaptcha.create(1, 7, 1)
|
||||
expect(res.length).to eq(2)
|
||||
expect(res[0].length).to eq(7)
|
||||
expect(res[1]).not_to eq(nil)
|
||||
end
|
||||
|
||||
it 'should work with line false' do
|
||||
res = RuCaptcha.create(1, 7, 0)
|
||||
expect(res.length).to eq(2)
|
||||
expect(res[0].length).to eq(7)
|
||||
expect(res[1]).not_to eq(nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue