simple_captcha2-0.5.0/ 0000755 0000041 0000041 00000000000 13576031220 014601 5 ustar www-data www-data simple_captcha2-0.5.0/README.md 0000644 0000041 0000041 00000022037 13576031220 016064 0 ustar www-data www-data # SimpleCaptcha2
[](https://travis-ci.org/pludoni/simple-captcha)
[](https://badge.fury.io/rb/simple_captcha2)
SimpleCaptcha(2) is the simplest and a robust captcha plugin. Its implementation requires adding up a single line in views and in controllers/models.
SimpleCaptcha2 is available to be used with Rails 3 + 4.
This is a fork of the popular Rubygem ``simple_captcha`` which got abandoned.
## Features
* Zero FileSystem usage (secret code moved to db-store and image storage removed).
* Provides various image styles.
* Provides three level of complexity of images.
* Works absolutely fine in distributed environment(session and db based implementation works fine in distributed environment).
* Implementation is as easy as just writing a single line in your view. ```<%= show_simple_captcha %>``` within the 'form' tags.
* Flexible DOM and CSS handling(There is a separate view partial for rendering SimpleCaptcha DOM elements).
* Automated removal of 1 hour old unmatched simple_captcha data.
## Requirements
* Ruby >= 1.9.3
* Rails >= 3.2
* ImageMagick should be installed on your machine to use this plugin.
visit http://www.imagemagick.org/script/index.php for more details.
## Installation
You might need to install Ghostscript on a Mac-System or a Debian-System:
```
brew install ghostscript
```
```
apt-get install ghostscript
```
The default font, that imagemagick uses is Arial. Make sure that font is available (``apt install ttf-mscorefonts-installer``) or change the font in the SimpleCaptcha config.
Put this into your Gemfile
```ruby
gem 'simple_captcha2', require: 'simple_captcha'
```
and run ``bundle install``.
## Setup
After installation, follow these simple steps to setup the plugin. The setup will depend on the version of rails your application is using.
```bash
rails generate simple_captcha [template_format] # Available options erb, haml. Default: erb
rake db:migrate # Mongoid: skip this step and remove the migration
```
## Usage
There are two usage scenarios:
### Controller Based
Add the following line in the file "app/controllers/application.rb"
```ruby
ApplicationController < ActionController::Base
include SimpleCaptcha::ControllerHelpers
end
```
In the view file within the form tags add this code
```erb
<%= show_simple_captcha %>
```
and in the controller's action authenticate it as
```ruby
if simple_captcha_valid?
do this
else
do that
end
```
### Model Based
This is suggested, if you want to integrate the error message into the normal form validation flow.
In the view file within the form tags write this code
```erb
<%= show_simple_captcha(:object=>"user") %>
```
and in the model class add this code
```ruby
class User < ActiveRecord::Base
apply_simple_captcha
end
```
Mongoid:
```ruby
class User
include SimpleCaptcha::ModelHelpers
apply_simple_captcha
end
```
#### Strong parameters (Rails 4.x)
Must add them:
```ruby
:captcha, :captcha_key
```
#### Form-Builder helper
```erb
<%= form_for @user do |form| -%>
...
<%= form.simple_captcha :label => "Enter numbers.." %>
...
<% end -%>
```
#### Validating with captcha
NOTE: @user.valid? will still work as it should, it will not validate the captcha code.
```ruby
@user.valid_with_captcha?
```
#### Saving with captcha
NOTE: @user.save will still work as it should, it will not validate the captcha code.
```ruby
@user.save_with_captcha
```
### Formtastic integration
SimpleCaptcha detects if you are using Formtastic:
```erb
<%= form.input :captcha, :as => :simple_captcha %>
```
### Tests
You can make the Captcha always pass with a initializer file: config/initializers/simple_captcha.rb
```ruby
SimpleCaptcha.always_pass = Rails.env.test?
```
You can also ask for the value, e.g. Acceptance Tests/Features:
```ruby
visit '/pages/form_tag'
assert_equal 1, SimpleCaptcha::SimpleCaptchaData.count
fill_in 'captcha', with: SimpleCaptcha::SimpleCaptchaData.first.value
```
## ORM support
simple-captcha2 supports 3 type of ORM: ActiveRecord, Sequel and Mongoid.
Selection of ORM is base on loaded classes. If `ActiveRecord` is loaded then it will be used for the simple captcha data model.
If `ActiveRecord` is undefined, `Sequel` presence is tested. If `Sequel` is defined it will used for the simple captcha data model.
If not, `Mongoid` is used.
For instance if your application is using Sequel as an ORM just make sure you require `sequel-rails` gem before `simple-captcha2`
in your Gemfile and respective model will be selected automatically.
## Options & Examples
### View Options
* ``:label`` - provides the custom text b/w the image and the text field, the default is "type the code from the image"
* ``:object`` - the name of the object of the model class, to implement the model based captcha.
* ``:code_type`` - return numeric only if set to 'numeric'
* ``:multiple`` - allow to use the same captcha in multiple forms in one page. True for the first appaerance and false for the rest.
### Global options
* ``:image_style`` - provides the specific image style for the captcha image.
There are eight different styles available with the plugin as...
1. simply_blue
2. simply_red
3. simply_green
4. charcoal_grey
5. embosed_silver
6. all_black
7. distorted_black
8. almost_invisible
Default style is 'simply_blue'.
You can also specify 'random' to select the random image style.
* ``:distortion`` - handles the complexity of the image. The :distortion can be set to 'low', 'medium' or 'high'. Default is 'low'.
* ``:implode`` - handles the complexity of the image. The :implode can be set to 'none', 'low', 'medium' or 'high'. Default is 'medium'.
Create "./config/initializers/simple_captcha.rb"
```ruby
SimpleCaptcha.setup do |sc|
# default: 100x28
sc.image_size = '120x40'
# default: 5
sc.length = 6
# default: simply_blue
# possible values:
# 'embosed_silver',
# 'simply_red',
# 'simply_green',
# 'simply_blue',
# 'distorted_black',
# 'all_black',
# 'charcoal_grey',
# 'almost_invisible'
# 'random'
sc.image_style = 'simply_green'
# default: low
# possible values: 'low', 'medium', 'high', 'random'
sc.distortion = 'medium'
# default: medium
# possible values: 'none', 'low', 'medium', 'high'
sc.implode = 'low'
end
```
You can add your own style:
```ruby
SimpleCaptcha.setup do |sc|
sc.image_style = 'mycaptha'
sc.add_image_style('mycaptha', [
"-background '#F4F7F8'",
"-fill '#86818B'",
"-border 1",
"-bordercolor '#E0E2E3'"])
end
```
You can provide the path where image_magick is installed as well:
```ruby
SimpleCaptcha.setup do |sc|
sc.image_magick_path = '/usr/bin' # you can check this from console by running: which convert
end
```
You can setup in which format the reload of the captcha is executed:
```ruby
SimpleCaptcha.setup do |sc|
sc.refresh_format = :prototype # or :jquery, or :plain_javascript default is :jquery
end
```
If needed, you can explicitly state the font used for generating the captcha:
```ruby
SimpleCaptcha.setup do |sc|
sc.font = "DejaVu-Sans"
end
```
### How to change the CSS for SimpleCaptcha DOM elements?
You can change the CSS of the SimpleCaptcha DOM elements as per your need in this file.
``app/views/simple_captcha/_simple_captcha.erb``
### View's Examples
#### Controller Based Example
```erb
<%= show_simple_captcha %>
<%= show_simple_captcha(:label => "human authentication") %>
```
#### Model Based Example
```erb
<%= show_simple_captcha(:object => 'user', :label => "human authentication") %>
```
#### Model Options
* ``:message`` - provides the custom message on failure of captcha authentication the default is "Secret Code did not match with the Image"
* ``:add_to_base`` - if set to true, appends the error message to the base.
##### Model's Example
```ruby
class User < ActiveRecord::Base
apply_simple_captcha
end
class User < ActiveRecord::Base
apply_simple_captcha :message => "The secret Image and code were different", :add_to_base => true
end
```
## I18n
```yaml
en:
simple_captcha:
placeholder: "Enter the image value"
label: "Enter the code in the box:"
refresh_button_text: "Refresh"
message:
default: "Secret Code did not match with the Image"
user: "The secret Image and code were different"
```
## Contributing
For testing, generate a temporary Rails dummy app inside test:
```bash
bundle
bundle exec rake dummy:setup
bundle exec rake app:db:migrate
bundle exec rake app:db:migrate RAILS_ENV=test
bundle exec rake test
```
Please add test cases when adding new functionality. I started with some basic example integration tests for a very basic coverage.
The tests will be run on [Travis-CI](https://travis-ci.org/pludoni/simple-captcha).
## Who's who?
Enjoy the simplest captcha implementation.
Original Author of the Version for Rails 2:
Author: Sur, Blog: http://expressica.com, Contact: sur.max@gmail.com
Plugin Homepage: http://expressica.com/simple_captcha
Plugin update for rails 3: http://github.com/galetahub
update for Rails 4, tests and forked by Stefan Wienert (pludoni GmbH)
simple_captcha2-0.5.0/Rakefile 0000644 0000041 0000041 00000003100 13576031220 016240 0 ustar www-data www-data begin
require 'bundler/setup'
rescue LoadError
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
end
require 'rdoc/task'
RDoc::Task.new(:rdoc) do |rdoc|
rdoc.rdoc_dir = 'rdoc'
rdoc.title = 'SimpleCaptcha'
rdoc.options << '--line-numbers'
rdoc.rdoc_files.include('README.rdoc')
rdoc.rdoc_files.include('lib/**/*.rb')
end
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
if File.exist? APP_RAKEFILE
load 'rails/tasks/engine.rake'
end
namespace :dummy do
desc 'Setup dummy Rails app for test purpose'
task :setup do
require 'rails'
require 'simple_captcha'
if ENV["SEQUEL"].nil?
require File.expand_path('../test/lib/generators/simple_captcha/dummy/dummy_generator', __FILE__)
generator_class = SimpleCaptcha::DummyGenerator
else
require File.expand_path('../test/lib/generators/simple_captcha/dummy/dummy_generator_sequel', __FILE__)
generator_class = SimpleCaptcha::DummyGeneratorSequel
end
generator_class.start %w(--quiet)
end
desc 'destroy dummy Rails app under test/dummy'
task :destroy do
FileUtils.rm_rf "test/dummy" if File.exist?("test/dummy")
end
desc 'redo'
task :redo do
sh 'rake dummy:destroy'
sh 'rake dummy:setup'
sh 'rake app:db:migrate'
sh 'rake app:db:migrate RAILS_ENV=test'
end
end
Bundler::GemHelper.install_tasks :name => 'simple_captcha2'
require 'rake/testtask'
Rake::TestTask.new(:test) do |t|
t.libs << 'lib'
t.libs << 'test'
t.pattern = 'test/**/*_test.rb'
t.verbose = false
end
task default: :test
simple_captcha2-0.5.0/lib/ 0000755 0000041 0000041 00000000000 13576031220 015347 5 ustar www-data www-data simple_captcha2-0.5.0/lib/simple_captcha.rb 0000644 0000041 0000041 00000004170 13576031220 020652 0 ustar www-data www-data # encoding: utf-8
module SimpleCaptcha
class << self
attr_accessor :always_pass
end
self.always_pass = Rails.env.test?
autoload :Utils, 'simple_captcha/utils'
autoload :ImageHelpers, 'simple_captcha/image'
autoload :ViewHelper, 'simple_captcha/view'
autoload :ControllerHelpers, 'simple_captcha/controller'
autoload :FormBuilder, 'simple_captcha/form_builder'
autoload :CustomFormBuilder, 'simple_captcha/formtastic'
autoload :ModelHelpers, 'simple_captcha/model_helpers'
if defined?(ActiveRecord)
autoload :SimpleCaptchaData, 'simple_captcha/simple_captcha_data'
elsif defined?(Sequel)
autoload :SimpleCaptchaData, 'simple_captcha/simple_captcha_data_sequel'
else
autoload :SimpleCaptchaData, 'simple_captcha/simple_captcha_data_mongoid.rb'
end
autoload :Middleware, 'simple_captcha/middleware'
mattr_accessor :image_size
@@image_size = "100x28"
mattr_accessor :length
@@length = 5
# 'embosed_silver',
# 'simply_red',
# 'simply_green',
# 'simply_blue',
# 'distorted_black',
# 'all_black',
# 'charcoal_grey',
# 'almost_invisible'
# 'random'
mattr_accessor :image_style
@@image_style = 'simply_blue'
# 'low', 'medium', 'high', 'random'
mattr_accessor :distortion
@@distortion = 'low'
# 'none', 'low', 'medium', 'high'
mattr_accessor :implode
@@implode = SimpleCaptcha::ImageHelpers::DEFAULT_IMPLODE
# 'jquery', 'prototype'
mattr_accessor :refresh_format
@@refresh_format = :jquery
# command path
mattr_accessor :image_magick_path
@@image_magick_path = ''
# tmp directory
mattr_accessor :tmp_path
@@tmp_path = nil
# additive noise
mattr_accessor :noise
@@noise = 0
# used font
mattr_accessor :font
@@font = ''
mattr_accessor :extra_response_headers
@@extra_response_headers = {}
mattr_accessor :partial_path
@@partial_path = 'simple_captcha/simple_captcha'
def self.add_image_style(name, params = [])
SimpleCaptcha::ImageHelpers.image_styles.update(name.to_s => params)
end
def self.setup
yield self
end
end
require 'simple_captcha/engine' if defined?(Rails)
simple_captcha2-0.5.0/lib/simple_captcha2.rb 0000644 0000041 0000041 00000000031 13576031220 020724 0 ustar www-data www-data require 'simple_captcha'
simple_captcha2-0.5.0/lib/generators/ 0000755 0000041 0000041 00000000000 13576031220 017520 5 ustar www-data www-data simple_captcha2-0.5.0/lib/generators/templates/ 0000755 0000041 0000041 00000000000 13576031220 021516 5 ustar www-data www-data simple_captcha2-0.5.0/lib/generators/templates/migration5.rb 0000644 0000041 0000041 00000000533 13576031220 024122 0 ustar www-data www-data class CreateSimpleCaptchaData < ActiveRecord::Migration[4.2]
def self.up
create_table :simple_captcha_data do |t|
t.string :key, :limit => 40
t.string :value, :limit => 6
t.timestamps
end
add_index :simple_captcha_data, :key, :name => "idx_key"
end
def self.down
drop_table :simple_captcha_data
end
end
simple_captcha2-0.5.0/lib/generators/templates/partial.haml 0000644 0000041 0000041 00000001624 13576031220 024020 0 ustar www-data www-data :css
.simple_captcha{border: 1px solid #ccc; padding: 5px !important;}
.simple_captcha,
.simple_captcha div{display: table;}
.simple_captcha .simple_captcha_field,
.simple_captcha .simple_captcha_image{
border: 1px solid #ccc;
margin: 0px 0px 2px 0px !important;
padding: 0px !important;
}
.simple_captcha .simple_captcha_image img{
margin: 0px !important;
padding: 0px !important;
width: 110px !important;
}
.simple_captcha .simple_captcha_label{font-size: 12px;}
.simple_captcha .simple_captcha_field input{
width: 150px !important;
font-size: 16px;
border: none;
background-color: #efefef;
}
.simple_captcha
.simple_captcha_image= simple_captcha_options[:image]
.simple_captcha_field= simple_captcha_options[:field]
.simple_captcha_label= simple_captcha_options[:label]
.simple_captcha_refresh_button= simple_captcha_options[:refresh_button]
simple_captcha2-0.5.0/lib/generators/templates/migration.rb 0000644 0000041 0000041 00000000532 13576031220 024034 0 ustar www-data www-data class CreateSimpleCaptchaData < ActiveRecord::Migration
def self.up
create_table :simple_captcha_data do |t|
t.string :key, :limit => 40
t.string :value, :limit => 6
t.timestamps
end
add_index :simple_captcha_data, :key, :name => "idx_key"
end
def self.down
drop_table :simple_captcha_data
end
end
simple_captcha2-0.5.0/lib/generators/templates/migration_sequel.rb 0000644 0000041 0000041 00000000464 13576031220 025416 0 ustar www-data www-data Sequel.migration do
up do
create_table :simple_captcha_data do
primary_key :id
String :key, size: 40
String :value, size: 6
DateTime :created_at
DateTime :updated_at
index :key, name: "idx_key"
end
end
down do
drop_table :simple_captcha_data
end
end
simple_captcha2-0.5.0/lib/generators/templates/partial.erb 0000644 0000041 0000041 00000002113 13576031220 023641 0 ustar www-data www-data
<%%= simple_captcha_options[:image] %>
<%%= simple_captcha_options[:field] %>
<%%= simple_captcha_options[:label] %>
<%%= simple_captcha_options[:refresh_button] %>
simple_captcha2-0.5.0/lib/generators/simple_captcha_generator.rb 0000644 0000041 0000041 00000001504 13576031220 025067 0 ustar www-data www-data require 'rails/generators'
class SimpleCaptchaGenerator < Rails::Generators::Base
argument :template_format, :type => :string, :default => 'erb'
include Rails::Generators::Migration
def self.source_root
@source_root ||= File.expand_path(File.join(File.dirname(__FILE__), 'templates/'))
end
def self.next_migration_number(dirname)
Time.now.strftime("%Y%m%d%H%M%S")
end
def create_partial
template "partial.#{template_format}", File.join('app/views', 'simple_captcha', "_simple_captcha.#{template_format}")
end
def create_captcha_migration
migration_template migration_file, File.join('db/migrate', "create_simple_captcha_data.rb")
end
private
def migration_file
return "migration_sequel.rb" if defined?(Sequel)
Rails::VERSION::MAJOR > 4 ? "migration5.rb" : "migration.rb"
end
end
simple_captcha2-0.5.0/lib/generators/USAGE 0000644 0000041 0000041 00000000450 13576031220 020306 0 ustar www-data www-data SimpleCaptcha
=============
# Generate migration and copy view partial
rails generate simple_captcha [template_format]
template_format Sets template format to be generated
Available options: erb, haml
Default: erb
simple_captcha2-0.5.0/lib/simple_captcha/ 0000755 0000041 0000041 00000000000 13576031220 020323 5 ustar www-data www-data simple_captcha2-0.5.0/lib/simple_captcha/version.rb 0000644 0000041 0000041 00000000064 13576031220 022335 0 ustar www-data www-data module SimpleCaptcha
VERSION = "0.5.0".freeze
end
simple_captcha2-0.5.0/lib/simple_captcha/image.rb 0000644 0000041 0000041 00000005730 13576031220 021737 0 ustar www-data www-data require 'tempfile'
module SimpleCaptcha #:nodoc
module ImageHelpers #:nodoc
mattr_accessor :image_styles
@@image_styles = {
'embosed_silver' => ['-fill darkblue', '-shade 20x60', '-background white'],
'simply_red' => ['-fill darkred', '-background white'],
'simply_green' => ['-fill darkgreen', '-background white'],
'simply_blue' => ['-fill darkblue', '-background white'],
'distorted_black' => ['-fill darkblue', '-edge 10', '-background white'],
'all_black' => ['-fill darkblue', '-edge 2', '-background white'],
'charcoal_grey' => ['-fill darkblue', '-charcoal 5', '-background white'],
'almost_invisible' => ['-fill red', '-solarize 50', '-background white']
}
DISTORTIONS = ['low', 'medium', 'high']
IMPLODES = { 'none' => 0, 'low' => 0.1, 'medium' => 0.2, 'high' => 0.3 }
DEFAULT_IMPLODE = 'medium'
class << self
def image_params(key = 'simply_blue')
image_keys = @@image_styles.keys
style = begin
if key == 'random'
image_keys[rand(image_keys.length)]
else
image_keys.include?(key) ? key : 'simply_blue'
end
end
@@image_styles[style]
end
def distortion(key='low')
key =
key == 'random' ?
DISTORTIONS[rand(DISTORTIONS.length)] :
DISTORTIONS.include?(key) ? key : 'low'
case key.to_s
when 'low' then return [0 + rand(2), 80 + rand(20)]
when 'medium' then return [2 + rand(2), 50 + rand(20)]
when 'high' then return [4 + rand(2), 30 + rand(20)]
end
end
def implode
IMPLODES[SimpleCaptcha.implode] || IMPLODES[DEFAULT_IMPLODE]
end
end
if RUBY_VERSION < '1.9'
class Tempfile < ::Tempfile
# Replaces Tempfile's +make_tmpname+ with one that honors file extensions.
def make_tmpname(basename, n = 0)
extension = File.extname(basename)
sprintf("%s,%d,%d%s", File.basename(basename, extension), $$, n, extension)
end
end
end
private
def generate_simple_captcha_image(simple_captcha_key) #:nodoc
amplitude, frequency = ImageHelpers.distortion(SimpleCaptcha.distortion)
text = Utils::simple_captcha_value(simple_captcha_key)
params = ImageHelpers.image_params(SimpleCaptcha.image_style).dup
params << "-size #{SimpleCaptcha.image_size}"
params << "-wave #{amplitude}x#{frequency}"
params << "-gravity Center"
params << "-pointsize 22"
params << "-implode #{ImageHelpers.implode}"
unless SimpleCaptcha.font.empty?
params << "-font #{SimpleCaptcha.font}"
end
params << "label:#{text}"
if SimpleCaptcha.noise and SimpleCaptcha.noise > 0
params << "-evaluate Uniform-noise #{SimpleCaptcha.noise}"
end
params << "jpeg:-"
SimpleCaptcha::Utils::run("convert", params.join(' '))
end
end
end
simple_captcha2-0.5.0/lib/simple_captcha/model_helpers.rb 0000644 0000041 0000041 00000004562 13576031220 023501 0 ustar www-data www-data module SimpleCaptcha #:nodoc
module ModelHelpers #:nodoc
def self.included(base)
base.extend(SingletonMethods)
end
# To implement model based simple captcha use this method in the model as...
#
# class User < ActiveRecord::Base
#
# apply_simple_captcha :message => "my customized message"
#
# end
#
# Customize the error message by using :message, the default message is "Captcha did not match".
# As in the applications captcha is needed with a very few cases like signing up the new user, but
# not every time you need to authenticate the captcha with @user.save. So as to maintain simplicity
# here we have the explicit method to save the instace with captcha validation as...
#
# * to validate the instance
#
# @user.valid_with_captcha? # whene captcha validation is required.
#
# @user.valid? # when captcha validation is not required.
#
# * to save the instance
#
# @user.save_with_captcha # whene captcha validation is required.
#
# @user.save # when captcha validation is not required.
module SingletonMethods
def apply_simple_captcha(options = {})
options = { :add_to_base => false }.merge(options)
class_attribute :simple_captcha_options
self.simple_captcha_options = options
unless self.is_a?(ClassMethods)
include InstanceMethods
extend ClassMethods
attr_accessor :captcha, :captcha_key
end
end
end
module ClassMethods
end
module InstanceMethods
def valid_with_captcha?
[valid?, is_captcha_valid?].all?
end
def is_captcha_valid?
return true if SimpleCaptcha.always_pass
if captcha && captcha.upcase.delete(" ") == SimpleCaptcha::Utils::simple_captcha_value(captcha_key)
SimpleCaptcha::Utils::simple_captcha_passed!(captcha_key)
return true
else
message = simple_captcha_options[:message] || I18n.t(self.class.model_name.to_s.downcase, :scope => [:simple_captcha, :message], :default => :default)
simple_captcha_options[:add_to_base] ? errors.add(:base, message) : errors.add(:captcha, message)
return false
end
end
def save_with_captcha
valid_with_captcha? && save(:validate => false)
end
end
end
end
simple_captcha2-0.5.0/lib/simple_captcha/simple_captcha_data_sequel.rb 0000644 0000041 0000041 00000000734 13576031220 026177 0 ustar www-data www-data module SimpleCaptcha
class SimpleCaptchaData < Sequel::Model
plugin :update_or_create
plugin :timestamps, update_on_create: true
class << self
def get_data(key)
find_or_new(key: key)
end
def remove_data(key)
where(key: key).delete
clear_old_data(1.hour.ago)
end
def clear_old_data(time = 1.hour.ago)
return unless Time === time
where {updated_at < time}.delete
end
end
end
end
simple_captcha2-0.5.0/lib/simple_captcha/simple_captcha_data.rb 0000644 0000041 0000041 00000002006 13576031220 024613 0 ustar www-data www-data module SimpleCaptcha
class SimpleCaptchaData < ::ActiveRecord::Base
if ::ActiveRecord::VERSION::MAJOR >= 3
# Fixes deprecation warning in Rails 3.2:
# DEPRECATION WARNING: Calling set_table_name is deprecated. Please use `self.table_name = 'the_name'` instead.
self.table_name = "simple_captcha_data"
else
set_table_name "simple_captcha_data"
end
if ::ActiveRecord::VERSION::MAJOR == 3 and defined? attr_protected
attr_protected
end
class << self
def get_data(key)
where(key: key).first_or_initialize
end
def remove_data(key)
where(["#{connection.quote_column_name(:key)} = ?", key]).delete_all
clear_old_data(1.hour.ago)
end
def clear_old_data(time = 1.hour.ago)
return unless Time === time
where(["#{connection.quote_column_name(:updated_at)} < ?", time]).delete_all
rescue ActiveRecord::Deadlocked => err
Rails.logger.error "#{err.class} #{err.message}"
end
end
end
end
simple_captcha2-0.5.0/lib/simple_captcha/engine.rb 0000644 0000041 0000041 00000001144 13576031220 022115 0 ustar www-data www-data # encoding: utf-8
require 'rails'
module SimpleCaptcha
class Engine < ::Rails::Engine
config.before_initialize do
ActiveSupport.on_load :active_record do
ActiveRecord::Base.send(:include, SimpleCaptcha::ModelHelpers)
end
end
config.after_initialize do
ActionView::Base.send(:include, SimpleCaptcha::ViewHelper)
ActionView::Helpers::FormBuilder.send(:include, SimpleCaptcha::FormBuilder)
if Object.const_defined?("Formtastic")
require 'simple_captcha/formtastic'
end
end
config.app_middleware.use SimpleCaptcha::Middleware
end
end
simple_captcha2-0.5.0/lib/simple_captcha/form_builder.rb 0000644 0000041 0000041 00000002602 13576031220 023321 0 ustar www-data www-data module SimpleCaptcha
module FormBuilder
def self.included(base)
base.send(:include, SimpleCaptcha::ViewHelper)
base.send(:include, SimpleCaptcha::FormBuilder::ClassMethods)
base.send(:include, ActionView::Helpers)
if defined? Sprockets::Helpers
base.send(:include, Sprockets::Helpers::RailsHelper)
base.send(:include, Sprockets::Helpers::IsolatedHelper)
end
base.delegate :render, :session, :to => :template
end
module ClassMethods
# Example:
# <% form_for :post, :url => posts_path do |form| %>
# ...
# <%= form.simple_captcha :label => "Enter numbers.." %>
# <% end %>
#
def simple_captcha(options = {})
options.update :object => @object_name
show_simple_captcha(objectify_options(options))
end
private
def template
@template
end
def simple_captcha_field(options={})
html = {:autocomplete => 'off', :autocorrect => 'off', :autocapitalize => 'off', :required => 'required', :value => ''}
html.merge!(options[:input_html] || {})
html[:placeholder] = options[:placeholder] || I18n.t('simple_captcha.placeholder')
text_field(:captcha, html) +
hidden_field(:captcha_key, {:value => options[:field_value], :id => simple_captch_hidden_field_id(options)})
end
end
end
end
simple_captcha2-0.5.0/lib/simple_captcha/utils.rb 0000644 0000041 0000041 00000001754 13576031220 022017 0 ustar www-data www-data require 'digest/sha1'
module SimpleCaptcha #:nodoc
module Utils #:nodoc
# Execute command with params and return output if exit status equal expected_outcodes
def self.run(cmd, params = "", expected_outcodes = 0)
command = %Q[#{cmd} #{params}].gsub(/\s+/, " ")
command = "#{command} 2>&1"
unless (image_magick_path = SimpleCaptcha.image_magick_path).blank?
command = File.join(image_magick_path, command)
end
output = `#{command}`
unless [expected_outcodes].flatten.include?($?.exitstatus)
raise ::StandardError, "Error while running #{cmd}: #{output}"
end
output
end
def self.simple_captcha_value(key) #:nodoc
SimpleCaptchaData.get_data(key).value rescue nil
end
def self.simple_captcha_passed!(key) #:nodoc
SimpleCaptchaData.remove_data(key)
end
def self.generate_key(*args)
args << (Time.now.to_f * 1_000_000_000).to_s
Digest::SHA1.hexdigest(args.join)
end
end
end
simple_captcha2-0.5.0/lib/simple_captcha/simple_captcha_data_mongoid.rb 0000644 0000041 0000041 00000001065 13576031220 026333 0 ustar www-data www-data module SimpleCaptcha
class SimpleCaptchaData
include Mongoid::Document
include Mongoid::Timestamps
field :key, type: String
field :value, type: String
class << self
def get_data(key)
data = where(:key => key).first || new(:key => key)
end
def remove_data(key)
where(:key => key).delete_all
clear_old_data(1.hour.ago)
end
def clear_old_data(time = 1.hour.ago)
return unless Time === time
where(:updated_at.lte => time).delete_all
end
end
end
end
simple_captcha2-0.5.0/lib/simple_captcha/view.rb 0000644 0000041 0000041 00000013224 13576031220 021624 0 ustar www-data www-data module SimpleCaptcha #:nodoc
module ViewHelper #:nodoc
# Simple Captcha is a very simplified captcha.
#
# It can be used as a *Model* or a *Controller* based Captcha depending on what options
# we are passing to the method show_simple_captcha.
#
# *show_simple_captcha* method will return the image, the label and the text box.
# This method should be called from the view within your form as...
#
# <%= show_simple_captcha %>
#
# The available options to pass to this method are
# * label
# * object
#
# Label:
#
# default label is "type the text from the image", it can be modified by passing :label as
#
# <%= show_simple_captcha(:label => "new captcha label") %>.
#
# *Object*
#
# This option is needed to create a model based captcha.
# If this option is not provided, the captcha will be controller based and
# should be checked in controller's action just by calling the method simple_captcha_valid?
#
# To make a model based captcha give this option as...
#
# <%= show_simple_captcha(:object => "user") %>
# and also call the method apply_simple_captcha in the model
# this will consider "user" as the object of the model class.
#
# *Examples*
# * controller based
# <%= show_simple_captcha(:label => "Human Authentication: type the text from image above") %>
# * model based
# <%= show_simple_captcha(:object => "person", :label => "Human Authentication: type the text from image above") %>
#
# Find more detailed examples with sample images here on my blog http://EXPRESSICA.com
#
# All Feedbacks/CommentS/Issues/Queries are welcome.
def show_simple_captcha(options = {})
render :partial => SimpleCaptcha.partial_path, :locals => { :simple_captcha_options => simple_captcha_options(options) }
end
def simple_captcha_options(options = {})
key = simple_captcha_key(options[:object])
if options[:multiple] === false
# It's not the first captcha, we only need to return the key
options[:field_value] = key
else
# It's the first captcha in the page, we generate a new key
options[:field_value] = set_simple_captcha_data(key, options)
end
{
:image => simple_captcha_image(key, options),
:label => I18n.t('simple_captcha.label'),
:field => simple_captcha_field(options),
:refresh_button => simple_captcha_refresh_button(options),
}.merge(options)
end
private
def simple_captcha_image(simple_captcha_key, options = {})
url = simple_captcha_image_url simple_captcha_key, options: options
id = simple_captcha_image_id(options)
tag('img', :src => url, :alt => 'captcha', :id => id)
end
def simple_captcha_image_url(simple_captcha_key, options = {})
defaults = {}
defaults[:time] = options[:time] || Time.now.to_i
query = defaults.to_query
path = "/simple_captcha?code=#{simple_captcha_key}{query}"
build_url(options, path)
end
def build_url(options, path)
if defined?(request) && request
"#{request.protocol}#{request.host_with_port}#{ENV['RAILS_RELATIVE_URL_ROOT']}#{path}"
else
"#{ENV['RAILS_RELATIVE_URL_ROOT']}#{path}"
end
end
def simple_captcha_field(options={})
html = {:autocomplete => 'off', :autocorrect => 'off', :autocapitalize => 'off', :required => 'required'}
html.merge!(options[:input_html] || {})
html[:placeholder] = options[:placeholder] || I18n.t('simple_captcha.placeholder')
if options[:object]
text_field(options[:object], :captcha, html.merge(:value => '')) +
hidden_field(options[:object], :captcha_key, {:value => options[:field_value], :id => simple_captch_hidden_field_id(options)})
else
text_field_tag(:captcha, nil, html) +
hidden_field_tag(:captcha_key, options[:field_value], :id => simple_captch_hidden_field_id(options))
end
end
def simple_captcha_refresh_button(options={})
html = {remote: true}
html.merge!(options[:refresh_button_html] || {})
text = options[:refresh_button_text] || I18n.t('simple_captcha.refresh_button_text', default: 'Refresh')
url = build_url(options, "/simple_captcha?id=#{simple_captcha_image_id(options)}")
link_to(text, url, html)
end
def simple_captcha_image_id(options={})
"simple_captcha-#{options[:field_value][0..10]}"
end
def simple_captch_hidden_field_id(image_id)
image_id = simple_captcha_image_id(image_id) if image_id.is_a?(Hash)
"simple-captcha-hidden-field-#{ image_id }"
end
def set_simple_captcha_data(key, options={})
code_type = options[:code_type]
value = generate_simple_captcha_data(code_type)
data = SimpleCaptcha::SimpleCaptchaData.get_data(key)
data.value = value
data.save
key
end
def generate_simple_captcha_data(code)
value = ''
case code
when 'numeric' then
SimpleCaptcha.length.times{value << (48 + rand(10)).chr}
else
SimpleCaptcha.length.times{value << (65 + rand(26)).chr}
end
return value
end
def simple_captcha_key(key_name = nil, prequest = request)
local_session = prequest.try(:session) || session
if key_name.nil?
local_session[:captcha] ||= SimpleCaptcha::Utils.generate_key(local_session[:id].to_s, 'captcha')
else
SimpleCaptcha::Utils.generate_key(local_session[:id].to_s, key_name)
end
end
end
end
simple_captcha2-0.5.0/lib/simple_captcha/controller.rb 0000644 0000041 0000041 00000002204 13576031220 023031 0 ustar www-data www-data module SimpleCaptcha #:nodoc
module ControllerHelpers #:nodoc
# This method is to validate the simple captcha in controller.
# It means when the captcha is controller based i.e. :object has not been passed to the method show_simple_captcha.
#
# *Example*
#
# If you want to save an object say @user only if the captcha is validated then do like this in action...
#
# if simple_captcha_valid?
# @user.save
# else
# flash[:notice] = "captcha did not match"
# redirect_to :action => "myaction"
# end
def simple_captcha_valid?
return true if SimpleCaptcha.always_pass
return @_simple_captcha_result unless !defined?(@_simple_captcha_result) || @_simple_captcha_result.nil?
if params[:captcha]
captcha_key = params[:captcha_key] || session[:captcha]
data = SimpleCaptcha::Utils::simple_captcha_value(captcha_key)
result = data == params[:captcha].delete(" ").upcase
SimpleCaptcha::Utils::simple_captcha_passed!(captcha_key) if result
@_simple_captcha_result = result
result
else
false
end
end
end
end
simple_captcha2-0.5.0/lib/simple_captcha/formtastic.rb 0000644 0000041 0000041 00000000572 13576031220 023027 0 ustar www-data www-data if defined? Formtastic
require 'formtastic/version'
if Formtastic::VERSION < '2.2'
raise 'Only Formtastic Version 2.2 or greater is supported by SimpleCaptcha'
end
class SimpleCaptchaInput
include Formtastic::Inputs::Base
def to_html
options.update :object => sanitized_object_name
builder.send(:show_simple_captcha, options)
end
end
end
simple_captcha2-0.5.0/lib/simple_captcha/middleware.rb 0000644 0000041 0000041 00000007663 13576031220 023001 0 ustar www-data www-data # encoding: utf-8
module SimpleCaptcha
class Middleware
include SimpleCaptcha::ImageHelpers
include SimpleCaptcha::ViewHelper
DEFAULT_SEND_FILE_OPTIONS = {
:type => 'application/octet-stream'.freeze,
:disposition => 'attachment'.freeze,
}.freeze
REFRESH_FORMATS = {
:jquery => %Q{
$("#%{id}").attr('src', '%{url}');
$("#%{captcha_hidden_field_id}").attr('value', '%{key}');
}.freeze,
:plain_javascript => %Q{
var img = document.getElementById("%{id}");
if (img != null) {
img.src = "%{url}";
}
var hidden = document.getElementById("%{captcha_hidden_field_id}");
if (hidden != null) {
hidden.value = "%{key}";
}
}.freeze,
:prototype => %Q{
$("%{id}").setAttribute('src', '%{url}');
$("%{captcha_hidden_field_id}").setAttribute('value', '%{key}');
}.freeze,
}.freeze
def initialize(app, options={})
@app = app
self
end
def call(env) # :nodoc:
if env["REQUEST_METHOD"] == "GET" && captcha_path?(env['PATH_INFO'])
request = Rack::Request.new(env)
if request.params.present? && request.params['code'].present?
make_image(env)
else
refresh_code(env)
end
else
@app.call(env)
end
end
protected
def make_image(env, headers = {}, status = 404)
request = Rack::Request.new(env)
code = request.params["code"]
body = []
if Utils::simple_captcha_value(code)
#status, headers, body = @app.call(env)
#status = 200
#body = generate_simple_captcha_image(code)
#headers['Content-Type'] = 'image/jpeg'
send_data(generate_simple_captcha_image(code), :type => 'image/jpeg', :disposition => 'inline', :filename => 'simple_captcha.jpg')
else
[status, headers, body]
end
end
def captcha_path?(request_path)
request_path.include?('/simple_captcha')
end
def send_file(path, options = {})
raise MissingFile, "Cannot read file #{path}" unless File.file?(path) and File.readable?(path)
options[:filename] ||= File.basename(path) unless options[:url_based_filename]
status = options[:status] || 200
headers = {"Content-Disposition" => "#{options[:disposition]}; filename='#{options[:filename]}'", "Content-Type" => options[:type], 'Content-Transfer-Encoding' => 'binary', 'Cache-Control' => 'private'}
response_body = File.open(path, "rb")
[status, headers, response_body]
end
def send_data(response_body, options = {})
status = options[:status] || 200
headers = {"Content-Disposition" => "#{options[:disposition]}; filename='#{options[:filename]}'", "Content-Type" => options[:type], 'Content-Transfer-Encoding' => 'binary', 'Cache-Control' => 'private'}
[status, headers, [response_body]]
end
def refresh_code(env)
request = Rack::Request.new(env)
request.session.delete :captcha
key = simple_captcha_key(nil, request)
options = {}
options[:field_value] = set_simple_captcha_data(key, options)
url = simple_captcha_image_url(key, options)
status = 200
id = request.params['id']
captcha_hidden_field_id = simple_captch_hidden_field_id(id)
format = SimpleCaptcha.refresh_format.to_sym
raise ::ArgumentError, "Format adapter '#{format}' is not available" unless format.in?(REFRESH_FORMATS)
body = REFRESH_FORMATS[format] % {id: id, url: url, captcha_hidden_field_id: captcha_hidden_field_id, key: key}
headers = {'Content-Type' => 'text/javascript; charset=utf-8', "Content-Disposition" => "inline; filename='captcha.js'", "Content-Length" => body.length.to_s}.merge(SimpleCaptcha.extra_response_headers)
[status, headers, [body]]
end
end
end
simple_captcha2-0.5.0/simple_captcha2.gemspec 0000644 0000041 0000041 00000006112 13576031220 021204 0 ustar www-data www-data #########################################################
# This file has been automatically generated by gem2tgz #
#########################################################
# -*- encoding: utf-8 -*-
# stub: simple_captcha2 0.5.0 ruby lib
Gem::Specification.new do |s|
s.name = "simple_captcha2".freeze
s.version = "0.5.0"
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
s.require_paths = ["lib".freeze]
s.authors = ["Pavlo Galeta".freeze, "Igor Galeta".freeze, "Stefan Wienert".freeze, "Konrad Mallok".freeze]
s.date = "2019-12-05"
s.description = "SimpleCaptcha is available to be used with Rails 3 + 4 or above and also it provides the backward compatibility with previous versions of Rails.".freeze
s.email = "stwienert@gmail.com".freeze
s.extra_rdoc_files = ["README.md".freeze]
s.files = ["README.md".freeze, "Rakefile".freeze, "lib/generators/USAGE".freeze, "lib/generators/simple_captcha_generator.rb".freeze, "lib/generators/templates/migration.rb".freeze, "lib/generators/templates/migration5.rb".freeze, "lib/generators/templates/migration_sequel.rb".freeze, "lib/generators/templates/partial.erb".freeze, "lib/generators/templates/partial.haml".freeze, "lib/simple_captcha.rb".freeze, "lib/simple_captcha/controller.rb".freeze, "lib/simple_captcha/engine.rb".freeze, "lib/simple_captcha/form_builder.rb".freeze, "lib/simple_captcha/formtastic.rb".freeze, "lib/simple_captcha/image.rb".freeze, "lib/simple_captcha/middleware.rb".freeze, "lib/simple_captcha/model_helpers.rb".freeze, "lib/simple_captcha/simple_captcha_data.rb".freeze, "lib/simple_captcha/simple_captcha_data_mongoid.rb".freeze, "lib/simple_captcha/simple_captcha_data_sequel.rb".freeze, "lib/simple_captcha/utils.rb".freeze, "lib/simple_captcha/version.rb".freeze, "lib/simple_captcha/view.rb".freeze, "lib/simple_captcha2.rb".freeze]
s.homepage = "http://github.com/pludoni/simple-captcha".freeze
s.rubygems_version = "2.5.2.1".freeze
s.summary = "SimpleCaptcha is the simplest and a robust captcha plugin.".freeze
if s.respond_to? :specification_version then
s.specification_version = 4
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
s.add_development_dependency(%q.freeze, [">= 0"])
s.add_development_dependency(%q.freeze, [">= 0"])
s.add_development_dependency(%q.freeze, [">= 0"])
s.add_runtime_dependency(%q.freeze, [">= 4.1"])
s.add_development_dependency(%q.freeze, [">= 0"])
else
s.add_dependency(%q.freeze, [">= 0"])
s.add_dependency(%q.freeze, [">= 0"])
s.add_dependency(%q.freeze, [">= 0"])
s.add_dependency(%q.freeze, [">= 4.1"])
s.add_dependency(%q.freeze, [">= 0"])
end
else
s.add_dependency(%q.freeze, [">= 0"])
s.add_dependency(%q.freeze, [">= 0"])
s.add_dependency(%q.freeze, [">= 0"])
s.add_dependency(%q.freeze, [">= 4.1"])
s.add_dependency(%q.freeze, [">= 0"])
end
end